48 namespace json_details {
60 template<options::LiteralAsStringOpt literal_as_string,
bool AtEnd =
false,
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,
178 parse_state.empty( ) or
179 parse_policy_details::at_end_of_item( parse_state.front( ) ),
180 ErrorReason::InvalidEndOfValue,
187 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
188 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
189 parse_value_signed( ParseState &parse_state ) {
190 using constructor_t = json_constructor_t<JsonMember>;
191 using element_t = json_base_type_t<JsonMember>;
193 typename daw::conditional_t<std::is_enum_v<element_t>,
194 std::underlying_type<element_t>,
195 daw::traits::identity<element_t>>::type;
197 static_assert( daw::is_signed_v<int_type>,
"Expected signed type" );
198 if constexpr( KnownBounds ) {
200 parse_policy_details::is_number_start( parse_state.front( ) ),
201 ErrorReason::InvalidNumberStart,
204 if constexpr( JsonMember::literal_as_string !=
205 options::LiteralAsStringOpt::Never ) {
206 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
208 }
else if constexpr( not ParseState::is_zero_terminated_string ) {
210 ErrorReason::UnexpectedEndOfData,
214 auto const sign =
static_cast<int_type
>(
215 parse_policy_details::validate_signed_first( parse_state ) );
217 typename daw::conditional_t<daw::is_system_integral_v<int_type>,
218 daw::make_unsigned<int_type>,
219 daw::traits::identity<int_type>>::type;
220 auto parsed_val = to_signed(
221 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
225 if constexpr( KnownBounds ) {
226 return construct_value<json_result_t<JsonMember>, constructor_t>(
227 parse_state,
static_cast<element_t
>( parsed_val ) );
230 construct_value<json_result_t<JsonMember>, constructor_t>(
231 parse_state,
static_cast<element_t
>( parsed_val ) );
232 if constexpr( JsonMember::literal_as_string !=
233 options::LiteralAsStringOpt::Never ) {
234 skip_quote_when_literal_as_string<JsonMember::literal_as_string,
238 parse_state.trim_left( );
240 not parse_state.has_more( ) or
241 parse_policy_details::at_end_of_item( parse_state.front( ) ),
242 ErrorReason::InvalidEndOfValue,
248 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
249 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
250 parse_value_unsigned( ParseState &parse_state ) {
251 using constructor_t = json_constructor_t<JsonMember>;
252 using element_t = json_base_type_t<JsonMember>;
254 typename daw::conditional_t<std::is_enum_v<element_t>,
255 std::underlying_type<element_t>,
256 daw::traits::identity<element_t>>::type;
258 if constexpr( KnownBounds ) {
259 parse_policy_details::validate_unsigned_first( parse_state );
261 return construct_value<json_result_t<JsonMember>, constructor_t>(
263 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
266 if constexpr( JsonMember::literal_as_string !=
267 options::LiteralAsStringOpt::Never ) {
268 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
270 if constexpr( not ParseState::is_zero_terminated_string ) {
272 ErrorReason::UnexpectedEndOfData,
275 }
else if constexpr( not ParseState::is_zero_terminated_string ) {
277 ErrorReason::UnexpectedEndOfData,
281 parse_policy_details::is_number( parse_state.front( ) ),
282 ErrorReason::InvalidNumber,
285 construct_value<json_result_t<JsonMember>, constructor_t>(
287 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
289 if constexpr( JsonMember::literal_as_string !=
290 options::LiteralAsStringOpt::Never ) {
291 skip_quote_when_literal_as_string<JsonMember::literal_as_string,
296 not parse_state.has_more( ) or
297 parse_policy_details::at_end_of_item( parse_state.front( ) ),
298 ErrorReason::InvalidEndOfValue,
304 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
305 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
306 parse_value_null( ParseState &parse_state ) {
308 using constructor_t = json_constructor_t<JsonMember>;
309 auto const construct_empty = [&] {
310 if constexpr( daw::is_callable_v<
312 concepts::construct_nullable_with_empty_t> ) {
313 return construct_value<
typename JsonMember::wrapped_type,
315 parse_state, concepts::construct_nullable_with_empty );
317 return construct_value<
typename JsonMember::wrapped_type,
318 constructor_t>( parse_state );
322 using base_member_type =
typename JsonMember::member_type;
323 static_assert( not std::is_same_v<base_member_type, JsonMember> );
324 if constexpr( KnownBounds ) {
326 if( parse_state.is_null( ) ) {
327 return construct_empty( );
329 return construct_value<base_member_type, constructor_t>(
331 parse_value<base_member_type,
333 base_member_type::expected_type>( parse_state ) );
334 }
else if constexpr( ParseState::is_unchecked_input ) {
335 if( not parse_state.has_more( ) or
336 parse_state.is_at_token_after_value( ) ) {
337 return construct_empty( );
339 if( parse_state.front( ) ==
'n' ) {
340 parse_state.remove_prefix( 4 );
341 parse_state.trim_left_unchecked( );
342 parse_state.remove_prefix( );
343 return construct_empty( );
345 return construct_value<base_member_type, constructor_t>(
347 parse_value<base_member_type,
349 base_member_type::expected_type>( parse_state ) );
351 if( parse_state.is_null( ) or not parse_state.has_more( ) or
352 parse_state.is_at_token_after_value( ) ) {
353 return construct_empty( );
355 if( parse_state.starts_with(
"null" ) ) {
356 parse_state.remove_prefix( 4 );
358 not parse_state.has_more( ) or
359 parse_policy_details::at_end_of_item( parse_state.front( ) ),
360 ErrorReason::InvalidLiteral,
362 parse_state.trim_left_checked( );
363 return construct_empty( );
365 using parse_to_t = json_result_t<base_member_type>;
366 if constexpr( not std::is_move_constructible_v<parse_to_t> and
367 not std::is_copy_constructible_v<parse_to_t> ) {
370 concepts::nullable_value_traits<json_result_t<JsonMember>>,
371 concepts::construct_nullable_with_pointer_t,
373 return construct_value<base_member_type, constructor_t>(
375 concepts::construct_nullable_with_pointer,
377 parse_value<base_member_type,
379 base_member_type::expected_type>( parse_state ) } );
381 return construct_value<base_member_type, constructor_t>(
383 parse_value<base_member_type,
385 base_member_type::expected_type>( parse_state ) );
390 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
391 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
392 parse_value_bool( ParseState &parse_state ) {
393 using constructor_t = json_constructor_t<JsonMember>;
395 if constexpr( KnownBounds ) {
397 if constexpr( ParseState::is_unchecked_input ) {
398 return static_cast<bool>( parse_state.counter );
400 switch( parse_state.front( ) ) {
402 return construct_value<json_result_t<JsonMember>, constructor_t>(
405 return construct_value<json_result_t<JsonMember>, constructor_t>(
406 parse_state, false );
412 if constexpr( JsonMember::literal_as_string !=
413 options::LiteralAsStringOpt::Never ) {
414 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
418 if constexpr( ParseState::is_unchecked_input ) {
419 if( parse_state.front( ) ==
't' ) {
421 parse_state.remove_prefix( 4 );
423 parse_state.remove_prefix( 5 );
426 if( parse_state.starts_with(
"true" ) ) {
427 parse_state.remove_prefix( 4 );
429 }
else if( parse_state.starts_with(
"false" ) ) {
430 parse_state.remove_prefix( 5 );
436 if constexpr( JsonMember::literal_as_string !=
437 options::LiteralAsStringOpt::Never ) {
438 skip_quote_when_literal_as_string<JsonMember::literal_as_string,
442 parse_state.trim_left( );
444 not parse_state.has_more( ) or
445 parse_policy_details::at_end_of_item( parse_state.front( ) ),
446 ErrorReason::InvalidEndOfValue,
448 return construct_value<json_result_t<JsonMember>, constructor_t>(
449 parse_state, result );
453 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
454 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
455 parse_value_string_raw( ParseState &parse_state ) {
457 using constructor_t = json_constructor_t<JsonMember>;
458 if constexpr( KnownBounds ) {
459 return construct_value<json_result_t<JsonMember>, constructor_t>(
460 parse_state, std::data( parse_state ), std::size( parse_state ) );
462 if constexpr( JsonMember::allow_escape_character ==
463 options::AllowEscapeCharacter::Allow ) {
464 auto const str = skip_string( parse_state );
465 return construct_value<json_result_t<JsonMember>, constructor_t>(
466 parse_state, std::data( str ), std::size( str ) );
468 parse_state.remove_prefix( );
470 char const *
const first = parse_state.first;
471 parse_state.template move_to_next_of<
'"'>( );
472 char const *
const last = parse_state.first;
473 parse_state.remove_prefix( );
474 return construct_value<json_result_t<JsonMember>, constructor_t>(
475 parse_state, first,
static_cast<std::size_t
>( last - first ) );
486 template<
typename JsonMember>
487 DAW_CPP20_CONCEPT can_parse_to_stdstring_fast_v =
488 can_single_allocation_string_v<json_result_t<JsonMember>> or
489 can_single_allocation_string_v<json_base_type_t<JsonMember>>;
492 json_constructor_t<T> );
497 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
498 [[nodiscard]] DAW_ATTRIB_INLINE
constexpr json_result_t<JsonMember>
499 parse_value_string_escaped( ParseState &parse_state ) {
500 static_assert( has_json_member_constructor_v<JsonMember> );
501 static_assert( has_json_member_parse_to_v<JsonMember> );
502 if constexpr( not KnownBounds ) {
504 ErrorReason::UnexpectedNull );
506 using constructor_t = json_constructor_t<JsonMember>;
507 if constexpr( can_parse_to_stdstring_fast_v<JsonMember> ) {
508 using AllowHighEightbits =
509 std::bool_constant<JsonMember::eight_bit_mode !=
510 options::EightBitModes::DisallowHigh>;
512 KnownBounds ? parse_state : skip_string( parse_state );
513 if( not AllowHighEightbits::value or
514 needs_slow_path( parse_state2 ) ) {
516 return parse_string_known_stdstring<AllowHighEightbits::value,
518 true>( parse_state2 );
522 return construct_value<json_result_t<JsonMember>, constructor_t>(
524 std::data( parse_state2 ),
525 daw::data_end( parse_state2 ) );
528 KnownBounds ? parse_state : skip_string( parse_state );
529 using AllowHighEightbits =
530 std::bool_constant<JsonMember::eight_bit_mode !=
531 options::EightBitModes::DisallowHigh>;
532 if( not AllowHighEightbits::value or
533 needs_slow_path( parse_state2 ) ) {
535 return parse_string_known_stdstring<AllowHighEightbits::value,
537 true>( parse_state2 );
541 return construct_value<json_result_t<JsonMember>, constructor_t>(
543 std::data( parse_state2 ),
544 daw::data_end( parse_state2 ) );
548 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
549 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
550 parse_value_date( ParseState &parse_state ) {
553 ErrorReason::UnexpectedEndOfData,
555 auto str = KnownBounds ? parse_state : skip_string( parse_state );
556 using constructor_t = json_constructor_t<JsonMember>;
557 return construct_value<json_result_t<JsonMember>, constructor_t>(
558 parse_state, std::data( str ), std::size( str ) );
561 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
562 [[nodiscard]]
static constexpr json_result_t<JsonMember>
563 parse_value_custom( ParseState &parse_state ) {
565 auto const str = [&] {
566 if constexpr( JsonMember::custom_json_type ==
567 options::JsonCustomTypes::String ) {
568 if constexpr( KnownBounds ) {
571 return skip_string( parse_state );
573 }
else if constexpr( JsonMember::custom_json_type ==
574 options::JsonCustomTypes::Literal ) {
575 return KnownBounds ? parse_state : skip_literal( parse_state );
577 static_assert( JsonMember::custom_json_type ==
578 options::JsonCustomTypes::Any );
582 if constexpr( KnownBounds ) {
583 auto result = parse_state;
584 if( *( result.first - 1 ) ==
'"' ) {
589 if( parse_state.front( ) ==
'"' ) {
590 auto result = skip_string( parse_state );
594 return skip_value( parse_state );
599 str.has_more( ) and not( str.front( ) ==
'[' or str.front( ) ==
'{' ),
600 ErrorReason::InvalidStartOfValue,
602 using constructor_t =
typename JsonMember::from_converter_t;
603 return construct_value<json_result_t<JsonMember>, constructor_t>(
604 parse_state, std::string_view( std::data( str ), std::size( str ) ) );
607 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
608 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
609 parse_value_class( ParseState &parse_state ) {
611 using element_t =
typename JsonMember::wrapped_type;
613 ErrorReason::UnexpectedEndOfData,
616 if constexpr( KnownBounds ) {
618 template parse_to_class<JsonMember, KnownBounds>( parse_state );
619 }
else if constexpr( is_pinned_type_v<element_t> ) {
620 auto const run_after_parse = daw::on_exit_success( [&] {
621 parse_state.trim_left_checked( );
623 (void)run_after_parse;
625 template parse_to_class<JsonMember, KnownBounds>( parse_state );
626 }
else if constexpr( is_deduced_empty_class_v<JsonMember> ) {
627 parse_state.trim_left_checked( );
628 return json_result_t<JsonMember>{ };
631 template parse_to_class<JsonMember, KnownBounds>( parse_state );
632 parse_state.trim_left_checked( );
637#if defined( DAW_JSON_HAS_REFLECTION )
638 template<
typename JsonMember,
bool ,
typename ParseState>
639 constexpr json_result_t<JsonMember>
640 parse_value_reflected_class( ParseState &parse_state ) {
642 ErrorReason::UnexpectedEndOfData,
645 return JsonMember::parse_to_class( parse_state );
657 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
658 [[nodiscard]]
static constexpr json_result_t<JsonMember>
659 parse_value_keyvalue( ParseState &parse_state ) {
661 static_assert( JsonMember::expected_type == JsonParseTypes::KeyValue,
662 "Expected a json_key_value" );
664 ErrorReason::ExpectedKeyValueToStartWithBrace,
667 parse_state.remove_prefix( );
668 parse_state.trim_left( );
671 json_parse_kv_class_iterator<JsonMember,
673 can_be_random_iterator_v<KnownBounds>>;
675 using constructor_t = json_constructor_t<JsonMember>;
676 return construct_value<json_result_t<JsonMember>, constructor_t>(
677 parse_state, iter_t( parse_state ), iter_t( ) );
688 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
689 [[nodiscard]]
static constexpr json_result_t<JsonMember>
690 parse_value_keyvalue_array( ParseState &parse_state ) {
692 static_assert( JsonMember::expected_type ==
693 JsonParseTypes::KeyValueArray,
694 "Expected a json_key_value" );
696 parse_state.is_opening_bracket_checked( ),
697 ErrorReason::ExpectedKeyValueArrayToStartWithBracket,
700 parse_state.remove_prefix( );
703 json_parse_kv_array_iterator<JsonMember,
705 can_be_random_iterator_v<KnownBounds>>;
706 using constructor_t = json_constructor_t<JsonMember>;
707 return construct_value<json_result_t<JsonMember>, constructor_t>(
708 parse_state, iter_t( parse_state ), iter_t( ) );
711 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
712 [[nodiscard]]
static constexpr json_result_t<JsonMember>
713 parse_value_array( ParseState &parse_state ) {
714 parse_state.trim_left( );
716 ErrorReason::InvalidArrayStart,
718 parse_state.remove_prefix( );
719 parse_state.trim_left_unchecked( );
724 json_parse_array_iterator<JsonMember,
726 can_be_random_iterator_v<KnownBounds>>;
727 using constructor_t = json_constructor_t<JsonMember>;
728 return construct_value<json_result_t<JsonMember>, constructor_t>(
729 parse_state, iterator_t( parse_state ), iterator_t( ) );
732 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
733 [[nodiscard]]
static constexpr json_result_t<JsonMember>
734 parse_value_sz_array( ParseState &parse_state ) {
736 using size_member = dependent_member_t<JsonMember>;
738 auto [parse_state2, is_found] = find_range<ParseState>(
739 ParseState( parse_state.class_first, parse_state.last ),
743 is_found, ErrorReason::TagMemberNotFound, parse_state );
745 parse_value<size_member, false, size_member::expected_type>(
748 if constexpr( KnownBounds and ParseState::is_unchecked_input ) {
751 auto cnt =
static_cast<std::ptrdiff_t
>( parse_state.counter );
753 ErrorReason::NumberOutOfRange,
756 parse_state.trim_left( );
758 ErrorReason::InvalidArrayStart,
760 parse_state.remove_prefix( );
761 parse_state.trim_left_unchecked( );
765 json_parse_array_iterator<JsonMember, ParseState, false>;
766 using constructor_t = json_constructor_t<JsonMember>;
767 return construct_value<json_result_t<JsonMember>, constructor_t>(
769 iterator_t( parse_state ),
771 static_cast<std::size_t
>( sz ) );
776 [[nodiscard]]
constexpr json_result_t<JsonMembers>
777 parse_variant_value( ParseState &parse_state ) {
778 using element_t =
typename JsonMembers::json_elements;
779 using idx = daw::constant<( JsonMembers::base_map::base_map
780 [
static_cast<std::int_fast8_t
>( BPT )] )>;
782 if constexpr( idx::value <
783 pack_size_v<typename element_t::element_map_t> ) {
785 pack_element_t<idx::value, typename element_t::element_map_t>;
786 return parse_value<JsonMember,
788 JsonMember::expected_type>( parse_state );
794 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
795 [[nodiscard]]
static constexpr json_result_t<JsonMember>
796 parse_value_variant( ParseState &parse_state ) {
797 if constexpr( KnownBounds ) {
800 if( *( parse_state.first - 1 ) ==
'"' ) {
802 return parse_variant_value<JsonBaseParseTypes::String,
804 KnownBounds>( parse_state );
807 switch( parse_state.front( ) ) {
809 return parse_variant_value<JsonBaseParseTypes::Class,
811 KnownBounds>( parse_state );
813 return parse_variant_value<JsonBaseParseTypes::Array,
815 KnownBounds>( parse_state );
818 return parse_variant_value<JsonBaseParseTypes::Bool,
820 KnownBounds>( parse_state );
822 return parse_variant_value<JsonBaseParseTypes::String,
824 KnownBounds>( parse_state );
837 return parse_variant_value<JsonBaseParseTypes::Number,
839 KnownBounds>( parse_state );
841 if constexpr( ParseState::is_unchecked_input ) {
844 daw_json_error(
true, ErrorReason::InvalidStartOfValue, parse_state );
848 template<
typename Result,
typename TypeList, std::size_t pos = 0,
850 DAW_ATTRIB_INLINE
constexpr Result
851 parse_visit( std::size_t idx, ParseState &parse_state ) {
853 using JsonMember = pack_element_t<pos, TypeList>;
854 if constexpr( std::is_same_v<json_result_t<JsonMember>, Result> ) {
855 return parse_value<JsonMember, false, JsonMember::expected_type>(
859 parse_value<JsonMember, false, JsonMember::expected_type>(
863 if constexpr( pos + 1 < pack_size_v<TypeList> ) {
864 return parse_visit<Result, TypeList, pos + 1>( idx, parse_state );
866 if constexpr( ParseState::is_unchecked_input ) {
870 true, ErrorReason::MissingMemberNameOrEndOfClass, parse_state );
875 template<
typename JsonMember,
typename ParseState>
876 [[nodiscard]]
constexpr auto find_index( ParseState
const &parse_state ) {
877 using tag_member =
typename JsonMember::tag_member;
878 using class_wrapper_t =
typename JsonMember::tag_member_class_wrapper;
880 using switcher_t =
typename JsonMember::switcher;
881 auto parse_state2 = ParseState( parse_state.class_first,
882 parse_state.class_last,
883 parse_state.class_first,
884 parse_state.class_last );
885 if constexpr( is_an_ordered_member_v<tag_member> ) {
888 ErrorReason::InvalidArrayStart,
890 return switcher_t{ }( std::get<0>(
891 parse_value<class_wrapper_t, false, class_wrapper_t::expected_type>(
896 ErrorReason::InvalidClassStart,
898 return switcher_t{ }( std::get<0>(
899 parse_value<class_wrapper_t, false, class_wrapper_t::expected_type>(
905 template<
typename JsonMember,
typename ParseState>
906 [[nodiscard]]
constexpr json_result_t<JsonMember>
907 parse_value_variant_tagged( ParseState &parse_state ) {
908 auto const index = find_index<JsonMember>( parse_state );
909 return parse_visit<json_result_t<JsonMember>,
910 typename JsonMember::json_elements::element_map_t>(
911 index, parse_state );
914 template<
typename JsonMember,
typename ParseState>
915 [[nodiscard]]
constexpr json_result_t<JsonMember>
916 parse_value_variant_intrusive( ParseState &parse_state ) {
917 auto const index = [&] {
918 using tag_submember =
typename JsonMember::tag_submember;
919 using class_wrapper_t =
920 typename JsonMember::tag_submember_class_wrapper;
921 auto parse_state2 = parse_state;
922 using switcher_t =
typename JsonMember::switcher;
923 if constexpr( is_an_ordered_member_v<tag_submember> ) {
924 return switcher_t{ }( std::get<0>(
925 parse_value<class_wrapper_t,
927 class_wrapper_t::expected_type>( parse_state2 ) ) );
929 return switcher_t{ }( std::get<0>(
930 parse_value<class_wrapper_t,
932 class_wrapper_t::expected_type>( parse_state2 )
937 return parse_visit<json_result_t<JsonMember>,
938 typename JsonMember::json_elements::element_map_t>(
939 index, parse_state );
942 template<
bool AllMembersMustExist,
typename ParseState,
943 typename OldClassPos>
944 DAW_ATTRIB_INLINE
constexpr void ordered_class_cleanup(
945 ParseState &parse_state,
948 if constexpr( AllMembersMustExist ) {
949 parse_state.trim_left( );
951 ErrorReason::UnknownMember,
953 parse_state.remove_prefix( );
954 parse_state.trim_left_checked( );
956 (void)parse_state.skip_array( );
958 parse_state.set_class_position( old_class_pos );
961 namespace pocm_details {
969 template<
bool Nullable,
typename ParseState>
970 constexpr void maybe_skip_members( ParseState &parse_state,
971 std::size_t ¤t_position,
972 std::size_t desired_position ) {
975 ErrorReason::OutOfOrderOrderedMembers,
977 using skip_check_end =
978 std::bool_constant<( ParseState::is_unchecked_input and Nullable )>;
979 while( ( current_position < desired_position ) &
980 ( skip_check_end::value or parse_state.front( ) !=
']' ) ) {
981 (void)skip_value( parse_state );
982 parse_state.move_next_member_or_end( );
985 ErrorReason::UnexpectedEndOfData,
990#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
991 template<
typename ParseState>
992 struct position_info {
996 constexpr explicit operator bool( )
const {
997 return not state.is_null( );
1008 template<
bool Nullable,
typename ParseState, std::
size_t N>
1009 DAW_ATTRIB_INLINE
static constexpr ParseState maybe_skip_members(
1010 ParseState &parse_state, std::size_t ¤t_position,
1011 std::size_t desired_position,
1012 std::array<position_info<ParseState>, N> &parse_locations ) {
1014 auto const desired = daw::algorithm::find_if(
1015 std::data( parse_locations ),
1016 daw::data_end( parse_locations ),
1017 [desired_position]( position_info<ParseState>
const &loc ) {
1018 return loc.index == desired_position;
1021 return desired->state;
1023#if not defined( NDEBUG )
1025 ErrorReason::UnexpectedEndOfData,
1028 using skip_check_end =
1029 std::bool_constant<( ParseState::is_unchecked_input and Nullable )>;
1030 while( ( current_position < desired_position ) &
1031 ( skip_check_end::value or parse_state.front( ) !=
']' ) ) {
1032 auto const current = daw::algorithm::find_if(
1033 std::data( parse_locations ),
1034 daw::data_end( parse_locations ),
1035 [current_position]( position_info<ParseState>
const &loc ) {
1036 return loc.index == current_position;
1038 auto state = skip_value( parse_state );
1039 if( current != daw::data_end( parse_locations ) ) {
1040 current->state = state;
1042 parse_state.move_next_member_or_end( );
1045 ErrorReason::UnexpectedEndOfData,
1053 template<
typename T>
1054 struct member_index_t {
1055 static constexpr std::size_t value = T::member_index;
1058 template<
typename Idx,
typename JsonMember>
1059 inline constexpr std::size_t member_index_v =
1060 daw::conditional_t<has_member_index_v<JsonMember>,
1061 member_index_t<JsonMember>, Idx>::value;
1064 template<
typename JsonMember,
bool KnownBounds,
typename ParseState,
1066 DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1067 parse_tuple_value( ParseState &parse_state, std::index_sequence<Is...> ) {
1068 parse_state.trim_left( );
1070 ErrorReason::InvalidArrayStart,
1073 auto const old_class_pos = parse_state.get_class_position( );
1074 parse_state.set_class_position( );
1075 parse_state.remove_prefix( );
1076 parse_state.move_next_member_or_end( );
1077 using tuple_t = json_base_type_t<JsonMember>;
1078 using tuple_members =
typename JsonMember::sub_member_list;
1080#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1081 using position_info_t = pocm_details::position_info<ParseState>;
1082 std::size_t parse_locations_last_index = 0U;
1083 std::array<position_info_t,
sizeof...( Is )> parse_locations{
1084 [&](
auto Index )
mutable -> position_info_t {
1085 constexpr std::size_t index =
decltype( Index )::value;
1086 using member_t = std::tuple_element_t<index, tuple_members>;
1087 if constexpr( is_an_ordered_member_v<member_t> ) {
1088 parse_locations_last_index = member_t::member_index;
1089 return { member_t::member_index };
1091 return { parse_locations_last_index++ };
1093 }(daw::constant_v<Is>)... };
1095 auto const parse_value_help = [&](
auto PackIdx,
1096 std::size_t &ClassIdx ) {
1097 using index_t =
decltype( PackIdx );
1098 using CurrentMember =
1099 std::tuple_element_t<index_t::value, tuple_members>;
1101 using json_member_t = ordered_member_subtype_t<CurrentMember>;
1103#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1104 ParseState parse_state2 =
1105 pocm_details::maybe_skip_members<is_json_nullable_v<json_member_t>>(
1108 pocm_details::member_index_v<index_t, CurrentMember>,
1110 if constexpr(
sizeof...( Is ) > 1 ) {
1112 if( parse_state2.first == parse_state.first ) {
1113 if constexpr( is_pinned_type_v<json_result_t<JsonMember>> ) {
1114 auto const run_after_parse = daw::on_exit_success( [&] {
1115 parse_state.move_next_member_or_end( );
1117 (void)run_after_parse;
1118 return parse_value<json_member_t,
1120 json_member_t::expected_type>( parse_state );
1123 parse_value<json_member_t,
1125 json_member_t::expected_type>( parse_state );
1126 parse_state.move_next_member_or_end( );
1131 return parse_value<json_member_t,
1133 json_member_t::expected_type>( parse_state2 );
1137 if constexpr( is_an_ordered_member_v<CurrentMember> ) {
1138 pocm_details::maybe_skip_members<
1139 is_json_nullable_v<json_member_t>>(
1140 parse_state, ClassIdx, CurrentMember::member_index );
1143 ErrorReason::UnexpectedEndOfData,
1147 if constexpr( is_pinned_type_v<json_result_t<JsonMember>> ) {
1148 auto const run_after_parse = daw::on_exit_success( [&] {
1149 parse_state.move_next_member_or_end( );
1151 (void)run_after_parse;
1152 return parse_value<json_member_t,
1154 json_member_t::expected_type>( parse_state );
1157 parse_value<json_member_t, false, json_member_t::expected_type>(
1159 parse_state.move_next_member_or_end( );
1162#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1167 static_assert( is_a_json_type_v<JsonMember> );
1168 using Constructor = json_constructor_t<JsonMember>;
1170 parse_state.trim_left( );
1172 std::size_t class_idx = 0;
1173 if constexpr( is_pinned_type_v<json_result_t<JsonMember>> ) {
1174 auto const run_after_parse = daw::on_exit_success( [&] {
1175 ordered_class_cleanup<
1176 all_json_members_must_exist_v<JsonMember, ParseState>,
1178 decltype( old_class_pos )>( parse_state, old_class_pos );
1180 (void)run_after_parse;
1185 parse_value_help( daw::constant_v<Is>, class_idx )... };
1187 return construct_value_tp<tuple_t, Constructor>(
1190 parse_value_help( daw::constant_v<Is>, class_idx )... } );
1198 parse_value_help( daw::constant_v<Is>, class_idx )... };
1200 return construct_value_tp<tuple_t, Constructor>(
1203 parse_value_help( daw::constant_v<Is>, class_idx )... } );
1206 if constexpr( all_json_members_must_exist_v<tuple_t, ParseState> ) {
1207 parse_state.trim_left( );
1209 ErrorReason::UnknownMember,
1211 parse_state.remove_prefix( );
1212 parse_state.trim_left( );
1214 (void)parse_state.skip_array( );
1216 parse_state.set_class_position( old_class_pos );
1221 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
1222 static constexpr json_result_t<JsonMember>
1223 parse_value_tuple( ParseState &parse_state ) {
1224 using element_pack =
1225 typename JsonMember::sub_member_list;
1227 return parse_tuple_value<JsonMember, KnownBounds>(
1229 std::make_index_sequence<std::tuple_size_v<element_pack>>{ } );
1232 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
1233 DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1234 parse_value_unknown( ParseState &parse_state ) {
1235 using constructor_t = json_constructor_t<JsonMember>;
1236 if constexpr( KnownBounds ) {
1237 return construct_value<json_result_t<JsonMember>, constructor_t>(
1238 parse_state, std::data( parse_state ), std::size( parse_state ) );
1240 auto value_parse_state = skip_value<true>( parse_state );
1241 return construct_value<json_result_t<JsonMember>, constructor_t>(
1243 std::data( value_parse_state ),
1244 std::size( value_parse_state ) );
1248 template<
typename JsonMember,
bool KnownBounds,
JsonParseTypes PTag,
1249 typename ParseState>
1250 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1251 parse_value( ParseState &parse_state ) {
1252 if constexpr( PTag == JsonParseTypes::Real ) {
1253 return parse_value_real<JsonMember, KnownBounds>( parse_state );
1254 }
else if constexpr( PTag == JsonParseTypes::Signed ) {
1255 return parse_value_signed<JsonMember, KnownBounds>( parse_state );
1256 }
else if constexpr( PTag == JsonParseTypes::Unsigned ) {
1257 return parse_value_unsigned<JsonMember, KnownBounds>( parse_state );
1258 }
else if constexpr( PTag == JsonParseTypes::Null ) {
1259 return parse_value_null<JsonMember, KnownBounds>( parse_state );
1260 }
else if constexpr( PTag == JsonParseTypes::Bool ) {
1261 return parse_value_bool<JsonMember, KnownBounds>( parse_state );
1262 }
else if constexpr( PTag == JsonParseTypes::StringRaw ) {
1263 return parse_value_string_raw<JsonMember, KnownBounds>( parse_state );
1264 }
else if constexpr( PTag == JsonParseTypes::StringEscaped ) {
1265 return parse_value_string_escaped<JsonMember, KnownBounds>(
1267 }
else if constexpr( PTag == JsonParseTypes::Date ) {
1268 return parse_value_date<JsonMember, KnownBounds>( parse_state );
1269 }
else if constexpr( PTag == JsonParseTypes::Custom ) {
1270 return parse_value_custom<JsonMember, KnownBounds>( parse_state );
1271 }
else if constexpr( PTag == JsonParseTypes::Class ) {
1272 return parse_value_class<JsonMember, KnownBounds>( parse_state );
1273 }
else if constexpr( PTag == JsonParseTypes::KeyValue ) {
1274 return parse_value_keyvalue<JsonMember, KnownBounds>( parse_state );
1275 }
else if constexpr( PTag == JsonParseTypes::KeyValueArray ) {
1276 return parse_value_keyvalue_array<JsonMember, KnownBounds>(
1278 }
else if constexpr( PTag == JsonParseTypes::Array ) {
1279 return parse_value_array<JsonMember, KnownBounds>( parse_state );
1280 }
else if constexpr( PTag == JsonParseTypes::SizedArray ) {
1281 return parse_value_sz_array<JsonMember, KnownBounds>( parse_state );
1282 }
else if constexpr( PTag == JsonParseTypes::Variant ) {
1283 return parse_value_variant<JsonMember, KnownBounds>( parse_state );
1284 }
else if constexpr( PTag == JsonParseTypes::VariantTagged ) {
1285 return parse_value_variant_tagged<JsonMember>( parse_state );
1286 }
else if constexpr( PTag == JsonParseTypes::VariantIntrusive ) {
1287 return parse_value_variant_intrusive<JsonMember>( parse_state );
1288 }
else if constexpr( PTag == JsonParseTypes::Tuple ) {
1289 return parse_value_tuple<JsonMember, KnownBounds>( parse_state );
1290#if defined( DAW_JSON_HAS_REFLECTION )
1291 }
else if constexpr( PTag == JsonParseTypes::ReflectedClass ) {
1292 return parse_value_reflected_class<JsonMember, KnownBounds>(
1296 static_assert( PTag == JsonParseTypes::Unknown,
1297 "Unexpected JsonParseType" );
1298 return parse_value_unknown<JsonMember, KnownBounds>( parse_state );
1302 template<std::size_t N,
typename JsonClass,
bool KnownBounds,
1303 typename... JsonClasses,
typename ParseState>
1304 DAW_ATTRIB_INLINE
constexpr json_result_t<JsonClass>
1305 parse_nth_class( std::size_t idx, ParseState &parse_state ) {
1307 DAW_ASSUME( idx <
sizeof...( JsonClasses ) );
1308 using T = json_base_type_t<JsonClass>;
1309 using Constructor = json_constructor_t<JsonClass>;
1310 if constexpr(
sizeof...( JsonClasses ) >= N + 8 ) {
1313 using cur_json_class_t =
1314 daw::traits::nth_element<N + 0, JsonClasses...>;
1315 return construct_value<T, Constructor>(
1317 parse_value<cur_json_class_t,
1319 cur_json_class_t::expected_type>( parse_state ) );
1322 using cur_json_class_t =
1323 daw::traits::nth_element<N + 1, JsonClasses...>;
1324 return construct_value<T, Constructor>(
1326 parse_value<cur_json_class_t,
1328 cur_json_class_t::expected_type>( parse_state ) );
1331 using cur_json_class_t =
1332 daw::traits::nth_element<N + 2, JsonClasses...>;
1333 return construct_value<T, Constructor>(
1335 parse_value<cur_json_class_t,
1337 cur_json_class_t::expected_type>( parse_state ) );
1340 using cur_json_class_t =
1341 daw::traits::nth_element<N + 3, JsonClasses...>;
1342 return construct_value<T, Constructor>(
1344 parse_value<cur_json_class_t,
1346 cur_json_class_t::expected_type>( parse_state ) );
1349 using cur_json_class_t =
1350 daw::traits::nth_element<N + 4, JsonClasses...>;
1351 return construct_value<T, Constructor>(
1353 parse_value<cur_json_class_t,
1355 cur_json_class_t::expected_type>( parse_state ) );
1358 using cur_json_class_t =
1359 daw::traits::nth_element<N + 5, JsonClasses...>;
1360 return construct_value<T, Constructor>(
1362 parse_value<cur_json_class_t,
1364 cur_json_class_t::expected_type>( parse_state ) );
1367 using cur_json_class_t =
1368 daw::traits::nth_element<N + 6, JsonClasses...>;
1369 return construct_value<T, Constructor>(
1371 parse_value<cur_json_class_t,
1373 cur_json_class_t::expected_type>( parse_state ) );
1376 using cur_json_class_t =
1377 daw::traits::nth_element<N + 7, JsonClasses...>;
1378 return construct_value<T, Constructor>(
1380 parse_value<cur_json_class_t,
1382 cur_json_class_t::expected_type>( parse_state ) );
1385 if constexpr(
sizeof...( JsonClasses ) >= N + 8 ) {
1386 return parse_nth_class<N + 8,
1389 JsonClasses...>( idx, parse_state );
1394 }
else if constexpr(
sizeof...( JsonClasses ) == N + 7 ) {
1397 using cur_json_class_t =
1398 daw::traits::nth_element<N + 0, JsonClasses...>;
1399 return construct_value<T, Constructor>(
1401 parse_value<cur_json_class_t,
1403 cur_json_class_t::expected_type>( parse_state ) );
1406 using cur_json_class_t =
1407 daw::traits::nth_element<N + 1, JsonClasses...>;
1408 return construct_value<T, Constructor>(
1410 parse_value<cur_json_class_t,
1412 cur_json_class_t::expected_type>( parse_state ) );
1415 using cur_json_class_t =
1416 daw::traits::nth_element<N + 2, JsonClasses...>;
1417 return construct_value<T, Constructor>(
1419 parse_value<cur_json_class_t,
1421 cur_json_class_t::expected_type>( parse_state ) );
1424 using cur_json_class_t =
1425 daw::traits::nth_element<N + 3, JsonClasses...>;
1426 return construct_value<T, Constructor>(
1428 parse_value<cur_json_class_t,
1430 cur_json_class_t::expected_type>( parse_state ) );
1433 using cur_json_class_t =
1434 daw::traits::nth_element<N + 4, JsonClasses...>;
1435 return construct_value<T, Constructor>(
1437 parse_value<cur_json_class_t,
1439 cur_json_class_t::expected_type>( parse_state ) );
1442 using cur_json_class_t =
1443 daw::traits::nth_element<N + 5, JsonClasses...>;
1444 return construct_value<T, Constructor>(
1446 parse_value<cur_json_class_t,
1448 cur_json_class_t::expected_type>( parse_state ) );
1451 DAW_ASSUME( idx == N + 6 );
1452 using cur_json_class_t =
1453 daw::traits::nth_element<N + 6, JsonClasses...>;
1454 return construct_value<T, Constructor>(
1456 parse_value<cur_json_class_t,
1458 cur_json_class_t::expected_type>( parse_state ) );
1461 }
else if constexpr(
sizeof...( JsonClasses ) == N + 6 ) {
1464 using cur_json_class_t =
1465 daw::traits::nth_element<N + 0, JsonClasses...>;
1466 return construct_value<T, Constructor>(
1468 parse_value<cur_json_class_t,
1470 cur_json_class_t::expected_type>( parse_state ) );
1473 using cur_json_class_t =
1474 daw::traits::nth_element<N + 1, JsonClasses...>;
1475 return construct_value<T, Constructor>(
1477 parse_value<cur_json_class_t,
1479 cur_json_class_t::expected_type>( parse_state ) );
1482 using cur_json_class_t =
1483 daw::traits::nth_element<N + 2, JsonClasses...>;
1484 return construct_value<T, Constructor>(
1486 parse_value<cur_json_class_t,
1488 cur_json_class_t::expected_type>( parse_state ) );
1491 using cur_json_class_t =
1492 daw::traits::nth_element<N + 3, JsonClasses...>;
1493 return construct_value<T, Constructor>(
1495 parse_value<cur_json_class_t,
1497 cur_json_class_t::expected_type>( parse_state ) );
1500 using cur_json_class_t =
1501 daw::traits::nth_element<N + 4, JsonClasses...>;
1502 return construct_value<T, Constructor>(
1504 parse_value<cur_json_class_t,
1506 cur_json_class_t::expected_type>( parse_state ) );
1509 DAW_ASSUME( idx == N + 5 );
1510 using cur_json_class_t =
1511 daw::traits::nth_element<N + 5, JsonClasses...>;
1512 return construct_value<T, Constructor>(
1514 parse_value<cur_json_class_t,
1516 cur_json_class_t::expected_type>( parse_state ) );
1519 }
else if constexpr(
sizeof...( JsonClasses ) == N + 5 ) {
1522 using cur_json_class_t =
1523 daw::traits::nth_element<N + 0, JsonClasses...>;
1524 return construct_value<T, Constructor>(
1526 parse_value<cur_json_class_t,
1528 cur_json_class_t::expected_type>( parse_state ) );
1531 using cur_json_class_t =
1532 daw::traits::nth_element<N + 1, JsonClasses...>;
1533 return construct_value<T, Constructor>(
1535 parse_value<cur_json_class_t,
1537 cur_json_class_t::expected_type>( parse_state ) );
1540 using cur_json_class_t =
1541 daw::traits::nth_element<N + 2, JsonClasses...>;
1542 return construct_value<T, Constructor>(
1544 parse_value<cur_json_class_t,
1546 cur_json_class_t::expected_type>( parse_state ) );
1549 using cur_json_class_t =
1550 daw::traits::nth_element<N + 3, JsonClasses...>;
1551 return construct_value<T, Constructor>(
1553 parse_value<cur_json_class_t,
1555 cur_json_class_t::expected_type>( parse_state ) );
1558 DAW_ASSUME( idx == N + 4 );
1559 using cur_json_class_t =
1560 daw::traits::nth_element<N + 4, JsonClasses...>;
1561 return construct_value<T, Constructor>(
1563 parse_value<cur_json_class_t,
1565 cur_json_class_t::expected_type>( parse_state ) );
1568 }
else if constexpr(
sizeof...( JsonClasses ) == N + 4 ) {
1571 using cur_json_class_t =
1572 daw::traits::nth_element<N + 0, JsonClasses...>;
1573 return construct_value<T, Constructor>(
1575 parse_value<cur_json_class_t,
1577 cur_json_class_t::expected_type>( parse_state ) );
1580 using cur_json_class_t =
1581 daw::traits::nth_element<N + 1, JsonClasses...>;
1582 return construct_value<T, Constructor>(
1584 parse_value<cur_json_class_t,
1586 cur_json_class_t::expected_type>( parse_state ) );
1589 using cur_json_class_t =
1590 daw::traits::nth_element<N + 2, JsonClasses...>;
1591 return construct_value<T, Constructor>(
1593 parse_value<cur_json_class_t,
1595 cur_json_class_t::expected_type>( parse_state ) );
1598 DAW_ASSUME( idx == N + 3 );
1599 using cur_json_class_t =
1600 daw::traits::nth_element<N + 3, JsonClasses...>;
1601 return construct_value<T, Constructor>(
1603 parse_value<cur_json_class_t,
1605 cur_json_class_t::expected_type>( parse_state ) );
1608 }
else if constexpr(
sizeof...( JsonClasses ) == N + 3 ) {
1611 using cur_json_class_t =
1612 daw::traits::nth_element<N + 0, JsonClasses...>;
1613 return construct_value<T, Constructor>(
1615 parse_value<cur_json_class_t,
1617 cur_json_class_t::expected_type>( parse_state ) );
1620 using cur_json_class_t =
1621 daw::traits::nth_element<N + 1, JsonClasses...>;
1622 return construct_value<T, Constructor>(
1624 parse_value<cur_json_class_t,
1626 cur_json_class_t::expected_type>( parse_state ) );
1629 DAW_ASSUME( idx == N + 2 );
1630 using cur_json_class_t =
1631 daw::traits::nth_element<N + 2, JsonClasses...>;
1632 return construct_value<T, Constructor>(
1634 parse_value<cur_json_class_t,
1636 cur_json_class_t::expected_type>( parse_state ) );
1639 }
else if constexpr(
sizeof...( JsonClasses ) == N + 2 ) {
1641 using cur_json_class_t =
1642 daw::traits::nth_element<N + 0, JsonClasses...>;
1643 return construct_value<T, Constructor>(
1645 parse_value<cur_json_class_t,
1647 cur_json_class_t::expected_type>( parse_state ) );
1649 using cur_json_class_t =
1650 daw::traits::nth_element<N + 1, JsonClasses...>;
1651 return construct_value<T, Constructor>(
1653 parse_value<cur_json_class_t,
1655 cur_json_class_t::expected_type>( parse_state ) );
1657 using cur_json_class_t =
1658 daw::traits::nth_element<N + 0, JsonClasses...>;
1659 return construct_value<T, Constructor>(
1661 parse_value<cur_json_class_t,
1663 cur_json_class_t::expected_type>( parse_state ) );