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( );
83 template<
typename ParseState>
84 DAW_ATTRIB_INLINE
constexpr void
85 skip_comments_after_value( ParseState &parse_state ) {
86 if constexpr( not std::is_same_v<
typename ParseState::CommentPolicy,
88 parse_state.trim_left( );
92 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
93 [[nodiscard]]
constexpr json_result_t<JsonMember>
94 parse_value_real( ParseState &parse_state ) {
95 using constructor_t = json_constructor_t<JsonMember>;
96 using element_t = json_base_type_t<JsonMember>;
98 if constexpr( JsonMember::literal_as_string !=
99 options::LiteralAsStringOpt::Never ) {
100 if constexpr( not KnownBounds ) {
101 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
104 if constexpr( JsonMember::allow_number_errors ==
105 options::JsonNumberErrors::AllowInf or
106 JsonMember::allow_number_errors ==
107 options::JsonNumberErrors::AllowNanInf ) {
108 element_t sign = element_t( 1.0 );
109 if( parse_state.front( ) ==
'-' ) {
110 sign = element_t( -1.0 );
114 if( parse_state.starts_with_skip(
"Inf" ) ) {
115 if( not( parse_state.starts_with_skip(
"\"" ) or
116 parse_state.starts_with_skip(
"inity\"" ) ) ) {
119 if constexpr( KnownBounds ) {
121 ErrorReason::InvalidNumber,
124 skip_comments_after_value( parse_state );
126 parse_policy_details::at_end_of_item(
127 parse_state.front( ) ),
128 ErrorReason::InvalidEndOfValue,
131 return daw::cxmath::copy_sign(
132 daw::numeric_limits<element_t>::infinity( ), sign );
133 }
else if( sign < element_t( 0 ) ) {
137 if constexpr( JsonMember::allow_number_errors ==
138 options::JsonNumberErrors::AllowNaN or
139 JsonMember::allow_number_errors ==
140 options::JsonNumberErrors::AllowNanInf ) {
141 if( parse_state.starts_with(
"NaN" ) ) {
142 parse_state.template move_to_next_of<
'"'>( );
143 parse_state.remove_prefix( );
144 if constexpr( KnownBounds ) {
146 ErrorReason::InvalidNumber,
149 skip_comments_after_value( parse_state );
151 parse_policy_details::at_end_of_item(
152 parse_state.front( ) ),
153 ErrorReason::InvalidEndOfValue,
156 return daw::numeric_limits<element_t>::quiet_NaN( );
160 if constexpr( KnownBounds and JsonMember::literal_as_string ==
161 options::LiteralAsStringOpt::Never ) {
162 return construct_value<json_result_t<JsonMember>, constructor_t>(
163 parse_state, parse_real<element_t, true>( parse_state ) );
166 parse_state.has_more( ) and
167 parse_policy_details::is_number_start( parse_state.front( ) ),
168 ErrorReason::InvalidNumberStart,
172 construct_value<json_result_t<JsonMember>, constructor_t>(
173 parse_state, parse_real<element_t, false>( parse_state ) );
175 if constexpr( KnownBounds ) {
177 parse_state.empty( ) or
178 parse_policy_details::at_end_of_item( parse_state.front( ) ),
179 ErrorReason::InvalidEndOfValue,
182 if constexpr( JsonMember::literal_as_string !=
183 options::LiteralAsStringOpt::Never ) {
184 skip_quote_when_literal_as_string<JsonMember::literal_as_string,
185 true>( parse_state );
187 skip_comments_after_value( parse_state );
189 parse_state.empty( ) or
190 parse_policy_details::at_end_of_item( parse_state.front( ) ),
191 ErrorReason::InvalidEndOfValue,
198 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
199 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
200 parse_value_signed( ParseState &parse_state ) {
201 using constructor_t = json_constructor_t<JsonMember>;
202 using element_t = json_base_type_t<JsonMember>;
204 typename daw::conditional_t<std::is_enum_v<element_t>,
205 std::underlying_type<element_t>,
206 daw::traits::identity<element_t>>::type;
208 static_assert( daw::is_signed_v<int_type>,
"Expected signed type" );
209 if constexpr( KnownBounds ) {
211 parse_policy_details::is_number_start( parse_state.front( ) ),
212 ErrorReason::InvalidNumberStart,
215 if constexpr( JsonMember::literal_as_string !=
216 options::LiteralAsStringOpt::Never ) {
217 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
219 }
else if constexpr( not ParseState::is_zero_terminated_string ) {
221 ErrorReason::UnexpectedEndOfData,
225 auto const sign =
static_cast<int_type
>(
226 parse_policy_details::validate_signed_first( parse_state ) );
228 typename daw::conditional_t<daw::is_system_integral_v<int_type>,
229 daw::make_unsigned<int_type>,
230 daw::traits::identity<int_type>>::type;
231 auto parsed_val = to_signed(
232 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
236 if constexpr( KnownBounds ) {
237 return construct_value<json_result_t<JsonMember>, constructor_t>(
238 parse_state,
static_cast<element_t
>( parsed_val ) );
241 construct_value<json_result_t<JsonMember>, constructor_t>(
242 parse_state,
static_cast<element_t
>( parsed_val ) );
243 if constexpr( JsonMember::literal_as_string !=
244 options::LiteralAsStringOpt::Never ) {
245 skip_quote_when_literal_as_string<JsonMember::literal_as_string,
246 true>( parse_state );
248 parse_state.trim_left( );
250 not parse_state.has_more( ) or
251 parse_policy_details::at_end_of_item( parse_state.front( ) ),
252 ErrorReason::InvalidEndOfValue,
258 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
259 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
260 parse_value_unsigned( ParseState &parse_state ) {
261 using constructor_t = json_constructor_t<JsonMember>;
262 using element_t = json_base_type_t<JsonMember>;
264 typename daw::conditional_t<std::is_enum_v<element_t>,
265 std::underlying_type<element_t>,
266 daw::traits::identity<element_t>>::type;
268 if constexpr( KnownBounds ) {
269 parse_policy_details::validate_unsigned_first( parse_state );
271 return construct_value<json_result_t<JsonMember>, constructor_t>(
273 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
276 if constexpr( JsonMember::literal_as_string !=
277 options::LiteralAsStringOpt::Never ) {
278 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
280 if constexpr( not ParseState::is_zero_terminated_string ) {
282 ErrorReason::UnexpectedEndOfData,
285 }
else if constexpr( not ParseState::is_zero_terminated_string ) {
287 ErrorReason::UnexpectedEndOfData,
291 parse_policy_details::is_number( parse_state.front( ) ),
292 ErrorReason::InvalidNumber,
295 construct_value<json_result_t<JsonMember>, constructor_t>(
297 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
299 if constexpr( JsonMember::literal_as_string !=
300 options::LiteralAsStringOpt::Never ) {
301 skip_quote_when_literal_as_string<JsonMember::literal_as_string,
302 true>( parse_state );
304 skip_comments_after_value( parse_state );
306 not parse_state.has_more( ) or
307 parse_policy_details::at_end_of_item( parse_state.front( ) ),
308 ErrorReason::InvalidEndOfValue,
314 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
315 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
316 parse_value_null( ParseState &parse_state ) {
318 using constructor_t = json_constructor_t<JsonMember>;
319 auto const construct_empty = [&] {
320 if constexpr( daw::is_callable_v<
322 concepts::construct_nullable_with_empty_t> ) {
323 return construct_value<
typename JsonMember::wrapped_type,
325 parse_state, concepts::construct_nullable_with_empty );
327 return construct_value<
typename JsonMember::wrapped_type,
328 constructor_t>( parse_state );
332 using base_member_type =
typename JsonMember::member_type;
333 static_assert( not std::is_same_v<base_member_type, JsonMember> );
334 if constexpr( KnownBounds ) {
336 if( parse_state.is_null( ) ) {
337 return construct_empty( );
339 return construct_value<base_member_type, constructor_t>(
341 parse_value<base_member_type,
343 base_member_type::expected_type>( parse_state ) );
344 }
else if constexpr( ParseState::is_unchecked_input ) {
345 if( not parse_state.has_more( ) or
346 parse_state.is_at_token_after_value( ) ) {
347 return construct_empty( );
349 if( parse_state.front( ) ==
'n' ) {
350 parse_state.remove_prefix( 4 );
351 parse_state.trim_left_unchecked( );
352 return construct_empty( );
354 return construct_value<base_member_type, constructor_t>(
356 parse_value<base_member_type,
358 base_member_type::expected_type>( parse_state ) );
360 if( parse_state.is_null( ) or not parse_state.has_more( ) or
361 parse_state.is_at_token_after_value( ) ) {
362 return construct_empty( );
364 if( parse_state.starts_with(
"null" ) ) {
365 parse_state.remove_prefix( 4 );
367 parse_state.trim_left_checked( );
369 not parse_state.has_more( ) or
370 parse_policy_details::at_end_of_item( parse_state.front( ) ),
371 ErrorReason::InvalidLiteral,
373 return construct_empty( );
375 using parse_to_t = json_result_t<base_member_type>;
376 if constexpr( not std::is_move_constructible_v<parse_to_t> and
377 not std::is_copy_constructible_v<parse_to_t> ) {
380 concepts::nullable_value_traits<json_result_t<JsonMember>>,
381 concepts::construct_nullable_with_pointer_t,
383 return construct_value<base_member_type, constructor_t>(
385 concepts::construct_nullable_with_pointer,
387 parse_value<base_member_type,
389 base_member_type::expected_type>( parse_state ) } );
391 return construct_value<base_member_type, constructor_t>(
393 parse_value<base_member_type,
395 base_member_type::expected_type>( parse_state ) );
400 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
401 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
402 parse_value_bool( ParseState &parse_state ) {
403 using constructor_t = json_constructor_t<JsonMember>;
405 if constexpr( KnownBounds ) {
407 if constexpr( ParseState::is_unchecked_input ) {
408 return static_cast<bool>( parse_state.counter );
410 switch( parse_state.front( ) ) {
412 return construct_value<json_result_t<JsonMember>, constructor_t>(
415 return construct_value<json_result_t<JsonMember>, constructor_t>(
416 parse_state, false );
422 if constexpr( JsonMember::literal_as_string !=
423 options::LiteralAsStringOpt::Never ) {
424 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
428 if constexpr( ParseState::is_unchecked_input ) {
429 if( parse_state.front( ) ==
't' ) {
431 parse_state.remove_prefix( 4 );
433 parse_state.remove_prefix( 5 );
436 if( parse_state.starts_with(
"true" ) ) {
437 parse_state.remove_prefix( 4 );
439 }
else if( parse_state.starts_with(
"false" ) ) {
440 parse_state.remove_prefix( 5 );
446 if constexpr( JsonMember::literal_as_string !=
447 options::LiteralAsStringOpt::Never ) {
448 skip_quote_when_literal_as_string<JsonMember::literal_as_string,
449 true>( parse_state );
451 parse_state.trim_left( );
453 not parse_state.has_more( ) or
454 parse_policy_details::at_end_of_item( parse_state.front( ) ),
455 ErrorReason::InvalidEndOfValue,
457 return construct_value<json_result_t<JsonMember>, constructor_t>(
458 parse_state, result );
462 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
463 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
464 parse_value_string_raw( ParseState &parse_state ) {
466 using constructor_t = json_constructor_t<JsonMember>;
467 if constexpr( KnownBounds ) {
468 return construct_value<json_result_t<JsonMember>, constructor_t>(
469 parse_state, std::data( parse_state ), std::size( parse_state ) );
471 if constexpr( JsonMember::allow_escape_character ==
472 options::AllowEscapeCharacter::Allow ) {
473 auto const str = skip_string( parse_state );
474 return construct_value<json_result_t<JsonMember>, constructor_t>(
475 parse_state, std::data( str ), std::size( str ) );
477 parse_state.remove_prefix( );
479 char const *
const first = parse_state.first;
480 parse_state.template move_to_next_of<
'"'>( );
481 char const *
const last = parse_state.first;
482 parse_state.remove_prefix( );
483 return construct_value<json_result_t<JsonMember>, constructor_t>(
484 parse_state, first,
static_cast<std::size_t
>( last - first ) );
495 template<
typename JsonMember>
496 DAW_CPP20_CONCEPT can_parse_to_stdstring_fast_v =
497 can_single_allocation_string_v<json_result_t<JsonMember>> or
498 can_single_allocation_string_v<json_base_type_t<JsonMember>>;
501 json_constructor_t<T> );
506 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
507 [[nodiscard]] DAW_ATTRIB_INLINE
constexpr json_result_t<JsonMember>
508 parse_value_string_escaped( ParseState &parse_state ) {
509 static_assert( has_json_member_constructor_v<JsonMember> );
510 static_assert( has_json_member_parse_to_v<JsonMember> );
511 if constexpr( not KnownBounds ) {
513 ErrorReason::UnexpectedNull );
515 using constructor_t = json_constructor_t<JsonMember>;
516 if constexpr( can_parse_to_stdstring_fast_v<JsonMember> ) {
517 using AllowHighEightbits =
518 std::bool_constant<JsonMember::eight_bit_mode !=
519 options::EightBitModes::DisallowHigh>;
521 KnownBounds ? parse_state : skip_string( parse_state );
522 if( not AllowHighEightbits::value or
523 needs_slow_path( parse_state2 ) ) {
525 return parse_string_known_stdstring<AllowHighEightbits::value,
527 true>( parse_state2 );
531 return construct_value<json_result_t<JsonMember>, constructor_t>(
533 std::data( parse_state2 ),
534 daw::data_end( parse_state2 ) );
537 KnownBounds ? parse_state : skip_string( parse_state );
538 using AllowHighEightbits =
539 std::bool_constant<JsonMember::eight_bit_mode !=
540 options::EightBitModes::DisallowHigh>;
541 if( not AllowHighEightbits::value or
542 needs_slow_path( parse_state2 ) ) {
544 return parse_string_known_stdstring<AllowHighEightbits::value,
546 true>( parse_state2 );
550 return construct_value<json_result_t<JsonMember>, constructor_t>(
551 parse_state, std::data( parse_state2 ), std::size( parse_state2 ) );
555 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
556 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
557 parse_value_date( ParseState &parse_state ) {
560 ErrorReason::UnexpectedEndOfData,
562 auto str = KnownBounds ? parse_state : skip_string( parse_state );
563 using constructor_t = json_constructor_t<JsonMember>;
564 return construct_value<json_result_t<JsonMember>, constructor_t>(
565 parse_state, std::data( str ), std::size( str ) );
568 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
569 [[nodiscard]]
static constexpr json_result_t<JsonMember>
570 parse_value_custom( ParseState &parse_state ) {
572 auto const str = [&] {
573 if constexpr( JsonMember::custom_json_type ==
574 options::JsonCustomTypes::String ) {
575 if constexpr( KnownBounds ) {
578 return skip_string( parse_state );
580 }
else if constexpr( JsonMember::custom_json_type ==
581 options::JsonCustomTypes::Literal ) {
582 return KnownBounds ? parse_state : skip_literal( parse_state );
584 static_assert( JsonMember::custom_json_type ==
585 options::JsonCustomTypes::Any );
589 if constexpr( KnownBounds ) {
590 auto result = parse_state;
591 if( *( result.first - 1 ) ==
'"' ) {
597 if( parse_state.front( ) ==
'"' ) {
598 return skip_string<true>( parse_state );
600 return skip_value( parse_state );
604 if constexpr( JsonMember::custom_json_type !=
605 options::JsonCustomTypes::Any ) {
607 str.front( ) ==
'{' ),
608 ErrorReason::InvalidStartOfValue,
611 using constructor_t =
typename JsonMember::from_converter_t;
612 return construct_value<json_result_t<JsonMember>, constructor_t>(
613 parse_state, std::string_view( std::data( str ), std::size( str ) ) );
616 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
617 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
618 parse_value_class( ParseState &parse_state ) {
620 using element_t =
typename JsonMember::wrapped_type;
622 ErrorReason::UnexpectedEndOfData,
625 if constexpr( is_deduced_empty_class_v<JsonMember> ) {
626 if constexpr( not KnownBounds ) {
627 auto const old_class_pos = parse_state.get_class_position( );
628 parse_state.set_class_position( );
629 parse_state.remove_prefix( );
630 parse_state.trim_left( );
631 parse_state.trim_left_checked( );
632 parse_state.move_next_member_or_end( );
633 parse_state.move_to_next_class_member( );
634 (void)parse_state.skip_class( );
635 parse_state.trim_left_checked( );
636 parse_state.set_class_position( old_class_pos );
638 return json_result_t<JsonMember>{ };
639 }
else if constexpr( KnownBounds ) {
641 template parse_to_class<JsonMember, KnownBounds>( parse_state );
642 }
else if constexpr( is_pinned_type_v<element_t> ) {
643 auto const run_after_parse = daw::on_exit_success( [&] {
644 parse_state.trim_left_checked( );
646 (void)run_after_parse;
648 template parse_to_class<JsonMember, KnownBounds>( parse_state );
651 template parse_to_class<JsonMember, KnownBounds>( parse_state );
652 parse_state.trim_left_checked( );
657#if defined( DAW_JSON_HAS_REFLECTION )
658 template<
typename JsonMember,
bool ,
typename ParseState>
659 constexpr json_result_t<JsonMember>
660 parse_value_reflected_class( ParseState &parse_state ) {
662 ErrorReason::UnexpectedEndOfData,
665 return JsonMember::parse_to_class( parse_state );
677 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
678 [[nodiscard]]
static constexpr json_result_t<JsonMember>
679 parse_value_keyvalue( ParseState &parse_state ) {
681 static_assert( JsonMember::expected_type == JsonParseTypes::KeyValue,
682 "Expected a json_key_value" );
684 ErrorReason::ExpectedKeyValueToStartWithBrace,
687 parse_state.remove_prefix( );
688 parse_state.trim_left( );
691 json_parse_kv_class_iterator<JsonMember,
693 can_be_random_iterator_v<KnownBounds>>;
695 using constructor_t = json_constructor_t<JsonMember>;
696 return construct_value<json_result_t<JsonMember>, constructor_t>(
697 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_keyvalue_array( ParseState &parse_state ) {
712 static_assert( JsonMember::expected_type ==
713 JsonParseTypes::KeyValueArray,
714 "Expected a json_key_value" );
716 parse_state.is_opening_bracket_checked( ),
717 ErrorReason::ExpectedKeyValueArrayToStartWithBracket,
720 parse_state.remove_prefix( );
723 json_parse_kv_array_iterator<JsonMember,
725 can_be_random_iterator_v<KnownBounds>>;
726 using constructor_t = json_constructor_t<JsonMember>;
727 return construct_value<json_result_t<JsonMember>, constructor_t>(
728 parse_state, iter_t( parse_state ), iter_t( ) );
731 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
732 [[nodiscard]]
static constexpr json_result_t<JsonMember>
733 parse_value_array( ParseState &parse_state ) {
734 parse_state.trim_left( );
736 ErrorReason::InvalidArrayStart,
738 parse_state.remove_prefix( );
739 parse_state.trim_left_unchecked( );
744 json_parse_array_iterator<JsonMember,
746 can_be_random_iterator_v<KnownBounds>>;
747 using constructor_t = json_constructor_t<JsonMember>;
748#if defined( DAW_JSON_HAS_CPP23_RANGE_CTOR )
749 if constexpr( KnownBounds and
750 is_vector_default_constructor_v<constructor_t> ) {
754 if( parse_state.counter > 0 ) {
755 using counted_iterator_t =
756 json_parse_array_counted_iterator<iterator_t>;
757 static_assert( std::ranges::sized_range<
758 iter_range_t<counted_iterator_t,
759 json_parse_array_sized_end>> );
760 return construct_value<json_result_t<JsonMember>, constructor_t>(
763 iterator_t( parse_state ),
764 static_cast<std::ptrdiff_t
>( parse_state.counter + 1U ) ),
765 json_parse_array_sized_end{ } );
769 auto size_hint = std::size_t{ 0 };
770 if constexpr( KnownBounds ) {
775 if( parse_state.has_more( ) and parse_state.front( ) !=
']' ) {
776 auto const max_elements =
777 static_cast<std::size_t
>( parse_state.last - parse_state.first ) /
779 size_hint = parse_state.counter < max_elements
780 ? parse_state.counter + 1U
784 return construct_value<json_result_t<JsonMember>, constructor_t>(
785 parse_state, iterator_t( parse_state, size_hint ), iterator_t( ) );
788 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
789 [[nodiscard]]
static constexpr json_result_t<JsonMember>
790 parse_value_sz_array( ParseState &parse_state ) {
792 using size_member = dependent_member_t<JsonMember>;
794 auto [parse_state2, is_found] = find_range<ParseState>(
795 ParseState( parse_state.class_first, parse_state.last ),
799 is_found, ErrorReason::TagMemberNotFound, parse_state );
801 parse_value<size_member, false, size_member::expected_type>(
804 if constexpr( KnownBounds and ParseState::is_unchecked_input ) {
807 auto cnt =
static_cast<std::ptrdiff_t
>( parse_state.counter );
809 ErrorReason::NumberOutOfRange,
812 parse_state.trim_left( );
814 ErrorReason::InvalidArrayStart,
816 parse_state.remove_prefix( );
817 parse_state.trim_left_unchecked( );
821 json_parse_array_iterator<JsonMember, ParseState, false>;
822 using constructor_t = json_constructor_t<JsonMember>;
823 return construct_value<json_result_t<JsonMember>, constructor_t>(
825 iterator_t( parse_state ),
827 static_cast<std::size_t
>( sz ) );
832 [[nodiscard]]
constexpr json_result_t<JsonMembers>
833 parse_variant_value( ParseState &parse_state ) {
834 using element_t =
typename JsonMembers::json_elements;
835 using idx = daw::constant<( JsonMembers::base_map::base_map
836 [
static_cast<std::int_fast8_t
>( BPT )] )>;
838 if constexpr( idx::value <
839 pack_size_v<typename element_t::element_map_t> ) {
841 pack_element_t<idx::value, typename element_t::element_map_t>;
842 return parse_value<JsonMember,
844 JsonMember::expected_type>( parse_state );
850 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
851 [[nodiscard]]
static constexpr json_result_t<JsonMember>
852 parse_value_variant( ParseState &parse_state ) {
853 if constexpr( KnownBounds ) {
856 if( *( parse_state.first - 1 ) ==
'"' ) {
858 return parse_variant_value<JsonBaseParseTypes::String,
860 KnownBounds>( parse_state );
863 switch( parse_state.front( ) ) {
865 return parse_variant_value<JsonBaseParseTypes::Class,
867 KnownBounds>( parse_state );
869 return parse_variant_value<JsonBaseParseTypes::Array,
871 KnownBounds>( parse_state );
874 return parse_variant_value<JsonBaseParseTypes::Bool,
876 KnownBounds>( parse_state );
878 return parse_variant_value<JsonBaseParseTypes::String,
880 KnownBounds>( parse_state );
893 return parse_variant_value<JsonBaseParseTypes::Number,
895 KnownBounds>( parse_state );
897 if constexpr( ParseState::is_unchecked_input ) {
900 daw_json_error(
true, ErrorReason::InvalidStartOfValue, parse_state );
904 template<
typename Result,
typename TypeList, std::size_t pos = 0,
906 DAW_ATTRIB_INLINE
constexpr Result
907 parse_visit( std::size_t idx, ParseState &parse_state ) {
909 using JsonMember = pack_element_t<pos, TypeList>;
910 if constexpr( std::is_same_v<json_result_t<JsonMember>, Result> ) {
911 return parse_value<JsonMember, false, JsonMember::expected_type>(
915 parse_value<JsonMember, false, JsonMember::expected_type>(
919 if constexpr( pos + 1 < pack_size_v<TypeList> ) {
920 return parse_visit<Result, TypeList, pos + 1>( idx, parse_state );
922 if constexpr( ParseState::is_unchecked_input ) {
926 true, ErrorReason::MissingMemberNameOrEndOfClass, parse_state );
931 template<
typename JsonMember,
typename ParseState>
932 [[nodiscard]]
constexpr auto find_index( ParseState
const &parse_state ) {
933 using tag_member =
typename JsonMember::tag_member;
934 using class_wrapper_t =
typename JsonMember::tag_member_class_wrapper;
936 using switcher_t =
typename JsonMember::switcher;
937 auto parse_state2 = ParseState( parse_state.class_first,
938 parse_state.class_last,
939 parse_state.class_first,
940 parse_state.class_last );
941 if constexpr( is_an_ordered_member_v<tag_member> ) {
944 ErrorReason::InvalidArrayStart,
946 return switcher_t{ }( std::get<0>(
947 parse_value<class_wrapper_t, false, class_wrapper_t::expected_type>(
952 ErrorReason::InvalidClassStart,
954 return switcher_t{ }( std::get<0>(
955 parse_value<class_wrapper_t, false, class_wrapper_t::expected_type>(
961 template<
typename JsonMember,
typename ParseState>
962 [[nodiscard]]
constexpr json_result_t<JsonMember>
963 parse_value_variant_tagged( ParseState &parse_state ) {
964 auto const index = find_index<JsonMember>( parse_state );
965 return parse_visit<json_result_t<JsonMember>,
966 typename JsonMember::json_elements::element_map_t>(
967 index, parse_state );
970 template<
typename JsonMember,
typename ParseState>
971 [[nodiscard]]
constexpr json_result_t<JsonMember>
972 parse_value_variant_intrusive( ParseState &parse_state ) {
973 auto const index = [&] {
974 using tag_submember =
typename JsonMember::tag_submember;
975 using class_wrapper_t =
976 typename JsonMember::tag_submember_class_wrapper;
977 auto parse_state2 = parse_state;
978 using switcher_t =
typename JsonMember::switcher;
979 if constexpr( is_an_ordered_member_v<tag_submember> ) {
980 return switcher_t{ }( std::get<0>(
981 parse_value<class_wrapper_t,
983 class_wrapper_t::expected_type>( parse_state2 ) ) );
985 return switcher_t{ }( std::get<0>(
986 parse_value<class_wrapper_t,
988 class_wrapper_t::expected_type>( parse_state2 )
993 return parse_visit<json_result_t<JsonMember>,
994 typename JsonMember::json_elements::element_map_t>(
995 index, parse_state );
998 template<
bool AllMembersMustExist,
typename ParseState,
999 typename OldClassPos>
1000 DAW_ATTRIB_INLINE
constexpr void ordered_class_cleanup(
1001 ParseState &parse_state,
1004 if constexpr( AllMembersMustExist ) {
1005 parse_state.trim_left( );
1007 ErrorReason::UnknownMember,
1009 parse_state.remove_prefix( );
1010 parse_state.trim_left_checked( );
1012 (void)parse_state.skip_array( );
1014 parse_state.set_class_position( old_class_pos );
1017 namespace pocm_details {
1025 template<
bool Nullable,
typename ParseState>
1026 constexpr void maybe_skip_members( ParseState &parse_state,
1027 std::size_t ¤t_position,
1028 std::size_t desired_position ) {
1031 ErrorReason::OutOfOrderOrderedMembers,
1033 using skip_check_end =
1034 std::bool_constant<( ParseState::is_unchecked_input and Nullable )>;
1035 while( ( current_position < desired_position ) &
1036 ( skip_check_end::value or parse_state.front( ) !=
']' ) ) {
1037 (void)skip_value( parse_state );
1038 parse_state.move_next_member_or_end( );
1041 ErrorReason::UnexpectedEndOfData,
1046#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1047 template<
typename ParseState>
1048 struct position_info {
1050 ParseState state{ };
1052 constexpr explicit operator bool( )
const {
1053 return not state.is_null( );
1064 template<
bool Nullable,
typename ParseState, std::
size_t N>
1065 DAW_ATTRIB_INLINE
static constexpr ParseState maybe_skip_members(
1066 ParseState &parse_state, std::size_t ¤t_position,
1067 std::size_t desired_position,
1068 std::array<position_info<ParseState>, N> &parse_locations ) {
1070 auto const desired = daw::algorithm::find_if(
1071 std::data( parse_locations ),
1072 daw::data_end( parse_locations ),
1073 [desired_position]( position_info<ParseState>
const &loc ) {
1074 return loc.index == desired_position;
1077 return desired->state;
1079#if not defined( NDEBUG )
1081 ErrorReason::UnexpectedEndOfData,
1084 using skip_check_end =
1085 std::bool_constant<( ParseState::is_unchecked_input and Nullable )>;
1086 while( ( current_position < desired_position ) &
1087 ( skip_check_end::value or parse_state.front( ) !=
']' ) ) {
1088 auto const current = daw::algorithm::find_if(
1089 std::data( parse_locations ),
1090 daw::data_end( parse_locations ),
1091 [current_position]( position_info<ParseState>
const &loc ) {
1092 return loc.index == current_position;
1094 auto state = skip_value( parse_state );
1095 if( current != daw::data_end( parse_locations ) ) {
1096 current->state = state;
1098 parse_state.move_next_member_or_end( );
1101 ErrorReason::UnexpectedEndOfData,
1109 template<
typename T>
1110 struct member_index_t {
1111 static constexpr std::size_t value = T::member_index;
1114 template<
typename Idx,
typename JsonMember>
1115 inline constexpr std::size_t member_index_v =
1116 daw::conditional_t<has_member_index_v<JsonMember>,
1117 member_index_t<JsonMember>, Idx>::value;
1120 template<
typename JsonMember,
bool KnownBounds,
typename ParseState,
1122 DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1123 parse_tuple_value( ParseState &parse_state, std::index_sequence<Is...> ) {
1124 parse_state.trim_left( );
1126 ErrorReason::InvalidArrayStart,
1129 auto const old_class_pos = parse_state.get_class_position( );
1130 parse_state.set_class_position( );
1131 parse_state.remove_prefix( );
1132 parse_state.move_next_member_or_end( );
1133 using tuple_t = json_base_type_t<JsonMember>;
1134 using tuple_members =
typename JsonMember::sub_member_list;
1136#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1137 using position_info_t = pocm_details::position_info<ParseState>;
1138 std::size_t parse_locations_last_index = 0U;
1139 std::array<position_info_t,
sizeof...( Is )> parse_locations{
1140 [&](
auto Index )
mutable -> position_info_t {
1141 constexpr std::size_t index =
decltype( Index )::value;
1142 using member_t = std::tuple_element_t<index, tuple_members>;
1143 if constexpr( is_an_ordered_member_v<member_t> ) {
1144 parse_locations_last_index = member_t::member_index;
1145 return { member_t::member_index };
1147 return { parse_locations_last_index++ };
1149 }(daw::constant_v<Is>)... };
1151 auto const parse_value_help = [&](
auto PackIdx,
1152 std::size_t &ClassIdx ) {
1153 using index_t =
decltype( PackIdx );
1154 using CurrentMember =
1155 std::tuple_element_t<index_t::value, tuple_members>;
1157 using json_member_t = ordered_member_subtype_t<CurrentMember>;
1159#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1160 ParseState parse_state2 =
1161 pocm_details::maybe_skip_members<is_json_nullable_v<json_member_t>>(
1164 pocm_details::member_index_v<index_t, CurrentMember>,
1166 if constexpr(
sizeof...( Is ) > 1 ) {
1168 if( parse_state2.first == parse_state.first ) {
1169 if constexpr( is_pinned_type_v<json_result_t<JsonMember>> ) {
1170 auto const run_after_parse = daw::on_exit_success( [&] {
1171 parse_state.move_next_member_or_end( );
1173 (void)run_after_parse;
1174 return parse_value<json_member_t,
1176 json_member_t::expected_type>( parse_state );
1179 parse_value<json_member_t,
1181 json_member_t::expected_type>( parse_state );
1182 parse_state.move_next_member_or_end( );
1187 return parse_value<json_member_t,
1189 json_member_t::expected_type>( parse_state2 );
1193 if constexpr( is_an_ordered_member_v<CurrentMember> ) {
1194 pocm_details::maybe_skip_members<
1195 is_json_nullable_v<json_member_t>>(
1196 parse_state, ClassIdx, CurrentMember::member_index );
1199 ErrorReason::UnexpectedEndOfData,
1203 if constexpr( is_pinned_type_v<json_result_t<JsonMember>> ) {
1204 auto const run_after_parse = daw::on_exit_success( [&] {
1205 parse_state.move_next_member_or_end( );
1207 (void)run_after_parse;
1208 return parse_value<json_member_t,
1210 json_member_t::expected_type>( parse_state );
1213 parse_value<json_member_t, false, json_member_t::expected_type>(
1215 parse_state.move_next_member_or_end( );
1218#if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1223 static_assert( is_a_json_type_v<JsonMember> );
1224 using Constructor = json_constructor_t<JsonMember>;
1226 parse_state.trim_left( );
1228 std::size_t class_idx = 0;
1229 if constexpr( is_pinned_type_v<json_result_t<JsonMember>> ) {
1230 auto const run_after_parse = daw::on_exit_success( [&] {
1231 ordered_class_cleanup<
1232 all_json_members_must_exist_v<JsonMember, ParseState>,
1234 decltype( old_class_pos )>( parse_state, old_class_pos );
1236 (void)run_after_parse;
1241 parse_value_help( daw::constant_v<Is>, class_idx )... };
1243 return construct_value_tp<tuple_t, Constructor>(
1246 parse_value_help( daw::constant_v<Is>, class_idx )... } );
1254 parse_value_help( daw::constant_v<Is>, class_idx )... };
1256 return construct_value_tp<tuple_t, Constructor>(
1259 parse_value_help( daw::constant_v<Is>, class_idx )... } );
1262 if constexpr( all_json_members_must_exist_v<tuple_t, ParseState> ) {
1263 parse_state.trim_left( );
1265 ErrorReason::UnknownMember,
1267 parse_state.remove_prefix( );
1268 parse_state.trim_left( );
1270 (void)parse_state.skip_array( );
1272 parse_state.set_class_position( old_class_pos );
1277 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
1278 static constexpr json_result_t<JsonMember>
1279 parse_value_tuple( ParseState &parse_state ) {
1280 using element_pack =
1281 typename JsonMember::sub_member_list;
1283 return parse_tuple_value<JsonMember, KnownBounds>(
1285 std::make_index_sequence<std::tuple_size_v<element_pack>>{ } );
1288 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
1289 DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1290 parse_value_unknown( ParseState &parse_state ) {
1291 using constructor_t = json_constructor_t<JsonMember>;
1292 if constexpr( KnownBounds ) {
1293 return construct_value<json_result_t<JsonMember>, constructor_t>(
1294 parse_state, std::data( parse_state ), std::size( parse_state ) );
1296 auto value_parse_state = skip_value<true>( parse_state );
1297 return construct_value<json_result_t<JsonMember>, constructor_t>(
1299 std::data( value_parse_state ),
1300 std::size( value_parse_state ) );
1304 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
1305 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1306 parse_value_submember( ParseState &parse_state ) {
1307 auto submember_state = [&] {
1308 if constexpr( KnownBounds ) {
1311 return skip_value( parse_state );
1316 find_range2( submember_state, JsonMember::json_path );
1318 found, ErrorReason::JSONPathNotFound, submember_state );
1320 using member_type =
typename JsonMember::member_type;
1321 return parse_value<member_type, false, member_type::expected_type>(
1325 template<
typename JsonMember,
bool KnownBounds,
JsonParseTypes PTag,
1326 typename ParseState>
1327 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1328 parse_value( ParseState &parse_state ) {
1329 if constexpr( PTag == JsonParseTypes::Real ) {
1330 return parse_value_real<JsonMember, KnownBounds>( parse_state );
1331 }
else if constexpr( PTag == JsonParseTypes::Signed ) {
1332 return parse_value_signed<JsonMember, KnownBounds>( parse_state );
1333 }
else if constexpr( PTag == JsonParseTypes::Unsigned ) {
1334 return parse_value_unsigned<JsonMember, KnownBounds>( parse_state );
1335 }
else if constexpr( PTag == JsonParseTypes::Null ) {
1336 return parse_value_null<JsonMember, KnownBounds>( parse_state );
1337 }
else if constexpr( PTag == JsonParseTypes::Bool ) {
1338 return parse_value_bool<JsonMember, KnownBounds>( parse_state );
1339 }
else if constexpr( PTag == JsonParseTypes::StringRaw ) {
1340 return parse_value_string_raw<JsonMember, KnownBounds>( parse_state );
1341 }
else if constexpr( PTag == JsonParseTypes::StringInsitu ) {
1342 return parse_value_string_escaped<JsonMember, KnownBounds>(
1344 }
else if constexpr( PTag == JsonParseTypes::StringEscaped ) {
1345 return parse_value_string_escaped<JsonMember, KnownBounds>(
1347 }
else if constexpr( PTag == JsonParseTypes::Date ) {
1348 return parse_value_date<JsonMember, KnownBounds>( parse_state );
1349 }
else if constexpr( PTag == JsonParseTypes::Custom ) {
1350 return parse_value_custom<JsonMember, KnownBounds>( parse_state );
1351 }
else if constexpr( PTag == JsonParseTypes::Class ) {
1352 return parse_value_class<JsonMember, KnownBounds>( parse_state );
1353 }
else if constexpr( PTag == JsonParseTypes::KeyValue ) {
1354 return parse_value_keyvalue<JsonMember, KnownBounds>( parse_state );
1355 }
else if constexpr( PTag == JsonParseTypes::KeyValueArray ) {
1356 return parse_value_keyvalue_array<JsonMember, KnownBounds>(
1358 }
else if constexpr( PTag == JsonParseTypes::Array ) {
1359 return parse_value_array<JsonMember, KnownBounds>( parse_state );
1360 }
else if constexpr( PTag == JsonParseTypes::SizedArray ) {
1361 return parse_value_sz_array<JsonMember, KnownBounds>( parse_state );
1362 }
else if constexpr( PTag == JsonParseTypes::Variant ) {
1363 return parse_value_variant<JsonMember, KnownBounds>( parse_state );
1364 }
else if constexpr( PTag == JsonParseTypes::VariantTagged ) {
1365 return parse_value_variant_tagged<JsonMember>( parse_state );
1366 }
else if constexpr( PTag == JsonParseTypes::VariantIntrusive ) {
1367 return parse_value_variant_intrusive<JsonMember>( parse_state );
1368 }
else if constexpr( PTag == JsonParseTypes::Tuple ) {
1369 return parse_value_tuple<JsonMember, KnownBounds>( parse_state );
1370 }
else if constexpr( PTag == JsonParseTypes::Submember ) {
1371 return parse_value_submember<JsonMember, KnownBounds>( parse_state );
1372#if defined( DAW_JSON_HAS_REFLECTION )
1373 }
else if constexpr( PTag == JsonParseTypes::ReflectedClass ) {
1374 return parse_value_reflected_class<JsonMember, KnownBounds>(
1378 static_assert( PTag == JsonParseTypes::Unknown,
1379 "Unexpected JsonParseType" );
1380 return parse_value_unknown<JsonMember, KnownBounds>( parse_state );
1384 template<std::size_t N,
typename JsonClass,
bool KnownBounds,
1385 typename... JsonClasses,
typename ParseState>
1386 DAW_ATTRIB_INLINE
constexpr json_result_t<JsonClass>
1387 parse_nth_class( std::size_t idx, ParseState &parse_state ) {
1389 DAW_ASSUME( idx <
sizeof...( JsonClasses ) );
1390 using T = json_base_type_t<JsonClass>;
1391 using Constructor = json_constructor_t<JsonClass>;
1392 if constexpr(
sizeof...( JsonClasses ) >= N + 8 ) {
1395 using cur_json_class_t =
1396 daw::traits::nth_element<N + 0, JsonClasses...>;
1397 return construct_value<T, Constructor>(
1399 parse_value<cur_json_class_t,
1401 cur_json_class_t::expected_type>( parse_state ) );
1404 using cur_json_class_t =
1405 daw::traits::nth_element<N + 1, JsonClasses...>;
1406 return construct_value<T, Constructor>(
1408 parse_value<cur_json_class_t,
1410 cur_json_class_t::expected_type>( parse_state ) );
1413 using cur_json_class_t =
1414 daw::traits::nth_element<N + 2, JsonClasses...>;
1415 return construct_value<T, Constructor>(
1417 parse_value<cur_json_class_t,
1419 cur_json_class_t::expected_type>( parse_state ) );
1422 using cur_json_class_t =
1423 daw::traits::nth_element<N + 3, JsonClasses...>;
1424 return construct_value<T, Constructor>(
1426 parse_value<cur_json_class_t,
1428 cur_json_class_t::expected_type>( parse_state ) );
1431 using cur_json_class_t =
1432 daw::traits::nth_element<N + 4, JsonClasses...>;
1433 return construct_value<T, Constructor>(
1435 parse_value<cur_json_class_t,
1437 cur_json_class_t::expected_type>( parse_state ) );
1440 using cur_json_class_t =
1441 daw::traits::nth_element<N + 5, JsonClasses...>;
1442 return construct_value<T, Constructor>(
1444 parse_value<cur_json_class_t,
1446 cur_json_class_t::expected_type>( parse_state ) );
1449 using cur_json_class_t =
1450 daw::traits::nth_element<N + 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 using cur_json_class_t =
1459 daw::traits::nth_element<N + 7, JsonClasses...>;
1460 return construct_value<T, Constructor>(
1462 parse_value<cur_json_class_t,
1464 cur_json_class_t::expected_type>( parse_state ) );
1467 if constexpr(
sizeof...( JsonClasses ) >= N + 8 ) {
1468 return parse_nth_class<N + 8,
1471 JsonClasses...>( idx, parse_state );
1476 }
else if constexpr(
sizeof...( JsonClasses ) == N + 7 ) {
1479 using cur_json_class_t =
1480 daw::traits::nth_element<N + 0, 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 + 1, 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 + 2, JsonClasses...>;
1499 return construct_value<T, Constructor>(
1501 parse_value<cur_json_class_t,
1503 cur_json_class_t::expected_type>( parse_state ) );
1506 using cur_json_class_t =
1507 daw::traits::nth_element<N + 3, JsonClasses...>;
1508 return construct_value<T, Constructor>(
1510 parse_value<cur_json_class_t,
1512 cur_json_class_t::expected_type>( parse_state ) );
1515 using cur_json_class_t =
1516 daw::traits::nth_element<N + 4, JsonClasses...>;
1517 return construct_value<T, Constructor>(
1519 parse_value<cur_json_class_t,
1521 cur_json_class_t::expected_type>( parse_state ) );
1524 using cur_json_class_t =
1525 daw::traits::nth_element<N + 5, JsonClasses...>;
1526 return construct_value<T, Constructor>(
1528 parse_value<cur_json_class_t,
1530 cur_json_class_t::expected_type>( parse_state ) );
1533 DAW_ASSUME( idx == N + 6 );
1534 using cur_json_class_t =
1535 daw::traits::nth_element<N + 6, JsonClasses...>;
1536 return construct_value<T, Constructor>(
1538 parse_value<cur_json_class_t,
1540 cur_json_class_t::expected_type>( parse_state ) );
1543 }
else if constexpr(
sizeof...( JsonClasses ) == N + 6 ) {
1546 using cur_json_class_t =
1547 daw::traits::nth_element<N + 0, JsonClasses...>;
1548 return construct_value<T, Constructor>(
1550 parse_value<cur_json_class_t,
1552 cur_json_class_t::expected_type>( parse_state ) );
1555 using cur_json_class_t =
1556 daw::traits::nth_element<N + 1, JsonClasses...>;
1557 return construct_value<T, Constructor>(
1559 parse_value<cur_json_class_t,
1561 cur_json_class_t::expected_type>( parse_state ) );
1564 using cur_json_class_t =
1565 daw::traits::nth_element<N + 2, JsonClasses...>;
1566 return construct_value<T, Constructor>(
1568 parse_value<cur_json_class_t,
1570 cur_json_class_t::expected_type>( parse_state ) );
1573 using cur_json_class_t =
1574 daw::traits::nth_element<N + 3, JsonClasses...>;
1575 return construct_value<T, Constructor>(
1577 parse_value<cur_json_class_t,
1579 cur_json_class_t::expected_type>( parse_state ) );
1582 using cur_json_class_t =
1583 daw::traits::nth_element<N + 4, JsonClasses...>;
1584 return construct_value<T, Constructor>(
1586 parse_value<cur_json_class_t,
1588 cur_json_class_t::expected_type>( parse_state ) );
1591 DAW_ASSUME( idx == N + 5 );
1592 using cur_json_class_t =
1593 daw::traits::nth_element<N + 5, JsonClasses...>;
1594 return construct_value<T, Constructor>(
1596 parse_value<cur_json_class_t,
1598 cur_json_class_t::expected_type>( parse_state ) );
1601 }
else if constexpr(
sizeof...( JsonClasses ) == N + 5 ) {
1604 using cur_json_class_t =
1605 daw::traits::nth_element<N + 0, JsonClasses...>;
1606 return construct_value<T, Constructor>(
1608 parse_value<cur_json_class_t,
1610 cur_json_class_t::expected_type>( parse_state ) );
1613 using cur_json_class_t =
1614 daw::traits::nth_element<N + 1, JsonClasses...>;
1615 return construct_value<T, Constructor>(
1617 parse_value<cur_json_class_t,
1619 cur_json_class_t::expected_type>( parse_state ) );
1622 using cur_json_class_t =
1623 daw::traits::nth_element<N + 2, JsonClasses...>;
1624 return construct_value<T, Constructor>(
1626 parse_value<cur_json_class_t,
1628 cur_json_class_t::expected_type>( parse_state ) );
1631 using cur_json_class_t =
1632 daw::traits::nth_element<N + 3, JsonClasses...>;
1633 return construct_value<T, Constructor>(
1635 parse_value<cur_json_class_t,
1637 cur_json_class_t::expected_type>( parse_state ) );
1640 DAW_ASSUME( idx == N + 4 );
1641 using cur_json_class_t =
1642 daw::traits::nth_element<N + 4, JsonClasses...>;
1643 return construct_value<T, Constructor>(
1645 parse_value<cur_json_class_t,
1647 cur_json_class_t::expected_type>( parse_state ) );
1650 }
else if constexpr(
sizeof...( JsonClasses ) == N + 4 ) {
1653 using cur_json_class_t =
1654 daw::traits::nth_element<N + 0, JsonClasses...>;
1655 return construct_value<T, Constructor>(
1657 parse_value<cur_json_class_t,
1659 cur_json_class_t::expected_type>( parse_state ) );
1662 using cur_json_class_t =
1663 daw::traits::nth_element<N + 1, JsonClasses...>;
1664 return construct_value<T, Constructor>(
1666 parse_value<cur_json_class_t,
1668 cur_json_class_t::expected_type>( parse_state ) );
1671 using cur_json_class_t =
1672 daw::traits::nth_element<N + 2, JsonClasses...>;
1673 return construct_value<T, Constructor>(
1675 parse_value<cur_json_class_t,
1677 cur_json_class_t::expected_type>( parse_state ) );
1680 DAW_ASSUME( idx == N + 3 );
1681 using cur_json_class_t =
1682 daw::traits::nth_element<N + 3, JsonClasses...>;
1683 return construct_value<T, Constructor>(
1685 parse_value<cur_json_class_t,
1687 cur_json_class_t::expected_type>( parse_state ) );
1690 }
else if constexpr(
sizeof...( JsonClasses ) == N + 3 ) {
1693 using cur_json_class_t =
1694 daw::traits::nth_element<N + 0, JsonClasses...>;
1695 return construct_value<T, Constructor>(
1697 parse_value<cur_json_class_t,
1699 cur_json_class_t::expected_type>( parse_state ) );
1702 using cur_json_class_t =
1703 daw::traits::nth_element<N + 1, JsonClasses...>;
1704 return construct_value<T, Constructor>(
1706 parse_value<cur_json_class_t,
1708 cur_json_class_t::expected_type>( parse_state ) );
1711 DAW_ASSUME( idx == N + 2 );
1712 using cur_json_class_t =
1713 daw::traits::nth_element<N + 2, JsonClasses...>;
1714 return construct_value<T, Constructor>(
1716 parse_value<cur_json_class_t,
1718 cur_json_class_t::expected_type>( parse_state ) );
1721 }
else if constexpr(
sizeof...( JsonClasses ) == N + 2 ) {
1723 using cur_json_class_t =
1724 daw::traits::nth_element<N + 0, JsonClasses...>;
1725 return construct_value<T, Constructor>(
1727 parse_value<cur_json_class_t,
1729 cur_json_class_t::expected_type>( parse_state ) );
1731 using cur_json_class_t =
1732 daw::traits::nth_element<N + 1, JsonClasses...>;
1733 return construct_value<T, Constructor>(
1735 parse_value<cur_json_class_t,
1737 cur_json_class_t::expected_type>( parse_state ) );
1739 using cur_json_class_t =
1740 daw::traits::nth_element<N + 0, JsonClasses...>;
1741 return construct_value<T, Constructor>(
1743 parse_value<cur_json_class_t,
1745 cur_json_class_t::expected_type>( parse_state ) );