47 namespace json_details {
48 DAW_MAKE_REQ_TRAIT_TYPE( is_json_member_list_v,
49 T::i_am_a_json_member_list );
52 using ordered_member_subtype_test =
typename T::json_member;
55 using ordered_member_subtype_t =
56 typename daw::detected_or_t<T, ordered_member_subtype_test, T>;
58 template<
typename T,
typename Default>
59 inline constexpr auto json_class_constructor =
60 json_class_constructor_t<T, Default>{ };
62 template<
typename Value,
typename Constructor,
typename ParseState,
64 DAW_ATTRIB_INLINE
static constexpr auto
65 construct_value( ParseState &parse_state, Args &&...args ) {
68 if constexpr( ParseState::has_allocator ) {
69 auto alloc = parse_state.template get_allocator_for<Value>( );
70 return daw::try_alloc_construct<Value, Constructor>(
71 std::move( alloc ), DAW_FWD( args )... );
74 daw::is_callable_v<Constructor, Args...>,
75 "Unable to construct value with the supplied arguments" );
76 return Constructor{ }( DAW_FWD( args )... );
80#if not defined( DAW_JSON_USE_GENERIC_LAMBDAS )
81 template<
typename Constructor>
82 struct construct_value_tp_invoke_t {
83 template<
typename... TArgs, std::size_t... Is>
84 DAW_ATTRIB_INLINE
constexpr auto
85 operator( )( fwd_pack<TArgs...> &&tp,
86 std::index_sequence<Is...> )
const {
87 return Constructor{ }( get<Is>( std::move( tp ) )... );
90 template<
typename... TArgs,
typename Allocator, std::size_t... Is>
91 DAW_ATTRIB_INLINE
constexpr auto
92 operator( )( fwd_pack<TArgs...> &&tp, Allocator &alloc,
93 std::index_sequence<Is...> )
const {
94 return Constructor{ }( get<Is>( std::move( tp ) )...,
98 template<
typename Alloc,
typename... TArgs, std::size_t... Is>
99 DAW_ATTRIB_INLINE
constexpr auto
100 operator( )( std::allocator_arg_t, Alloc &&alloc,
101 fwd_pack<TArgs...> &&tp,
102 std::index_sequence<Is...> )
const {
104 return Constructor{ }( std::allocator_arg,
106 get<Is>( std::move( tp ) )... );
109 template<
typename Constructor>
110 inline constexpr auto construct_value_tp_invoke =
111 construct_value_tp_invoke_t<Constructor>{ };
114 template<
typename Value,
typename Constructor,
typename ParseState,
116 DAW_ATTRIB_FLATINLINE
static constexpr auto
117 construct_value_tp( ParseState &parse_state,
118 fwd_pack<Args...> &&tp_args ) {
120#if defined( DAW_JSON_USE_GENERIC_LAMBDAS )
121 if constexpr( ParseState::has_allocator ) {
125 typename ParseState::template allocator_type_as<Value>;
126 auto alloc = parse_state.template get_allocator_for<Value>( );
128 if constexpr( daw::is_callable_v<Constructor, Args..., alloc_t> ) {
129 return [&]<std::size_t... Is>( std::index_sequence<Is...> ) {
131 return Constructor{ }( get<Is>( std::move( tp_args ) )...,
132 std::move( alloc ) );
133 }( std::make_index_sequence<
sizeof...( Args )>{ } );
134 }
else if constexpr( daw::is_callable_v<Constructor,
135 std::allocator_arg_t,
139 return [&]<std::size_t... Is>( std::index_sequence<Is...> ) {
140 return Constructor{ }( std::allocator_arg,
142 get<Is>( std::move( tp_args ) )... );
143 }( std::make_index_sequence<
sizeof...( Args )>{ } );
149 daw::is_callable_v<Constructor, Args...>,
150 "Unable to construct value with the supplied arguments" );
151 return [&]<std::size_t... Is>( std::index_sequence<Is...> ) {
152 return Constructor{ }( get<Is>( std::move( tp_args ) )... );
153 }( std::make_index_sequence<
sizeof...( Args )>{ } );
161 daw::is_callable_v<Constructor, Args...>,
162 "Unable to construct value with the supplied arguments" );
163 return [&]<std::size_t... Is>( std::index_sequence<Is...> ) {
164 return Constructor{ }( get<Is>( std::move( tp_args ) )... );
165 }( std::make_index_sequence<
sizeof...( Args )>{ } );
168 if constexpr( ParseState::has_allocator ) {
172 typename ParseState::template allocator_type_as<Value>;
173 auto alloc = parse_state.template get_allocator_for<Value>( );
174 if constexpr( daw::is_callable_v<Constructor, Args..., alloc_t> ) {
176 return construct_value_tp_invoke<Constructor>(
177 std::move( tp_args ),
179 std::index_sequence_for<Args...>{ } );
180 }
else if constexpr( daw::is_callable_v<Constructor,
181 std::allocator_arg_t,
185 return construct_value_tp_invoke<Constructor>(
188 std::move( tp_args ),
189 std::index_sequence_for<Args...>{ } );
195 daw::is_callable_v<Constructor, Args...>,
196 "Unable to construct value with the supplied arguments" );
197 return construct_value_tp_invoke<Constructor>(
198 std::move( tp_args ), std::index_sequence_for<Args...>{ } );
206 daw::is_callable_v<Constructor, Args...>,
207 "Unable to construct value with the supplied arguments" );
208 return construct_value_tp_invoke<Constructor>(
209 std::move( tp_args ), std::index_sequence_for<Args...>{ } );
215 DAW_CPP20_CONCEPT has_json_data_contract_trait_v =
216 not std::is_same_v<missing_json_data_contract_for_or_unknown_type<T>,
220 has_json_to_json_data_v,
224 is_submember_tagged_variant_v,
228 using json_nullable_member_type_t =
typename T::member_type;
234 template<
json_options_t CurrentOptions,
auto option,
auto... options>
236 set_bits(
number_opts, CurrentOptions, option, options... );
238 template<
json_options_t CurrentOptions,
auto option,
auto... options>
240 set_bits(
bool_opts, CurrentOptions, option, options... );
242 template<
json_options_t CurrentOptions,
auto option,
auto... options>
244 set_bits(
string_opts, CurrentOptions, option, options... );
246 template<
json_options_t CurrentOptions,
auto option,
auto... options>
250 template<
json_options_t CurrentOptions,
auto option,
auto... options>
261 namespace json_base {
268 template<
typename T,
typename JsonMember = use_default,
270 typename Constructor = use_default>
274 namespace json_details {
276 inline constexpr bool is_json_nullable_v =
false;
278 template<
typename T,
typename JsonMember,
JsonNullable NullableType,
279 typename Constructor>
280 inline constexpr bool is_json_nullable_v<
285 struct json_empty_class {
286 static_assert( std::is_empty_v<T>,
"T is expected to empty" );
287 using i_am_a_json_type = void;
288 using i_am_a_deduced_empty_class = void;
289 using wrapped_type = T;
292 using parse_to_t = T;
294 static constexpr auto expected_type = JsonParseTypes::Class;
295 static constexpr auto underlying_json_type = JsonBaseParseTypes::Class;
299 struct json_ordered_class {
300 static_assert( can_convert_to_tuple_v<T>,
"T is expected to empty" );
301 using i_am_a_json_type = void;
302 using i_am_a_deduced_ordered_class = void;
303 using wrapped_type = T;
306 using parse_to_t = T;
308 static constexpr auto expected_type = JsonParseTypes::Tuple;
310 static constexpr auto underlying_json_type = JsonBaseParseTypes::Class;
314 namespace json_base {
316 template<
typename T,
typename Constructor = use_default>
319 template<
typename T,
JsonNullable NullableType = JsonNullable::Nullable,
320 typename Constructor = use_default>
325 template<
typename JsonElement,
typename Container = use_default,
326 typename Constructor = use_default>
329 template<
typename T,
typename FromJsonConverter = use_default,
330 typename ToJsonConverter = use_default,
334 template<
typename Variant,
typename JsonElements = use_default,
335 typename Constructor = use_default>
338 template<
typename T,
typename TagMember,
typename Switcher,
339 typename JsonElements = use_default,
340 typename Constructor = use_default>
344 typename Constructor = use_default>
349 typename Constructor = use_default>
352 NullableType, Constructor>;
355 typename Constructor = use_default>
360 typename Constructor = use_default>
363 NullableType, Constructor>;
366 typename Constructor = use_default>
371 typename Constructor = use_default>
374 NullableType, Constructor>;
376 template<
typename T,
typename Constructor = use_default>
380 typename Constructor = use_default>
385 typename Constructor = use_default>
388 NullableType, Constructor>;
390 template<
typename Container,
typename JsonValueType = use_default,
391 typename JsonKeyType = use_default,
392 typename Constructor = use_default>
395 template<
typename Container,
typename JsonValueType = use_default,
396 typename JsonKeyType = use_default,
397 typename Constructor = use_default>
400 template<
typename Container,
typename JsonValueType,
typename JsonKeyType,
402 typename Constructor = use_default>
406 JsonValueType, JsonKeyType>,
407 NullableType, Constructor>;
409 template<
typename Tuple,
typename JsonTupleTypesList = use_default,
410 typename Constructor = use_default>
413 template<
typename Tuple,
typename JsonTupleTypesList = use_default,
415 typename Constructor = use_default>
418 NullableType, Constructor>;
428 template<
typename T,
typename Constructor = use_default>
440 template<
typename T,
JsonNullable NullableType = JsonNullable::Nullable,
441 typename Constructor = use_default>
447 namespace json_details {
450 number_parse_type_impl_test( ) {
451 if constexpr( daw::is_floating_point_v<T> ) {
452 return JsonParseTypes::Real;
453 }
else if constexpr( daw::is_signed_v<T> ) {
454 return JsonParseTypes::Signed;
456 static_assert( daw::is_unsigned_v<T> );
457 return JsonParseTypes::Unsigned;
462 DAW_ATTRIB_INLINE DAW_CONSTEVAL
JsonParseTypes number_parse_type_test( ) {
463 if constexpr( std::is_enum_v<T> ) {
464 return number_parse_type_impl_test<std::underlying_type_t<T>>( );
466 return number_parse_type_impl_test<T>( );
472 number_parse_type_test<T>( );
474 template<
typename,
typename =
void>
475 struct json_deduced_type_map {
476 static constexpr bool is_null =
false;
477 static constexpr auto parse_type = JsonParseTypes::Unknown;
479 static constexpr bool type_map_found =
false;
482 template<
typename JsonType>
484 struct json_deduced_type_map<
485 JsonType DAW_ENABLEIF_S( is_a_json_type_v<JsonType> )> {
486 static constexpr bool is_null =
false;
487 static constexpr auto parse_type = JsonParseTypes::Unknown;
489 using type = JsonType;
490 static constexpr bool type_map_found =
true;
495 struct json_deduced_type_map<
496 T DAW_ENABLEIF_S( has_json_data_contract_trait_v<T> )> {
497 static constexpr bool is_null =
false;
498 using type =
typename json_data_contract<T>::type;
499 static_assert( is_json_member_list_v<type>,
500 "Expected a JSON member list" );
501 static constexpr auto parse_type = JsonParseTypes::Unknown;
503 static constexpr bool type_map_found =
true;
507 struct json_deduced_type_map<
daw::string_view> {
508 static constexpr bool is_null =
false;
509 static constexpr auto parse_type = JsonParseTypes::StringRaw;
511 static constexpr bool type_map_found =
true;
515 struct json_deduced_type_map<
std::string_view> {
516 static constexpr bool is_null =
false;
517 static constexpr auto parse_type = JsonParseTypes::StringRaw;
519 static constexpr bool type_map_found =
true;
523 struct json_deduced_type_map<
std::string> {
524 static constexpr bool is_null =
false;
525 static constexpr auto parse_type = JsonParseTypes::StringEscaped;
527 static constexpr bool type_map_found =
true;
531 struct json_deduced_type_map<bool> {
532 static constexpr bool is_null =
false;
533 static constexpr auto parse_type = JsonParseTypes::Bool;
534 static constexpr bool type_map_found =
true;
539#if defined( _LIBCPP_VERSION )
541 struct json_deduced_type_map<
542 typename
std::vector<bool>::const_reference> {
544 static constexpr bool is_null =
false;
545 static constexpr auto parse_type = JsonParseTypes::Bool;
547 static constexpr bool type_map_found =
true;
551 template<
typename Integer>
553 not json_details::has_json_data_contract_trait_v<Integer> and
554 daw::is_integral_v<Integer> )
555 struct json_deduced_type_map<Integer DAW_ENABLEIF_S(
556 not json_details::has_json_data_contract_trait_v<Integer> and
557 daw::is_integral_v<Integer> )> {
558 static constexpr bool is_null =
false;
559 static constexpr auto parse_type = daw::is_signed_v<Integer>
560 ? JsonParseTypes::Signed
561 : JsonParseTypes::Unsigned;
563 static constexpr bool type_map_found =
true;
566 template<
typename Enum>
567 DAW_REQUIRES( not json_details::has_json_data_contract_trait_v<Enum> and
568 std::is_enum_v<Enum> )
569 struct json_deduced_type_map<Enum DAW_ENABLEIF_S(
570 not json_details::has_json_data_contract_trait_v<Enum> and
571 std::is_enum_v<Enum> )> {
572 static constexpr bool is_null =
false;
573 static constexpr auto parse_type =
574 daw::is_signed_v<std::underlying_type<Enum>>
575 ? JsonParseTypes::Signed
576 : JsonParseTypes::Unsigned;
578 static constexpr bool type_map_found =
true;
581 template<
typename FloatingPo
int>
583 not json_details::has_json_data_contract_trait_v<FloatingPoint> and
584 daw::is_floating_point_v<FloatingPoint> )
585 struct json_deduced_type_map<FloatingPoint DAW_ENABLEIF_S(
586 not json_details::has_json_data_contract_trait_v<FloatingPoint> and
587 daw::is_floating_point_v<FloatingPoint> )> {
588 static constexpr bool is_null =
false;
589 static constexpr auto parse_type = JsonParseTypes::Real;
591 static constexpr bool type_map_found =
true;
594 template<
typename Tuple>
595 DAW_REQUIRES( not json_details::has_json_data_contract_trait_v<Tuple> and
597 struct json_deduced_type_map<
Tuple DAW_ENABLEIF_S(
598 not json_details::has_json_data_contract_trait_v<Tuple> and
599 is_tuple_v<Tuple> )> {
600 static constexpr bool is_null =
false;
601 static constexpr auto parse_type = JsonParseTypes::Tuple;
603 static constexpr bool type_map_found =
true;
606 namespace container_detect {
608 using is_string_test =
609 decltype( (void)( std::begin( std::declval<T &>( ) ) ),
610 (
void)( std::end( std::declval<T &>( ) ) ),
611 std::declval<typename T::value_type>( ) );
614 template<
typename String>
615 DAW_CPP20_CONCEPT is_string_v = std::is_convertible_v<
616 char, daw::detected_t<container_detect::is_string_test, String>>;
619 is_associative_container_v,
620 ( (
void)( std::begin( std::declval<T &>( ) ) ),
621 (
void)( std::end( std::declval<T &>( ) ) ),
622 (
void)( std::declval<typename T::value_type>( ) ),
623 (
void)( std::declval<typename T::key_type>( ) ),
624 (
void)( std::declval<typename T::mapped_type>( ) ) ) );
626 template<
typename AssociativeContainer>
627 DAW_REQUIRES( not has_json_data_contract_trait_v<AssociativeContainer> and
628 is_associative_container_v<AssociativeContainer> )
629 struct json_deduced_type_map<AssociativeContainer DAW_ENABLEIF_S(
630 not has_json_data_contract_trait_v<AssociativeContainer> and
631 is_associative_container_v<AssociativeContainer> )> {
632 static constexpr bool is_null =
false;
633 using key =
typename AssociativeContainer::key_type;
634 using value =
typename AssociativeContainer::mapped_type;
635 static constexpr auto parse_type = JsonParseTypes::KeyValue;
637 static constexpr bool type_map_found =
true;
641 DAW_CPP20_CONCEPT is_deduced_array_v =
642 not has_json_data_contract_trait_v<T> and
643 not is_associative_container_v<T> and concepts::is_container_v<T> and
646 template<
typename Container>
648 struct json_deduced_type_map<
649 Container DAW_ENABLEIF_S( is_deduced_array_v<Container> )> {
650 static constexpr bool is_null =
false;
651 using value =
typename Container::value_type;
652 static constexpr auto parse_type = JsonParseTypes::Array;
654 static constexpr bool type_map_found =
true;
658 DAW_CPP20_CONCEPT has_nullable_type_map_v =
659 concepts::is_nullable_value_v<T> and
660 not has_json_data_contract_trait_v<T> and
661 daw::is_detected_v<json_deduced_type_map,
662 concepts::nullable_value_type_t<T>>;
666 struct json_deduced_type_map<
667 T DAW_ENABLEIF_S( has_nullable_type_map_v<T> )> {
668 static constexpr bool is_null =
true;
669 using sub_type = concepts::nullable_value_type_t<T>;
670 using type = json_deduced_type_map<sub_type>;
671 static constexpr auto parse_type = type::parse_type;
672 static constexpr bool type_map_found =
true;
676 DAW_CPP20_CONCEPT has_deduced_type_mapping_v =
677 json_deduced_type_map<T>::type_map_found;
679 template<
typename... Ts>
680 DAW_CPP20_CONCEPT are_deduced_type_mapped_v =
681 ( has_deduced_type_mapping_v<Ts> and ... );
683 template<
typename Mapped,
bool Found = true>
684 struct json_link_quick_map_type {
685 static constexpr bool value = Found;
686 using mapped_type = Mapped;
689 template<JsonParseTypes Value>
690 DAW_CPP20_CONCEPT is_arithmetic_parse_type_v =
691 daw::traits::equal_to_any_of_v<Value, JsonParseTypes::Signed,
692 JsonParseTypes::Unsigned,
693 JsonParseTypes::Real>;
696 DAW_ATTRIB_INLINE DAW_CONSTEVAL
auto json_link_quick_map( ) noexcept {
697 if constexpr( is_a_json_type_v<T> ) {
698 return json_link_quick_map_type<T>{ };
699 }
else if constexpr( has_deduced_type_mapping_v<T> ) {
700 using mapped_type_t = json_deduced_type_map<T>;
701 using parse_type = daw::constant<mapped_type_t::parse_type>;
702 using is_null = daw::constant<mapped_type_t::is_null>;
703 if constexpr( parse_type::value == JsonParseTypes::Unknown ) {
704 if constexpr( is_null::value ) {
705 if constexpr( has_json_data_contract_trait_v<
706 typename mapped_type_t::sub_type> ) {
707 return json_link_quick_map_type<
708 json_base::json_class_null<T>>{ };
710 return json_link_quick_map_type<json_base::json_raw_null<T>>{ };
713 return json_link_quick_map_type<json_base::json_raw<T>>{ };
715 }
else if constexpr( parse_type::value ==
716 JsonParseTypes::StringRaw ) {
717 if constexpr( is_null::value ) {
718 return json_link_quick_map_type<
719 json_base::json_string_raw_null<T>>{ };
721 return json_link_quick_map_type<json_base::json_string_raw<T>>{ };
723 }
else if constexpr( parse_type::value ==
724 JsonParseTypes::StringEscaped ) {
725 if constexpr( is_null::value ) {
726 return json_link_quick_map_type<
727 json_base::json_string_null<T>>{ };
729 return json_link_quick_map_type<json_base::json_string<T>>{ };
731 }
else if constexpr( parse_type::value == JsonParseTypes::Bool ) {
732 if constexpr( is_null::value ) {
733 return json_link_quick_map_type<json_base::json_bool_null<T>>{ };
735 return json_link_quick_map_type<json_base::json_bool<T>>{ };
737 }
else if constexpr( is_arithmetic_parse_type_v<parse_type::value> ) {
738 if constexpr( is_null::value ) {
739 return json_link_quick_map_type<
740 json_base::json_number_null<T>>{ };
742 return json_link_quick_map_type<json_base::json_number<T>>{ };
744 }
else if constexpr( parse_type::value == JsonParseTypes::Tuple ) {
745 if constexpr( is_null::value ) {
746 return json_link_quick_map_type<json_base::json_tuple_null<T>>{ };
748 return json_link_quick_map_type<json_base::json_tuple<T>>{ };
750 }
else if constexpr( parse_type::value == JsonParseTypes::KeyValue ) {
751 if constexpr( is_null::value ) {
752 using b_t = json_base_type_t<mapped_type_t>;
753 using k_t =
typename b_t::key;
754 using v_t =
typename b_t::value;
755 return json_link_quick_map_type<
756 json_base::json_key_value_null<T, v_t, k_t>>{ };
758 using k_t =
typename mapped_type_t::key;
759 using v_t =
typename mapped_type_t::value;
760 return json_link_quick_map_type<
761 json_base::json_key_value<T, v_t, k_t>>{ };
763 }
else if constexpr( parse_type::value == JsonParseTypes::Array ) {
764 if constexpr( is_null::value ) {
765 using b_t = json_base_type_t<mapped_type_t>;
766 using v_t =
typename b_t::value;
767 return json_link_quick_map_type<
768 json_base::json_nullable<T, json_base::json_array<v_t, T>>>{ };
770 using v_t =
typename mapped_type_t::value;
771 return json_link_quick_map_type<json_base::json_array<v_t, T>>{ };
774 return json_link_quick_map_type<void, false>{ };
777 return json_link_quick_map_type<void, false>{ };
783 DAW_CPP20_CONCEPT has_json_link_quick_map_v =
784 decltype( json_link_quick_map<T>( ) )::value;
788 using json_link_quick_map_t =
789 typename decltype( json_link_quick_map<T>( ) )::mapped_type;
791 template<
typename JsonType>
792 struct json_class_map_type {
793 using type =
typename json_data_contract_trait_t<JsonType>::json_member;
797 struct is_json_class_map : std::false_type {};
801 inline constexpr bool is_json_class_map_v =
802 has_json_data_contract_trait_v<T> and
803 is_json_class_map_v<json_data_contract_trait_t<T>>;
806 DAW_ATTRIB_INLINE DAW_CONSTEVAL
auto json_deduced_type_impl( ) noexcept {
807 if constexpr( is_a_basic_json_value<T> ) {
808 return daw::traits::identity<json_base::json_raw<T>>{ };
809 }
else if constexpr( is_an_ordered_member_v<T> ) {
811 return daw::traits::identity<type>{ };
812 }
else if constexpr( has_json_data_contract_trait_v<T> ) {
813 static_assert( not std::is_same_v<T, void> );
815 using type = json_base::json_class<T>;
817 static_assert( not std::is_same_v<daw::remove_cvref_t<type>,
void>,
818 "Detection failure" );
819 static_assert( not is_nonesuch_v<remove_cvref_t<type>>,
820 "Detection failure" );
821 return daw::traits::identity<type>{ };
822 }
else if constexpr( has_json_link_quick_map_v<T> ) {
823 static_assert( not std::is_same_v<T, void> );
824 using type = json_link_quick_map_t<T>;
825 using rcvref_type = remove_cvref_t<type>;
826 static_assert( not std::is_same_v<rcvref_type, void>,
827 "Detection failure" );
828 static_assert( not is_nonesuch_v<rcvref_type>,
"Detection failure" );
829 return daw::traits::identity<type>{ };
830 }
else if constexpr( is_a_json_type_v<T> ) {
831 static_assert( not std::is_same_v<T, void> );
833 typename daw::conditional_t<is_json_class_map_v<T>,
834 json_class_map_type<T>,
835 daw::traits::identity<T>>::type;
836 static_assert( not std::is_same_v<daw::remove_cvref_t<type>,
void>,
837 "Detection failure" );
838 static_assert( not is_nonesuch_v<remove_cvref_t<type>>,
839 "Detection failure" );
840 return daw::traits::identity<type>{ };
841 }
else if constexpr( concepts::is_nullable_value_v<T> ) {
842 using value_type = concepts::nullable_value_type_t<T>;
844 typename decltype( json_deduced_type_impl<value_type>( ) )::type;
845 using type = json_base::json_nullable<T, sub_type>;
846 return daw::traits::identity<type>{ };
847 }
else if constexpr( concepts::is_container_v<T> ) {
848 using type = json_base::json_array<typename T::value_type, T>;
849 return daw::traits::identity<type>{ };
850 }
else if constexpr( std::is_empty_v<T> and
851 std::is_default_constructible_v<T> ) {
853 using type = json_details::json_empty_class<T>;
854 return daw::traits::identity<type>{ };
855 }
else if constexpr( can_convert_to_tuple_v<T> ) {
856 using type = json_base::json_tuple<T>;
857 return daw::traits::identity<type>{ };
859 static_assert( daw::deduced_false_v<T>,
860 "Could not deduced data contract type" );
865 using json_deduced_type =
866 typename DAW_TYPEOF( json_deduced_type_impl<T>( ) )::type;
869 DAW_CPP20_CONCEPT has_json_deduced_type_v =
870 not std::is_same_v<json_deduced_type<T>,
871 missing_json_data_contract_for_or_unknown_type<T>>;
873 template<
typename... Ts>
874 DAW_CPP20_CONCEPT all_have_deduced_type_v =
875 ( has_json_deduced_type_v<Ts> and ... );
877 template<
typename JsonElement,
typename Container,
typename Constructor>
878 struct json_constructor<
879 json_base::json_array<JsonElement, Container, Constructor>> {
880 using json_element_t = json_deduced_type<JsonElement>;
881 using json_element_parse_to_t = json_result_t<json_element_t>;
884 daw::conditional_t<std::is_same_v<Container, use_default>,
885 std::vector<json_element_parse_to_t>, Container>;
888 daw::conditional_t<std::is_same_v<use_default, Constructor>,
889 default_constructor<container_t>, Constructor>;
892 daw::is_callable_v<type, json_element_parse_to_t
const *,
893 json_element_parse_to_t
const *>,
894 "Constructor must support copy and/or move construction" );
897 template<
typename JsonElement,
typename Container,
typename Constructor>
899 json_base::json_array<JsonElement, Container, Constructor>> {
900 using constructor_t =
typename json_constructor<
901 json_base::json_array<JsonElement, Container, Constructor>>::type;
902 using json_element_t = json_deduced_type<JsonElement>;
903 using json_element_parse_to_t =
904 typename json_result<json_element_t>::type;
906 std::invoke_result_t<constructor_t, json_element_parse_to_t
const *,
907 json_element_parse_to_t
const *>;
911 DAW_CPP20_CONCEPT has_unnamed_default_type_mapping_v =
912 has_json_deduced_type_v<T>;
914 template<
typename JsonMember>
915 using from_json_result_t = json_result_t<json_deduced_type<JsonMember>>;
917 template<
typename Constructor,
typename... Members>
918 using json_class_parse_result_impl2 =
919 std::invoke_result_t<Constructor, json_result_t<Members>...>;
921 template<
typename Constructor,
typename... Members>
922 using json_class_parse_result_impl =
923 daw::detected_t<json_class_parse_result_impl2, Constructor, Members...>;
925 template<
typename Constructor,
typename... Members>
926 struct could_not_construct_from_members_error;
928 template<
typename Constructor,
typename... Members>
929 using json_class_parse_result_t =
typename daw::conditional_t<
930 daw::is_callable_v<Constructor, json_result_t<Members>...>,
931 std::invoke_result<Constructor, json_result_t<Members>...>,
932 daw::traits::identity<could_not_construct_from_members_error<
933 Constructor, Members...>>>::type;
935 template<
typename JsonMember>
936 using dependent_member_t =
typename JsonMember::dependent_member;
938 template<
typename JsonMember,
typename =
void>
939 inline constexpr bool has_dependent_member_v =
false;
941 template<
typename JsonMember>
942 inline constexpr bool has_dependent_member_v<
943 JsonMember, std::void_t<dependent_member_t<JsonMember>>> =
true;
946 T::member_type::dependent_member );
948 template<
typename JsonMember>
950 inline constexpr bool has_dependent_member_v<
951 JsonMember DAW_ENABLEIF_S( is_json_nullable_v<JsonMember> )> =
952 has_nullable_dependent_member_v<JsonMember>;
954 template<
typename Constructor>
955 [[nodiscard]] DAW_ATTRIB_INLINE
constexpr auto
956 construct_nullable_empty( ) {
957 if constexpr( daw::is_callable_v<
959 concepts::construct_nullable_with_empty_t> ) {
960 return Constructor{ }( concepts::construct_nullable_with_empty );
962 return Constructor{ }( );