26 namespace json_details {
27 template<
typename ParseState,
bool>
28 struct json_parse_kv_class_iterator_base {
29 using iterator_category = std::input_iterator_tag;
30 using difference_type = std::ptrdiff_t;
31 ParseState *parse_state =
nullptr;
34 template<
typename ParseState>
35 struct json_parse_kv_class_iterator_base<ParseState, true> {
36#if defined( DAW_JSON_HAS_CPP23_RANGE_CTOR )
37 using iterator_category = std::input_iterator_tag;
40 using iterator_category = std::random_access_iterator_tag;
42 using difference_type = std::ptrdiff_t;
43 ParseState *parse_state =
nullptr;
45 constexpr difference_type
46 operator-( json_parse_kv_class_iterator_base
const &rhs )
const {
47 if( rhs.parse_state ) {
48 return static_cast<difference_type
>( rhs.parse_state->counter );
54 namespace kv_class_iter_impl {
56 using container_value_t =
typename T::value_type;
58 template<
typename JsonMember>
59 using default_value_type =
60 std::pair<
typename JsonMember::json_key_t,
61 typename JsonMember::json_element_t>;
63 template<
typename JsonMember,
typename T>
64 using container_value_type_or =
65 daw::detected_or_t<default_value_type<JsonMember>, container_value_t,
69 template<
typename JsonMember,
typename ParseState,
bool IsKnown>
70 struct json_parse_kv_class_iterator
71 : json_parse_kv_class_iterator_base<ParseState,
72 can_be_random_iterator_v<IsKnown>> {
75 json_parse_kv_class_iterator_base<ParseState,
76 can_be_random_iterator_v<IsKnown>>;
77 using iterator_category =
typename base::iterator_category;
78 using element_t =
typename JsonMember::json_element_t;
79 using member_container_type = json_base_type_t<JsonMember>;
81 kv_class_iter_impl::container_value_type_or<JsonMember,
82 member_container_type>;
83 using reference = value_type;
84 using pointer = arrow_proxy<value_type>;
85 using iterator_range_t = ParseState;
86 using difference_type =
typename base::difference_type;
88 using key_t =
typename JsonMember::json_key_t;
89 using value_t =
typename JsonMember::json_element_t;
91 json_parse_kv_class_iterator( ) =
default;
93 constexpr explicit json_parse_kv_class_iterator( iterator_range_t &r )
96 ErrorReason::UnexpectedEndOfData );
97 if( base::parse_state->front( ) ==
'}' ) {
100 base::parse_state->remove_prefix( );
101 base::parse_state->trim_left_checked( );
104 base::parse_state =
nullptr;
108 [[noreturn]] DAW_ATTRIB_NOINLINE value_type operator*( )
const {
113 constexpr value_type operator*( ) {
115 base::parse_state->has_more( ),
116 ErrorReason::UnexpectedEndOfData,
117 *base::parse_state );
118 auto key = parse_value<key_t, false, key_t::expected_type>(
119 *base::parse_state );
120 name::name_parser::trim_end_of_name( *base::parse_state );
122 return json_class_constructor<value_type,
125 parse_value<value_t, false, value_t::expected_type>(
126 *base::parse_state ) );
129 constexpr json_parse_kv_class_iterator &operator++( ) {
131 ErrorReason::AttemptToAccessPastEndOfValue,
132 *base::parse_state );
133 base::parse_state->move_next_member_or_end( );
135 ErrorReason::UnexpectedEndOfData,
136 *base::parse_state );
137 if( base::parse_state->front( ) ==
'}' ) {
138#if not defined( NDEBUG )
139 if constexpr( IsKnown ) {
140 if( base::parse_state ) {
142 ErrorReason::AttemptToAccessPastEndOfValue,
143 *base::parse_state );
144 base::parse_state->counter--;
149 base::parse_state->remove_prefix( );
150 base::parse_state->trim_left_checked( );
152 base::parse_state =
nullptr;
154#if not defined( NDEBUG )
155 if constexpr( IsKnown ) {
156 if( base::parse_state ) {
158 ErrorReason::AttemptToAccessPastEndOfValue,
159 *base::parse_state );
160 base::parse_state->counter--;
167 DAW_ATTRIB_INLINE
constexpr void operator++(
int ) {
171 friend constexpr bool
172 operator==( json_parse_kv_class_iterator
const &lhs,
173 json_parse_kv_class_iterator
const &rhs ) {
175 return lhs.parse_state == rhs.base::parse_state;
178 friend constexpr bool
179 operator!=( json_parse_kv_class_iterator
const &lhs,
180 json_parse_kv_class_iterator
const &rhs ) {
181 return not( lhs == rhs );