48 namespace json_details {
60 template<options::LiteralAsStringOpt literal_as_string,
61 bool AtEnd =
false,
typename ParseState>
62 DAW_ATTRIB_INLINE
constexpr void
63 skip_quote_when_literal_as_string( ParseState &parse_state ) {
64 if constexpr( literal_as_string ==
65 options::LiteralAsStringOpt::Always ) {
67 ErrorReason::InvalidNumberUnexpectedQuoting,
69 parse_state.remove_prefix( );
70 }
else if constexpr( literal_as_string ==
71 options::LiteralAsStringOpt::Maybe ) {
72 if constexpr( not AtEnd ) {
74 ErrorReason::UnexpectedEndOfData,
77 if( parse_state.has_more( ) and parse_state.front( ) ==
'"' ) {
78 parse_state.remove_prefix( );
83 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
84 [[nodiscard]]
constexpr json_result_t<JsonMember>
85 parse_value_real( ParseState &parse_state ) {
86 using constructor_t = json_constructor_t<JsonMember>;
87 using element_t = json_base_type_t<JsonMember>;
89 if constexpr( JsonMember::literal_as_string !=
90 options::LiteralAsStringOpt::Never ) {
91 if constexpr( not KnownBounds ) {
92 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
95 if constexpr( JsonMember::allow_number_errors ==
96 options::JsonNumberErrors::AllowInf or
97 JsonMember::allow_number_errors ==
98 options::JsonNumberErrors::AllowNanInf ) {
99 element_t sign = element_t( 1.0 );
100 if( parse_state.front( ) ==
'-' ) {
101 sign = element_t( -1.0 );
105 if( parse_state.starts_with_skip(
"Inf" ) ) {
106 if( not( parse_state.starts_with_skip(
"\"" ) or
107 parse_state.starts_with_skip(
"inity\"" ) ) ) {
110 if constexpr( KnownBounds ) {
112 ErrorReason::InvalidNumber,
116 parse_policy_details::at_end_of_item(
117 parse_state.front( ) ),
118 ErrorReason::InvalidEndOfValue,
121 return daw::cxmath::copy_sign(
122 daw::numeric_limits<element_t>::infinity( ), sign );
123 }
else if( sign < element_t( 0 ) ) {
127 if constexpr( JsonMember::allow_number_errors ==
128 options::JsonNumberErrors::AllowNaN or
129 JsonMember::allow_number_errors ==
130 options::JsonNumberErrors::AllowNanInf ) {
131 if( parse_state.starts_with(
"NaN" ) ) {
132 parse_state.template move_to_next_of<
'"'>( );
133 parse_state.remove_prefix( );
134 if constexpr( KnownBounds ) {
136 ErrorReason::InvalidNumber,
140 parse_policy_details::at_end_of_item(
141 parse_state.front( ) ),
142 ErrorReason::InvalidEndOfValue,
145 return daw::numeric_limits<element_t>::quiet_NaN( );
149 if constexpr( KnownBounds and JsonMember::literal_as_string ==
150 options::LiteralAsStringOpt::Never ) {
151 return construct_value<json_result_t<JsonMember>, constructor_t>(
152 parse_state, parse_real<element_t, true>( parse_state ) );
155 parse_state.has_more( ) and
156 parse_policy_details::is_number_start( parse_state.front( ) ),
157 ErrorReason::InvalidNumberStart,
161 construct_value<json_result_t<JsonMember>, constructor_t>(
162 parse_state, parse_real<element_t, false>( parse_state ) );
164 if constexpr( KnownBounds ) {
166 parse_state.empty( ) or
167 parse_policy_details::at_end_of_item( parse_state.front( ) ),
168 ErrorReason::InvalidEndOfValue,
171 if constexpr( JsonMember::literal_as_string !=
172 options::LiteralAsStringOpt::Never ) {
173 skip_quote_when_literal_as_string<JsonMember::literal_as_string,
174 true>( parse_state );
177 parse_state.empty( ) or
178 parse_policy_details::at_end_of_item( parse_state.front( ) ),
179 ErrorReason::InvalidEndOfValue,
186 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
187 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
188 parse_value_signed( ParseState &parse_state ) {
189 using constructor_t = json_constructor_t<JsonMember>;
190 using element_t = json_base_type_t<JsonMember>;
192 typename daw::conditional_t<std::is_enum_v<element_t>,
193 std::underlying_type<element_t>,
194 daw::traits::identity<element_t>>::type;
196 static_assert( daw::is_signed_v<int_type>,
"Expected signed type" );
197 if constexpr( KnownBounds ) {
199 parse_policy_details::is_number_start( parse_state.front( ) ),
200 ErrorReason::InvalidNumberStart,
203 if constexpr( JsonMember::literal_as_string !=
204 options::LiteralAsStringOpt::Never ) {
205 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
207 }
else if constexpr( not ParseState::is_zero_terminated_string ) {
209 ErrorReason::UnexpectedEndOfData,
213 auto const sign =
static_cast<int_type
>(
214 parse_policy_details::validate_signed_first( parse_state ) );
216 typename daw::conditional_t<daw::is_system_integral_v<int_type>,
217 daw::make_unsigned<int_type>,
218 daw::traits::identity<int_type>>::type;
219 auto parsed_val = to_signed(
220 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
224 if constexpr( KnownBounds ) {
225 return construct_value<json_result_t<JsonMember>, constructor_t>(
226 parse_state,
static_cast<element_t
>( parsed_val ) );
229 construct_value<json_result_t<JsonMember>, constructor_t>(
230 parse_state,
static_cast<element_t
>( parsed_val ) );
231 if constexpr( JsonMember::literal_as_string !=
232 options::LiteralAsStringOpt::Never ) {
233 skip_quote_when_literal_as_string<JsonMember::literal_as_string,
234 true>( parse_state );
236 parse_state.trim_left( );
238 not parse_state.has_more( ) or
239 parse_policy_details::at_end_of_item( parse_state.front( ) ),
240 ErrorReason::InvalidEndOfValue,
246 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
247 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
248 parse_value_unsigned( ParseState &parse_state ) {
249 using constructor_t = json_constructor_t<JsonMember>;
250 using element_t = json_base_type_t<JsonMember>;
252 typename daw::conditional_t<std::is_enum_v<element_t>,
253 std::underlying_type<element_t>,
254 daw::traits::identity<element_t>>::type;
256 if constexpr( KnownBounds ) {
257 parse_policy_details::validate_unsigned_first( parse_state );
259 return construct_value<json_result_t<JsonMember>, constructor_t>(
261 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
264 if constexpr( JsonMember::literal_as_string !=
265 options::LiteralAsStringOpt::Never ) {
266 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
268 if constexpr( not ParseState::is_zero_terminated_string ) {
270 ErrorReason::UnexpectedEndOfData,
273 }
else if constexpr( not ParseState::is_zero_terminated_string ) {
275 ErrorReason::UnexpectedEndOfData,
279 parse_policy_details::is_number( parse_state.front( ) ),
280 ErrorReason::InvalidNumber,
283 construct_value<json_result_t<JsonMember>, constructor_t>(
285 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
287 if constexpr( JsonMember::literal_as_string !=
288 options::LiteralAsStringOpt::Never ) {
289 skip_quote_when_literal_as_string<JsonMember::literal_as_string,
290 true>( parse_state );
293 not parse_state.has_more( ) or
294 parse_policy_details::at_end_of_item( parse_state.front( ) ),
295 ErrorReason::InvalidEndOfValue,
301 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
302 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
303 parse_value_null( ParseState &parse_state ) {
305 using constructor_t = json_constructor_t<JsonMember>;
306 auto const construct_empty = [&] {
307 if constexpr( daw::is_callable_v<
309 concepts::construct_nullable_with_empty_t> ) {
310 return construct_value<
typename JsonMember::wrapped_type,
312 parse_state, concepts::construct_nullable_with_empty );
314 return construct_value<
typename JsonMember::wrapped_type,
315 constructor_t>( parse_state );
319 using base_member_type =
typename JsonMember::member_type;
320 static_assert( not std::is_same_v<base_member_type, JsonMember> );
321 if constexpr( KnownBounds ) {
323 if( parse_state.is_null( ) ) {
324 return construct_empty( );
326 return construct_value<base_member_type, constructor_t>(
328 parse_value<base_member_type,
330 base_member_type::expected_type>( parse_state ) );
331 }
else if constexpr( ParseState::is_unchecked_input ) {
332 if( not parse_state.has_more( ) or
333 parse_state.is_at_token_after_value( ) ) {
334 return construct_empty( );
336 if( parse_state.front( ) ==
'n' ) {
337 parse_state.remove_prefix( 4 );
338 parse_state.trim_left_unchecked( );
339 parse_state.remove_prefix( );
340 return construct_empty( );
342 return construct_value<base_member_type, constructor_t>(
344 parse_value<base_member_type,
346 base_member_type::expected_type>( parse_state ) );
348 if( parse_state.is_null( ) or not parse_state.has_more( ) or
349 parse_state.is_at_token_after_value( ) ) {
350 return construct_empty( );
352 if( parse_state.starts_with(
"null" ) ) {
353 parse_state.remove_prefix( 4 );
355 not parse_state.has_more( ) or
356 parse_policy_details::at_end_of_item( parse_state.front( ) ),
357 ErrorReason::InvalidLiteral,
359 parse_state.trim_left_checked( );
360 return construct_empty( );
362 using parse_to_t = json_result_t<base_member_type>;
363 if constexpr( not std::is_move_constructible_v<parse_to_t> and
364 not std::is_copy_constructible_v<parse_to_t> ) {
367 concepts::nullable_value_traits<json_result_t<JsonMember>>,
368 concepts::construct_nullable_with_pointer_t,
370 return construct_value<base_member_type, constructor_t>(
372 concepts::construct_nullable_with_pointer,
374 parse_value<base_member_type,
376 base_member_type::expected_type>( parse_state ) } );
378 return construct_value<base_member_type, constructor_t>(
380 parse_value<base_member_type,
382 base_member_type::expected_type>( parse_state ) );
387 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
388 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
389 parse_value_bool( ParseState &parse_state ) {
390 using constructor_t = json_constructor_t<JsonMember>;
392 if constexpr( KnownBounds ) {
394 if constexpr( ParseState::is_unchecked_input ) {
395 return static_cast<bool>( parse_state.counter );
397 switch( parse_state.front( ) ) {
399 return construct_value<json_result_t<JsonMember>, constructor_t>(
402 return construct_value<json_result_t<JsonMember>, constructor_t>(
403 parse_state, false );
409 if constexpr( JsonMember::literal_as_string !=
410 options::LiteralAsStringOpt::Never ) {
411 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
415 if constexpr( ParseState::is_unchecked_input ) {
416 if( parse_state.front( ) ==
't' ) {
418 parse_state.remove_prefix( 4 );
420 parse_state.remove_prefix( 5 );
423 if( parse_state.starts_with(
"true" ) ) {
424 parse_state.remove_prefix( 4 );
426 }
else if( parse_state.starts_with(
"false" ) ) {
427 parse_state.remove_prefix( 5 );
433 if constexpr( JsonMember::literal_as_string !=
434 options::LiteralAsStringOpt::Never ) {
435 skip_quote_when_literal_as_string<JsonMember::literal_as_string,
436 true>( parse_state );
438 parse_state.trim_left( );
440 not parse_state.has_more( ) or
441 parse_policy_details::at_end_of_item( parse_state.front( ) ),
442 ErrorReason::InvalidEndOfValue,
444 return construct_value<json_result_t<JsonMember>, constructor_t>(
445 parse_state, result );
449 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
450 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
451 parse_value_string_raw( ParseState &parse_state ) {
453 using constructor_t = json_constructor_t<JsonMember>;
454 if constexpr( KnownBounds ) {
455 return construct_value<json_result_t<JsonMember>, constructor_t>(
456 parse_state, std::data( parse_state ), std::size( parse_state ) );
458 if constexpr( JsonMember::allow_escape_character ==
459 options::AllowEscapeCharacter::Allow ) {
460 auto const str = skip_string( parse_state );
461 return construct_value<json_result_t<JsonMember>, constructor_t>(
462 parse_state, std::data( str ), std::size( str ) );
464 parse_state.remove_prefix( );
466 char const *
const first = parse_state.first;
467 parse_state.template move_to_next_of<
'"'>( );
468 char const *
const last = parse_state.first;
469 parse_state.remove_prefix( );
470 return construct_value<json_result_t<JsonMember>, constructor_t>(
471 parse_state, first,
static_cast<std::size_t
>( last - first ) );
482 template<
typename JsonMember>
483 DAW_CPP20_CONCEPT can_parse_to_stdstring_fast_v =
484 can_single_allocation_string_v<json_result_t<JsonMember>> or
485 can_single_allocation_string_v<json_base_type_t<JsonMember>>;
488 json_constructor_t<T> );
493 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
494 [[nodiscard]] DAW_ATTRIB_INLINE
constexpr json_result_t<JsonMember>
495 parse_value_string_escaped( ParseState &parse_state ) {
496 static_assert( has_json_member_constructor_v<JsonMember> );
497 static_assert( has_json_member_parse_to_v<JsonMember> );
498 if constexpr( not KnownBounds ) {
500 ErrorReason::UnexpectedNull );
502 using constructor_t = json_constructor_t<JsonMember>;
503 if constexpr( can_parse_to_stdstring_fast_v<JsonMember> ) {
504 using AllowHighEightbits =
505 std::bool_constant<JsonMember::eight_bit_mode !=
506 options::EightBitModes::DisallowHigh>;
508 KnownBounds ? parse_state : skip_string( parse_state );
509 if( not AllowHighEightbits::value or
510 needs_slow_path( parse_state2 ) ) {
512 return parse_string_known_stdstring<AllowHighEightbits::value,
514 true>( parse_state2 );
518 return construct_value<json_result_t<JsonMember>, constructor_t>(
520 std::data( parse_state2 ),
521 daw::data_end( parse_state2 ) );
524 KnownBounds ? parse_state : skip_string( parse_state );
525 using AllowHighEightbits =
526 std::bool_constant<JsonMember::eight_bit_mode !=
527 options::EightBitModes::DisallowHigh>;
528 if( not AllowHighEightbits::value or
529 needs_slow_path( parse_state2 ) ) {
531 return parse_string_known_stdstring<AllowHighEightbits::value,
533 true>( parse_state2 );
537 return construct_value<json_result_t<JsonMember>, constructor_t>(
539 std::data( parse_state2 ),
540 daw::data_end( parse_state2 ) );
544 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
545 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
546 parse_value_date( ParseState &parse_state ) {
549 ErrorReason::UnexpectedEndOfData,
551 auto str = KnownBounds ? parse_state : skip_string( parse_state );
552 using constructor_t = json_constructor_t<JsonMember>;
553 return construct_value<json_result_t<JsonMember>, constructor_t>(
554 parse_state, std::data( str ), std::size( str ) );
557 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
558 [[nodiscard]]
static constexpr json_result_t<JsonMember>
559 parse_value_custom( ParseState &parse_state ) {
561 auto const str = [&] {
562 if constexpr( JsonMember::custom_json_type ==
563 options::JsonCustomTypes::String ) {
564 if constexpr( KnownBounds ) {
567 return skip_string( parse_state );
569 }
else if constexpr( JsonMember::custom_json_type ==
570 options::JsonCustomTypes::Literal ) {
571 return KnownBounds ? parse_state : skip_literal( parse_state );
573 static_assert( JsonMember::custom_json_type ==
574 options::JsonCustomTypes::Any );
578 if constexpr( KnownBounds ) {
579 auto result = parse_state;
580 if( *( result.first - 1 ) ==
'"' ) {
585 if( parse_state.front( ) ==
'"' ) {
586 auto result = skip_string( parse_state );
590 return skip_value( parse_state );
595 str.has_more( ) and not( str.front( ) ==
'[' or str.front( ) ==
'{' ),
596 ErrorReason::InvalidStartOfValue,
598 using constructor_t =
typename JsonMember::from_converter_t;
599 return construct_value<json_result_t<JsonMember>, constructor_t>(
600 parse_state, std::string_view( std::data( str ), std::size( str ) ) );
603 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
604 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
605 parse_value_class( ParseState &parse_state ) {
607 using element_t =
typename JsonMember::wrapped_type;
609 ErrorReason::UnexpectedEndOfData,
612 if constexpr( is_deduced_empty_class_v<JsonMember> ) {
613 if constexpr( not KnownBounds ) {
614 auto const old_class_pos = parse_state.get_class_position( );
615 parse_state.set_class_position( );
616 parse_state.remove_prefix( );
617 parse_state.trim_left( );
618 parse_state.trim_left_checked( );
619 parse_state.move_next_member_or_end( );
620 parse_state.move_to_next_class_member( );
621 (void)parse_state.skip_class( );
622 parse_state.trim_left_checked( );
623 parse_state.set_class_position( old_class_pos );
625 return json_result_t<JsonMember>{ };
626 }
else if constexpr( KnownBounds ) {
628 template parse_to_class<JsonMember, KnownBounds>( parse_state );
629 }
else if constexpr( is_pinned_type_v<element_t> ) {
630 auto const run_after_parse = daw::on_exit_success( [&] {
631 parse_state.trim_left_checked( );
633 (void)run_after_parse;
635 template parse_to_class<JsonMember, KnownBounds>( parse_state );
638 template parse_to_class<JsonMember, KnownBounds>( parse_state );
639 parse_state.trim_left_checked( );
644#if defined( DAW_JSON_HAS_REFLECTION )
645 template<
typename JsonMember,
bool ,
typename ParseState>
646 constexpr json_result_t<JsonMember>
647 parse_value_reflected_class( ParseState &parse_state ) {
649 ErrorReason::UnexpectedEndOfData,
652 return JsonMember::parse_to_class( parse_state );
664 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
665 [[nodiscard]]
static constexpr json_result_t<JsonMember>
666 parse_value_keyvalue( ParseState &parse_state ) {
668 static_assert( JsonMember::expected_type == JsonParseTypes::KeyValue,
669 "Expected a json_key_value" );
671 ErrorReason::ExpectedKeyValueToStartWithBrace,
674 parse_state.remove_prefix( );
675 parse_state.trim_left( );
678 json_parse_kv_class_iterator<JsonMember,
680 can_be_random_iterator_v<KnownBounds>>;
682 using constructor_t = json_constructor_t<JsonMember>;
683 return construct_value<json_result_t<JsonMember>, constructor_t>(
684 parse_state, iter_t( parse_state ), iter_t( ) );
695 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
696 [[nodiscard]]
static constexpr json_result_t<JsonMember>
697 parse_value_keyvalue_array( ParseState &parse_state ) {
699 static_assert( JsonMember::expected_type ==
700 JsonParseTypes::KeyValueArray,
701 "Expected a json_key_value" );
703 parse_state.is_opening_bracket_checked( ),
704 ErrorReason::ExpectedKeyValueArrayToStartWithBracket,
707 parse_state.remove_prefix( );
710 json_parse_kv_array_iterator<JsonMember,
712 can_be_random_iterator_v<KnownBounds>>;
713 using constructor_t = json_constructor_t<JsonMember>;
714 return construct_value<json_result_t<JsonMember>, constructor_t>(
715 parse_state, iter_t( parse_state ), iter_t( ) );
718 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
719 [[nodiscard]]
static constexpr json_result_t<JsonMember>
720 parse_value_array( ParseState &parse_state ) {
721 parse_state.trim_left( );
723 ErrorReason::InvalidArrayStart,
725 parse_state.remove_prefix( );
726 parse_state.trim_left_unchecked( );
731 json_parse_array_iterator<JsonMember,
733 can_be_random_iterator_v<KnownBounds>>;
734 using constructor_t = json_constructor_t<JsonMember>;
735 return construct_value<json_result_t<JsonMember>, constructor_t>(
736 parse_state, iterator_t( parse_state ), iterator_t( ) );
739 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
740 [[nodiscard]]
static constexpr json_result_t<JsonMember>
741 parse_value_sz_array( ParseState &parse_state ) {
743 using size_member = dependent_member_t<JsonMember>;
745 auto [parse_state2, is_found] = find_range<ParseState>(
746 ParseState( parse_state.class_first, parse_state.last ),
750 is_found, ErrorReason::TagMemberNotFound, parse_state );
752 parse_value<size_member, false, size_member::expected_type>(
755 if constexpr( KnownBounds and ParseState::is_unchecked_input ) {
758 auto cnt =
static_cast<std::ptrdiff_t
>( parse_state.counter );
760 ErrorReason::NumberOutOfRange,
763 parse_state.trim_left( );
765 ErrorReason::InvalidArrayStart,
767 parse_state.remove_prefix( );
768 parse_state.trim_left_unchecked( );
772 json_parse_array_iterator<JsonMember, ParseState, false>;
773 using constructor_t = json_constructor_t<JsonMember>;
774 return construct_value<json_result_t<JsonMember>, constructor_t>(
776 iterator_t( parse_state ),
778 static_cast<std::size_t
>( sz ) );
783 [[nodiscard]]
constexpr json_result_t<JsonMembers>
784 parse_variant_value( ParseState &parse_state ) {
785 using element_t =
typename JsonMembers::json_elements;
786 using idx = daw::constant<( JsonMembers::base_map::base_map
787 [
static_cast<std::int_fast8_t
>( BPT )] )>;
789 if constexpr( idx::value <
790 pack_size_v<typename element_t::element_map_t> ) {
792 pack_element_t<idx::value, typename element_t::element_map_t>;
793 return parse_value<JsonMember,
795 JsonMember::expected_type>( parse_state );
801 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
802 [[nodiscard]]
static constexpr json_result_t<JsonMember>
803 parse_value_variant( ParseState &parse_state ) {
804 if constexpr( KnownBounds ) {
807 if( *( parse_state.first - 1 ) ==
'"' ) {
809 return parse_variant_value<JsonBaseParseTypes::String,
811 KnownBounds>( parse_state );
814 switch( parse_state.front( ) ) {
816 return parse_variant_value<JsonBaseParseTypes::Class,
818 KnownBounds>( parse_state );
820 return parse_variant_value<JsonBaseParseTypes::Array,
822 KnownBounds>( parse_state );
825 return parse_variant_value<JsonBaseParseTypes::Bool,
827 KnownBounds>( parse_state );
829 return parse_variant_value<JsonBaseParseTypes::String,
831 KnownBounds>( parse_state );
844 return parse_variant_value<JsonBaseParseTypes::Number,
846 KnownBounds>( parse_state );
848 if constexpr( ParseState::is_unchecked_input ) {
851 daw_json_error(
true, ErrorReason::InvalidStartOfValue, parse_state );
855 template<
typename Result,
typename TypeList, std::size_t pos = 0,
857 DAW_ATTRIB_INLINE
constexpr Result
858 parse_visit( std::size_t idx, ParseState &parse_state ) {
860 using JsonMember = pack_element_t<pos, TypeList>;
861 if constexpr( std::is_same_v<json_result_t<JsonMember>, Result> ) {
862 return parse_value<JsonMember, false, JsonMember::expected_type>(
866 parse_value<JsonMember, false, JsonMember::expected_type>(
870 if constexpr( pos + 1 < pack_size_v<TypeList> ) {
871 return parse_visit<Result, TypeList, pos + 1>( idx, parse_state );
873 if constexpr( ParseState::is_unchecked_input ) {
877 true, ErrorReason::MissingMemberNameOrEndOfClass, parse_state );
882 template<
typename JsonMember,
typename ParseState>
883 [[nodiscard]]
constexpr auto find_index( ParseState
const &parse_state ) {
884 using tag_member =
typename JsonMember::tag_member;
885 using class_wrapper_t =
typename JsonMember::tag_member_class_wrapper;
887 using switcher_t =
typename JsonMember::switcher;
888 auto parse_state2 = ParseState( parse_state.class_first,
889 parse_state.class_last,
890 parse_state.class_first,
891 parse_state.class_last );
892 if constexpr( is_an_ordered_member_v<tag_member> ) {
895 ErrorReason::InvalidArrayStart,
897 return switcher_t{ }( std::get<0>(
898 parse_value<class_wrapper_t, false, class_wrapper_t::expected_type>(
903 ErrorReason::InvalidClassStart,
905 return switcher_t{ }( std::get<0>(
906 parse_value<class_wrapper_t, false, class_wrapper_t::expected_type>(
912 template<
typename JsonMember,
typename ParseState>
913 [[nodiscard]]
constexpr json_result_t<JsonMember>
914 parse_value_variant_tagged( ParseState &parse_state ) {
915 auto const index = find_index<JsonMember>( parse_state );
916 return parse_visit<json_result_t<JsonMember>,
917 typename JsonMember::json_elements::element_map_t>(
918 index, parse_state );
921 template<
typename JsonMember,
typename ParseState>
922 [[nodiscard]]
constexpr json_result_t<JsonMember>
923 parse_value_variant_intrusive( ParseState &parse_state ) {
924 auto const index = [&] {
925 using tag_submember =
typename JsonMember::tag_submember;
926 using class_wrapper_t =
927 typename JsonMember::tag_submember_class_wrapper;
928 auto parse_state2 = parse_state;
929 using switcher_t =
typename JsonMember::switcher;
930 if constexpr( is_an_ordered_member_v<tag_submember> ) {
931 return switcher_t{ }( std::get<0>(
932 parse_value<class_wrapper_t,
934 class_wrapper_t::expected_type>( parse_state2 ) ) );
936 return switcher_t{ }( std::get<0>(
937 parse_value<class_wrapper_t,
939 class_wrapper_t::expected_type>( parse_state2 )
944 return parse_visit<json_result_t<JsonMember>,
945 typename JsonMember::json_elements::element_map_t>(
946 index, parse_state );
949 template<
bool AllMembersMustExist,
typename ParseState,
950 typename OldClassPos>
951 DAW_ATTRIB_INLINE
constexpr void ordered_class_cleanup(
952 ParseState &parse_state,
955 if constexpr( AllMembersMustExist ) {
956 parse_state.trim_left( );
958 ErrorReason::UnknownMember,
960 parse_state.remove_prefix( );
961 parse_state.trim_left_checked( );
963 (void)parse_state.skip_array( );
965 parse_state.set_class_position( old_class_pos );
968 namespace pocm_details {
976 template<
bool Nullable,
typename ParseState>
977 constexpr void maybe_skip_members( ParseState &parse_state,
978 std::size_t ¤t_position,
979 std::size_t desired_position ) {
982 ErrorReason::OutOfOrderOrderedMembers,
984 using skip_check_end =
985 std::bool_constant<( ParseState::is_unchecked_input and Nullable )>;
986 while( ( current_position < desired_position ) &
987 ( skip_check_end::value or parse_state.front( ) !=
']' ) ) {
988 (void)skip_value( parse_state );
989 parse_state.move_next_member_or_end( );
992 ErrorReason::UnexpectedEndOfData,
997#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
998 template<
typename ParseState>
999 struct position_info {
1001 ParseState state{ };
1003 constexpr explicit operator bool( )
const {
1004 return not state.is_null( );
1015 template<
bool Nullable,
typename ParseState, std::
size_t N>
1016 DAW_ATTRIB_INLINE
static constexpr ParseState maybe_skip_members(
1017 ParseState &parse_state, std::size_t ¤t_position,
1018 std::size_t desired_position,
1019 std::array<position_info<ParseState>, N> &parse_locations ) {
1021 auto const desired = daw::algorithm::find_if(
1022 std::data( parse_locations ),
1023 daw::data_end( parse_locations ),
1024 [desired_position]( position_info<ParseState>
const &loc ) {
1025 return loc.index == desired_position;
1028 return desired->state;
1030#if not defined( NDEBUG )
1032 ErrorReason::UnexpectedEndOfData,
1035 using skip_check_end =
1036 std::bool_constant<( ParseState::is_unchecked_input and Nullable )>;
1037 while( ( current_position < desired_position ) &
1038 ( skip_check_end::value or parse_state.front( ) !=
']' ) ) {
1039 auto const current = daw::algorithm::find_if(
1040 std::data( parse_locations ),
1041 daw::data_end( parse_locations ),
1042 [current_position]( position_info<ParseState>
const &loc ) {
1043 return loc.index == current_position;
1045 auto state = skip_value( parse_state );
1046 if( current != daw::data_end( parse_locations ) ) {
1047 current->state = state;
1049 parse_state.move_next_member_or_end( );
1052 ErrorReason::UnexpectedEndOfData,
1060 template<
typename T>
1061 struct member_index_t {
1062 static constexpr std::size_t value = T::member_index;
1065 template<
typename Idx,
typename JsonMember>
1066 inline constexpr std::size_t member_index_v =
1067 daw::conditional_t<has_member_index_v<JsonMember>,
1068 member_index_t<JsonMember>, Idx>::value;
1071 template<
typename JsonMember,
bool KnownBounds,
typename ParseState,
1073 DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1074 parse_tuple_value( ParseState &parse_state, std::index_sequence<Is...> ) {
1075 parse_state.trim_left( );
1077 ErrorReason::InvalidArrayStart,
1080 auto const old_class_pos = parse_state.get_class_position( );
1081 parse_state.set_class_position( );
1082 parse_state.remove_prefix( );
1083 parse_state.move_next_member_or_end( );
1084 using tuple_t = json_base_type_t<JsonMember>;
1085 using tuple_members =
typename JsonMember::sub_member_list;
1087#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1088 using position_info_t = pocm_details::position_info<ParseState>;
1089 std::size_t parse_locations_last_index = 0U;
1090 std::array<position_info_t,
sizeof...( Is )> parse_locations{
1091 [&](
auto Index )
mutable -> position_info_t {
1092 constexpr std::size_t index =
decltype( Index )::value;
1093 using member_t = std::tuple_element_t<index, tuple_members>;
1094 if constexpr( is_an_ordered_member_v<member_t> ) {
1095 parse_locations_last_index = member_t::member_index;
1096 return { member_t::member_index };
1098 return { parse_locations_last_index++ };
1100 }(daw::constant_v<Is>)... };
1102 auto const parse_value_help = [&](
auto PackIdx,
1103 std::size_t &ClassIdx ) {
1104 using index_t =
decltype( PackIdx );
1105 using CurrentMember =
1106 std::tuple_element_t<index_t::value, tuple_members>;
1108 using json_member_t = ordered_member_subtype_t<CurrentMember>;
1110#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1111 ParseState parse_state2 =
1112 pocm_details::maybe_skip_members<is_json_nullable_v<json_member_t>>(
1115 pocm_details::member_index_v<index_t, CurrentMember>,
1117 if constexpr(
sizeof...( Is ) > 1 ) {
1119 if( parse_state2.first == parse_state.first ) {
1120 if constexpr( is_pinned_type_v<json_result_t<JsonMember>> ) {
1121 auto const run_after_parse = daw::on_exit_success( [&] {
1122 parse_state.move_next_member_or_end( );
1124 (void)run_after_parse;
1125 return parse_value<json_member_t,
1127 json_member_t::expected_type>( parse_state );
1130 parse_value<json_member_t,
1132 json_member_t::expected_type>( parse_state );
1133 parse_state.move_next_member_or_end( );
1138 return parse_value<json_member_t,
1140 json_member_t::expected_type>( parse_state2 );
1144 if constexpr( is_an_ordered_member_v<CurrentMember> ) {
1145 pocm_details::maybe_skip_members<
1146 is_json_nullable_v<json_member_t>>(
1147 parse_state, ClassIdx, CurrentMember::member_index );
1150 ErrorReason::UnexpectedEndOfData,
1154 if constexpr( is_pinned_type_v<json_result_t<JsonMember>> ) {
1155 auto const run_after_parse = daw::on_exit_success( [&] {
1156 parse_state.move_next_member_or_end( );
1158 (void)run_after_parse;
1159 return parse_value<json_member_t,
1161 json_member_t::expected_type>( parse_state );
1164 parse_value<json_member_t, false, json_member_t::expected_type>(
1166 parse_state.move_next_member_or_end( );
1169#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1174 static_assert( is_a_json_type_v<JsonMember> );
1175 using Constructor = json_constructor_t<JsonMember>;
1177 parse_state.trim_left( );
1179 std::size_t class_idx = 0;
1180 if constexpr( is_pinned_type_v<json_result_t<JsonMember>> ) {
1181 auto const run_after_parse = daw::on_exit_success( [&] {
1182 ordered_class_cleanup<
1183 all_json_members_must_exist_v<JsonMember, ParseState>,
1185 decltype( old_class_pos )>( parse_state, old_class_pos );
1187 (void)run_after_parse;
1192 parse_value_help( daw::constant_v<Is>, class_idx )... };
1194 return construct_value_tp<tuple_t, Constructor>(
1197 parse_value_help( daw::constant_v<Is>, class_idx )... } );
1205 parse_value_help( daw::constant_v<Is>, class_idx )... };
1207 return construct_value_tp<tuple_t, Constructor>(
1210 parse_value_help( daw::constant_v<Is>, class_idx )... } );
1213 if constexpr( all_json_members_must_exist_v<tuple_t, ParseState> ) {
1214 parse_state.trim_left( );
1216 ErrorReason::UnknownMember,
1218 parse_state.remove_prefix( );
1219 parse_state.trim_left( );
1221 (void)parse_state.skip_array( );
1223 parse_state.set_class_position( old_class_pos );
1228 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
1229 static constexpr json_result_t<JsonMember>
1230 parse_value_tuple( ParseState &parse_state ) {
1231 using element_pack =
1232 typename JsonMember::sub_member_list;
1234 return parse_tuple_value<JsonMember, KnownBounds>(
1236 std::make_index_sequence<std::tuple_size_v<element_pack>>{ } );
1239 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
1240 DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1241 parse_value_unknown( ParseState &parse_state ) {
1242 using constructor_t = json_constructor_t<JsonMember>;
1243 if constexpr( KnownBounds ) {
1244 return construct_value<json_result_t<JsonMember>, constructor_t>(
1245 parse_state, std::data( parse_state ), std::size( parse_state ) );
1247 auto value_parse_state = skip_value<true>( parse_state );
1248 return construct_value<json_result_t<JsonMember>, constructor_t>(
1250 std::data( value_parse_state ),
1251 std::size( value_parse_state ) );
1255 template<
typename JsonMember,
bool KnownBounds,
JsonParseTypes PTag,
1256 typename ParseState>
1257 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1258 parse_value( ParseState &parse_state ) {
1259 if constexpr( PTag == JsonParseTypes::Real ) {
1260 return parse_value_real<JsonMember, KnownBounds>( parse_state );
1261 }
else if constexpr( PTag == JsonParseTypes::Signed ) {
1262 return parse_value_signed<JsonMember, KnownBounds>( parse_state );
1263 }
else if constexpr( PTag == JsonParseTypes::Unsigned ) {
1264 return parse_value_unsigned<JsonMember, KnownBounds>( parse_state );
1265 }
else if constexpr( PTag == JsonParseTypes::Null ) {
1266 return parse_value_null<JsonMember, KnownBounds>( parse_state );
1267 }
else if constexpr( PTag == JsonParseTypes::Bool ) {
1268 return parse_value_bool<JsonMember, KnownBounds>( parse_state );
1269 }
else if constexpr( PTag == JsonParseTypes::StringRaw ) {
1270 return parse_value_string_raw<JsonMember, KnownBounds>( parse_state );
1271 }
else if constexpr( PTag == JsonParseTypes::StringEscaped ) {
1272 return parse_value_string_escaped<JsonMember, KnownBounds>(
1274 }
else if constexpr( PTag == JsonParseTypes::Date ) {
1275 return parse_value_date<JsonMember, KnownBounds>( parse_state );
1276 }
else if constexpr( PTag == JsonParseTypes::Custom ) {
1277 return parse_value_custom<JsonMember, KnownBounds>( parse_state );
1278 }
else if constexpr( PTag == JsonParseTypes::Class ) {
1279 return parse_value_class<JsonMember, KnownBounds>( parse_state );
1280 }
else if constexpr( PTag == JsonParseTypes::KeyValue ) {
1281 return parse_value_keyvalue<JsonMember, KnownBounds>( parse_state );
1282 }
else if constexpr( PTag == JsonParseTypes::KeyValueArray ) {
1283 return parse_value_keyvalue_array<JsonMember, KnownBounds>(
1285 }
else if constexpr( PTag == JsonParseTypes::Array ) {
1286 return parse_value_array<JsonMember, KnownBounds>( parse_state );
1287 }
else if constexpr( PTag == JsonParseTypes::SizedArray ) {
1288 return parse_value_sz_array<JsonMember, KnownBounds>( parse_state );
1289 }
else if constexpr( PTag == JsonParseTypes::Variant ) {
1290 return parse_value_variant<JsonMember, KnownBounds>( parse_state );
1291 }
else if constexpr( PTag == JsonParseTypes::VariantTagged ) {
1292 return parse_value_variant_tagged<JsonMember>( parse_state );
1293 }
else if constexpr( PTag == JsonParseTypes::VariantIntrusive ) {
1294 return parse_value_variant_intrusive<JsonMember>( parse_state );
1295 }
else if constexpr( PTag == JsonParseTypes::Tuple ) {
1296 return parse_value_tuple<JsonMember, KnownBounds>( parse_state );
1297#if defined( DAW_JSON_HAS_REFLECTION )
1298 }
else if constexpr( PTag == JsonParseTypes::ReflectedClass ) {
1299 return parse_value_reflected_class<JsonMember, KnownBounds>(
1303 static_assert( PTag == JsonParseTypes::Unknown,
1304 "Unexpected JsonParseType" );
1305 return parse_value_unknown<JsonMember, KnownBounds>( parse_state );
1309 template<std::size_t N,
typename JsonClass,
bool KnownBounds,
1310 typename... JsonClasses,
typename ParseState>
1311 DAW_ATTRIB_INLINE
constexpr json_result_t<JsonClass>
1312 parse_nth_class( std::size_t idx, ParseState &parse_state ) {
1314 DAW_ASSUME( idx <
sizeof...( JsonClasses ) );
1315 using T = json_base_type_t<JsonClass>;
1316 using Constructor = json_constructor_t<JsonClass>;
1317 if constexpr(
sizeof...( JsonClasses ) >= N + 8 ) {
1320 using cur_json_class_t =
1321 daw::traits::nth_element<N + 0, JsonClasses...>;
1322 return construct_value<T, Constructor>(
1324 parse_value<cur_json_class_t,
1326 cur_json_class_t::expected_type>( parse_state ) );
1329 using cur_json_class_t =
1330 daw::traits::nth_element<N + 1, JsonClasses...>;
1331 return construct_value<T, Constructor>(
1333 parse_value<cur_json_class_t,
1335 cur_json_class_t::expected_type>( parse_state ) );
1338 using cur_json_class_t =
1339 daw::traits::nth_element<N + 2, JsonClasses...>;
1340 return construct_value<T, Constructor>(
1342 parse_value<cur_json_class_t,
1344 cur_json_class_t::expected_type>( parse_state ) );
1347 using cur_json_class_t =
1348 daw::traits::nth_element<N + 3, JsonClasses...>;
1349 return construct_value<T, Constructor>(
1351 parse_value<cur_json_class_t,
1353 cur_json_class_t::expected_type>( parse_state ) );
1356 using cur_json_class_t =
1357 daw::traits::nth_element<N + 4, JsonClasses...>;
1358 return construct_value<T, Constructor>(
1360 parse_value<cur_json_class_t,
1362 cur_json_class_t::expected_type>( parse_state ) );
1365 using cur_json_class_t =
1366 daw::traits::nth_element<N + 5, JsonClasses...>;
1367 return construct_value<T, Constructor>(
1369 parse_value<cur_json_class_t,
1371 cur_json_class_t::expected_type>( parse_state ) );
1374 using cur_json_class_t =
1375 daw::traits::nth_element<N + 6, JsonClasses...>;
1376 return construct_value<T, Constructor>(
1378 parse_value<cur_json_class_t,
1380 cur_json_class_t::expected_type>( parse_state ) );
1383 using cur_json_class_t =
1384 daw::traits::nth_element<N + 7, JsonClasses...>;
1385 return construct_value<T, Constructor>(
1387 parse_value<cur_json_class_t,
1389 cur_json_class_t::expected_type>( parse_state ) );
1392 if constexpr(
sizeof...( JsonClasses ) >= N + 8 ) {
1393 return parse_nth_class<N + 8,
1396 JsonClasses...>( idx, parse_state );
1401 }
else if constexpr(
sizeof...( JsonClasses ) == N + 7 ) {
1404 using cur_json_class_t =
1405 daw::traits::nth_element<N + 0, JsonClasses...>;
1406 return construct_value<T, Constructor>(
1408 parse_value<cur_json_class_t,
1410 cur_json_class_t::expected_type>( parse_state ) );
1413 using cur_json_class_t =
1414 daw::traits::nth_element<N + 1, JsonClasses...>;
1415 return construct_value<T, Constructor>(
1417 parse_value<cur_json_class_t,
1419 cur_json_class_t::expected_type>( parse_state ) );
1422 using cur_json_class_t =
1423 daw::traits::nth_element<N + 2, JsonClasses...>;
1424 return construct_value<T, Constructor>(
1426 parse_value<cur_json_class_t,
1428 cur_json_class_t::expected_type>( parse_state ) );
1431 using cur_json_class_t =
1432 daw::traits::nth_element<N + 3, JsonClasses...>;
1433 return construct_value<T, Constructor>(
1435 parse_value<cur_json_class_t,
1437 cur_json_class_t::expected_type>( parse_state ) );
1440 using cur_json_class_t =
1441 daw::traits::nth_element<N + 4, JsonClasses...>;
1442 return construct_value<T, Constructor>(
1444 parse_value<cur_json_class_t,
1446 cur_json_class_t::expected_type>( parse_state ) );
1449 using cur_json_class_t =
1450 daw::traits::nth_element<N + 5, JsonClasses...>;
1451 return construct_value<T, Constructor>(
1453 parse_value<cur_json_class_t,
1455 cur_json_class_t::expected_type>( parse_state ) );
1458 DAW_ASSUME( idx == N + 6 );
1459 using cur_json_class_t =
1460 daw::traits::nth_element<N + 6, JsonClasses...>;
1461 return construct_value<T, Constructor>(
1463 parse_value<cur_json_class_t,
1465 cur_json_class_t::expected_type>( parse_state ) );
1468 }
else if constexpr(
sizeof...( JsonClasses ) == N + 6 ) {
1471 using cur_json_class_t =
1472 daw::traits::nth_element<N + 0, JsonClasses...>;
1473 return construct_value<T, Constructor>(
1475 parse_value<cur_json_class_t,
1477 cur_json_class_t::expected_type>( parse_state ) );
1480 using cur_json_class_t =
1481 daw::traits::nth_element<N + 1, JsonClasses...>;
1482 return construct_value<T, Constructor>(
1484 parse_value<cur_json_class_t,
1486 cur_json_class_t::expected_type>( parse_state ) );
1489 using cur_json_class_t =
1490 daw::traits::nth_element<N + 2, JsonClasses...>;
1491 return construct_value<T, Constructor>(
1493 parse_value<cur_json_class_t,
1495 cur_json_class_t::expected_type>( parse_state ) );
1498 using cur_json_class_t =
1499 daw::traits::nth_element<N + 3, JsonClasses...>;
1500 return construct_value<T, Constructor>(
1502 parse_value<cur_json_class_t,
1504 cur_json_class_t::expected_type>( parse_state ) );
1507 using cur_json_class_t =
1508 daw::traits::nth_element<N + 4, JsonClasses...>;
1509 return construct_value<T, Constructor>(
1511 parse_value<cur_json_class_t,
1513 cur_json_class_t::expected_type>( parse_state ) );
1516 DAW_ASSUME( idx == N + 5 );
1517 using cur_json_class_t =
1518 daw::traits::nth_element<N + 5, JsonClasses...>;
1519 return construct_value<T, Constructor>(
1521 parse_value<cur_json_class_t,
1523 cur_json_class_t::expected_type>( parse_state ) );
1526 }
else if constexpr(
sizeof...( JsonClasses ) == N + 5 ) {
1529 using cur_json_class_t =
1530 daw::traits::nth_element<N + 0, JsonClasses...>;
1531 return construct_value<T, Constructor>(
1533 parse_value<cur_json_class_t,
1535 cur_json_class_t::expected_type>( parse_state ) );
1538 using cur_json_class_t =
1539 daw::traits::nth_element<N + 1, JsonClasses...>;
1540 return construct_value<T, Constructor>(
1542 parse_value<cur_json_class_t,
1544 cur_json_class_t::expected_type>( parse_state ) );
1547 using cur_json_class_t =
1548 daw::traits::nth_element<N + 2, JsonClasses...>;
1549 return construct_value<T, Constructor>(
1551 parse_value<cur_json_class_t,
1553 cur_json_class_t::expected_type>( parse_state ) );
1556 using cur_json_class_t =
1557 daw::traits::nth_element<N + 3, JsonClasses...>;
1558 return construct_value<T, Constructor>(
1560 parse_value<cur_json_class_t,
1562 cur_json_class_t::expected_type>( parse_state ) );
1565 DAW_ASSUME( idx == N + 4 );
1566 using cur_json_class_t =
1567 daw::traits::nth_element<N + 4, JsonClasses...>;
1568 return construct_value<T, Constructor>(
1570 parse_value<cur_json_class_t,
1572 cur_json_class_t::expected_type>( parse_state ) );
1575 }
else if constexpr(
sizeof...( JsonClasses ) == N + 4 ) {
1578 using cur_json_class_t =
1579 daw::traits::nth_element<N + 0, JsonClasses...>;
1580 return construct_value<T, Constructor>(
1582 parse_value<cur_json_class_t,
1584 cur_json_class_t::expected_type>( parse_state ) );
1587 using cur_json_class_t =
1588 daw::traits::nth_element<N + 1, JsonClasses...>;
1589 return construct_value<T, Constructor>(
1591 parse_value<cur_json_class_t,
1593 cur_json_class_t::expected_type>( parse_state ) );
1596 using cur_json_class_t =
1597 daw::traits::nth_element<N + 2, JsonClasses...>;
1598 return construct_value<T, Constructor>(
1600 parse_value<cur_json_class_t,
1602 cur_json_class_t::expected_type>( parse_state ) );
1605 DAW_ASSUME( idx == N + 3 );
1606 using cur_json_class_t =
1607 daw::traits::nth_element<N + 3, JsonClasses...>;
1608 return construct_value<T, Constructor>(
1610 parse_value<cur_json_class_t,
1612 cur_json_class_t::expected_type>( parse_state ) );
1615 }
else if constexpr(
sizeof...( JsonClasses ) == N + 3 ) {
1618 using cur_json_class_t =
1619 daw::traits::nth_element<N + 0, JsonClasses...>;
1620 return construct_value<T, Constructor>(
1622 parse_value<cur_json_class_t,
1624 cur_json_class_t::expected_type>( parse_state ) );
1627 using cur_json_class_t =
1628 daw::traits::nth_element<N + 1, JsonClasses...>;
1629 return construct_value<T, Constructor>(
1631 parse_value<cur_json_class_t,
1633 cur_json_class_t::expected_type>( parse_state ) );
1636 DAW_ASSUME( idx == N + 2 );
1637 using cur_json_class_t =
1638 daw::traits::nth_element<N + 2, JsonClasses...>;
1639 return construct_value<T, Constructor>(
1641 parse_value<cur_json_class_t,
1643 cur_json_class_t::expected_type>( parse_state ) );
1646 }
else if constexpr(
sizeof...( JsonClasses ) == N + 2 ) {
1648 using cur_json_class_t =
1649 daw::traits::nth_element<N + 0, JsonClasses...>;
1650 return construct_value<T, Constructor>(
1652 parse_value<cur_json_class_t,
1654 cur_json_class_t::expected_type>( parse_state ) );
1656 using cur_json_class_t =
1657 daw::traits::nth_element<N + 1, JsonClasses...>;
1658 return construct_value<T, Constructor>(
1660 parse_value<cur_json_class_t,
1662 cur_json_class_t::expected_type>( parse_state ) );
1664 using cur_json_class_t =
1665 daw::traits::nth_element<N + 0, JsonClasses...>;
1666 return construct_value<T, Constructor>(
1668 parse_value<cur_json_class_t,
1670 cur_json_class_t::expected_type>( parse_state ) );