45 namespace json_details {
57 template<options::LiteralAsStringOpt literal_as_string,
58 bool AtEnd =
false,
typename ParseState>
59 DAW_ATTRIB_INLINE
constexpr void
60 skip_quote_when_literal_as_string( ParseState &parse_state ) {
61 if constexpr( literal_as_string ==
62 options::LiteralAsStringOpt::Always ) {
64 ErrorReason::InvalidNumberUnexpectedQuoting,
66 parse_state.remove_prefix( );
67 }
else if constexpr( literal_as_string ==
68 options::LiteralAsStringOpt::Maybe ) {
69 if constexpr( not AtEnd ) {
71 ErrorReason::UnexpectedEndOfData,
74 if( parse_state.has_more( ) and parse_state.front( ) ==
'"' ) {
75 parse_state.remove_prefix( );
80 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
81 [[nodiscard]]
constexpr json_result_t<JsonMember>
82 parse_value_real( ParseState &parse_state ) {
83 using constructor_t = json_constructor_t<JsonMember>;
84 using element_t = json_base_type_t<JsonMember>;
86 if constexpr( JsonMember::literal_as_string !=
87 options::LiteralAsStringOpt::Never ) {
88 if constexpr( not KnownBounds ) {
89 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
92 if constexpr( JsonMember::allow_number_errors ==
93 options::JsonNumberErrors::AllowInf or
94 JsonMember::allow_number_errors ==
95 options::JsonNumberErrors::AllowNanInf ) {
96 element_t sign = element_t( 1.0 );
97 if( parse_state.front( ) ==
'-' ) {
98 sign = element_t( -1.0 );
102 if( parse_state.starts_with_skip(
"Inf" ) ) {
103 if( not( parse_state.starts_with_skip(
"\"" ) or
104 parse_state.starts_with_skip(
"inity\"" ) ) ) {
107 if constexpr( KnownBounds ) {
109 ErrorReason::InvalidNumber,
113 parse_policy_details::at_end_of_item(
114 parse_state.front( ) ),
115 ErrorReason::InvalidEndOfValue,
118 return daw::cxmath::copy_sign(
119 daw::numeric_limits<element_t>::infinity( ), sign );
120 }
else if( sign < element_t( 0 ) ) {
124 if constexpr( JsonMember::allow_number_errors ==
125 options::JsonNumberErrors::AllowNaN or
126 JsonMember::allow_number_errors ==
127 options::JsonNumberErrors::AllowNanInf ) {
128 if( parse_state.starts_with(
"NaN" ) ) {
129 parse_state.template move_to_next_of<
'"'>( );
130 parse_state.remove_prefix( );
131 if constexpr( KnownBounds ) {
133 ErrorReason::InvalidNumber,
137 parse_policy_details::at_end_of_item(
138 parse_state.front( ) ),
139 ErrorReason::InvalidEndOfValue,
142 return daw::numeric_limits<element_t>::quiet_NaN( );
146 if constexpr( KnownBounds and JsonMember::literal_as_string ==
147 options::LiteralAsStringOpt::Never ) {
148 return construct_value<json_result_t<JsonMember>, constructor_t>(
149 parse_state, parse_real<element_t, true>( parse_state ) );
152 parse_state.has_more( ) and
153 parse_policy_details::is_number_start( parse_state.front( ) ),
154 ErrorReason::InvalidNumberStart,
158 construct_value<json_result_t<JsonMember>, constructor_t>(
159 parse_state, parse_real<element_t, false>( parse_state ) );
161 if constexpr( KnownBounds ) {
163 parse_state.empty( ) or
164 parse_policy_details::at_end_of_item( parse_state.front( ) ),
165 ErrorReason::InvalidEndOfValue,
168 if constexpr( JsonMember::literal_as_string !=
169 options::LiteralAsStringOpt::Never ) {
170 skip_quote_when_literal_as_string<JsonMember::literal_as_string,
171 true>( parse_state );
174 parse_state.empty( ) or
175 parse_policy_details::at_end_of_item( parse_state.front( ) ),
176 ErrorReason::InvalidEndOfValue,
183 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
184 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
185 parse_value_signed( ParseState &parse_state ) {
186 using constructor_t = json_constructor_t<JsonMember>;
187 using element_t = json_base_type_t<JsonMember>;
189 typename daw::conditional_t<std::is_enum_v<element_t>,
190 std::underlying_type<element_t>,
191 daw::traits::identity<element_t>>::type;
193 static_assert( daw::is_signed_v<int_type>,
"Expected signed type" );
194 if constexpr( KnownBounds ) {
196 parse_policy_details::is_number_start( parse_state.front( ) ),
197 ErrorReason::InvalidNumberStart,
200 if constexpr( JsonMember::literal_as_string !=
201 options::LiteralAsStringOpt::Never ) {
202 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
204 }
else if constexpr( not ParseState::is_zero_terminated_string ) {
206 ErrorReason::UnexpectedEndOfData,
210 auto const sign =
static_cast<int_type
>(
211 parse_policy_details::validate_signed_first( parse_state ) );
213 typename daw::conditional_t<daw::is_system_integral_v<int_type>,
214 daw::make_unsigned<int_type>,
215 daw::traits::identity<int_type>>::type;
216 auto parsed_val = to_signed(
217 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
221 if constexpr( KnownBounds ) {
222 return construct_value<json_result_t<JsonMember>, constructor_t>(
223 parse_state,
static_cast<element_t
>( parsed_val ) );
226 construct_value<json_result_t<JsonMember>, constructor_t>(
227 parse_state,
static_cast<element_t
>( parsed_val ) );
228 if constexpr( JsonMember::literal_as_string !=
229 options::LiteralAsStringOpt::Never ) {
230 skip_quote_when_literal_as_string<JsonMember::literal_as_string,
231 true>( parse_state );
233 parse_state.trim_left( );
235 not parse_state.has_more( ) or
236 parse_policy_details::at_end_of_item( parse_state.front( ) ),
237 ErrorReason::InvalidEndOfValue,
243 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
244 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
245 parse_value_unsigned( ParseState &parse_state ) {
246 using constructor_t = json_constructor_t<JsonMember>;
247 using element_t = json_base_type_t<JsonMember>;
249 typename daw::conditional_t<std::is_enum_v<element_t>,
250 std::underlying_type<element_t>,
251 daw::traits::identity<element_t>>::type;
253 if constexpr( KnownBounds ) {
254 parse_policy_details::validate_unsigned_first( parse_state );
256 return construct_value<json_result_t<JsonMember>, constructor_t>(
258 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
261 if constexpr( JsonMember::literal_as_string !=
262 options::LiteralAsStringOpt::Never ) {
263 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
265 if constexpr( not ParseState::is_zero_terminated_string ) {
267 ErrorReason::UnexpectedEndOfData,
270 }
else if constexpr( not ParseState::is_zero_terminated_string ) {
272 ErrorReason::UnexpectedEndOfData,
276 parse_policy_details::is_number( parse_state.front( ) ),
277 ErrorReason::InvalidNumber,
280 construct_value<json_result_t<JsonMember>, constructor_t>(
282 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
284 if constexpr( JsonMember::literal_as_string !=
285 options::LiteralAsStringOpt::Never ) {
286 skip_quote_when_literal_as_string<JsonMember::literal_as_string,
287 true>( parse_state );
290 not parse_state.has_more( ) or
291 parse_policy_details::at_end_of_item( parse_state.front( ) ),
292 ErrorReason::InvalidEndOfValue,
298 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
299 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
300 parse_value_null( ParseState &parse_state ) {
302 using constructor_t = json_constructor_t<JsonMember>;
303 auto const construct_empty = [&] {
304 if constexpr( daw::is_callable_v<
306 concepts::construct_nullable_with_empty_t> ) {
307 return construct_value<
typename JsonMember::wrapped_type,
309 parse_state, concepts::construct_nullable_with_empty );
311 return construct_value<
typename JsonMember::wrapped_type,
312 constructor_t>( parse_state );
316 using base_member_type =
typename JsonMember::member_type;
317 static_assert( not std::is_same_v<base_member_type, JsonMember> );
318 if constexpr( KnownBounds ) {
320 if( parse_state.is_null( ) ) {
321 return construct_empty( );
323 return construct_value<base_member_type, constructor_t>(
325 parse_value<base_member_type,
327 base_member_type::expected_type>( parse_state ) );
328 }
else if constexpr( ParseState::is_unchecked_input ) {
329 if( not parse_state.has_more( ) or
330 parse_state.is_at_token_after_value( ) ) {
331 return construct_empty( );
333 if( parse_state.front( ) ==
'n' ) {
334 parse_state.remove_prefix( 4 );
335 parse_state.trim_left_unchecked( );
336 return construct_empty( );
338 return construct_value<base_member_type, constructor_t>(
340 parse_value<base_member_type,
342 base_member_type::expected_type>( parse_state ) );
344 if( parse_state.is_null( ) or not parse_state.has_more( ) or
345 parse_state.is_at_token_after_value( ) ) {
346 return construct_empty( );
348 if( parse_state.starts_with(
"null" ) ) {
349 parse_state.remove_prefix( 4 );
351 not parse_state.has_more( ) or
352 parse_policy_details::at_end_of_item( parse_state.front( ) ),
353 ErrorReason::InvalidLiteral,
355 parse_state.trim_left_checked( );
356 return construct_empty( );
358 using parse_to_t = json_result_t<base_member_type>;
359 if constexpr( not std::is_move_constructible_v<parse_to_t> and
360 not std::is_copy_constructible_v<parse_to_t> ) {
363 concepts::nullable_value_traits<json_result_t<JsonMember>>,
364 concepts::construct_nullable_with_pointer_t,
366 return construct_value<base_member_type, constructor_t>(
368 concepts::construct_nullable_with_pointer,
370 parse_value<base_member_type,
372 base_member_type::expected_type>( parse_state ) } );
374 return construct_value<base_member_type, constructor_t>(
376 parse_value<base_member_type,
378 base_member_type::expected_type>( parse_state ) );
383 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
384 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
385 parse_value_bool( ParseState &parse_state ) {
386 using constructor_t = json_constructor_t<JsonMember>;
388 if constexpr( KnownBounds ) {
390 if constexpr( ParseState::is_unchecked_input ) {
391 return static_cast<bool>( parse_state.counter );
393 switch( parse_state.front( ) ) {
395 return construct_value<json_result_t<JsonMember>, constructor_t>(
398 return construct_value<json_result_t<JsonMember>, constructor_t>(
399 parse_state, false );
405 if constexpr( JsonMember::literal_as_string !=
406 options::LiteralAsStringOpt::Never ) {
407 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
411 if constexpr( ParseState::is_unchecked_input ) {
412 if( parse_state.front( ) ==
't' ) {
414 parse_state.remove_prefix( 4 );
416 parse_state.remove_prefix( 5 );
419 if( parse_state.starts_with(
"true" ) ) {
420 parse_state.remove_prefix( 4 );
422 }
else if( parse_state.starts_with(
"false" ) ) {
423 parse_state.remove_prefix( 5 );
429 if constexpr( JsonMember::literal_as_string !=
430 options::LiteralAsStringOpt::Never ) {
431 skip_quote_when_literal_as_string<JsonMember::literal_as_string,
432 true>( parse_state );
434 parse_state.trim_left( );
436 not parse_state.has_more( ) or
437 parse_policy_details::at_end_of_item( parse_state.front( ) ),
438 ErrorReason::InvalidEndOfValue,
440 return construct_value<json_result_t<JsonMember>, constructor_t>(
441 parse_state, result );
445 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
446 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
447 parse_value_string_raw( ParseState &parse_state ) {
449 using constructor_t = json_constructor_t<JsonMember>;
450 if constexpr( KnownBounds ) {
451 return construct_value<json_result_t<JsonMember>, constructor_t>(
452 parse_state, std::data( parse_state ), std::size( parse_state ) );
454 if constexpr( JsonMember::allow_escape_character ==
455 options::AllowEscapeCharacter::Allow ) {
456 auto const str = skip_string( parse_state );
457 return construct_value<json_result_t<JsonMember>, constructor_t>(
458 parse_state, std::data( str ), std::size( str ) );
460 parse_state.remove_prefix( );
462 char const *
const first = parse_state.first;
463 parse_state.template move_to_next_of<
'"'>( );
464 char const *
const last = parse_state.first;
465 parse_state.remove_prefix( );
466 return construct_value<json_result_t<JsonMember>, constructor_t>(
467 parse_state, first,
static_cast<std::size_t
>( last - first ) );
478 template<
typename JsonMember>
479 DAW_CPP20_CONCEPT can_parse_to_stdstring_fast_v =
480 can_single_allocation_string_v<json_result_t<JsonMember>> or
481 can_single_allocation_string_v<json_base_type_t<JsonMember>>;
484 json_constructor_t<T> );
489 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
490 [[nodiscard]] DAW_ATTRIB_INLINE
constexpr json_result_t<JsonMember>
491 parse_value_string_escaped( ParseState &parse_state ) {
492 static_assert( has_json_member_constructor_v<JsonMember> );
493 static_assert( has_json_member_parse_to_v<JsonMember> );
494 if constexpr( not KnownBounds ) {
496 ErrorReason::UnexpectedNull );
498 using constructor_t = json_constructor_t<JsonMember>;
499 if constexpr( can_parse_to_stdstring_fast_v<JsonMember> ) {
500 using AllowHighEightbits =
501 std::bool_constant<JsonMember::eight_bit_mode !=
502 options::EightBitModes::DisallowHigh>;
504 KnownBounds ? parse_state : skip_string( parse_state );
505 if( not AllowHighEightbits::value or
506 needs_slow_path( parse_state2 ) ) {
508 return parse_string_known_stdstring<AllowHighEightbits::value,
510 true>( parse_state2 );
514 return construct_value<json_result_t<JsonMember>, constructor_t>(
516 std::data( parse_state2 ),
517 daw::data_end( parse_state2 ) );
520 KnownBounds ? parse_state : skip_string( parse_state );
521 using AllowHighEightbits =
522 std::bool_constant<JsonMember::eight_bit_mode !=
523 options::EightBitModes::DisallowHigh>;
524 if( not AllowHighEightbits::value or
525 needs_slow_path( parse_state2 ) ) {
527 return parse_string_known_stdstring<AllowHighEightbits::value,
529 true>( parse_state2 );
533 return construct_value<json_result_t<JsonMember>, constructor_t>(
534 parse_state, std::data( parse_state2 ), std::size( parse_state2 ) );
538 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
539 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
540 parse_value_date( ParseState &parse_state ) {
543 ErrorReason::UnexpectedEndOfData,
545 auto str = KnownBounds ? parse_state : skip_string( parse_state );
546 using constructor_t = json_constructor_t<JsonMember>;
547 return construct_value<json_result_t<JsonMember>, constructor_t>(
548 parse_state, std::data( str ), std::size( str ) );
551 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
552 [[nodiscard]]
static constexpr json_result_t<JsonMember>
553 parse_value_custom( ParseState &parse_state ) {
555 auto const str = [&] {
556 if constexpr( JsonMember::custom_json_type ==
557 options::JsonCustomTypes::String ) {
558 if constexpr( KnownBounds ) {
561 return skip_string( parse_state );
563 }
else if constexpr( JsonMember::custom_json_type ==
564 options::JsonCustomTypes::Literal ) {
565 return KnownBounds ? parse_state : skip_literal( parse_state );
567 static_assert( JsonMember::custom_json_type ==
568 options::JsonCustomTypes::Any );
572 if constexpr( KnownBounds ) {
573 auto result = parse_state;
574 if( *( result.first - 1 ) ==
'"' ) {
580 if( parse_state.front( ) ==
'"' ) {
581 return skip_string<true>( parse_state );
583 return skip_value( parse_state );
587 if constexpr( JsonMember::custom_json_type !=
588 options::JsonCustomTypes::Any ) {
590 str.front( ) ==
'{' ),
591 ErrorReason::InvalidStartOfValue,
594 using constructor_t =
typename JsonMember::from_converter_t;
595 return construct_value<json_result_t<JsonMember>, constructor_t>(
596 parse_state, std::string_view( std::data( str ), std::size( str ) ) );
599 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
600 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
601 parse_value_class( ParseState &parse_state ) {
603 using element_t =
typename JsonMember::wrapped_type;
605 ErrorReason::UnexpectedEndOfData,
608 if constexpr( is_deduced_empty_class_v<JsonMember> ) {
609 if constexpr( not KnownBounds ) {
610 auto const old_class_pos = parse_state.get_class_position( );
611 parse_state.set_class_position( );
612 parse_state.remove_prefix( );
613 parse_state.trim_left( );
614 parse_state.trim_left_checked( );
615 parse_state.move_next_member_or_end( );
616 parse_state.move_to_next_class_member( );
617 (void)parse_state.skip_class( );
618 parse_state.trim_left_checked( );
619 parse_state.set_class_position( old_class_pos );
621 return json_result_t<JsonMember>{ };
622 }
else if constexpr( KnownBounds ) {
624 template parse_to_class<JsonMember, KnownBounds>( parse_state );
625 }
else if constexpr( is_pinned_type_v<element_t> ) {
626 auto const run_after_parse = daw::on_exit_success( [&] {
627 parse_state.trim_left_checked( );
629 (void)run_after_parse;
631 template parse_to_class<JsonMember, KnownBounds>( parse_state );
634 template parse_to_class<JsonMember, KnownBounds>( parse_state );
635 parse_state.trim_left_checked( );
640#if defined( DAW_JSON_HAS_REFLECTION )
641 template<
typename JsonMember,
bool ,
typename ParseState>
642 constexpr json_result_t<JsonMember>
643 parse_value_reflected_class( ParseState &parse_state ) {
645 ErrorReason::UnexpectedEndOfData,
648 return JsonMember::parse_to_class( parse_state );
660 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
661 [[nodiscard]]
static constexpr json_result_t<JsonMember>
662 parse_value_keyvalue( ParseState &parse_state ) {
664 static_assert( JsonMember::expected_type == JsonParseTypes::KeyValue,
665 "Expected a json_key_value" );
667 ErrorReason::ExpectedKeyValueToStartWithBrace,
670 parse_state.remove_prefix( );
671 parse_state.trim_left( );
674 json_parse_kv_class_iterator<JsonMember,
676 can_be_random_iterator_v<KnownBounds>>;
678 using constructor_t = json_constructor_t<JsonMember>;
679 return construct_value<json_result_t<JsonMember>, constructor_t>(
680 parse_state, iter_t( parse_state ), iter_t( ) );
691 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
692 [[nodiscard]]
static constexpr json_result_t<JsonMember>
693 parse_value_keyvalue_array( ParseState &parse_state ) {
695 static_assert( JsonMember::expected_type ==
696 JsonParseTypes::KeyValueArray,
697 "Expected a json_key_value" );
699 parse_state.is_opening_bracket_checked( ),
700 ErrorReason::ExpectedKeyValueArrayToStartWithBracket,
703 parse_state.remove_prefix( );
706 json_parse_kv_array_iterator<JsonMember,
708 can_be_random_iterator_v<KnownBounds>>;
709 using constructor_t = json_constructor_t<JsonMember>;
710 return construct_value<json_result_t<JsonMember>, constructor_t>(
711 parse_state, iter_t( parse_state ), iter_t( ) );
714 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
715 [[nodiscard]]
static constexpr json_result_t<JsonMember>
716 parse_value_array( ParseState &parse_state ) {
717 parse_state.trim_left( );
719 ErrorReason::InvalidArrayStart,
721 parse_state.remove_prefix( );
722 parse_state.trim_left_unchecked( );
727 json_parse_array_iterator<JsonMember,
729 can_be_random_iterator_v<KnownBounds>>;
730 using constructor_t = json_constructor_t<JsonMember>;
731 return construct_value<json_result_t<JsonMember>, constructor_t>(
732 parse_state, iterator_t( parse_state ), iterator_t( ) );
735 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
736 [[nodiscard]]
static constexpr json_result_t<JsonMember>
737 parse_value_sz_array( ParseState &parse_state ) {
739 using size_member = dependent_member_t<JsonMember>;
741 auto [parse_state2, is_found] = find_range<ParseState>(
742 ParseState( parse_state.class_first, parse_state.last ),
746 is_found, ErrorReason::TagMemberNotFound, parse_state );
748 parse_value<size_member, false, size_member::expected_type>(
751 if constexpr( KnownBounds and ParseState::is_unchecked_input ) {
754 auto cnt =
static_cast<std::ptrdiff_t
>( parse_state.counter );
756 ErrorReason::NumberOutOfRange,
759 parse_state.trim_left( );
761 ErrorReason::InvalidArrayStart,
763 parse_state.remove_prefix( );
764 parse_state.trim_left_unchecked( );
768 json_parse_array_iterator<JsonMember, ParseState, false>;
769 using constructor_t = json_constructor_t<JsonMember>;
770 return construct_value<json_result_t<JsonMember>, constructor_t>(
772 iterator_t( parse_state ),
774 static_cast<std::size_t
>( sz ) );
779 [[nodiscard]]
constexpr json_result_t<JsonMembers>
780 parse_variant_value( ParseState &parse_state ) {
781 using element_t =
typename JsonMembers::json_elements;
782 using idx = daw::constant<( JsonMembers::base_map::base_map
783 [
static_cast<std::int_fast8_t
>( BPT )] )>;
785 if constexpr( idx::value <
786 pack_size_v<typename element_t::element_map_t> ) {
788 pack_element_t<idx::value, typename element_t::element_map_t>;
789 return parse_value<JsonMember,
791 JsonMember::expected_type>( parse_state );
797 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
798 [[nodiscard]]
static constexpr json_result_t<JsonMember>
799 parse_value_variant( ParseState &parse_state ) {
800 if constexpr( KnownBounds ) {
803 if( *( parse_state.first - 1 ) ==
'"' ) {
805 return parse_variant_value<JsonBaseParseTypes::String,
807 KnownBounds>( parse_state );
810 switch( parse_state.front( ) ) {
812 return parse_variant_value<JsonBaseParseTypes::Class,
814 KnownBounds>( parse_state );
816 return parse_variant_value<JsonBaseParseTypes::Array,
818 KnownBounds>( parse_state );
821 return parse_variant_value<JsonBaseParseTypes::Bool,
823 KnownBounds>( parse_state );
825 return parse_variant_value<JsonBaseParseTypes::String,
827 KnownBounds>( parse_state );
840 return parse_variant_value<JsonBaseParseTypes::Number,
842 KnownBounds>( parse_state );
844 if constexpr( ParseState::is_unchecked_input ) {
847 daw_json_error(
true, ErrorReason::InvalidStartOfValue, parse_state );
851 template<
typename Result,
typename TypeList, std::size_t pos = 0,
853 DAW_ATTRIB_INLINE
constexpr Result
854 parse_visit( std::size_t idx, ParseState &parse_state ) {
856 using JsonMember = pack_element_t<pos, TypeList>;
857 if constexpr( std::is_same_v<json_result_t<JsonMember>, Result> ) {
858 return parse_value<JsonMember, false, JsonMember::expected_type>(
862 parse_value<JsonMember, false, JsonMember::expected_type>(
866 if constexpr( pos + 1 < pack_size_v<TypeList> ) {
867 return parse_visit<Result, TypeList, pos + 1>( idx, parse_state );
869 if constexpr( ParseState::is_unchecked_input ) {
873 true, ErrorReason::MissingMemberNameOrEndOfClass, parse_state );
878 template<
typename JsonMember,
typename ParseState>
879 [[nodiscard]]
constexpr auto find_index( ParseState
const &parse_state ) {
880 using tag_member =
typename JsonMember::tag_member;
881 using class_wrapper_t =
typename JsonMember::tag_member_class_wrapper;
883 using switcher_t =
typename JsonMember::switcher;
884 auto parse_state2 = ParseState( parse_state.class_first,
885 parse_state.class_last,
886 parse_state.class_first,
887 parse_state.class_last );
888 if constexpr( is_an_ordered_member_v<tag_member> ) {
891 ErrorReason::InvalidArrayStart,
893 return switcher_t{ }( std::get<0>(
894 parse_value<class_wrapper_t, false, class_wrapper_t::expected_type>(
899 ErrorReason::InvalidClassStart,
901 return switcher_t{ }( std::get<0>(
902 parse_value<class_wrapper_t, false, class_wrapper_t::expected_type>(
908 template<
typename JsonMember,
typename ParseState>
909 [[nodiscard]]
constexpr json_result_t<JsonMember>
910 parse_value_variant_tagged( ParseState &parse_state ) {
911 auto const index = find_index<JsonMember>( parse_state );
912 return parse_visit<json_result_t<JsonMember>,
913 typename JsonMember::json_elements::element_map_t>(
914 index, parse_state );
917 template<
typename JsonMember,
typename ParseState>
918 [[nodiscard]]
constexpr json_result_t<JsonMember>
919 parse_value_variant_intrusive( ParseState &parse_state ) {
920 auto const index = [&] {
921 using tag_submember =
typename JsonMember::tag_submember;
922 using class_wrapper_t =
923 typename JsonMember::tag_submember_class_wrapper;
924 auto parse_state2 = parse_state;
925 using switcher_t =
typename JsonMember::switcher;
926 if constexpr( is_an_ordered_member_v<tag_submember> ) {
927 return switcher_t{ }( std::get<0>(
928 parse_value<class_wrapper_t,
930 class_wrapper_t::expected_type>( parse_state2 ) ) );
932 return switcher_t{ }( std::get<0>(
933 parse_value<class_wrapper_t,
935 class_wrapper_t::expected_type>( parse_state2 )
940 return parse_visit<json_result_t<JsonMember>,
941 typename JsonMember::json_elements::element_map_t>(
942 index, parse_state );
945 template<
bool AllMembersMustExist,
typename ParseState,
946 typename OldClassPos>
947 DAW_ATTRIB_INLINE
constexpr void ordered_class_cleanup(
948 ParseState &parse_state,
951 if constexpr( AllMembersMustExist ) {
952 parse_state.trim_left( );
954 ErrorReason::UnknownMember,
956 parse_state.remove_prefix( );
957 parse_state.trim_left_checked( );
959 (void)parse_state.skip_array( );
961 parse_state.set_class_position( old_class_pos );
964 namespace pocm_details {
972 template<
bool Nullable,
typename ParseState>
973 constexpr void maybe_skip_members( ParseState &parse_state,
974 std::size_t ¤t_position,
975 std::size_t desired_position ) {
978 ErrorReason::OutOfOrderOrderedMembers,
980 using skip_check_end =
981 std::bool_constant<( ParseState::is_unchecked_input and Nullable )>;
982 while( ( current_position < desired_position ) &
983 ( skip_check_end::value or parse_state.front( ) !=
']' ) ) {
984 (void)skip_value( parse_state );
985 parse_state.move_next_member_or_end( );
988 ErrorReason::UnexpectedEndOfData,
993#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
994 template<
typename ParseState>
995 struct position_info {
999 constexpr explicit operator bool( )
const {
1000 return not state.is_null( );
1011 template<
bool Nullable,
typename ParseState, std::
size_t N>
1012 DAW_ATTRIB_INLINE
static constexpr ParseState maybe_skip_members(
1013 ParseState &parse_state, std::size_t ¤t_position,
1014 std::size_t desired_position,
1015 std::array<position_info<ParseState>, N> &parse_locations ) {
1017 auto const desired = daw::algorithm::find_if(
1018 std::data( parse_locations ),
1019 daw::data_end( parse_locations ),
1020 [desired_position]( position_info<ParseState>
const &loc ) {
1021 return loc.index == desired_position;
1024 return desired->state;
1026#if not defined( NDEBUG )
1028 ErrorReason::UnexpectedEndOfData,
1031 using skip_check_end =
1032 std::bool_constant<( ParseState::is_unchecked_input and Nullable )>;
1033 while( ( current_position < desired_position ) &
1034 ( skip_check_end::value or parse_state.front( ) !=
']' ) ) {
1035 auto const current = daw::algorithm::find_if(
1036 std::data( parse_locations ),
1037 daw::data_end( parse_locations ),
1038 [current_position]( position_info<ParseState>
const &loc ) {
1039 return loc.index == current_position;
1041 auto state = skip_value( parse_state );
1042 if( current != daw::data_end( parse_locations ) ) {
1043 current->state = state;
1045 parse_state.move_next_member_or_end( );
1048 ErrorReason::UnexpectedEndOfData,
1056 template<
typename T>
1057 struct member_index_t {
1058 static constexpr std::size_t value = T::member_index;
1061 template<
typename Idx,
typename JsonMember>
1062 inline constexpr std::size_t member_index_v =
1063 daw::conditional_t<has_member_index_v<JsonMember>,
1064 member_index_t<JsonMember>, Idx>::value;
1067 template<
typename JsonMember,
bool KnownBounds,
typename ParseState,
1069 DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1070 parse_tuple_value( ParseState &parse_state, std::index_sequence<Is...> ) {
1071 parse_state.trim_left( );
1073 ErrorReason::InvalidArrayStart,
1076 auto const old_class_pos = parse_state.get_class_position( );
1077 parse_state.set_class_position( );
1078 parse_state.remove_prefix( );
1079 parse_state.move_next_member_or_end( );
1080 using tuple_t = json_base_type_t<JsonMember>;
1081 using tuple_members =
typename JsonMember::sub_member_list;
1083#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1084 using position_info_t = pocm_details::position_info<ParseState>;
1085 std::size_t parse_locations_last_index = 0U;
1086 std::array<position_info_t,
sizeof...( Is )> parse_locations{
1087 [&](
auto Index )
mutable -> position_info_t {
1088 constexpr std::size_t index =
decltype( Index )::value;
1089 using member_t = std::tuple_element_t<index, tuple_members>;
1090 if constexpr( is_an_ordered_member_v<member_t> ) {
1091 parse_locations_last_index = member_t::member_index;
1092 return { member_t::member_index };
1094 return { parse_locations_last_index++ };
1096 }(daw::constant_v<Is>)... };
1098 auto const parse_value_help = [&](
auto PackIdx,
1099 std::size_t &ClassIdx ) {
1100 using index_t =
decltype( PackIdx );
1101 using CurrentMember =
1102 std::tuple_element_t<index_t::value, tuple_members>;
1104 using json_member_t = ordered_member_subtype_t<CurrentMember>;
1106#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1107 ParseState parse_state2 =
1108 pocm_details::maybe_skip_members<is_json_nullable_v<json_member_t>>(
1111 pocm_details::member_index_v<index_t, CurrentMember>,
1113 if constexpr(
sizeof...( Is ) > 1 ) {
1115 if( parse_state2.first == parse_state.first ) {
1116 if constexpr( is_pinned_type_v<json_result_t<JsonMember>> ) {
1117 auto const run_after_parse = daw::on_exit_success( [&] {
1118 parse_state.move_next_member_or_end( );
1120 (void)run_after_parse;
1121 return parse_value<json_member_t,
1123 json_member_t::expected_type>( parse_state );
1126 parse_value<json_member_t,
1128 json_member_t::expected_type>( parse_state );
1129 parse_state.move_next_member_or_end( );
1134 return parse_value<json_member_t,
1136 json_member_t::expected_type>( parse_state2 );
1140 if constexpr( is_an_ordered_member_v<CurrentMember> ) {
1141 pocm_details::maybe_skip_members<
1142 is_json_nullable_v<json_member_t>>(
1143 parse_state, ClassIdx, CurrentMember::member_index );
1146 ErrorReason::UnexpectedEndOfData,
1150 if constexpr( is_pinned_type_v<json_result_t<JsonMember>> ) {
1151 auto const run_after_parse = daw::on_exit_success( [&] {
1152 parse_state.move_next_member_or_end( );
1154 (void)run_after_parse;
1155 return parse_value<json_member_t,
1157 json_member_t::expected_type>( parse_state );
1160 parse_value<json_member_t, false, json_member_t::expected_type>(
1162 parse_state.move_next_member_or_end( );
1165#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1170 static_assert( is_a_json_type_v<JsonMember> );
1171 using Constructor = json_constructor_t<JsonMember>;
1173 parse_state.trim_left( );
1175 std::size_t class_idx = 0;
1176 if constexpr( is_pinned_type_v<json_result_t<JsonMember>> ) {
1177 auto const run_after_parse = daw::on_exit_success( [&] {
1178 ordered_class_cleanup<
1179 all_json_members_must_exist_v<JsonMember, ParseState>,
1181 decltype( old_class_pos )>( parse_state, old_class_pos );
1183 (void)run_after_parse;
1188 parse_value_help( daw::constant_v<Is>, class_idx )... };
1190 return construct_value_tp<tuple_t, Constructor>(
1193 parse_value_help( daw::constant_v<Is>, class_idx )... } );
1201 parse_value_help( daw::constant_v<Is>, class_idx )... };
1203 return construct_value_tp<tuple_t, Constructor>(
1206 parse_value_help( daw::constant_v<Is>, class_idx )... } );
1209 if constexpr( all_json_members_must_exist_v<tuple_t, ParseState> ) {
1210 parse_state.trim_left( );
1212 ErrorReason::UnknownMember,
1214 parse_state.remove_prefix( );
1215 parse_state.trim_left( );
1217 (void)parse_state.skip_array( );
1219 parse_state.set_class_position( old_class_pos );
1224 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
1225 static constexpr json_result_t<JsonMember>
1226 parse_value_tuple( ParseState &parse_state ) {
1227 using element_pack =
1228 typename JsonMember::sub_member_list;
1230 return parse_tuple_value<JsonMember, KnownBounds>(
1232 std::make_index_sequence<std::tuple_size_v<element_pack>>{ } );
1235 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
1236 DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1237 parse_value_unknown( ParseState &parse_state ) {
1238 using constructor_t = json_constructor_t<JsonMember>;
1239 if constexpr( KnownBounds ) {
1240 return construct_value<json_result_t<JsonMember>, constructor_t>(
1241 parse_state, std::data( parse_state ), std::size( parse_state ) );
1243 auto value_parse_state = skip_value<true>( parse_state );
1244 return construct_value<json_result_t<JsonMember>, constructor_t>(
1246 std::data( value_parse_state ),
1247 std::size( value_parse_state ) );
1251 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
1252 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1253 parse_value_submember( ParseState &parse_state ) {
1254 auto submember_state = [&] {
1255 if constexpr( KnownBounds ) {
1258 return skip_value( parse_state );
1263 find_range2( submember_state, JsonMember::json_path );
1265 found, ErrorReason::JSONPathNotFound, submember_state );
1267 using member_type =
typename JsonMember::member_type;
1268 return parse_value<member_type, false, member_type::expected_type>(
1272 template<
typename JsonMember,
bool KnownBounds,
JsonParseTypes PTag,
1273 typename ParseState>
1274 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1275 parse_value( ParseState &parse_state ) {
1276 if constexpr( PTag == JsonParseTypes::Real ) {
1277 return parse_value_real<JsonMember, KnownBounds>( parse_state );
1278 }
else if constexpr( PTag == JsonParseTypes::Signed ) {
1279 return parse_value_signed<JsonMember, KnownBounds>( parse_state );
1280 }
else if constexpr( PTag == JsonParseTypes::Unsigned ) {
1281 return parse_value_unsigned<JsonMember, KnownBounds>( parse_state );
1282 }
else if constexpr( PTag == JsonParseTypes::Null ) {
1283 return parse_value_null<JsonMember, KnownBounds>( parse_state );
1284 }
else if constexpr( PTag == JsonParseTypes::Bool ) {
1285 return parse_value_bool<JsonMember, KnownBounds>( parse_state );
1286 }
else if constexpr( PTag == JsonParseTypes::StringRaw ) {
1287 return parse_value_string_raw<JsonMember, KnownBounds>( parse_state );
1288 }
else if constexpr( PTag == JsonParseTypes::StringInsitu ) {
1289 return parse_value_string_escaped<JsonMember, KnownBounds>(
1291 }
else if constexpr( PTag == JsonParseTypes::StringEscaped ) {
1292 return parse_value_string_escaped<JsonMember, KnownBounds>(
1294 }
else if constexpr( PTag == JsonParseTypes::Date ) {
1295 return parse_value_date<JsonMember, KnownBounds>( parse_state );
1296 }
else if constexpr( PTag == JsonParseTypes::Custom ) {
1297 return parse_value_custom<JsonMember, KnownBounds>( parse_state );
1298 }
else if constexpr( PTag == JsonParseTypes::Class ) {
1299 return parse_value_class<JsonMember, KnownBounds>( parse_state );
1300 }
else if constexpr( PTag == JsonParseTypes::KeyValue ) {
1301 return parse_value_keyvalue<JsonMember, KnownBounds>( parse_state );
1302 }
else if constexpr( PTag == JsonParseTypes::KeyValueArray ) {
1303 return parse_value_keyvalue_array<JsonMember, KnownBounds>(
1305 }
else if constexpr( PTag == JsonParseTypes::Array ) {
1306 return parse_value_array<JsonMember, KnownBounds>( parse_state );
1307 }
else if constexpr( PTag == JsonParseTypes::SizedArray ) {
1308 return parse_value_sz_array<JsonMember, KnownBounds>( parse_state );
1309 }
else if constexpr( PTag == JsonParseTypes::Variant ) {
1310 return parse_value_variant<JsonMember, KnownBounds>( parse_state );
1311 }
else if constexpr( PTag == JsonParseTypes::VariantTagged ) {
1312 return parse_value_variant_tagged<JsonMember>( parse_state );
1313 }
else if constexpr( PTag == JsonParseTypes::VariantIntrusive ) {
1314 return parse_value_variant_intrusive<JsonMember>( parse_state );
1315 }
else if constexpr( PTag == JsonParseTypes::Tuple ) {
1316 return parse_value_tuple<JsonMember, KnownBounds>( parse_state );
1317 }
else if constexpr( PTag == JsonParseTypes::Submember ) {
1318 return parse_value_submember<JsonMember, KnownBounds>( parse_state );
1319#if defined( DAW_JSON_HAS_REFLECTION )
1320 }
else if constexpr( PTag == JsonParseTypes::ReflectedClass ) {
1321 return parse_value_reflected_class<JsonMember, KnownBounds>(
1325 static_assert( PTag == JsonParseTypes::Unknown,
1326 "Unexpected JsonParseType" );
1327 return parse_value_unknown<JsonMember, KnownBounds>( parse_state );
1331 template<std::size_t N,
typename JsonClass,
bool KnownBounds,
1332 typename... JsonClasses,
typename ParseState>
1333 DAW_ATTRIB_INLINE
constexpr json_result_t<JsonClass>
1334 parse_nth_class( std::size_t idx, ParseState &parse_state ) {
1336 DAW_ASSUME( idx <
sizeof...( JsonClasses ) );
1337 using T = json_base_type_t<JsonClass>;
1338 using Constructor = json_constructor_t<JsonClass>;
1339 if constexpr(
sizeof...( JsonClasses ) >= N + 8 ) {
1342 using cur_json_class_t =
1343 daw::traits::nth_element<N + 0, JsonClasses...>;
1344 return construct_value<T, Constructor>(
1346 parse_value<cur_json_class_t,
1348 cur_json_class_t::expected_type>( parse_state ) );
1351 using cur_json_class_t =
1352 daw::traits::nth_element<N + 1, JsonClasses...>;
1353 return construct_value<T, Constructor>(
1355 parse_value<cur_json_class_t,
1357 cur_json_class_t::expected_type>( parse_state ) );
1360 using cur_json_class_t =
1361 daw::traits::nth_element<N + 2, JsonClasses...>;
1362 return construct_value<T, Constructor>(
1364 parse_value<cur_json_class_t,
1366 cur_json_class_t::expected_type>( parse_state ) );
1369 using cur_json_class_t =
1370 daw::traits::nth_element<N + 3, JsonClasses...>;
1371 return construct_value<T, Constructor>(
1373 parse_value<cur_json_class_t,
1375 cur_json_class_t::expected_type>( parse_state ) );
1378 using cur_json_class_t =
1379 daw::traits::nth_element<N + 4, JsonClasses...>;
1380 return construct_value<T, Constructor>(
1382 parse_value<cur_json_class_t,
1384 cur_json_class_t::expected_type>( parse_state ) );
1387 using cur_json_class_t =
1388 daw::traits::nth_element<N + 5, JsonClasses...>;
1389 return construct_value<T, Constructor>(
1391 parse_value<cur_json_class_t,
1393 cur_json_class_t::expected_type>( parse_state ) );
1396 using cur_json_class_t =
1397 daw::traits::nth_element<N + 6, JsonClasses...>;
1398 return construct_value<T, Constructor>(
1400 parse_value<cur_json_class_t,
1402 cur_json_class_t::expected_type>( parse_state ) );
1405 using cur_json_class_t =
1406 daw::traits::nth_element<N + 7, JsonClasses...>;
1407 return construct_value<T, Constructor>(
1409 parse_value<cur_json_class_t,
1411 cur_json_class_t::expected_type>( parse_state ) );
1414 if constexpr(
sizeof...( JsonClasses ) >= N + 8 ) {
1415 return parse_nth_class<N + 8,
1418 JsonClasses...>( idx, parse_state );
1423 }
else if constexpr(
sizeof...( JsonClasses ) == N + 7 ) {
1426 using cur_json_class_t =
1427 daw::traits::nth_element<N + 0, JsonClasses...>;
1428 return construct_value<T, Constructor>(
1430 parse_value<cur_json_class_t,
1432 cur_json_class_t::expected_type>( parse_state ) );
1435 using cur_json_class_t =
1436 daw::traits::nth_element<N + 1, JsonClasses...>;
1437 return construct_value<T, Constructor>(
1439 parse_value<cur_json_class_t,
1441 cur_json_class_t::expected_type>( parse_state ) );
1444 using cur_json_class_t =
1445 daw::traits::nth_element<N + 2, JsonClasses...>;
1446 return construct_value<T, Constructor>(
1448 parse_value<cur_json_class_t,
1450 cur_json_class_t::expected_type>( parse_state ) );
1453 using cur_json_class_t =
1454 daw::traits::nth_element<N + 3, JsonClasses...>;
1455 return construct_value<T, Constructor>(
1457 parse_value<cur_json_class_t,
1459 cur_json_class_t::expected_type>( parse_state ) );
1462 using cur_json_class_t =
1463 daw::traits::nth_element<N + 4, JsonClasses...>;
1464 return construct_value<T, Constructor>(
1466 parse_value<cur_json_class_t,
1468 cur_json_class_t::expected_type>( parse_state ) );
1471 using cur_json_class_t =
1472 daw::traits::nth_element<N + 5, JsonClasses...>;
1473 return construct_value<T, Constructor>(
1475 parse_value<cur_json_class_t,
1477 cur_json_class_t::expected_type>( parse_state ) );
1480 DAW_ASSUME( idx == N + 6 );
1481 using cur_json_class_t =
1482 daw::traits::nth_element<N + 6, JsonClasses...>;
1483 return construct_value<T, Constructor>(
1485 parse_value<cur_json_class_t,
1487 cur_json_class_t::expected_type>( parse_state ) );
1490 }
else if constexpr(
sizeof...( JsonClasses ) == N + 6 ) {
1493 using cur_json_class_t =
1494 daw::traits::nth_element<N + 0, JsonClasses...>;
1495 return construct_value<T, Constructor>(
1497 parse_value<cur_json_class_t,
1499 cur_json_class_t::expected_type>( parse_state ) );
1502 using cur_json_class_t =
1503 daw::traits::nth_element<N + 1, JsonClasses...>;
1504 return construct_value<T, Constructor>(
1506 parse_value<cur_json_class_t,
1508 cur_json_class_t::expected_type>( parse_state ) );
1511 using cur_json_class_t =
1512 daw::traits::nth_element<N + 2, JsonClasses...>;
1513 return construct_value<T, Constructor>(
1515 parse_value<cur_json_class_t,
1517 cur_json_class_t::expected_type>( parse_state ) );
1520 using cur_json_class_t =
1521 daw::traits::nth_element<N + 3, JsonClasses...>;
1522 return construct_value<T, Constructor>(
1524 parse_value<cur_json_class_t,
1526 cur_json_class_t::expected_type>( parse_state ) );
1529 using cur_json_class_t =
1530 daw::traits::nth_element<N + 4, JsonClasses...>;
1531 return construct_value<T, Constructor>(
1533 parse_value<cur_json_class_t,
1535 cur_json_class_t::expected_type>( parse_state ) );
1538 DAW_ASSUME( idx == N + 5 );
1539 using cur_json_class_t =
1540 daw::traits::nth_element<N + 5, JsonClasses...>;
1541 return construct_value<T, Constructor>(
1543 parse_value<cur_json_class_t,
1545 cur_json_class_t::expected_type>( parse_state ) );
1548 }
else if constexpr(
sizeof...( JsonClasses ) == N + 5 ) {
1551 using cur_json_class_t =
1552 daw::traits::nth_element<N + 0, JsonClasses...>;
1553 return construct_value<T, Constructor>(
1555 parse_value<cur_json_class_t,
1557 cur_json_class_t::expected_type>( parse_state ) );
1560 using cur_json_class_t =
1561 daw::traits::nth_element<N + 1, JsonClasses...>;
1562 return construct_value<T, Constructor>(
1564 parse_value<cur_json_class_t,
1566 cur_json_class_t::expected_type>( parse_state ) );
1569 using cur_json_class_t =
1570 daw::traits::nth_element<N + 2, JsonClasses...>;
1571 return construct_value<T, Constructor>(
1573 parse_value<cur_json_class_t,
1575 cur_json_class_t::expected_type>( parse_state ) );
1578 using cur_json_class_t =
1579 daw::traits::nth_element<N + 3, JsonClasses...>;
1580 return construct_value<T, Constructor>(
1582 parse_value<cur_json_class_t,
1584 cur_json_class_t::expected_type>( parse_state ) );
1587 DAW_ASSUME( idx == N + 4 );
1588 using cur_json_class_t =
1589 daw::traits::nth_element<N + 4, JsonClasses...>;
1590 return construct_value<T, Constructor>(
1592 parse_value<cur_json_class_t,
1594 cur_json_class_t::expected_type>( parse_state ) );
1597 }
else if constexpr(
sizeof...( JsonClasses ) == N + 4 ) {
1600 using cur_json_class_t =
1601 daw::traits::nth_element<N + 0, JsonClasses...>;
1602 return construct_value<T, Constructor>(
1604 parse_value<cur_json_class_t,
1606 cur_json_class_t::expected_type>( parse_state ) );
1609 using cur_json_class_t =
1610 daw::traits::nth_element<N + 1, JsonClasses...>;
1611 return construct_value<T, Constructor>(
1613 parse_value<cur_json_class_t,
1615 cur_json_class_t::expected_type>( parse_state ) );
1618 using cur_json_class_t =
1619 daw::traits::nth_element<N + 2, JsonClasses...>;
1620 return construct_value<T, Constructor>(
1622 parse_value<cur_json_class_t,
1624 cur_json_class_t::expected_type>( parse_state ) );
1627 DAW_ASSUME( idx == N + 3 );
1628 using cur_json_class_t =
1629 daw::traits::nth_element<N + 3, JsonClasses...>;
1630 return construct_value<T, Constructor>(
1632 parse_value<cur_json_class_t,
1634 cur_json_class_t::expected_type>( parse_state ) );
1637 }
else if constexpr(
sizeof...( JsonClasses ) == N + 3 ) {
1640 using cur_json_class_t =
1641 daw::traits::nth_element<N + 0, JsonClasses...>;
1642 return construct_value<T, Constructor>(
1644 parse_value<cur_json_class_t,
1646 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 ) );
1658 DAW_ASSUME( idx == N + 2 );
1659 using cur_json_class_t =
1660 daw::traits::nth_element<N + 2, JsonClasses...>;
1661 return construct_value<T, Constructor>(
1663 parse_value<cur_json_class_t,
1665 cur_json_class_t::expected_type>( parse_state ) );
1668 }
else if constexpr(
sizeof...( JsonClasses ) == N + 2 ) {
1670 using cur_json_class_t =
1671 daw::traits::nth_element<N + 0, JsonClasses...>;
1672 return construct_value<T, Constructor>(
1674 parse_value<cur_json_class_t,
1676 cur_json_class_t::expected_type>( parse_state ) );
1678 using cur_json_class_t =
1679 daw::traits::nth_element<N + 1, JsonClasses...>;
1680 return construct_value<T, Constructor>(
1682 parse_value<cur_json_class_t,
1684 cur_json_class_t::expected_type>( parse_state ) );
1686 using cur_json_class_t =
1687 daw::traits::nth_element<N + 0, JsonClasses...>;
1688 return construct_value<T, Constructor>(
1690 parse_value<cur_json_class_t,
1692 cur_json_class_t::expected_type>( parse_state ) );