32 namespace json_details {
46 template<
typename JsonMember,
typename ParseState>
47 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
48 parse_ordered_class_member( std::size_t &member_index,
49 ParseState &parse_state ) {
51 using json_member_t = ordered_member_subtype_t<JsonMember>;
53 parse_state.move_next_member_or_end( );
58 if constexpr( is_an_ordered_member_v<JsonMember> ) {
59 pocm_details::maybe_skip_members<is_json_nullable_v<json_member_t>>(
60 parse_state, member_index, JsonMember::member_index );
63 ErrorReason::UnexpectedEndOfData,
70 if( DAW_UNLIKELY( parse_state.front( ) ==
']' ) ) {
71 if constexpr( is_json_nullable_v<json_member_t> ) {
73 auto loc = ParseState{ };
74 return parse_value<json_member_t,
76 json_member_t::expected_type>( loc );
79 true, missing_member(
"ordered_class_member" ), parse_state );
82 return parse_value<json_member_t, false, json_member_t::expected_type>(
96 template<
typename JsonMember,
bool NeedsClassPositions,
98 [[nodiscard]]
constexpr json_result_t<JsonMember>
99 parse_class_member_impl( ParseState &parse_state,
100 find_result<ParseState> fr ) {
102 auto [loc, known] = fr;
106 if constexpr( NeedsClassPositions ) {
107 auto const cf = parse_state.class_first;
108 auto const cl = parse_state.class_last;
110 json_result_t<without_name<JsonMember>>> ) {
111 auto const after_parse = daw::on_scope_exit( [&] {
112 parse_state.class_first = cf;
113 parse_state.class_last = cl;
115 return parse_value<without_name<JsonMember>,
117 JsonMember::expected_type>( parse_state );
120 parse_value<without_name<JsonMember>,
122 JsonMember::expected_type>( parse_state );
123 parse_state.class_first = cf;
124 parse_state.class_last = cl;
128 return parse_value<without_name<JsonMember>,
130 JsonMember::expected_type>( parse_state );
134 if( loc.is_null( ) ) {
135 if constexpr( is_json_nullable_v<JsonMember> ) {
136 return parse_value_null<without_name<JsonMember>,
true>( loc );
139 missing_member( std::string_view(
140 std::data( JsonMember::name ),
141 std::size( JsonMember::name ) ) ),
147 return parse_value<without_name<JsonMember>,
149 JsonMember::expected_type>( loc );
152 template<std::size_t member_position,
typename JsonMember,
153 AllMembersMustExist must_exist,
bool NeedsClassPositions,
154 typename ParseState, std::size_t N,
bool B>
155 [[nodiscard]] DAW_ATTRIB_INLINE
constexpr json_result_t<JsonMember>
156 parse_class_member( ParseState &parse_state,
157 locations_info_t<N, B, typename ParseState::iterator> &locations ) {
158 parse_state.move_next_member_or_end( );
161 parse_state.is_at_next_class_member( ),
162 ErrorReason::MissingMemberNameOrEndOfClass,
165 return parse_class_member_impl<JsonMember, NeedsClassPositions>(
167 find_class_member<member_position, must_exist>(
170 is_json_nullable_v<JsonMember>,
171 JsonMember::name ) );
174 template<
bool IsExactClass,
typename ParseState,
typename OldClassPos>
175 DAW_ATTRIB_INLINE
static constexpr void
176 class_cleanup_now( ParseState &parse_state,
177 OldClassPos
const &old_class_pos ) {
179 ErrorReason::UnexpectedEndOfData,
181 parse_state.move_next_member_or_end( );
183 parse_state.move_to_next_class_member( );
184 if constexpr( IsExactClass ) {
186 ErrorReason::UnknownMember,
188 parse_state.remove_prefix( );
190 (void)parse_state.skip_class( );
194 parse_state.trim_left_checked( );
195 parse_state.set_class_position( old_class_pos );
205 template<
typename JsonClass,
typename... JsonMembers,
typename ParseState,
207 [[nodiscard]] DAW_ATTRIB_INLINE
constexpr json_result_t<JsonClass>
208 parse_json_class( ParseState &parse_state, std::index_sequence<Is...> ) {
209 static_assert( is_a_json_type_v<JsonClass> );
210 using T = json_result_t<JsonClass>;
211 using Constructor = json_constructor_t<JsonClass>;
212 static_assert( has_json_data_contract_trait_v<T>,
"Unexpected type" );
214 daw::constant<( all_json_members_must_exist_v<T, ParseState>
215 ? AllMembersMustExist::yes
216 : AllMembersMustExist::no )>;
218 parse_state.trim_left( );
221 ErrorReason::InvalidClassStart,
224 auto const old_class_pos = parse_state.get_class_position( );
225 parse_state.set_class_position( );
226 parse_state.remove_prefix( );
227 parse_state.trim_left( );
229 if constexpr(
sizeof...( JsonMembers ) == 0 ) {
231 class_cleanup_now<all_json_members_must_exist_v<T, ParseState>>(
232 parse_state, old_class_pos );
239 return construct_value_tp<T, Constructor>( parse_state,
243 using NeedClassPositions = std::bool_constant<(
244 ( must_be_class_member_v<typename JsonMembers::without_name> or
247#if defined( DAW_JSON_BUGFIX_MSVC_KNOWN_LOC_ICE_003 )
248 auto known_locations =
249 make_locations_info<ParseState, JsonMembers...>( );
251 auto known_locations = DAW_AS_CONSTANT(
252 ( make_locations_info<ParseState, JsonMembers...>( ) ) );
255 if constexpr( is_pinned_type_v<json_result_t<JsonClass>> ) {
259 auto const run_after_parse = daw::on_exit_success( [&] {
260 class_cleanup_now<all_json_members_must_exist_v<T, ParseState>>(
261 parse_state, old_class_pos );
263 (void)run_after_parse;
269 parse_class_member<Is,
270 daw::traits::nth_element<Is, JsonMembers...>,
272 NeedClassPositions::value>(
273 parse_state, known_locations )... };
275 return construct_value_tp<T, Constructor>(
277 fwd_pack{ parse_class_member<
279 daw::traits::nth_element<Is, JsonMembers...>,
281 NeedClassPositions::value>( parse_state,
282 known_locations )... } );
289 parse_class_member<Is,
290 daw::traits::nth_element<Is, JsonMembers...>,
292 NeedClassPositions::value>(
293 parse_state, known_locations )... };
295 class_cleanup_now<all_json_members_must_exist_v<T, ParseState>>(
296 parse_state, old_class_pos );
299 auto result = construct_value_tp<T, Constructor>(
301 fwd_pack{ parse_class_member<
303 daw::traits::nth_element<Is, JsonMembers...>,
305 NeedClassPositions::value>( parse_state,
306 known_locations )... } );
308 class_cleanup_now<all_json_members_must_exist_v<T, ParseState>>(
309 parse_state, old_class_pos );
315#if defined( DAW_JSON_HAS_REFLECTION )
316 template<
typename JsonClass,
typename... JsonMembers,
typename ParseState,
318 [[nodiscard]] DAW_ATTRIB_INLINE
constexpr json_result_t<JsonClass>
319 parse_json_reflected_class( ParseState &parse_state,
320 std::index_sequence<Is...> ) {
321 static_assert(
sizeof...( JsonMembers ) > 0 );
322 using T = json_result_t<JsonClass>;
323 static_assert( refl_details::PotentiallyReflectable<T> );
325 static constexpr auto must_exist =
326 all_json_members_must_exist_v<T, ParseState>
327 ? AllMembersMustExist::yes
328 : AllMembersMustExist::no;
330 parse_state.trim_left( );
333 ErrorReason::InvalidClassStart,
336 auto const old_class_pos = parse_state.get_class_position( );
337 parse_state.set_class_position( );
338 parse_state.remove_prefix( );
339 parse_state.trim_left( );
341 static constexpr auto NeedClassPositions =
342 ( must_be_class_member_v<typename JsonMembers::without_name> or ... );
344 auto known_locations =
345 make_locations_info<ParseState, JsonMembers...>( );
347 auto result = T{ parse_class_member<Is,
351 parse_state, known_locations )... };
353 class_cleanup_now<all_json_members_must_exist_v<T, ParseState>>(
354 parse_state, old_class_pos );
363 template<
typename JsonClass,
typename... JsonMembers,
typename ParseState>
364 [[nodiscard]]
static constexpr json_result_t<JsonClass>
365 parse_json_tuple_class( ParseState &parse_state ) {
366 static_assert( is_a_json_type_v<JsonClass> );
367 using T = json_base_type_t<JsonClass>;
368 using Constructor = json_constructor_t<JsonClass>;
369 static_assert( has_json_data_contract_trait_v<T>,
"Unexpected type" );
371 daw::is_callable_v<Constructor, json_result_t<JsonMembers>...>,
372 "Supplied types cannot be used for construction of this type" );
374 parse_state.trim_left( );
376 ErrorReason::InvalidArrayStart,
378 auto const old_class_pos = parse_state.get_class_position( );
379 parse_state.set_class_position( );
380 parse_state.remove_prefix( );
381 parse_state.trim_left( );
383 std::size_t current_idx = 0;
385 if constexpr( is_pinned_type_v<json_result_t<JsonClass>> ) {
386 auto const run_after_parse = daw::on_exit_success( [&] {
387 ordered_class_cleanup<all_json_members_must_exist_v<T, ParseState>,
389 decltype( old_class_pos )>( parse_state,
392 (void)run_after_parse;
396 return T{ parse_ordered_class_member<JsonMembers>(
397 current_idx, parse_state )... };
399 return construct_value_tp<T, Constructor>(
401 fwd_pack{ parse_ordered_class_member<JsonMembers>(
402 current_idx, parse_state )... } );
409 return T{ parse_ordered_class_member<JsonMembers>(
410 current_idx, parse_state )... };
412 return construct_value_tp<T, Constructor>(
414 fwd_pack{ parse_ordered_class_member<JsonMembers>(
415 current_idx, parse_state )... } );
418 if constexpr( all_json_members_must_exist_v<T, ParseState> ) {
419 parse_state.trim_left( );
421 ErrorReason::UnknownMember,
423 parse_state.remove_prefix( );
424 parse_state.trim_left( );
426 (void)parse_state.skip_array( );
428 parse_state.set_class_position( old_class_pos );