23 namespace json_details {
24 template<
typename ParseState,
bool>
25 struct json_parse_kv_array_iterator_base {
26 using iterator_category = std::input_iterator_tag;
27 using difference_type = std::ptrdiff_t;
28 static constexpr bool has_counter =
false;
29 ParseState *parse_state =
nullptr;
32 template<
typename ParseState>
33 struct json_parse_kv_array_iterator_base<ParseState, true> {
34#if defined( DAW_JSON_HAS_CPP23_RANGE_CTOR )
35 using iterator_category = std::input_iterator_tag;
38 using iterator_category = std::random_access_iterator_tag;
40 using difference_type = std::ptrdiff_t;
41 static constexpr bool has_counter =
true;
42 ParseState *parse_state =
nullptr;
43 difference_type counter = 0;
45 explicit json_parse_kv_array_iterator_base( ) =
default;
47 explicit constexpr json_parse_kv_array_iterator_base(
48 daw::not_null<ParseState *> pd ) noexcept
50 , counter(
static_cast<difference_type
>( pd->counter ) ) {}
52 constexpr difference_type
53 operator-( json_parse_kv_array_iterator_base
const &rhs )
const {
61 template<
typename JsonMember,
typename ParseState,
bool KnownBounds>
62 struct json_parse_kv_array_iterator final
63 : json_parse_kv_array_iterator_base<
64 ParseState, can_be_random_iterator_v<KnownBounds>> {
66 using base = json_parse_kv_array_iterator_base<
67 ParseState, can_be_random_iterator_v<KnownBounds>>;
68 using iterator_category =
typename base::iterator_category;
69 using json_key_t =
typename JsonMember::json_key_t;
70 using json_element_t =
typename JsonMember::json_value_t;
71 using value_type = std::pair<json_result_t<json_key_t>
const,
72 json_result_t<json_element_t>>;
73 using reference = value_type;
74 using pointer = arrow_proxy<value_type>;
75 using parse_state_t = ParseState;
76 using difference_type =
typename base::difference_type;
78 using json_class_type =
typename JsonMember::json_class_t;
79 explicit json_parse_kv_array_iterator( ) =
default;
81 explicit constexpr json_parse_kv_array_iterator( parse_state_t &r )
83 if( DAW_UNLIKELY( base::parse_state->front( ) ==
']' ) ) {
84 if constexpr( not KnownBounds ) {
86 base::parse_state->remove_prefix( );
87 base::parse_state->trim_left_checked( );
90 base::parse_state =
nullptr;
94 static constexpr value_type
95 get_pair( json_result_t<json_class_type> &&v ) {
96 return value_type( std::get<0>( std::move( v.members ) ),
97 std::get<1>( std::move( v.members ) ) );
100 DAW_ATTRIB_NOINLINE value_type operator*( )
const {
105 DAW_ATTRIB_INLINE
constexpr value_type operator*( ) {
107 base::parse_state->has_more( ),
108 ErrorReason::UnexpectedEndOfData,
109 *base::parse_state );
112 parse_value<json_class_type, false, JsonParseTypes::Class>(
113 *base::parse_state ) );
116 DAW_ATTRIB_INLINE
constexpr json_parse_kv_array_iterator &
119 ErrorReason::UnexpectedEndOfData );
120 base::parse_state->trim_left( );
123 base::parse_state->has_more( ) and
124 base::parse_state->is_at_next_array_element( ),
125 ErrorReason::UnexpectedEndOfData,
126 *base::parse_state );
128 base::parse_state->move_next_member_or_end( );
130 ErrorReason::UnexpectedEndOfData );
131 if( DAW_UNLIKELY( base::parse_state->front( ) ==
']' ) ) {
132#if not defined( NDEBUG )
133 if constexpr( base::has_counter ) {
135 ErrorReason::UnexpectedEndOfData );
138 if constexpr( not KnownBounds ) {
140 base::parse_state->remove_prefix( );
141 base::parse_state->trim_left_checked( );
144 base::parse_state =
nullptr;
146#if not defined( NDEBUG )
147 if constexpr( base::has_counter ) {
149 ErrorReason::UnexpectedEndOfData );
156 DAW_ATTRIB_INLINE
constexpr void operator++(
int ) {
160 friend constexpr bool
161 operator==( json_parse_kv_array_iterator
const &lhs,
162 json_parse_kv_array_iterator
const &rhs ) {
163 return lhs.parse_state == rhs.parse_state;
166 friend constexpr bool
167 operator!=( json_parse_kv_array_iterator
const &lhs,
168 json_parse_kv_array_iterator
const &rhs ) {
169 return not( lhs == rhs );