48 namespace json_details {
58 template<options::LiteralAsStringOpt literal_as_string,
60 DAW_ATTRIB_INLINE
constexpr void
61 skip_quote_when_literal_as_string( ParseState &parse_state ) {
62 if constexpr( literal_as_string ==
63 options::LiteralAsStringOpt::Always ) {
65 ErrorReason::InvalidNumberUnexpectedQuoting,
67 parse_state.remove_prefix( );
68 }
else if constexpr( literal_as_string ==
69 options::LiteralAsStringOpt::Maybe ) {
71 ErrorReason::UnexpectedEndOfData,
73 if( parse_state.front( ) ==
'"' ) {
74 parse_state.remove_prefix( );
79 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
80 [[nodiscard]]
constexpr json_result_t<JsonMember>
81 parse_value_real( ParseState &parse_state ) {
82 using constructor_t = json_constructor_t<JsonMember>;
83 using element_t = json_base_type_t<JsonMember>;
85 if constexpr( JsonMember::literal_as_string !=
86 options::LiteralAsStringOpt::Never ) {
87 if constexpr( not KnownBounds ) {
88 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
91 if constexpr( JsonMember::allow_number_errors ==
92 options::JsonNumberErrors::AllowInf or
93 JsonMember::allow_number_errors ==
94 options::JsonNumberErrors::AllowNanInf ) {
95 element_t sign = element_t( 1.0 );
96 if( parse_state.front( ) ==
'-' ) {
97 sign = element_t( -1.0 );
101 if( parse_state.starts_with_skip(
"Inf" ) ) {
102 if( not( parse_state.starts_with_skip(
"\"" ) or
103 parse_state.starts_with_skip(
"inity\"" ) ) ) {
106 if constexpr( KnownBounds ) {
108 ErrorReason::InvalidNumber,
112 parse_policy_details::at_end_of_item(
113 parse_state.front( ) ),
114 ErrorReason::InvalidEndOfValue,
117 return daw::cxmath::copy_sign(
118 daw::numeric_limits<element_t>::infinity( ), sign );
119 }
else if( sign < element_t( 0 ) ) {
123 if constexpr( JsonMember::allow_number_errors ==
124 options::JsonNumberErrors::AllowNaN or
125 JsonMember::allow_number_errors ==
126 options::JsonNumberErrors::AllowNanInf ) {
127 if( parse_state.starts_with(
"NaN" ) ) {
128 parse_state.template move_to_next_of<
'"'>( );
129 parse_state.remove_prefix( );
130 if constexpr( KnownBounds ) {
132 ErrorReason::InvalidNumber,
136 parse_policy_details::at_end_of_item(
137 parse_state.front( ) ),
138 ErrorReason::InvalidEndOfValue,
141 return daw::numeric_limits<element_t>::quiet_NaN( );
145 if constexpr( KnownBounds and JsonMember::literal_as_string ==
146 options::LiteralAsStringOpt::Never ) {
147 return construct_value<json_result_t<JsonMember>, constructor_t>(
148 parse_state, parse_real<element_t, true>( parse_state ) );
151 parse_state.has_more( ) and
152 parse_policy_details::is_number_start( parse_state.front( ) ),
153 ErrorReason::InvalidNumberStart,
157 construct_value<json_result_t<JsonMember>, constructor_t>(
158 parse_state, parse_real<element_t, false>( parse_state ) );
160 if constexpr( KnownBounds ) {
162 parse_state.empty( ) or
163 parse_policy_details::at_end_of_item( parse_state.front( ) ),
164 ErrorReason::InvalidEndOfValue,
167 if constexpr( JsonMember::literal_as_string !=
168 options::LiteralAsStringOpt::Never ) {
169 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
173 parse_state.empty( ) or
174 parse_policy_details::at_end_of_item( parse_state.front( ) ),
175 ErrorReason::InvalidEndOfValue,
182 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
183 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
184 parse_value_signed( ParseState &parse_state ) {
185 using constructor_t = json_constructor_t<JsonMember>;
186 using element_t = json_base_type_t<JsonMember>;
188 typename daw::conditional_t<std::is_enum_v<element_t>,
189 std::underlying_type<element_t>,
190 daw::traits::identity<element_t>>::type;
192 static_assert( daw::is_signed_v<int_type>,
"Expected signed type" );
193 if constexpr( KnownBounds ) {
195 parse_policy_details::is_number_start( parse_state.front( ) ),
196 ErrorReason::InvalidNumberStart,
199 if constexpr( JsonMember::literal_as_string !=
200 options::LiteralAsStringOpt::Never ) {
201 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
203 }
else if constexpr( not ParseState::is_zero_terminated_string ) {
205 ErrorReason::UnexpectedEndOfData,
209 auto const sign =
static_cast<int_type
>(
210 parse_policy_details::validate_signed_first( parse_state ) );
212 typename daw::conditional_t<daw::is_system_integral_v<int_type>,
213 daw::make_unsigned<int_type>,
214 daw::traits::identity<int_type>>::type;
215 auto parsed_val = to_signed(
216 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
220 if constexpr( KnownBounds ) {
221 return construct_value<json_result_t<JsonMember>, constructor_t>(
222 parse_state,
static_cast<element_t
>( parsed_val ) );
225 construct_value<json_result_t<JsonMember>, constructor_t>(
226 parse_state,
static_cast<element_t
>( parsed_val ) );
227 if constexpr( JsonMember::literal_as_string !=
228 options::LiteralAsStringOpt::Never ) {
229 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
232 parse_state.trim_left( );
234 not parse_state.has_more( ) or
235 parse_policy_details::at_end_of_item( parse_state.front( ) ),
236 ErrorReason::InvalidEndOfValue,
242 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
243 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
244 parse_value_unsigned( ParseState &parse_state ) {
245 using constructor_t = json_constructor_t<JsonMember>;
246 using element_t = json_base_type_t<JsonMember>;
248 typename daw::conditional_t<std::is_enum_v<element_t>,
249 std::underlying_type<element_t>,
250 daw::traits::identity<element_t>>::type;
252 if constexpr( KnownBounds ) {
253 parse_policy_details::validate_unsigned_first( parse_state );
255 return construct_value<json_result_t<JsonMember>, constructor_t>(
257 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
260 if constexpr( JsonMember::literal_as_string !=
261 options::LiteralAsStringOpt::Never ) {
262 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
264 if constexpr( not ParseState::is_zero_terminated_string ) {
266 ErrorReason::UnexpectedEndOfData,
269 }
else if constexpr( not ParseState::is_zero_terminated_string ) {
271 ErrorReason::UnexpectedEndOfData,
275 parse_policy_details::is_number( parse_state.front( ) ),
276 ErrorReason::InvalidNumber,
279 construct_value<json_result_t<JsonMember>, constructor_t>(
281 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
283 if constexpr( JsonMember::literal_as_string !=
284 options::LiteralAsStringOpt::Never ) {
285 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
287 if constexpr( not ParseState::is_zero_terminated_string ) {
289 ErrorReason::UnexpectedEndOfData,
294 not parse_state.has_more( ) or
295 parse_policy_details::at_end_of_item( parse_state.front( ) ),
296 ErrorReason::InvalidEndOfValue,
302 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
303 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
304 parse_value_null( ParseState &parse_state ) {
306 using constructor_t = json_constructor_t<JsonMember>;
307 auto const construct_empty = [&] {
308 if constexpr( daw::is_callable_v<
310 concepts::construct_nullable_with_empty_t> ) {
311 return construct_value<
typename JsonMember::wrapped_type,
313 parse_state, concepts::construct_nullable_with_empty );
315 return construct_value<
typename JsonMember::wrapped_type,
316 constructor_t>( parse_state );
320 using base_member_type =
typename JsonMember::member_type;
321 static_assert( not std::is_same_v<base_member_type, JsonMember> );
322 if constexpr( KnownBounds ) {
324 if( parse_state.is_null( ) ) {
325 return construct_empty( );
327 return construct_value<base_member_type, constructor_t>(
329 parse_value<base_member_type,
331 base_member_type::expected_type>( parse_state ) );
332 }
else if constexpr( ParseState::is_unchecked_input ) {
333 if( not parse_state.has_more( ) or
334 parse_state.is_at_token_after_value( ) ) {
335 return construct_empty( );
337 if( parse_state.front( ) ==
'n' ) {
338 parse_state.remove_prefix( 4 );
339 parse_state.trim_left_unchecked( );
340 parse_state.remove_prefix( );
341 return construct_empty( );
343 return construct_value<base_member_type, constructor_t>(
345 parse_value<base_member_type,
347 base_member_type::expected_type>( parse_state ) );
349 if( not parse_state.has_more( ) or
350 parse_state.is_at_token_after_value( ) ) {
351 return construct_empty( );
353 if( parse_state.starts_with(
"null" ) ) {
354 parse_state.remove_prefix( 4 );
356 not parse_state.has_more( ) or
357 parse_policy_details::at_end_of_item( parse_state.front( ) ),
358 ErrorReason::InvalidLiteral,
360 parse_state.trim_left_checked( );
361 return construct_empty( );
363 using parse_to_t = json_result_t<base_member_type>;
364 if constexpr( not std::is_move_constructible_v<parse_to_t> and
365 not std::is_copy_constructible_v<parse_to_t> ) {
368 concepts::nullable_value_traits<json_result_t<JsonMember>>,
369 concepts::construct_nullable_with_pointer_t,
371 return construct_value<base_member_type, constructor_t>(
373 concepts::construct_nullable_with_pointer,
375 parse_value<base_member_type,
377 base_member_type::expected_type>( parse_state ) } );
379 return construct_value<base_member_type, constructor_t>(
381 parse_value<base_member_type,
383 base_member_type::expected_type>( parse_state ) );
388 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
389 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
390 parse_value_bool( ParseState &parse_state ) {
391 using constructor_t = json_constructor_t<JsonMember>;
393 if constexpr( KnownBounds ) {
395 if constexpr( ParseState::is_unchecked_input ) {
396 return static_cast<bool>( parse_state.counter );
398 switch( parse_state.front( ) ) {
400 return construct_value<json_result_t<JsonMember>, constructor_t>(
403 return construct_value<json_result_t<JsonMember>, constructor_t>(
404 parse_state, false );
410 if constexpr( JsonMember::literal_as_string !=
411 options::LiteralAsStringOpt::Never ) {
412 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
416 if constexpr( ParseState::is_unchecked_input ) {
417 if( parse_state.front( ) ==
't' ) {
419 parse_state.remove_prefix( 4 );
421 parse_state.remove_prefix( 5 );
424 if( parse_state.starts_with(
"true" ) ) {
425 parse_state.remove_prefix( 4 );
427 }
else if( parse_state.starts_with(
"false" ) ) {
428 parse_state.remove_prefix( 5 );
434 if constexpr( JsonMember::literal_as_string !=
435 options::LiteralAsStringOpt::Never ) {
436 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
439 parse_state.trim_left( );
441 not parse_state.has_more( ) or
442 parse_policy_details::at_end_of_item( parse_state.front( ) ),
443 ErrorReason::InvalidEndOfValue,
445 return construct_value<json_result_t<JsonMember>, constructor_t>(
446 parse_state, result );
450 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
451 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
452 parse_value_string_raw( ParseState &parse_state ) {
454 using constructor_t = json_constructor_t<JsonMember>;
455 if constexpr( KnownBounds ) {
456 return construct_value<json_result_t<JsonMember>, constructor_t>(
457 parse_state, std::data( parse_state ), std::size( parse_state ) );
459 if constexpr( JsonMember::allow_escape_character ==
460 options::AllowEscapeCharacter::Allow ) {
461 auto const str = skip_string( parse_state );
462 return construct_value<json_result_t<JsonMember>, constructor_t>(
463 parse_state, std::data( str ), std::size( str ) );
465 parse_state.remove_prefix( );
467 char const *
const first = parse_state.first;
468 parse_state.template move_to_next_of<
'"'>( );
469 char const *
const last = parse_state.first;
470 parse_state.remove_prefix( );
471 return construct_value<json_result_t<JsonMember>, constructor_t>(
472 parse_state, first,
static_cast<std::size_t
>( last - first ) );
483 template<
typename JsonMember>
484 DAW_CPP20_CONCEPT can_parse_to_stdstring_fast_v =
485 can_single_allocation_string_v<json_result_t<JsonMember>> or
486 can_single_allocation_string_v<json_base_type_t<JsonMember>>;
489 json_constructor_t<T> );
494 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
495 [[nodiscard]] DAW_ATTRIB_INLINE
constexpr json_result_t<JsonMember>
496 parse_value_string_escaped( ParseState &parse_state ) {
497 static_assert( has_json_member_constructor_v<JsonMember> );
498 static_assert( has_json_member_parse_to_v<JsonMember> );
499 if constexpr( not KnownBounds ) {
501 ErrorReason::UnexpectedNull );
503 using constructor_t = json_constructor_t<JsonMember>;
504 if constexpr( can_parse_to_stdstring_fast_v<JsonMember> ) {
505 using AllowHighEightbits =
506 std::bool_constant<JsonMember::eight_bit_mode !=
507 options::EightBitModes::DisallowHigh>;
509 KnownBounds ? parse_state : skip_string( parse_state );
510 if( not AllowHighEightbits::value or
511 needs_slow_path( parse_state2 ) ) {
513 return parse_string_known_stdstring<AllowHighEightbits::value,
515 true>( parse_state2 );
519 return construct_value<json_result_t<JsonMember>, constructor_t>(
521 std::data( parse_state2 ),
522 daw::data_end( parse_state2 ) );
525 KnownBounds ? parse_state : skip_string( parse_state );
526 using AllowHighEightbits =
527 std::bool_constant<JsonMember::eight_bit_mode !=
528 options::EightBitModes::DisallowHigh>;
529 if( not AllowHighEightbits::value or
530 needs_slow_path( parse_state2 ) ) {
532 return parse_string_known_stdstring<AllowHighEightbits::value,
534 true>( parse_state2 );
538 return construct_value<json_result_t<JsonMember>, constructor_t>(
540 std::data( parse_state2 ),
541 daw::data_end( parse_state2 ) );
545 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
546 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
547 parse_value_date( ParseState &parse_state ) {
550 ErrorReason::UnexpectedEndOfData,
552 auto str = KnownBounds ? parse_state : skip_string( parse_state );
553 using constructor_t = json_constructor_t<JsonMember>;
554 return construct_value<json_result_t<JsonMember>, constructor_t>(
555 parse_state, std::data( str ), std::size( str ) );
558 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
559 [[nodiscard]]
static constexpr json_result_t<JsonMember>
560 parse_value_custom( ParseState &parse_state ) {
562 auto const str = [&] {
563 if constexpr( JsonMember::custom_json_type ==
564 options::JsonCustomTypes::String ) {
565 if constexpr( KnownBounds ) {
568 return skip_string( parse_state );
570 }
else if constexpr( JsonMember::custom_json_type ==
571 options::JsonCustomTypes::Literal ) {
572 return KnownBounds ? parse_state : skip_literal( parse_state );
574 static_assert( JsonMember::custom_json_type ==
575 options::JsonCustomTypes::Any );
579 if constexpr( KnownBounds ) {
580 auto result = parse_state;
581 if( *( result.first - 1 ) ==
'"' ) {
586 if( parse_state.front( ) ==
'"' ) {
587 auto result = skip_string( parse_state );
591 return skip_value( parse_state );
596 str.has_more( ) and not( str.front( ) ==
'[' or str.front( ) ==
'{' ),
597 ErrorReason::InvalidStartOfValue,
599 using constructor_t =
typename JsonMember::from_converter_t;
600 return construct_value<json_result_t<JsonMember>, constructor_t>(
601 parse_state, std::string_view( std::data( str ), std::size( str ) ) );
604 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
605 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
606 parse_value_class( ParseState &parse_state ) {
608 using element_t =
typename JsonMember::wrapped_type;
610 ErrorReason::UnexpectedEndOfData,
613 if constexpr( KnownBounds ) {
615 template parse_to_class<JsonMember, KnownBounds>( parse_state );
616 }
else if constexpr( is_pinned_type_v<element_t> ) {
617 auto const run_after_parse = daw::on_exit_success( [&] {
618 parse_state.trim_left_checked( );
620 (void)run_after_parse;
622 template parse_to_class<JsonMember, KnownBounds>( parse_state );
623 }
else if constexpr( is_deduced_empty_class_v<JsonMember> ) {
624 parse_state.trim_left_checked( );
625 return json_result_t<JsonMember>{ };
628 template parse_to_class<JsonMember, KnownBounds>( parse_state );
629 parse_state.trim_left_checked( );
634#if defined( DAW_JSON_HAS_REFLECTION )
635 template<
typename JsonMember,
bool ,
typename ParseState>
636 constexpr json_result_t<JsonMember>
637 parse_value_reflected_class( ParseState &parse_state ) {
639 ErrorReason::UnexpectedEndOfData,
642 return JsonMember::parse_to_class( parse_state );
654 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
655 [[nodiscard]]
static constexpr json_result_t<JsonMember>
656 parse_value_keyvalue( ParseState &parse_state ) {
658 static_assert( JsonMember::expected_type == JsonParseTypes::KeyValue,
659 "Expected a json_key_value" );
661 ErrorReason::ExpectedKeyValueToStartWithBrace,
664 parse_state.remove_prefix( );
665 parse_state.trim_left( );
668 json_parse_kv_class_iterator<JsonMember,
670 can_be_random_iterator_v<KnownBounds>>;
672 using constructor_t = json_constructor_t<JsonMember>;
673 return construct_value<json_result_t<JsonMember>, constructor_t>(
674 parse_state, iter_t( parse_state ), iter_t( ) );
685 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
686 [[nodiscard]]
static constexpr json_result_t<JsonMember>
687 parse_value_keyvalue_array( ParseState &parse_state ) {
689 static_assert( JsonMember::expected_type ==
690 JsonParseTypes::KeyValueArray,
691 "Expected a json_key_value" );
693 parse_state.is_opening_bracket_checked( ),
694 ErrorReason::ExpectedKeyValueArrayToStartWithBracket,
697 parse_state.remove_prefix( );
700 json_parse_kv_array_iterator<JsonMember,
702 can_be_random_iterator_v<KnownBounds>>;
703 using constructor_t = json_constructor_t<JsonMember>;
704 return construct_value<json_result_t<JsonMember>, constructor_t>(
705 parse_state, iter_t( parse_state ), iter_t( ) );
708 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
709 [[nodiscard]]
static constexpr json_result_t<JsonMember>
710 parse_value_array( ParseState &parse_state ) {
711 parse_state.trim_left( );
713 ErrorReason::InvalidArrayStart,
715 parse_state.remove_prefix( );
716 parse_state.trim_left_unchecked( );
721 json_parse_array_iterator<JsonMember,
723 can_be_random_iterator_v<KnownBounds>>;
724 using constructor_t = json_constructor_t<JsonMember>;
725 return construct_value<json_result_t<JsonMember>, constructor_t>(
726 parse_state, iterator_t( parse_state ), iterator_t( ) );
729 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
730 [[nodiscard]]
static constexpr json_result_t<JsonMember>
731 parse_value_sz_array( ParseState &parse_state ) {
733 using size_member = dependent_member_t<JsonMember>;
735 auto [parse_state2, is_found] = find_range<ParseState>(
736 ParseState( parse_state.class_first, parse_state.last ),
740 is_found, ErrorReason::TagMemberNotFound, parse_state );
742 parse_value<size_member, false, size_member::expected_type>(
745 if constexpr( KnownBounds and ParseState::is_unchecked_input ) {
748 auto cnt =
static_cast<std::ptrdiff_t
>( parse_state.counter );
750 ErrorReason::NumberOutOfRange,
753 parse_state.trim_left( );
755 ErrorReason::InvalidArrayStart,
757 parse_state.remove_prefix( );
758 parse_state.trim_left_unchecked( );
762 json_parse_array_iterator<JsonMember, ParseState, false>;
763 using constructor_t = json_constructor_t<JsonMember>;
764 return construct_value<json_result_t<JsonMember>, constructor_t>(
766 iterator_t( parse_state ),
768 static_cast<std::size_t
>( sz ) );
773 [[nodiscard]]
constexpr json_result_t<JsonMembers>
774 parse_variant_value( ParseState &parse_state ) {
775 using element_t =
typename JsonMembers::json_elements;
776 using idx = daw::constant<( JsonMembers::base_map::base_map
777 [
static_cast<std::int_fast8_t
>( BPT )] )>;
779 if constexpr( idx::value <
780 pack_size_v<typename element_t::element_map_t> ) {
782 pack_element_t<idx::value, typename element_t::element_map_t>;
783 return parse_value<JsonMember,
785 JsonMember::expected_type>( parse_state );
791 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
792 [[nodiscard]]
static constexpr json_result_t<JsonMember>
793 parse_value_variant( ParseState &parse_state ) {
794 if constexpr( KnownBounds ) {
797 if( *( parse_state.first - 1 ) ==
'"' ) {
799 return parse_variant_value<JsonBaseParseTypes::String,
801 KnownBounds>( parse_state );
804 switch( parse_state.front( ) ) {
806 return parse_variant_value<JsonBaseParseTypes::Class,
808 KnownBounds>( parse_state );
810 return parse_variant_value<JsonBaseParseTypes::Array,
812 KnownBounds>( parse_state );
815 return parse_variant_value<JsonBaseParseTypes::Bool,
817 KnownBounds>( parse_state );
819 return parse_variant_value<JsonBaseParseTypes::String,
821 KnownBounds>( parse_state );
834 return parse_variant_value<JsonBaseParseTypes::Number,
836 KnownBounds>( parse_state );
838 if constexpr( ParseState::is_unchecked_input ) {
841 daw_json_error(
true, ErrorReason::InvalidStartOfValue, parse_state );
845 template<
typename Result,
typename TypeList, std::size_t pos = 0,
847 DAW_ATTRIB_INLINE
constexpr Result
848 parse_visit( std::size_t idx, ParseState &parse_state ) {
850 using JsonMember = pack_element_t<pos, TypeList>;
851 if constexpr( std::is_same_v<json_result_t<JsonMember>, Result> ) {
852 return parse_value<JsonMember, false, JsonMember::expected_type>(
856 parse_value<JsonMember, false, JsonMember::expected_type>(
860 if constexpr( pos + 1 < pack_size_v<TypeList> ) {
861 return parse_visit<Result, TypeList, pos + 1>( idx, parse_state );
863 if constexpr( ParseState::is_unchecked_input ) {
867 true, ErrorReason::MissingMemberNameOrEndOfClass, parse_state );
872 template<
typename JsonMember,
typename ParseState>
873 [[nodiscard]]
constexpr auto find_index( ParseState
const &parse_state ) {
874 using tag_member =
typename JsonMember::tag_member;
875 using class_wrapper_t =
typename JsonMember::tag_member_class_wrapper;
877 using switcher_t =
typename JsonMember::switcher;
878 auto parse_state2 = ParseState( parse_state.class_first,
879 parse_state.class_last,
880 parse_state.class_first,
881 parse_state.class_last );
882 if constexpr( is_an_ordered_member_v<tag_member> ) {
885 ErrorReason::InvalidArrayStart,
887 return switcher_t{ }( std::get<0>(
888 parse_value<class_wrapper_t, false, class_wrapper_t::expected_type>(
893 ErrorReason::InvalidClassStart,
895 return switcher_t{ }( std::get<0>(
896 parse_value<class_wrapper_t, false, class_wrapper_t::expected_type>(
902 template<
typename JsonMember,
typename ParseState>
903 [[nodiscard]]
constexpr json_result_t<JsonMember>
904 parse_value_variant_tagged( ParseState &parse_state ) {
905 auto const index = find_index<JsonMember>( parse_state );
906 return parse_visit<json_result_t<JsonMember>,
907 typename JsonMember::json_elements::element_map_t>(
908 index, parse_state );
911 template<
typename JsonMember,
typename ParseState>
912 [[nodiscard]]
constexpr json_result_t<JsonMember>
913 parse_value_variant_intrusive( ParseState &parse_state ) {
914 auto const index = [&] {
915 using tag_submember =
typename JsonMember::tag_submember;
916 using class_wrapper_t =
917 typename JsonMember::tag_submember_class_wrapper;
918 auto parse_state2 = parse_state;
919 using switcher_t =
typename JsonMember::switcher;
920 if constexpr( is_an_ordered_member_v<tag_submember> ) {
921 return switcher_t{ }( std::get<0>(
922 parse_value<class_wrapper_t,
924 class_wrapper_t::expected_type>( parse_state2 ) ) );
926 return switcher_t{ }( std::get<0>(
927 parse_value<class_wrapper_t,
929 class_wrapper_t::expected_type>( parse_state2 )
934 return parse_visit<json_result_t<JsonMember>,
935 typename JsonMember::json_elements::element_map_t>(
936 index, parse_state );
939 template<
bool AllMembersMustExist,
typename ParseState,
940 typename OldClassPos>
941 DAW_ATTRIB_INLINE
constexpr void ordered_class_cleanup(
942 ParseState &parse_state,
945 if constexpr( AllMembersMustExist ) {
946 parse_state.trim_left( );
948 ErrorReason::UnknownMember,
950 parse_state.remove_prefix( );
951 parse_state.trim_left_checked( );
953 (void)parse_state.skip_array( );
955 parse_state.set_class_position( old_class_pos );
958 namespace pocm_details {
966 template<
bool Nullable,
typename ParseState>
967 constexpr void maybe_skip_members( ParseState &parse_state,
968 std::size_t ¤t_position,
969 std::size_t desired_position ) {
972 ErrorReason::OutOfOrderOrderedMembers,
974 using skip_check_end =
975 std::bool_constant<( ParseState::is_unchecked_input and Nullable )>;
976 while( ( current_position < desired_position ) &
977 ( skip_check_end::value or parse_state.front( ) !=
']' ) ) {
978 (void)skip_value( parse_state );
979 parse_state.move_next_member_or_end( );
982 ErrorReason::UnexpectedEndOfData,
987#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
988 template<
typename ParseState>
989 struct position_info {
993 constexpr explicit operator bool( )
const {
994 return not state.is_null( );
1005 template<
bool Nullable,
typename ParseState, std::
size_t N>
1006 DAW_ATTRIB_INLINE
static constexpr ParseState maybe_skip_members(
1007 ParseState &parse_state, std::size_t ¤t_position,
1008 std::size_t desired_position,
1009 std::array<position_info<ParseState>, N> &parse_locations ) {
1011 auto const desired = daw::algorithm::find_if(
1012 std::data( parse_locations ),
1013 daw::data_end( parse_locations ),
1014 [desired_position]( position_info<ParseState>
const &loc ) {
1015 return loc.index == desired_position;
1018 return desired->state;
1020#if not defined( NDEBUG )
1022 ErrorReason::UnexpectedEndOfData,
1025 using skip_check_end =
1026 std::bool_constant<( ParseState::is_unchecked_input and Nullable )>;
1027 while( ( current_position < desired_position ) &
1028 ( skip_check_end::value or parse_state.front( ) !=
']' ) ) {
1029 auto const current = daw::algorithm::find_if(
1030 std::data( parse_locations ),
1031 daw::data_end( parse_locations ),
1032 [current_position]( position_info<ParseState>
const &loc ) {
1033 return loc.index == current_position;
1035 auto state = skip_value( parse_state );
1036 if( current != daw::data_end( parse_locations ) ) {
1037 current->state = state;
1039 parse_state.move_next_member_or_end( );
1042 ErrorReason::UnexpectedEndOfData,
1050 template<
typename T>
1051 struct member_index_t {
1052 static constexpr std::size_t value = T::member_index;
1055 template<
typename Idx,
typename JsonMember>
1056 inline constexpr std::size_t member_index_v =
1057 daw::conditional_t<has_member_index_v<JsonMember>,
1058 member_index_t<JsonMember>, Idx>::value;
1061 template<
typename JsonMember,
bool KnownBounds,
typename ParseState,
1063 DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1064 parse_tuple_value( ParseState &parse_state, std::index_sequence<Is...> ) {
1065 parse_state.trim_left( );
1067 ErrorReason::InvalidArrayStart,
1070 auto const old_class_pos = parse_state.get_class_position( );
1071 parse_state.set_class_position( );
1072 parse_state.remove_prefix( );
1073 parse_state.move_next_member_or_end( );
1074 using tuple_t = json_base_type_t<JsonMember>;
1075 using tuple_members =
typename JsonMember::sub_member_list;
1077#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1078 using position_info_t = pocm_details::position_info<ParseState>;
1079 std::size_t parse_locations_last_index = 0U;
1080 std::array<position_info_t,
sizeof...( Is )> parse_locations{
1081 [&](
auto Index )
mutable -> position_info_t {
1082 constexpr std::size_t index =
decltype( Index )::value;
1083 using member_t = std::tuple_element_t<index, tuple_members>;
1084 if constexpr( is_an_ordered_member_v<member_t> ) {
1085 parse_locations_last_index = member_t::member_index;
1086 return { member_t::member_index };
1088 return { parse_locations_last_index++ };
1090 }(daw::constant_v<Is>)... };
1092 auto const parse_value_help = [&](
auto PackIdx,
1093 std::size_t &ClassIdx ) {
1094 using index_t =
decltype( PackIdx );
1095 using CurrentMember =
1096 std::tuple_element_t<index_t::value, tuple_members>;
1098 using json_member_t = ordered_member_subtype_t<CurrentMember>;
1100#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1101 ParseState parse_state2 =
1102 pocm_details::maybe_skip_members<is_json_nullable_v<json_member_t>>(
1105 pocm_details::member_index_v<index_t, CurrentMember>,
1107 if constexpr(
sizeof...( Is ) > 1 ) {
1109 if( parse_state2.first == parse_state.first ) {
1110 if constexpr( is_pinned_type_v<json_result_t<JsonMember>> ) {
1111 auto const run_after_parse = daw::on_exit_success( [&] {
1112 parse_state.move_next_member_or_end( );
1114 (void)run_after_parse;
1115 return parse_value<json_member_t,
1117 json_member_t::expected_type>( parse_state );
1120 parse_value<json_member_t,
1122 json_member_t::expected_type>( parse_state );
1123 parse_state.move_next_member_or_end( );
1128 return parse_value<json_member_t,
1130 json_member_t::expected_type>( parse_state2 );
1134 if constexpr( is_an_ordered_member_v<CurrentMember> ) {
1135 pocm_details::maybe_skip_members<
1136 is_json_nullable_v<json_member_t>>(
1137 parse_state, ClassIdx, CurrentMember::member_index );
1140 ErrorReason::UnexpectedEndOfData,
1144 if constexpr( is_pinned_type_v<json_result_t<JsonMember>> ) {
1145 auto const run_after_parse = daw::on_exit_success( [&] {
1146 parse_state.move_next_member_or_end( );
1148 (void)run_after_parse;
1149 return parse_value<json_member_t,
1151 json_member_t::expected_type>( parse_state );
1154 parse_value<json_member_t, false, json_member_t::expected_type>(
1156 parse_state.move_next_member_or_end( );
1159#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1164 static_assert( is_a_json_type_v<JsonMember> );
1165 using Constructor = json_constructor_t<JsonMember>;
1167 parse_state.trim_left( );
1169 std::size_t class_idx = 0;
1170 if constexpr( is_pinned_type_v<json_result_t<JsonMember>> ) {
1171 auto const run_after_parse = daw::on_exit_success( [&] {
1172 ordered_class_cleanup<
1173 all_json_members_must_exist_v<JsonMember, ParseState>,
1175 decltype( old_class_pos )>( parse_state, old_class_pos );
1177 (void)run_after_parse;
1182 parse_value_help( daw::constant_v<Is>, class_idx )... };
1184 return construct_value_tp<tuple_t, Constructor>(
1187 parse_value_help( daw::constant_v<Is>, class_idx )... } );
1195 parse_value_help( daw::constant_v<Is>, class_idx )... };
1197 return construct_value_tp<tuple_t, Constructor>(
1200 parse_value_help( daw::constant_v<Is>, class_idx )... } );
1203 if constexpr( all_json_members_must_exist_v<tuple_t, ParseState> ) {
1204 parse_state.trim_left( );
1206 ErrorReason::UnknownMember,
1208 parse_state.remove_prefix( );
1209 parse_state.trim_left( );
1211 (void)parse_state.skip_array( );
1213 parse_state.set_class_position( old_class_pos );
1218 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
1219 static constexpr json_result_t<JsonMember>
1220 parse_value_tuple( ParseState &parse_state ) {
1221 using element_pack =
1222 typename JsonMember::sub_member_list;
1224 return parse_tuple_value<JsonMember, KnownBounds>(
1226 std::make_index_sequence<std::tuple_size_v<element_pack>>{ } );
1229 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
1230 DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1231 parse_value_unknown( ParseState &parse_state ) {
1232 using constructor_t = json_constructor_t<JsonMember>;
1233 if constexpr( KnownBounds ) {
1234 return construct_value<json_result_t<JsonMember>, constructor_t>(
1235 parse_state, std::data( parse_state ), std::size( parse_state ) );
1237 auto value_parse_state = skip_value<true>( parse_state );
1238 return construct_value<json_result_t<JsonMember>, constructor_t>(
1240 std::data( value_parse_state ),
1241 std::size( value_parse_state ) );
1245 template<
typename JsonMember,
bool KnownBounds,
JsonParseTypes PTag,
1246 typename ParseState>
1247 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1248 parse_value( ParseState &parse_state ) {
1249 if constexpr( PTag == JsonParseTypes::Real ) {
1250 return parse_value_real<JsonMember, KnownBounds>( parse_state );
1251 }
else if constexpr( PTag == JsonParseTypes::Signed ) {
1252 return parse_value_signed<JsonMember, KnownBounds>( parse_state );
1253 }
else if constexpr( PTag == JsonParseTypes::Unsigned ) {
1254 return parse_value_unsigned<JsonMember, KnownBounds>( parse_state );
1255 }
else if constexpr( PTag == JsonParseTypes::Null ) {
1256 return parse_value_null<JsonMember, KnownBounds>( parse_state );
1257 }
else if constexpr( PTag == JsonParseTypes::Bool ) {
1258 return parse_value_bool<JsonMember, KnownBounds>( parse_state );
1259 }
else if constexpr( PTag == JsonParseTypes::StringRaw ) {
1260 return parse_value_string_raw<JsonMember, KnownBounds>( parse_state );
1261 }
else if constexpr( PTag == JsonParseTypes::StringEscaped ) {
1262 return parse_value_string_escaped<JsonMember, KnownBounds>(
1264 }
else if constexpr( PTag == JsonParseTypes::Date ) {
1265 return parse_value_date<JsonMember, KnownBounds>( parse_state );
1266 }
else if constexpr( PTag == JsonParseTypes::Custom ) {
1267 return parse_value_custom<JsonMember, KnownBounds>( parse_state );
1268 }
else if constexpr( PTag == JsonParseTypes::Class ) {
1269 return parse_value_class<JsonMember, KnownBounds>( parse_state );
1270 }
else if constexpr( PTag == JsonParseTypes::KeyValue ) {
1271 return parse_value_keyvalue<JsonMember, KnownBounds>( parse_state );
1272 }
else if constexpr( PTag == JsonParseTypes::KeyValueArray ) {
1273 return parse_value_keyvalue_array<JsonMember, KnownBounds>(
1275 }
else if constexpr( PTag == JsonParseTypes::Array ) {
1276 return parse_value_array<JsonMember, KnownBounds>( parse_state );
1277 }
else if constexpr( PTag == JsonParseTypes::SizedArray ) {
1278 return parse_value_sz_array<JsonMember, KnownBounds>( parse_state );
1279 }
else if constexpr( PTag == JsonParseTypes::Variant ) {
1280 return parse_value_variant<JsonMember, KnownBounds>( parse_state );
1281 }
else if constexpr( PTag == JsonParseTypes::VariantTagged ) {
1282 return parse_value_variant_tagged<JsonMember>( parse_state );
1283 }
else if constexpr( PTag == JsonParseTypes::VariantIntrusive ) {
1284 return parse_value_variant_intrusive<JsonMember>( parse_state );
1285 }
else if constexpr( PTag == JsonParseTypes::Tuple ) {
1286 return parse_value_tuple<JsonMember, KnownBounds>( parse_state );
1287#if defined( DAW_JSON_HAS_REFLECTION )
1288 }
else if constexpr( PTag == JsonParseTypes::ReflectedClass ) {
1289 return parse_value_reflected_class<JsonMember, KnownBounds>(
1293 static_assert( PTag == JsonParseTypes::Unknown,
1294 "Unexpected JsonParseType" );
1295 return parse_value_unknown<JsonMember, KnownBounds>( parse_state );
1299 template<std::size_t N,
typename JsonClass,
bool KnownBounds,
1300 typename... JsonClasses,
typename ParseState>
1301 DAW_ATTRIB_INLINE
constexpr json_result_t<JsonClass>
1302 parse_nth_class( std::size_t idx, ParseState &parse_state ) {
1304 DAW_ASSUME( idx <
sizeof...( JsonClasses ) );
1305 using T = json_base_type_t<JsonClass>;
1306 using Constructor = json_constructor_t<JsonClass>;
1307 if constexpr(
sizeof...( JsonClasses ) >= N + 8 ) {
1310 using cur_json_class_t =
1311 daw::traits::nth_element<N + 0, JsonClasses...>;
1312 return construct_value<T, Constructor>(
1314 parse_value<cur_json_class_t,
1316 cur_json_class_t::expected_type>( parse_state ) );
1319 using cur_json_class_t =
1320 daw::traits::nth_element<N + 1, JsonClasses...>;
1321 return construct_value<T, Constructor>(
1323 parse_value<cur_json_class_t,
1325 cur_json_class_t::expected_type>( parse_state ) );
1328 using cur_json_class_t =
1329 daw::traits::nth_element<N + 2, JsonClasses...>;
1330 return construct_value<T, Constructor>(
1332 parse_value<cur_json_class_t,
1334 cur_json_class_t::expected_type>( parse_state ) );
1337 using cur_json_class_t =
1338 daw::traits::nth_element<N + 3, JsonClasses...>;
1339 return construct_value<T, Constructor>(
1341 parse_value<cur_json_class_t,
1343 cur_json_class_t::expected_type>( parse_state ) );
1346 using cur_json_class_t =
1347 daw::traits::nth_element<N + 4, JsonClasses...>;
1348 return construct_value<T, Constructor>(
1350 parse_value<cur_json_class_t,
1352 cur_json_class_t::expected_type>( parse_state ) );
1355 using cur_json_class_t =
1356 daw::traits::nth_element<N + 5, JsonClasses...>;
1357 return construct_value<T, Constructor>(
1359 parse_value<cur_json_class_t,
1361 cur_json_class_t::expected_type>( parse_state ) );
1364 using cur_json_class_t =
1365 daw::traits::nth_element<N + 6, JsonClasses...>;
1366 return construct_value<T, Constructor>(
1368 parse_value<cur_json_class_t,
1370 cur_json_class_t::expected_type>( parse_state ) );
1373 using cur_json_class_t =
1374 daw::traits::nth_element<N + 7, JsonClasses...>;
1375 return construct_value<T, Constructor>(
1377 parse_value<cur_json_class_t,
1379 cur_json_class_t::expected_type>( parse_state ) );
1382 if constexpr(
sizeof...( JsonClasses ) >= N + 8 ) {
1383 return parse_nth_class<N + 8,
1386 JsonClasses...>( idx, parse_state );
1391 }
else if constexpr(
sizeof...( JsonClasses ) == N + 7 ) {
1394 using cur_json_class_t =
1395 daw::traits::nth_element<N + 0, JsonClasses...>;
1396 return construct_value<T, Constructor>(
1398 parse_value<cur_json_class_t,
1400 cur_json_class_t::expected_type>( parse_state ) );
1403 using cur_json_class_t =
1404 daw::traits::nth_element<N + 1, JsonClasses...>;
1405 return construct_value<T, Constructor>(
1407 parse_value<cur_json_class_t,
1409 cur_json_class_t::expected_type>( parse_state ) );
1412 using cur_json_class_t =
1413 daw::traits::nth_element<N + 2, JsonClasses...>;
1414 return construct_value<T, Constructor>(
1416 parse_value<cur_json_class_t,
1418 cur_json_class_t::expected_type>( parse_state ) );
1421 using cur_json_class_t =
1422 daw::traits::nth_element<N + 3, JsonClasses...>;
1423 return construct_value<T, Constructor>(
1425 parse_value<cur_json_class_t,
1427 cur_json_class_t::expected_type>( parse_state ) );
1430 using cur_json_class_t =
1431 daw::traits::nth_element<N + 4, JsonClasses...>;
1432 return construct_value<T, Constructor>(
1434 parse_value<cur_json_class_t,
1436 cur_json_class_t::expected_type>( parse_state ) );
1439 using cur_json_class_t =
1440 daw::traits::nth_element<N + 5, JsonClasses...>;
1441 return construct_value<T, Constructor>(
1443 parse_value<cur_json_class_t,
1445 cur_json_class_t::expected_type>( parse_state ) );
1448 DAW_ASSUME( idx == N + 6 );
1449 using cur_json_class_t =
1450 daw::traits::nth_element<N + 6, JsonClasses...>;
1451 return construct_value<T, Constructor>(
1453 parse_value<cur_json_class_t,
1455 cur_json_class_t::expected_type>( parse_state ) );
1458 }
else if constexpr(
sizeof...( JsonClasses ) == N + 6 ) {
1461 using cur_json_class_t =
1462 daw::traits::nth_element<N + 0, JsonClasses...>;
1463 return construct_value<T, Constructor>(
1465 parse_value<cur_json_class_t,
1467 cur_json_class_t::expected_type>( parse_state ) );
1470 using cur_json_class_t =
1471 daw::traits::nth_element<N + 1, JsonClasses...>;
1472 return construct_value<T, Constructor>(
1474 parse_value<cur_json_class_t,
1476 cur_json_class_t::expected_type>( parse_state ) );
1479 using cur_json_class_t =
1480 daw::traits::nth_element<N + 2, JsonClasses...>;
1481 return construct_value<T, Constructor>(
1483 parse_value<cur_json_class_t,
1485 cur_json_class_t::expected_type>( parse_state ) );
1488 using cur_json_class_t =
1489 daw::traits::nth_element<N + 3, JsonClasses...>;
1490 return construct_value<T, Constructor>(
1492 parse_value<cur_json_class_t,
1494 cur_json_class_t::expected_type>( parse_state ) );
1497 using cur_json_class_t =
1498 daw::traits::nth_element<N + 4, JsonClasses...>;
1499 return construct_value<T, Constructor>(
1501 parse_value<cur_json_class_t,
1503 cur_json_class_t::expected_type>( parse_state ) );
1506 DAW_ASSUME( idx == N + 5 );
1507 using cur_json_class_t =
1508 daw::traits::nth_element<N + 5, JsonClasses...>;
1509 return construct_value<T, Constructor>(
1511 parse_value<cur_json_class_t,
1513 cur_json_class_t::expected_type>( parse_state ) );
1516 }
else if constexpr(
sizeof...( JsonClasses ) == N + 5 ) {
1519 using cur_json_class_t =
1520 daw::traits::nth_element<N + 0, JsonClasses...>;
1521 return construct_value<T, Constructor>(
1523 parse_value<cur_json_class_t,
1525 cur_json_class_t::expected_type>( parse_state ) );
1528 using cur_json_class_t =
1529 daw::traits::nth_element<N + 1, JsonClasses...>;
1530 return construct_value<T, Constructor>(
1532 parse_value<cur_json_class_t,
1534 cur_json_class_t::expected_type>( parse_state ) );
1537 using cur_json_class_t =
1538 daw::traits::nth_element<N + 2, JsonClasses...>;
1539 return construct_value<T, Constructor>(
1541 parse_value<cur_json_class_t,
1543 cur_json_class_t::expected_type>( parse_state ) );
1546 using cur_json_class_t =
1547 daw::traits::nth_element<N + 3, JsonClasses...>;
1548 return construct_value<T, Constructor>(
1550 parse_value<cur_json_class_t,
1552 cur_json_class_t::expected_type>( parse_state ) );
1555 DAW_ASSUME( idx == N + 4 );
1556 using cur_json_class_t =
1557 daw::traits::nth_element<N + 4, JsonClasses...>;
1558 return construct_value<T, Constructor>(
1560 parse_value<cur_json_class_t,
1562 cur_json_class_t::expected_type>( parse_state ) );
1565 }
else if constexpr(
sizeof...( JsonClasses ) == N + 4 ) {
1568 using cur_json_class_t =
1569 daw::traits::nth_element<N + 0, JsonClasses...>;
1570 return construct_value<T, Constructor>(
1572 parse_value<cur_json_class_t,
1574 cur_json_class_t::expected_type>( parse_state ) );
1577 using cur_json_class_t =
1578 daw::traits::nth_element<N + 1, JsonClasses...>;
1579 return construct_value<T, Constructor>(
1581 parse_value<cur_json_class_t,
1583 cur_json_class_t::expected_type>( parse_state ) );
1586 using cur_json_class_t =
1587 daw::traits::nth_element<N + 2, JsonClasses...>;
1588 return construct_value<T, Constructor>(
1590 parse_value<cur_json_class_t,
1592 cur_json_class_t::expected_type>( parse_state ) );
1595 DAW_ASSUME( idx == N + 3 );
1596 using cur_json_class_t =
1597 daw::traits::nth_element<N + 3, JsonClasses...>;
1598 return construct_value<T, Constructor>(
1600 parse_value<cur_json_class_t,
1602 cur_json_class_t::expected_type>( parse_state ) );
1605 }
else if constexpr(
sizeof...( JsonClasses ) == N + 3 ) {
1608 using cur_json_class_t =
1609 daw::traits::nth_element<N + 0, JsonClasses...>;
1610 return construct_value<T, Constructor>(
1612 parse_value<cur_json_class_t,
1614 cur_json_class_t::expected_type>( parse_state ) );
1617 using cur_json_class_t =
1618 daw::traits::nth_element<N + 1, JsonClasses...>;
1619 return construct_value<T, Constructor>(
1621 parse_value<cur_json_class_t,
1623 cur_json_class_t::expected_type>( parse_state ) );
1626 DAW_ASSUME( idx == N + 2 );
1627 using cur_json_class_t =
1628 daw::traits::nth_element<N + 2, JsonClasses...>;
1629 return construct_value<T, Constructor>(
1631 parse_value<cur_json_class_t,
1633 cur_json_class_t::expected_type>( parse_state ) );
1636 }
else if constexpr(
sizeof...( JsonClasses ) == N + 2 ) {
1638 using cur_json_class_t =
1639 daw::traits::nth_element<N + 0, JsonClasses...>;
1640 return construct_value<T, Constructor>(
1642 parse_value<cur_json_class_t,
1644 cur_json_class_t::expected_type>( parse_state ) );
1646 using cur_json_class_t =
1647 daw::traits::nth_element<N + 1, JsonClasses...>;
1648 return construct_value<T, Constructor>(
1650 parse_value<cur_json_class_t,
1652 cur_json_class_t::expected_type>( parse_state ) );
1654 using cur_json_class_t =
1655 daw::traits::nth_element<N + 0, JsonClasses...>;
1656 return construct_value<T, Constructor>(
1658 parse_value<cur_json_class_t,
1660 cur_json_class_t::expected_type>( parse_state ) );