27 #include <daw/algorithms/daw_algorithm_find.h>
28 #include <daw/daw_arith_traits.h>
29 #include <daw/daw_attributes.h>
30 #include <daw/daw_constant.h>
31 #include <daw/daw_cxmath.h>
32 #include <daw/daw_scope_guard.h>
33 #include <daw/traits/daw_traits_conditional.h>
34 #include <daw/traits/daw_traits_identity.h>
38 #include <daw/stdinc/data_access.h>
39 #include <daw/stdinc/tuple_traits.h>
40 #include <type_traits>
44 namespace json_details {
56 DAW_ATTRIB_INLINE constexpr
void
57 skip_quote_when_literal_as_string( ParseState &parse_state ) {
58 if constexpr( literal_as_string ==
59 options::LiteralAsStringOpt::Always ) {
61 ErrorReason::InvalidNumberUnexpectedQuoting,
63 parse_state.remove_prefix( );
64 }
else if constexpr( literal_as_string ==
65 options::LiteralAsStringOpt::Maybe ) {
67 ErrorReason::UnexpectedEndOfData, parse_state );
68 if( parse_state.front( ) ==
'"' ) {
69 parse_state.remove_prefix( );
74 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
75 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
76 parse_value_real( ParseState &parse_state ) {
77 using constructor_t = json_constructor_t<JsonMember>;
78 using element_t = json_base_type_t<JsonMember>;
80 if constexpr( JsonMember::literal_as_string !=
81 options::LiteralAsStringOpt::Never ) {
82 if constexpr( not KnownBounds ) {
83 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
86 if constexpr( JsonMember::allow_number_errors ==
87 options::JsonNumberErrors::AllowInf or
88 JsonMember::allow_number_errors ==
89 options::JsonNumberErrors::AllowNanInf ) {
90 element_t sign = element_t( 1.0 );
91 if( parse_state.front( ) ==
'-' ) {
92 sign = element_t( -1.0 );
96 if( parse_state.size( ) >= 4 and
97 parse_state.starts_with(
"Inf" ) ) {
99 parse_state.first += 3;
100 if( parse_state.front( ) ==
'"' ) {
102 }
else if( parse_state.size( ) >= 6 and
103 parse_state.starts_with( R
"(inity")" ) ) {
104 parse_state.first += 6;
108 if constexpr( KnownBounds ) {
110 ErrorReason::InvalidNumber, parse_state );
113 parse_state.empty( ) or parse_policy_details::at_end_of_item(
114 parse_state.front( ) ),
115 ErrorReason::InvalidEndOfValue, parse_state );
117 return daw::cxmath::copy_sign(
118 daw::numeric_limits<element_t>::infinity( ), sign );
119 }
else if( sign < element_t( 0 ) ) {
123 if constexpr( JsonMember::allow_number_errors ==
124 options::JsonNumberErrors::AllowNaN or
125 JsonMember::allow_number_errors ==
126 options::JsonNumberErrors::AllowNanInf ) {
127 if( parse_state.starts_with(
"NaN" ) ) {
128 parse_state.template move_to_next_of<
'"'>( );
129 parse_state.remove_prefix( );
130 if constexpr( KnownBounds ) {
132 ErrorReason::InvalidNumber, parse_state );
135 parse_state.empty( ) or parse_policy_details::at_end_of_item(
136 parse_state.front( ) ),
137 ErrorReason::InvalidEndOfValue, parse_state );
139 return daw::numeric_limits<element_t>::quiet_NaN( );
143 if constexpr( KnownBounds and JsonMember::literal_as_string ==
144 options::LiteralAsStringOpt::Never ) {
145 return construct_value<json_result_t<JsonMember>, constructor_t>(
146 parse_state, parse_real<element_t, true>( parse_state ) );
149 parse_state.has_more( ) and
150 parse_policy_details::is_number_start( parse_state.front( ) ),
151 ErrorReason::InvalidNumberStart, parse_state );
154 construct_value<json_result_t<JsonMember>, constructor_t>(
155 parse_state, parse_real<element_t, false>( parse_state ) );
157 if constexpr( KnownBounds ) {
159 parse_state.empty( ) or
160 parse_policy_details::at_end_of_item( parse_state.front( ) ),
161 ErrorReason::InvalidEndOfValue, parse_state );
163 if constexpr( JsonMember::literal_as_string !=
164 options::LiteralAsStringOpt::Never ) {
165 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
169 parse_state.empty( ) or
170 parse_policy_details::at_end_of_item( parse_state.front( ) ),
171 ErrorReason::InvalidEndOfValue, parse_state );
177 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
178 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
179 parse_value_signed( ParseState &parse_state ) {
180 using constructor_t = json_constructor_t<JsonMember>;
181 using element_t = json_base_type_t<JsonMember>;
183 typename daw::conditional_t<std::is_enum_v<element_t>,
184 std::underlying_type<element_t>,
185 daw::traits::identity<element_t>>::type;
187 static_assert( daw::is_signed_v<int_type>,
"Expected signed type" );
188 if constexpr( KnownBounds ) {
190 parse_policy_details::is_number_start( parse_state.front( ) ),
191 ErrorReason::InvalidNumberStart, parse_state );
193 if constexpr( JsonMember::literal_as_string !=
194 options::LiteralAsStringOpt::Never ) {
195 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
199 ErrorReason::UnexpectedEndOfData,
203 auto const sign =
static_cast<int_type
>(
204 parse_policy_details::validate_signed_first( parse_state ) );
206 typename daw::conditional_t<daw::is_system_integral_v<int_type>,
207 daw::make_unsigned<int_type>,
208 daw::traits::identity<int_type>>::type;
209 auto parsed_val = to_signed(
210 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
211 ParseState::exec_tag, parse_state ),
214 if constexpr( KnownBounds ) {
215 return construct_value<json_result_t<JsonMember>, constructor_t>(
216 parse_state,
static_cast<element_t
>( parsed_val ) );
219 construct_value<json_result_t<JsonMember>, constructor_t>(
220 parse_state,
static_cast<element_t
>( parsed_val ) );
221 if constexpr( JsonMember::literal_as_string !=
222 options::LiteralAsStringOpt::Never ) {
223 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
226 parse_state.trim_left( );
228 not parse_state.has_more( ) or
229 parse_policy_details::at_end_of_item( parse_state.front( ) ),
230 ErrorReason::InvalidEndOfValue, parse_state );
235 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
236 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
237 parse_value_unsigned( ParseState &parse_state ) {
238 using constructor_t = json_constructor_t<JsonMember>;
239 using element_t = json_base_type_t<JsonMember>;
241 typename daw::conditional_t<std::is_enum_v<element_t>,
242 std::underlying_type<element_t>,
243 daw::traits::identity<element_t>>::type;
245 if constexpr( KnownBounds ) {
246 parse_policy_details::validate_unsigned_first( parse_state );
248 return construct_value<json_result_t<JsonMember>, constructor_t>(
250 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
251 ParseState::exec_tag, parse_state ) );
253 if constexpr( JsonMember::literal_as_string !=
254 options::LiteralAsStringOpt::Never ) {
255 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
259 ErrorReason::UnexpectedEndOfData,
264 ErrorReason::UnexpectedEndOfData,
269 ErrorReason::InvalidNumber, parse_state );
271 construct_value<json_result_t<JsonMember>, constructor_t>(
273 unsigned_parser<uint_type, JsonMember::range_check, KnownBounds>(
274 ParseState::exec_tag, parse_state ) );
275 if constexpr( JsonMember::literal_as_string !=
276 options::LiteralAsStringOpt::Never ) {
277 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
281 ErrorReason::UnexpectedEndOfData,
286 not parse_state.has_more( ) or
287 parse_policy_details::at_end_of_item( parse_state.front( ) ),
288 ErrorReason::InvalidEndOfValue, parse_state );
293 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
294 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
295 parse_value_null( ParseState &parse_state ) {
297 using constructor_t = json_constructor_t<JsonMember>;
298 auto const construct_empty = [&] {
299 if constexpr( std::is_invocable_v<
301 concepts::construct_nullable_with_empty_t> ) {
302 return construct_value<
typename JsonMember::wrapped_type,
306 return construct_value<
typename JsonMember::wrapped_type,
307 constructor_t>( parse_state );
311 using base_member_type =
typename JsonMember::member_type;
312 static_assert( not std::is_same_v<base_member_type, JsonMember> );
313 if constexpr( KnownBounds ) {
315 if( parse_state.is_null( ) ) {
316 return construct_empty( );
318 return construct_value<base_member_type, constructor_t>(
320 parse_value<base_member_type,
true,
321 base_member_type::expected_type>( parse_state ) );
322 }
else if constexpr( ParseState::is_unchecked_input ) {
323 if( not parse_state.has_more( ) or
324 parse_state.is_at_token_after_value( ) ) {
325 return construct_empty( );
327 if( parse_state.front( ) ==
'n' ) {
328 parse_state.remove_prefix( 4 );
329 parse_state.trim_left_unchecked( );
330 parse_state.remove_prefix( );
331 return construct_empty( );
333 return construct_value<base_member_type, constructor_t>(
335 parse_value<base_member_type,
false,
336 base_member_type::expected_type>( parse_state ) );
338 if( not parse_state.has_more( ) or
339 parse_state.is_at_token_after_value( ) ) {
340 return construct_empty( );
342 if( parse_state.starts_with(
"null" ) ) {
343 parse_state.remove_prefix( 4 );
345 not parse_state.has_more( ) or
346 parse_policy_details::at_end_of_item( parse_state.front( ) ),
347 ErrorReason::InvalidLiteral, parse_state );
348 parse_state.trim_left_checked( );
349 return construct_empty( );
351 using parse_to_t = json_result_t<base_member_type>;
352 if constexpr( not std::is_move_constructible_v<parse_to_t> and
353 not std::is_copy_constructible_v<parse_to_t> ) {
356 concepts::nullable_value_traits<json_result_t<JsonMember>>,
357 concepts::construct_nullable_with_pointer_t, parse_to_t *> );
358 return construct_value<base_member_type, constructor_t>(
361 parse_value<base_member_type,
false,
362 base_member_type::expected_type>( parse_state ) } );
364 return construct_value<base_member_type, constructor_t>(
366 parse_value<base_member_type,
false,
367 base_member_type::expected_type>( parse_state ) );
372 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
373 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
374 parse_value_bool( ParseState &parse_state ) {
375 using constructor_t = json_constructor_t<JsonMember>;
377 if constexpr( KnownBounds ) {
379 if constexpr( ParseState::is_unchecked_input ) {
380 return static_cast<bool>( parse_state.counter );
382 switch( parse_state.front( ) ) {
384 return construct_value<json_result_t<JsonMember>, constructor_t>(
387 return construct_value<json_result_t<JsonMember>, constructor_t>(
388 parse_state, false );
394 if constexpr( JsonMember::literal_as_string !=
395 options::LiteralAsStringOpt::Never ) {
396 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
400 if constexpr( ParseState::is_unchecked_input ) {
401 if( parse_state.front( ) ==
't' ) {
403 parse_state.remove_prefix( 4 );
405 parse_state.remove_prefix( 5 );
408 if( parse_state.starts_with(
"true" ) ) {
409 parse_state.remove_prefix( 4 );
411 }
else if( parse_state.starts_with(
"false" ) ) {
412 parse_state.remove_prefix( 5 );
418 if constexpr( JsonMember::literal_as_string !=
419 options::LiteralAsStringOpt::Never ) {
420 skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
423 parse_state.trim_left( );
425 not parse_state.has_more( ) or
426 parse_policy_details::at_end_of_item( parse_state.front( ) ),
427 ErrorReason::InvalidEndOfValue, parse_state );
428 return construct_value<json_result_t<JsonMember>, constructor_t>(
429 parse_state, result );
433 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
434 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
435 parse_value_string_raw( ParseState &parse_state ) {
437 using constructor_t = json_constructor_t<JsonMember>;
438 if constexpr( KnownBounds ) {
439 return construct_value<json_result_t<JsonMember>, constructor_t>(
440 parse_state, std::data( parse_state ), std::size( parse_state ) );
442 if constexpr( JsonMember::allow_escape_character ==
443 options::AllowEscapeCharacter::Allow ) {
444 auto const str = skip_string( parse_state );
445 return construct_value<json_result_t<JsonMember>, constructor_t>(
446 parse_state, std::data( str ), std::size( str ) );
448 parse_state.remove_prefix( );
450 char const *
const first = parse_state.first;
451 parse_state.template move_to_next_of<
'"'>( );
452 char const *
const last = parse_state.first;
453 parse_state.remove_prefix( );
454 return construct_value<json_result_t<JsonMember>, constructor_t>(
455 parse_state, first,
static_cast<std::size_t
>( last - first ) );
466 template<
typename JsonMember>
467 inline constexpr
bool can_parse_to_stdstring_fast_v =
468 can_single_allocation_string_v<json_result_t<JsonMember>> or
469 can_single_allocation_string_v<json_base_type_t<JsonMember>>;
472 json_constructor_t<T> );
477 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
478 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
479 parse_value_string_escaped( ParseState &parse_state ) {
480 static_assert( has_json_member_constructor_v<JsonMember> );
481 static_assert( has_json_member_parse_to_v<JsonMember> );
482 if constexpr( not KnownBounds ) {
484 ErrorReason::UnexpectedNull );
486 using constructor_t = json_constructor_t<JsonMember>;
487 if constexpr( can_parse_to_stdstring_fast_v<JsonMember> ) {
488 using AllowHighEightbits =
489 std::bool_constant<JsonMember::eight_bit_mode !=
490 options::EightBitModes::DisallowHigh>;
492 KnownBounds ? parse_state : skip_string( parse_state );
493 if( not AllowHighEightbits::value or
494 needs_slow_path( parse_state2 ) ) {
496 return parse_string_known_stdstring<AllowHighEightbits::value,
502 return construct_value<json_result_t<JsonMember>, constructor_t>(
503 parse_state, std::data( parse_state2 ),
504 daw::data_end( parse_state2 ) );
507 KnownBounds ? parse_state : skip_string( parse_state );
508 using AllowHighEightbits =
509 std::bool_constant<JsonMember::eight_bit_mode !=
510 options::EightBitModes::DisallowHigh>;
511 if( not AllowHighEightbits::value or
512 needs_slow_path( parse_state2 ) ) {
514 return parse_string_known_stdstring<AllowHighEightbits::value,
520 return construct_value<json_result_t<JsonMember>, constructor_t>(
521 parse_state, std::data( parse_state2 ),
522 daw::data_end( parse_state2 ) );
526 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
527 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
528 parse_value_date( ParseState &parse_state ) {
531 ErrorReason::UnexpectedEndOfData, parse_state );
532 auto str = KnownBounds ? parse_state : skip_string( parse_state );
533 using constructor_t = json_constructor_t<JsonMember>;
534 return construct_value<json_result_t<JsonMember>, constructor_t>(
535 parse_state, std::data( str ), std::size( str ) );
538 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
539 [[nodiscard]]
static constexpr json_result_t<JsonMember>
540 parse_value_custom( ParseState &parse_state ) {
542 auto const str = [&] {
543 if constexpr( JsonMember::custom_json_type ==
544 options::JsonCustomTypes::String ) {
545 if constexpr( KnownBounds ) {
548 return skip_string( parse_state );
550 }
else if constexpr( JsonMember::custom_json_type ==
551 options::JsonCustomTypes::Literal ) {
552 return KnownBounds ? parse_state : skip_literal( parse_state );
554 static_assert( JsonMember::custom_json_type ==
555 options::JsonCustomTypes::Any );
559 if constexpr( KnownBounds ) {
560 auto result = parse_state;
561 if( *( result.first - 1 ) ==
'"' ) {
566 if( parse_state.front( ) ==
'"' ) {
567 auto result = skip_string( parse_state );
571 return skip_value( parse_state );
576 str.has_more( ) and not( str.front( ) ==
'[' or str.front( ) ==
'{' ),
577 ErrorReason::InvalidStartOfValue, str );
578 using constructor_t =
typename JsonMember::from_converter_t;
579 return construct_value<json_result_t<JsonMember>, constructor_t>(
580 parse_state, std::string_view( std::data( str ), std::size( str ) ) );
583 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
584 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
585 parse_value_class( ParseState &parse_state ) {
587 using element_t =
typename JsonMember::wrapped_type;
589 ErrorReason::UnexpectedEndOfData, parse_state );
591 if constexpr( KnownBounds ) {
593 JsonMember, KnownBounds>( parse_state );
594 }
else if constexpr( is_pinned_type_v<element_t> ) {
595 auto const run_after_parse = daw::on_exit_success( [&] {
596 parse_state.trim_left_checked( );
598 (void)run_after_parse;
600 JsonMember, KnownBounds>( parse_state );
601 }
else if constexpr( is_deduced_empty_class_v<JsonMember> ) {
602 parse_state.trim_left_checked( );
603 return json_result_t<JsonMember>{ };
607 JsonMember, KnownBounds>( parse_state );
608 parse_state.trim_left_checked( );
621 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
622 [[nodiscard]]
static constexpr json_result_t<JsonMember>
623 parse_value_keyvalue( ParseState &parse_state ) {
625 static_assert( JsonMember::expected_type == JsonParseTypes::KeyValue,
626 "Expected a json_key_value" );
628 ErrorReason::ExpectedKeyValueToStartWithBrace,
631 parse_state.remove_prefix( );
632 parse_state.trim_left( );
635 json_parse_kv_class_iterator<JsonMember, ParseState,
636 can_be_random_iterator_v<KnownBounds>>;
638 using constructor_t = json_constructor_t<JsonMember>;
639 return construct_value<json_result_t<JsonMember>, constructor_t>(
640 parse_state, iter_t( parse_state ), iter_t( ) );
651 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
652 [[nodiscard]]
static constexpr json_result_t<JsonMember>
653 parse_value_keyvalue_array( ParseState &parse_state ) {
655 static_assert( JsonMember::expected_type ==
656 JsonParseTypes::KeyValueArray,
657 "Expected a json_key_value" );
659 parse_state.is_opening_bracket_checked( ),
660 ErrorReason::ExpectedKeyValueArrayToStartWithBracket, parse_state );
662 parse_state.remove_prefix( );
665 json_parse_kv_array_iterator<JsonMember, ParseState,
666 can_be_random_iterator_v<KnownBounds>>;
667 using constructor_t = json_constructor_t<JsonMember>;
668 return construct_value<json_result_t<JsonMember>, constructor_t>(
669 parse_state, iter_t( parse_state ), iter_t( ) );
672 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
673 [[nodiscard]]
static constexpr json_result_t<JsonMember>
674 parse_value_array( ParseState &parse_state ) {
675 parse_state.trim_left( );
677 ErrorReason::InvalidArrayStart, parse_state );
678 parse_state.remove_prefix( );
679 parse_state.trim_left_unchecked( );
684 json_parse_array_iterator<JsonMember, ParseState,
685 can_be_random_iterator_v<KnownBounds>>;
686 using constructor_t = json_constructor_t<JsonMember>;
687 return construct_value<json_result_t<JsonMember>, constructor_t>(
688 parse_state, iterator_t( parse_state ), iterator_t( ) );
691 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
692 [[nodiscard]]
static constexpr json_result_t<JsonMember>
693 parse_value_sz_array( ParseState &parse_state ) {
695 using size_member = dependent_member_t<JsonMember>;
697 auto [parse_state2, is_found] = find_range<ParseState>(
698 ParseState( parse_state.class_first, parse_state.last ),
704 parse_value<size_member, false, size_member::expected_type>(
707 if constexpr( KnownBounds and ParseState::is_unchecked_input ) {
710 auto cnt =
static_cast<std::ptrdiff_t
>( parse_state.counter );
712 ErrorReason::NumberOutOfRange, parse_state );
714 parse_state.trim_left( );
716 ErrorReason::InvalidArrayStart, parse_state );
717 parse_state.remove_prefix( );
718 parse_state.trim_left_unchecked( );
722 json_parse_array_iterator<JsonMember, ParseState, false>;
723 using constructor_t = json_constructor_t<JsonMember>;
724 return construct_value<json_result_t<JsonMember>, constructor_t>(
725 parse_state, iterator_t( parse_state ), iterator_t( ),
726 static_cast<std::size_t
>( sz ) );
731 [[nodiscard]] DAW_ATTRIB_FLATINLINE
static constexpr json_result_t<
733 parse_variant_value( ParseState &parse_state ) {
734 using element_t =
typename JsonMembers::json_elements;
735 using idx = daw::constant<( JsonMembers::base_map::base_map
736 [
static_cast<std::int_fast8_t
>( BPT )] )>;
738 if constexpr( idx::value <
739 pack_size_v<typename element_t::element_map_t> ) {
741 pack_element_t<idx::value, typename element_t::element_map_t>;
742 return parse_value<JsonMember, KnownBounds,
743 JsonMember::expected_type>( parse_state );
749 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
750 [[nodiscard]]
static constexpr json_result_t<JsonMember>
751 parse_value_variant( ParseState &parse_state ) {
752 if constexpr( KnownBounds ) {
755 if( *( parse_state.first - 1 ) ==
'"' ) {
757 return parse_variant_value<JsonBaseParseTypes::String, JsonMember,
758 KnownBounds>( parse_state );
761 switch( parse_state.front( ) ) {
763 return parse_variant_value<JsonBaseParseTypes::Class, JsonMember,
764 KnownBounds>( parse_state );
766 return parse_variant_value<JsonBaseParseTypes::Array, JsonMember,
767 KnownBounds>( parse_state );
770 return parse_variant_value<JsonBaseParseTypes::Bool, JsonMember,
771 KnownBounds>( parse_state );
773 return parse_variant_value<JsonBaseParseTypes::String, JsonMember,
774 KnownBounds>( parse_state );
787 return parse_variant_value<JsonBaseParseTypes::Number, JsonMember,
788 KnownBounds>( parse_state );
790 if constexpr( ParseState::is_unchecked_input ) {
797 template<
typename Result,
typename TypeList, std::size_t pos = 0,
799 DAW_ATTRIB_INLINE
static constexpr Result
800 parse_visit( std::size_t idx, ParseState &parse_state ) {
802 using JsonMember = pack_element_t<pos, TypeList>;
803 if constexpr( std::is_same_v<json_result_t<JsonMember>, Result> ) {
804 return parse_value<JsonMember, false, JsonMember::expected_type>(
808 parse_value<JsonMember, false, JsonMember::expected_type>(
812 if constexpr( pos + 1 < pack_size_v<TypeList> ) {
813 return parse_visit<Result, TypeList, pos + 1>( idx, parse_state );
815 if constexpr( ParseState::is_unchecked_input ) {
824 template<
typename JsonMember,
typename ParseState>
825 static constexpr
auto find_index( ParseState
const &parse_state ) {
826 using tag_member =
typename JsonMember::tag_member;
827 using class_wrapper_t =
typename JsonMember::tag_member_class_wrapper;
829 using switcher_t =
typename JsonMember::switcher;
831 ParseState( parse_state.class_first, parse_state.class_last,
832 parse_state.class_first, parse_state.class_last );
833 if constexpr( is_an_ordered_member_v<tag_member> ) {
836 ErrorReason::InvalidArrayStart, parse_state );
837 return switcher_t{ }( std::get<0>(
838 parse_value<class_wrapper_t, false, class_wrapper_t::expected_type>(
843 ErrorReason::InvalidClassStart, parse_state );
844 return switcher_t{ }( std::get<0>(
845 parse_value<class_wrapper_t, false, class_wrapper_t::expected_type>(
851 template<
typename JsonMember,
typename ParseState>
852 [[nodiscard]]
static constexpr json_result_t<JsonMember>
853 parse_value_variant_tagged( ParseState &parse_state ) {
854 auto const index = find_index<JsonMember>( parse_state );
855 return parse_visit<json_result_t<JsonMember>,
856 typename JsonMember::json_elements::element_map_t>(
857 index, parse_state );
860 template<
typename JsonMember,
typename ParseState>
861 [[nodiscard]]
static constexpr json_result_t<JsonMember>
862 parse_value_variant_intrusive( ParseState &parse_state ) {
863 auto const index = [&] {
864 using tag_submember =
typename JsonMember::tag_submember;
865 using class_wrapper_t =
866 typename JsonMember::tag_submember_class_wrapper;
867 auto parse_state2 = parse_state;
868 using switcher_t =
typename JsonMember::switcher;
869 if constexpr( is_an_ordered_member_v<tag_submember> ) {
870 return switcher_t{ }( std::get<0>(
871 parse_value<class_wrapper_t,
false,
872 class_wrapper_t::expected_type>( parse_state2 ) ) );
874 return switcher_t{ }( std::get<0>(
875 parse_value<class_wrapper_t,
false,
876 class_wrapper_t::expected_type>( parse_state2 )
881 return parse_visit<json_result_t<JsonMember>,
882 typename JsonMember::json_elements::element_map_t>(
883 index, parse_state );
886 template<
bool AllMembersMustExist,
typename ParseState,
887 typename OldClassPos>
888 DAW_ATTRIB_INLINE
static constexpr
void ordered_class_cleanup(
889 ParseState &parse_state,
892 if constexpr( AllMembersMustExist ) {
893 parse_state.trim_left( );
895 ErrorReason::UnknownMember, parse_state );
896 parse_state.remove_prefix( );
897 parse_state.trim_left_checked( );
899 (void)parse_state.skip_array( );
901 parse_state.set_class_position( old_class_pos );
904 namespace pocm_details {
912 template<
bool Nullable,
typename ParseState>
913 DAW_ATTRIB_INLINE
static constexpr
void
914 maybe_skip_members( ParseState &parse_state,
915 std::size_t ¤t_position,
916 std::size_t desired_position ) {
919 ErrorReason::OutOfOrderOrderedMembers,
921 using skip_check_end =
922 std::bool_constant<( ParseState::is_unchecked_input and Nullable )>;
923 while( ( current_position < desired_position ) &
924 ( skip_check_end::value or parse_state.front( ) !=
']' ) ) {
925 (void)skip_value( parse_state );
926 parse_state.move_next_member_or_end( );
929 ErrorReason::UnexpectedEndOfData,
934 #if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
935 template<
typename ParseState>
936 struct position_info {
940 constexpr
explicit operator bool( )
const {
941 return not state.is_null( );
952 template<
bool Nullable,
typename ParseState, std::
size_t N>
953 DAW_ATTRIB_INLINE
static constexpr ParseState maybe_skip_members(
954 ParseState &parse_state, std::size_t ¤t_position,
955 std::size_t desired_position,
956 std::array<position_info<ParseState>, N> &parse_locations ) {
958 auto const desired = daw::algorithm::find_if(
959 std::data( parse_locations ), daw::data_end( parse_locations ),
960 [desired_position]( position_info<ParseState>
const &loc ) {
961 return loc.index == desired_position;
964 return desired->state;
966 #if not defined( NDEBUG )
968 ErrorReason::UnexpectedEndOfData, parse_state );
970 using skip_check_end =
971 std::bool_constant<( ParseState::is_unchecked_input and Nullable )>;
972 while( ( current_position < desired_position ) &
973 ( skip_check_end::value or parse_state.front( ) !=
']' ) ) {
974 auto const current = daw::algorithm::find_if(
975 std::data( parse_locations ), daw::data_end( parse_locations ),
976 [current_position]( position_info<ParseState>
const &loc ) {
977 return loc.index == current_position;
979 auto state = skip_value( parse_state );
980 if( current != daw::data_end( parse_locations ) ) {
981 current->state = state;
983 parse_state.move_next_member_or_end( );
986 ErrorReason::UnexpectedEndOfData,
995 struct member_index_t {
996 static constexpr std::size_t value = T::member_index;
999 template<
typename Idx,
typename JsonMember>
1000 inline constexpr std::size_t member_index_v =
1001 daw::conditional_t<has_member_index_v<JsonMember>,
1002 member_index_t<JsonMember>, Idx>::value;
1005 template<
typename JsonMember,
bool KnownBounds,
typename ParseState,
1007 DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1008 parse_tuple_value( ParseState &parse_state, std::index_sequence<Is...> ) {
1009 parse_state.trim_left( );
1011 ErrorReason::InvalidArrayStart, parse_state );
1013 auto const old_class_pos = parse_state.get_class_position( );
1014 parse_state.set_class_position( );
1015 parse_state.remove_prefix( );
1016 parse_state.move_next_member_or_end( );
1017 using tuple_t = json_base_type_t<JsonMember>;
1018 using tuple_members =
typename JsonMember::sub_member_list;
1020 #if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1021 using position_info_t = pocm_details::position_info<ParseState>;
1022 std::size_t parse_locations_last_index = 0U;
1023 std::array<position_info_t,
sizeof...( Is )> parse_locations{
1024 [&](
auto Index )
mutable -> position_info_t {
1025 constexpr std::size_t index = decltype( Index )::value;
1026 using member_t = std::tuple_element_t<index, tuple_members>;
1027 if constexpr( is_an_ordered_member_v<member_t> ) {
1028 parse_locations_last_index = member_t::member_index;
1029 return { member_t::member_index };
1031 return { parse_locations_last_index++ };
1033 }(daw::constant_v<Is>)... };
1035 auto const parse_value_help = [&](
auto PackIdx,
1036 std::size_t &ClassIdx ) {
1037 using index_t = decltype( PackIdx );
1038 using CurrentMember =
1039 std::tuple_element_t<index_t::value, tuple_members>;
1041 using json_member_t = ordered_member_subtype_t<CurrentMember>;
1043 #if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1044 ParseState parse_state2 =
1045 pocm_details::maybe_skip_members<is_json_nullable_v<json_member_t>>(
1046 parse_state, ClassIdx,
1047 pocm_details::member_index_v<index_t, CurrentMember>,
1049 if constexpr(
sizeof...( Is ) > 1 ) {
1051 if( parse_state2.first == parse_state.first ) {
1053 auto const run_after_parse = daw::on_exit_success( [&] {
1054 parse_state.move_next_member_or_end( );
1056 (void)run_after_parse;
1057 return parse_value<json_member_t,
false,
1058 json_member_t::expected_type>( parse_state );
1061 parse_value<json_member_t,
false,
1062 json_member_t::expected_type>( parse_state );
1063 parse_state.move_next_member_or_end( );
1068 return parse_value<json_member_t,
true,
1069 json_member_t::expected_type>( parse_state2 );
1073 if constexpr( is_an_ordered_member_v<CurrentMember> ) {
1074 pocm_details::maybe_skip_members<
1075 is_json_nullable_v<json_member_t>>(
1076 parse_state, ClassIdx, CurrentMember::member_index );
1079 ErrorReason::UnexpectedEndOfData,
1084 auto const run_after_parse = daw::on_exit_success( [&] {
1085 parse_state.move_next_member_or_end( );
1087 (void)run_after_parse;
1088 return parse_value<json_member_t,
false,
1089 json_member_t::expected_type>( parse_state );
1092 parse_value<json_member_t, false, json_member_t::expected_type>(
1094 parse_state.move_next_member_or_end( );
1097 #if defined( DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002 )
1102 static_assert( is_a_json_type_v<JsonMember> );
1103 using Constructor = json_constructor_t<JsonMember>;
1105 parse_state.trim_left( );
1107 std::size_t class_idx = 0;
1109 auto const run_after_parse = daw::on_exit_success( [&] {
1110 ordered_class_cleanup<
1111 all_json_members_must_exist_v<JsonMember, ParseState>, ParseState,
1112 decltype( old_class_pos )>( parse_state, old_class_pos );
1114 (void)run_after_parse;
1118 parse_value_help( daw::constant_v<Is>, class_idx )... };
1120 return construct_value_tp<tuple_t, Constructor>(
1121 parse_state, fwd_pack{ parse_value_help( daw::constant_v<Is>,
1129 parse_value_help( daw::constant_v<Is>, class_idx )... };
1131 return construct_value_tp<tuple_t, Constructor>(
1132 parse_state, fwd_pack{ parse_value_help( daw::constant_v<Is>,
1136 if constexpr( all_json_members_must_exist_v<tuple_t, ParseState> ) {
1137 parse_state.trim_left( );
1139 ErrorReason::UnknownMember, parse_state );
1140 parse_state.remove_prefix( );
1141 parse_state.trim_left( );
1143 (void)parse_state.skip_array( );
1145 parse_state.set_class_position( old_class_pos );
1150 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
1151 static constexpr json_result_t<JsonMember>
1152 parse_value_tuple( ParseState &parse_state ) {
1153 using element_pack =
1154 typename JsonMember::sub_member_list;
1156 return parse_tuple_value<JsonMember, KnownBounds>(
1158 std::make_index_sequence<std::tuple_size_v<element_pack>>{ } );
1161 template<
typename JsonMember,
bool KnownBounds,
typename ParseState>
1162 DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1163 parse_value_unknown( ParseState &parse_state ) {
1164 using constructor_t = json_constructor_t<JsonMember>;
1165 if constexpr( KnownBounds ) {
1166 return construct_value<json_result_t<JsonMember>, constructor_t>(
1167 parse_state, std::data( parse_state ), std::size( parse_state ) );
1169 auto value_parse_state = skip_value<true>( parse_state );
1170 return construct_value<json_result_t<JsonMember>, constructor_t>(
1171 parse_state, std::data( value_parse_state ),
1172 std::size( value_parse_state ) );
1176 template<
typename JsonMember,
bool KnownBounds,
JsonParseTypes PTag,
1177 typename ParseState>
1178 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr json_result_t<JsonMember>
1179 parse_value( ParseState &parse_state ) {
1180 if constexpr( PTag == JsonParseTypes::Real ) {
1181 return parse_value_real<JsonMember, KnownBounds>( parse_state );
1182 }
else if constexpr( PTag == JsonParseTypes::Signed ) {
1183 return parse_value_signed<JsonMember, KnownBounds>( parse_state );
1184 }
else if constexpr( PTag == JsonParseTypes::Unsigned ) {
1185 return parse_value_unsigned<JsonMember, KnownBounds>( parse_state );
1186 }
else if constexpr( PTag == JsonParseTypes::Null ) {
1187 return parse_value_null<JsonMember, KnownBounds>( parse_state );
1188 }
else if constexpr( PTag == JsonParseTypes::Bool ) {
1189 return parse_value_bool<JsonMember, KnownBounds>( parse_state );
1190 }
else if constexpr( PTag == JsonParseTypes::StringRaw ) {
1191 return parse_value_string_raw<JsonMember, KnownBounds>( parse_state );
1192 }
else if constexpr( PTag == JsonParseTypes::StringEscaped ) {
1193 return parse_value_string_escaped<JsonMember, KnownBounds>(
1195 }
else if constexpr( PTag == JsonParseTypes::Date ) {
1196 return parse_value_date<JsonMember, KnownBounds>( parse_state );
1197 }
else if constexpr( PTag == JsonParseTypes::Custom ) {
1198 return parse_value_custom<JsonMember, KnownBounds>( parse_state );
1199 }
else if constexpr( PTag == JsonParseTypes::Class ) {
1200 return parse_value_class<JsonMember, KnownBounds>( parse_state );
1201 }
else if constexpr( PTag == JsonParseTypes::KeyValue ) {
1202 return parse_value_keyvalue<JsonMember, KnownBounds>( parse_state );
1203 }
else if constexpr( PTag == JsonParseTypes::KeyValueArray ) {
1204 return parse_value_keyvalue_array<JsonMember, KnownBounds>(
1206 }
else if constexpr( PTag == JsonParseTypes::Array ) {
1207 return parse_value_array<JsonMember, KnownBounds>( parse_state );
1208 }
else if constexpr( PTag == JsonParseTypes::SizedArray ) {
1209 return parse_value_sz_array<JsonMember, KnownBounds>( parse_state );
1210 }
else if constexpr( PTag == JsonParseTypes::Variant ) {
1211 return parse_value_variant<JsonMember, KnownBounds>( parse_state );
1212 }
else if constexpr( PTag == JsonParseTypes::VariantTagged ) {
1213 return parse_value_variant_tagged<JsonMember>( parse_state );
1214 }
else if constexpr( PTag == JsonParseTypes::VariantIntrusive ) {
1215 return parse_value_variant_intrusive<JsonMember>( parse_state );
1216 }
else if constexpr( PTag == JsonParseTypes::Tuple ) {
1217 return parse_value_tuple<JsonMember, KnownBounds>( parse_state );
1219 static_assert( PTag == JsonParseTypes::Unknown,
1220 "Unexpected JsonParseType" );
1221 return parse_value_unknown<JsonMember, KnownBounds>( parse_state );
1225 template<std::size_t N,
typename JsonClass,
bool KnownBounds,
1226 typename... JsonClasses,
typename ParseState>
1227 DAW_ATTRIB_INLINE constexpr json_result_t<JsonClass>
1228 parse_nth_class( std::size_t idx, ParseState &parse_state ) {
1230 DAW_ASSUME( idx <
sizeof...( JsonClasses ) );
1231 using T = json_base_type_t<JsonClass>;
1232 using Constructor = json_constructor_t<JsonClass>;
1233 if constexpr(
sizeof...( JsonClasses ) >= N + 8 ) {
1236 using cur_json_class_t =
1237 daw::traits::nth_element<N + 0, JsonClasses...>;
1238 return construct_value<T, Constructor>(
1240 parse_value<cur_json_class_t,
false,
1241 cur_json_class_t::expected_type>( parse_state ) );
1244 using cur_json_class_t =
1245 daw::traits::nth_element<N + 1, JsonClasses...>;
1246 return construct_value<T, Constructor>(
1248 parse_value<cur_json_class_t,
false,
1249 cur_json_class_t::expected_type>( parse_state ) );
1252 using cur_json_class_t =
1253 daw::traits::nth_element<N + 2, JsonClasses...>;
1254 return construct_value<T, Constructor>(
1256 parse_value<cur_json_class_t,
false,
1257 cur_json_class_t::expected_type>( parse_state ) );
1260 using cur_json_class_t =
1261 daw::traits::nth_element<N + 3, JsonClasses...>;
1262 return construct_value<T, Constructor>(
1264 parse_value<cur_json_class_t,
false,
1265 cur_json_class_t::expected_type>( parse_state ) );
1268 using cur_json_class_t =
1269 daw::traits::nth_element<N + 4, JsonClasses...>;
1270 return construct_value<T, Constructor>(
1272 parse_value<cur_json_class_t,
false,
1273 cur_json_class_t::expected_type>( parse_state ) );
1276 using cur_json_class_t =
1277 daw::traits::nth_element<N + 5, JsonClasses...>;
1278 return construct_value<T, Constructor>(
1280 parse_value<cur_json_class_t,
false,
1281 cur_json_class_t::expected_type>( parse_state ) );
1284 using cur_json_class_t =
1285 daw::traits::nth_element<N + 6, JsonClasses...>;
1286 return construct_value<T, Constructor>(
1288 parse_value<cur_json_class_t,
false,
1289 cur_json_class_t::expected_type>( parse_state ) );
1292 using cur_json_class_t =
1293 daw::traits::nth_element<N + 7, JsonClasses...>;
1294 return construct_value<T, Constructor>(
1296 parse_value<cur_json_class_t,
false,
1297 cur_json_class_t::expected_type>( parse_state ) );
1300 if constexpr(
sizeof...( JsonClasses ) >= N + 8 ) {
1301 return parse_nth_class<N + 8, JsonClass, KnownBounds,
1302 JsonClasses...>( idx, parse_state );
1307 }
else if constexpr(
sizeof...( JsonClasses ) == N + 7 ) {
1310 using cur_json_class_t =
1311 daw::traits::nth_element<N + 0, JsonClasses...>;
1312 return construct_value<T, Constructor>(
1314 parse_value<cur_json_class_t,
false,
1315 cur_json_class_t::expected_type>( parse_state ) );
1318 using cur_json_class_t =
1319 daw::traits::nth_element<N + 1, JsonClasses...>;
1320 return construct_value<T, Constructor>(
1322 parse_value<cur_json_class_t,
false,
1323 cur_json_class_t::expected_type>( parse_state ) );
1326 using cur_json_class_t =
1327 daw::traits::nth_element<N + 2, JsonClasses...>;
1328 return construct_value<T, Constructor>(
1330 parse_value<cur_json_class_t,
false,
1331 cur_json_class_t::expected_type>( parse_state ) );
1334 using cur_json_class_t =
1335 daw::traits::nth_element<N + 3, JsonClasses...>;
1336 return construct_value<T, Constructor>(
1338 parse_value<cur_json_class_t,
false,
1339 cur_json_class_t::expected_type>( parse_state ) );
1342 using cur_json_class_t =
1343 daw::traits::nth_element<N + 4, JsonClasses...>;
1344 return construct_value<T, Constructor>(
1346 parse_value<cur_json_class_t,
false,
1347 cur_json_class_t::expected_type>( parse_state ) );
1350 using cur_json_class_t =
1351 daw::traits::nth_element<N + 5, JsonClasses...>;
1352 return construct_value<T, Constructor>(
1354 parse_value<cur_json_class_t,
false,
1355 cur_json_class_t::expected_type>( parse_state ) );
1358 DAW_ASSUME( idx == N + 6 );
1359 using cur_json_class_t =
1360 daw::traits::nth_element<N + 6, JsonClasses...>;
1361 return construct_value<T, Constructor>(
1363 parse_value<cur_json_class_t,
false,
1364 cur_json_class_t::expected_type>( parse_state ) );
1367 }
else if constexpr(
sizeof...( JsonClasses ) == N + 6 ) {
1370 using cur_json_class_t =
1371 daw::traits::nth_element<N + 0, JsonClasses...>;
1372 return construct_value<T, Constructor>(
1374 parse_value<cur_json_class_t,
false,
1375 cur_json_class_t::expected_type>( parse_state ) );
1378 using cur_json_class_t =
1379 daw::traits::nth_element<N + 1, JsonClasses...>;
1380 return construct_value<T, Constructor>(
1382 parse_value<cur_json_class_t,
false,
1383 cur_json_class_t::expected_type>( parse_state ) );
1386 using cur_json_class_t =
1387 daw::traits::nth_element<N + 2, JsonClasses...>;
1388 return construct_value<T, Constructor>(
1390 parse_value<cur_json_class_t,
false,
1391 cur_json_class_t::expected_type>( parse_state ) );
1394 using cur_json_class_t =
1395 daw::traits::nth_element<N + 3, JsonClasses...>;
1396 return construct_value<T, Constructor>(
1398 parse_value<cur_json_class_t,
false,
1399 cur_json_class_t::expected_type>( parse_state ) );
1402 using cur_json_class_t =
1403 daw::traits::nth_element<N + 4, JsonClasses...>;
1404 return construct_value<T, Constructor>(
1406 parse_value<cur_json_class_t,
false,
1407 cur_json_class_t::expected_type>( parse_state ) );
1410 DAW_ASSUME( idx == N + 5 );
1411 using cur_json_class_t =
1412 daw::traits::nth_element<N + 5, JsonClasses...>;
1413 return construct_value<T, Constructor>(
1415 parse_value<cur_json_class_t,
false,
1416 cur_json_class_t::expected_type>( parse_state ) );
1419 }
else if constexpr(
sizeof...( JsonClasses ) == N + 5 ) {
1422 using cur_json_class_t =
1423 daw::traits::nth_element<N + 0, JsonClasses...>;
1424 return construct_value<T, Constructor>(
1426 parse_value<cur_json_class_t,
false,
1427 cur_json_class_t::expected_type>( parse_state ) );
1430 using cur_json_class_t =
1431 daw::traits::nth_element<N + 1, JsonClasses...>;
1432 return construct_value<T, Constructor>(
1434 parse_value<cur_json_class_t,
false,
1435 cur_json_class_t::expected_type>( parse_state ) );
1438 using cur_json_class_t =
1439 daw::traits::nth_element<N + 2, JsonClasses...>;
1440 return construct_value<T, Constructor>(
1442 parse_value<cur_json_class_t,
false,
1443 cur_json_class_t::expected_type>( parse_state ) );
1446 using cur_json_class_t =
1447 daw::traits::nth_element<N + 3, JsonClasses...>;
1448 return construct_value<T, Constructor>(
1450 parse_value<cur_json_class_t,
false,
1451 cur_json_class_t::expected_type>( parse_state ) );
1454 DAW_ASSUME( idx == N + 4 );
1455 using cur_json_class_t =
1456 daw::traits::nth_element<N + 4, JsonClasses...>;
1457 return construct_value<T, Constructor>(
1459 parse_value<cur_json_class_t,
false,
1460 cur_json_class_t::expected_type>( parse_state ) );
1463 }
else if constexpr(
sizeof...( JsonClasses ) == N + 4 ) {
1466 using cur_json_class_t =
1467 daw::traits::nth_element<N + 0, JsonClasses...>;
1468 return construct_value<T, Constructor>(
1470 parse_value<cur_json_class_t,
false,
1471 cur_json_class_t::expected_type>( parse_state ) );
1474 using cur_json_class_t =
1475 daw::traits::nth_element<N + 1, JsonClasses...>;
1476 return construct_value<T, Constructor>(
1478 parse_value<cur_json_class_t,
false,
1479 cur_json_class_t::expected_type>( parse_state ) );
1482 using cur_json_class_t =
1483 daw::traits::nth_element<N + 2, JsonClasses...>;
1484 return construct_value<T, Constructor>(
1486 parse_value<cur_json_class_t,
false,
1487 cur_json_class_t::expected_type>( parse_state ) );
1490 DAW_ASSUME( idx == N + 3 );
1491 using cur_json_class_t =
1492 daw::traits::nth_element<N + 3, JsonClasses...>;
1493 return construct_value<T, Constructor>(
1495 parse_value<cur_json_class_t,
false,
1496 cur_json_class_t::expected_type>( parse_state ) );
1499 }
else if constexpr(
sizeof...( JsonClasses ) == N + 3 ) {
1502 using cur_json_class_t =
1503 daw::traits::nth_element<N + 0, JsonClasses...>;
1504 return construct_value<T, Constructor>(
1506 parse_value<cur_json_class_t,
false,
1507 cur_json_class_t::expected_type>( parse_state ) );
1510 using cur_json_class_t =
1511 daw::traits::nth_element<N + 1, JsonClasses...>;
1512 return construct_value<T, Constructor>(
1514 parse_value<cur_json_class_t,
false,
1515 cur_json_class_t::expected_type>( parse_state ) );
1518 DAW_ASSUME( idx == N + 2 );
1519 using cur_json_class_t =
1520 daw::traits::nth_element<N + 2, JsonClasses...>;
1521 return construct_value<T, Constructor>(
1523 parse_value<cur_json_class_t,
false,
1524 cur_json_class_t::expected_type>( parse_state ) );
1527 }
else if constexpr(
sizeof...( JsonClasses ) == N + 2 ) {
1529 using cur_json_class_t =
1530 daw::traits::nth_element<N + 0, JsonClasses...>;
1531 return construct_value<T, Constructor>(
1533 parse_value<cur_json_class_t,
false,
1534 cur_json_class_t::expected_type>( parse_state ) );
1536 using cur_json_class_t =
1537 daw::traits::nth_element<N + 1, JsonClasses...>;
1538 return construct_value<T, Constructor>(
1540 parse_value<cur_json_class_t,
false,
1541 cur_json_class_t::expected_type>( parse_state ) );
1543 using cur_json_class_t =
1544 daw::traits::nth_element<N + 0, JsonClasses...>;
1545 return construct_value<T, Constructor>(
1547 parse_value<cur_json_class_t,
false,
1548 cur_json_class_t::expected_type>( parse_state ) );
#define daw_json_assert_weak(Bool,...)
Assert that Bool is true when in Checked Input mode If false pass rest of args to daw_json_error.
#define daw_json_ensure(Bool,...)
Ensure that Bool is true. If false pass rest of args to daw_json_error.
#define DAW_JSON_MAKE_REQ_TRAIT(Name,...)
Disable concepts on gcc < 13.3. See https://github.com/beached/daw_json_link/issues/454.
#define DAW_JSON_MAKE_REQ_TYPE_ALIAS_TRAIT_NT(Name,...)
DAW_ATTRIB_NOINLINE void daw_json_error(ErrorReason reason)
typename json_data_contract< T >::type json_data_contract_trait_t
This trait gets us the mapping type from the contract.
JsonParseTypes
The tags used by the parser to determine what parser to call.
JsonBaseParseTypes
The fundamental JSON types.
constexpr bool is_number(char c)
constexpr bool is_pinned_type_v
Is the type pinned in memory and unable to be copied/moved after construction(e.g....
constexpr bool should_construct_explicitly_v
std::bool_constant< is_zero_terminated_string_v< T > > is_zero_terminated_string
LiteralAsStringOpt
Controls the ability to parse numbers that are encoded as strings.
constexpr auto construct_nullable_with_empty
constexpr auto construct_nullable_with_pointer
Customization point traits.
constexpr bool use_daw_json_exceptions_v
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.