17 #include <daw/daw_algorithm.h>
18 #include <daw/daw_arith_traits.h>
19 #include <daw/daw_cpp_feature_check.h>
20 #include <daw/daw_cxmath.h>
21 #include <daw/daw_likely.h>
22 #include <daw/daw_move.h>
23 #include <daw/daw_traits.h>
24 #include <daw/daw_visit.h>
25 #include <utf8/unchecked.h>
33 #ifndef DAW_JSON_CUSTOM_D2S
34 #include <third_party/dragonbox/dragonbox.h>
35 #elif DAW_HAS_INCLUDE( "custom_d2s.h" )
36 #include "custom_d2s.h"
38 #error Request for local d2s, but no custom_d2s.h supplied with char * d2s( Real const & value, char * ); declaration/definition in namespace daw::json
40 #include <type_traits>
45 template<
typename Real,
typename OutputIterator>
47 OutputIterator out_it ) {
49 #ifndef DAW_JSON_CUSTOM_D2S
50 if constexpr( std::is_same<Real, float>::value ) {
51 return jkj::dragonbox::to_chars_n( value, out_it );
53 return jkj::dragonbox::to_chars_n(
static_cast<double>( value ),
57 if constexpr( std::is_same<Real, float>::value ) {
58 return d2s( value, out_it );
60 return d2s(
static_cast<double>( value ), out_it );
65 namespace json_details::to_strings {
70 [[nodiscard, maybe_unused]] constexpr
auto
81 -> decltype(
to_string( DAW_FWD2( T, v ) ) );
90 daw::is_detected<to_string_test::to_string_result, T>;
96 namespace json_details {
99 std::declval<daw::tag_t<T>>( ), std::declval<std::string_view>( ) ) );
103 daw::is_detected_v<from_string_test, T>;
105 template<
typename T,
typename U>
107 std::declval<T &>( ), std::declval<U const &>( ) ) );
109 template<
typename T,
typename U>
111 std::declval<T &>( ), std::declval<U const &>( ) ) );
115 daw::is_detected_v<has_lshift_test, std::stringstream, T>;
119 daw::is_detected_v<has_rshift_test, std::stringstream, T>;
134 std::stringstream ss{ };
136 return DAW_MOVE( ss ).str( );
140 [[nodiscard]]
inline constexpr
auto operator( )( U
const &value )
const {
141 if constexpr( json_details::is_string_view_like_v<U> ) {
142 return std::string_view( std::data( value ), std::size( value ) );
143 }
else if constexpr( json_details::to_strings::has_to_string_v<U> ) {
146 }
else if constexpr( json_details::has_ostream_op_v<U> ) {
148 }
else if constexpr( std::is_convertible_v<U, std::string_view> ) {
149 return static_cast<std::string_view
>( value );
150 }
else if constexpr( std::is_convertible_v<U, std::string> ) {
151 return static_cast<std::string
>( value );
152 }
else if constexpr( daw::is_arithmetic_v<U> ) {
154 }
else if constexpr( std::is_enum_v<U> ) {
155 return to_string(
static_cast<std::underlying_type_t<U>
>( value ) );
156 }
else if constexpr( json_details::can_deref_v<U> ) {
157 static_assert( json_details::has_op_bool_v<U>,
158 "default_to_converter cannot work with type" );
159 using deref_t = daw::remove_cvref_t<decltype( *value )>;
160 if constexpr( json_details::is_string_view_like_v<deref_t> ) {
162 auto const &v = *value;
163 return std::string_view( std::data( v ), std::size( v ) );
165 return std::string_view(
"null", 4 );
173 daw::remove_cvref_t<decltype(
to_string( *value ) )>;
174 return result_t{
"null" };
176 }
else if constexpr( std::is_convertible_v<
deref_t,
177 std::string_view> ) {
179 return static_cast<std::string_view
>( value );
181 return std::string_view{
"null" };
182 }
else if constexpr( std::is_convertible_v<deref_t, std::string> ) {
184 return static_cast<std::string
>( value );
186 return std::string(
"null" );
191 return std::string(
"null" );
198 namespace from_json_conv_details {
200 [[nodiscard]]
inline auto use_stream( std::string_view sv ) {
201 std::stringstream ss{ };
211 [[nodiscard]]
inline constexpr decltype(
auto )
212 operator( )( std::string_view sv )
const {
213 if constexpr( std::disjunction<
214 std::is_same<T, std::string_view>,
215 std::is_same<T, std::optional<std::string_view>>>::
218 }
else if constexpr( json_details::has_from_string_v<T> ) {
219 return from_string( daw::tag<T>, sv );
220 }
else if constexpr( std::is_convertible_v<std::string_view, T> ) {
221 return static_cast<T
>( sv );
222 }
else if constexpr( std::is_convertible_v<std::string, T> ) {
223 return static_cast<T
>(
static_cast<std::string
>( sv ) );
225 static_assert( json_details::has_istream_op_v<T>,
226 "Unsupported type in default to converter. Must "
227 "supply a custom one" );
228 static_assert( std::is_default_constructible_v<T>,
229 "Unsupported type in default to converter. Must "
230 "supply a custom one" );
231 return from_json_conv_details::use_stream<T>( sv );
236 namespace json_details {
237 template<
typename JsonMember,
typename OutputIterator,
241 parse_to_t
const &value );
243 template<
typename JsonMember,
typename OutputIterator,
245 [[nodiscard]] constexpr OutputIterator
247 parse_to_t
const &value );
249 template<
typename JsonMember,
typename OutputIterator,
251 [[nodiscard]] constexpr OutputIterator
253 OutputIterator
it, parse_to_t
const &value );
255 template<
typename JsonMember,
typename OutputIterator,
257 [[nodiscard]] constexpr OutputIterator
259 OutputIterator
it, parse_to_t
const &value );
261 template<
typename JsonMember,
typename OutputIterator,
263 [[nodiscard]] constexpr OutputIterator
265 parse_to_t
const &value );
267 template<
typename JsonMember,
typename OutputIterator,
269 [[nodiscard]] constexpr OutputIterator
271 parse_to_t
const &value );
273 template<
typename JsonMember,
typename OutputIterator,
275 [[nodiscard]] constexpr OutputIterator
277 parse_to_t
const &value );
279 template<
typename JsonMember,
typename OutputIterator,
281 [[nodiscard]] constexpr OutputIterator
283 parse_to_t
const &value );
285 template<
typename JsonMember,
typename OutputIterator,
287 [[nodiscard]]
inline OutputIterator
289 parse_to_t
const &value );
291 template<
typename JsonMember,
typename OutputIterator,
293 [[nodiscard]] constexpr OutputIterator
295 parse_to_t
const &value );
297 template<
typename JsonMember,
typename OutputIterator,
299 [[nodiscard]] constexpr OutputIterator
301 parse_to_t
const &value );
303 template<
typename JsonMember,
typename OutputIterator,
305 [[nodiscard]] constexpr OutputIterator
307 OutputIterator
it, parse_to_t
const &value );
309 template<
typename JsonMember,
typename OutputIterator,
311 [[nodiscard]] constexpr OutputIterator
313 OutputIterator
it, parse_to_t
const &value );
315 template<
typename JsonMember,
typename OutputIterator,
317 [[nodiscard]] constexpr OutputIterator
319 parse_to_t
const &value );
321 template<
typename JsonMember,
typename OutputIterator,
323 [[nodiscard]] constexpr OutputIterator
325 parse_to_t
const &value );
328 template<
typename Char>
330 auto const u =
static_cast<unsigned>(
static_cast<unsigned char>( c ) );
333 return static_cast<char>( u +
static_cast<unsigned char>(
'0' ) );
335 return static_cast<char>( ( u - 10U ) +
336 static_cast<unsigned char>(
'A' ) );
340 template<
typename OutputIterator>
342 OutputIterator
it ) {
343 char const nibbles[] = {
'\\',
359 template<
typename OutputIterator>
362 *
it++ =
static_cast<char>( cp );
366 *
it++ =
static_cast<char>( ( cp >> 6U ) | 0b11000000U );
367 *
it++ =
static_cast<char>( ( cp & 0b00111111U ) | 0b10000000U );
370 if( cp <= 0xFFFFU ) {
371 *
it++ =
static_cast<char>( ( cp >> 12U ) | 0b11100000U );
373 static_cast<char>( ( ( cp >> 6U ) & 0b00111111U ) | 0b10000000U );
374 *
it++ =
static_cast<char>( ( cp & 0b00111111U ) | 0b10000000U );
377 if( cp <= 0x10FFFFU ) {
378 *
it++ =
static_cast<char>( ( cp >> 18U ) | 0b11110000U );
380 static_cast<char>( ( ( cp >> 12U ) & 0b00111111U ) | 0b10000000U );
382 static_cast<char>( ( ( cp >> 6U ) & 0b00111111U ) | 0b10000000U );
383 *
it++ =
static_cast<char>( ( cp & 0b00111111U ) | 0b10000000U );
391 template<
bool do_escape =
false,
393 typename OutputIterator,
typename Container,
395 traits::is_container_like_v<daw::remove_cvref_t<Container>>,
396 std::nullptr_t> =
nullptr>
397 [[nodiscard]] constexpr OutputIterator
399 if constexpr( do_escape ) {
400 using iter = daw::remove_cvref_t<decltype( std::begin( container ) )>;
401 using it_t = utf8::unchecked::iterator<iter>;
402 auto first = it_t( std::begin( container ) );
403 auto const last = it_t( std::end( container ) );
404 while( first != last ) {
405 auto const cp = *first++;
442 if( cp >= 0x7FU and cp <= 0xFFFFU ) {
444 static_cast<std::uint16_t
>( cp ),
it );
449 static_cast<std::uint16_t
>( 0xD7C0U + ( cp >> 10U ) ),
it );
451 static_cast<std::uint16_t
>( 0xDC00U + ( cp & 0x3FFU ) ),
461 for(
auto c : container ) {
464 static_cast<unsigned char>( c ) <= 0x7FU ),
465 ErrorReason::InvalidStringHighASCII );
473 template<
bool do_escape =
false,
475 typename OutputIterator>
476 [[nodiscard]] constexpr OutputIterator
478 if( ptr ==
nullptr ) {
481 if constexpr( do_escape ) {
483 auto chr_it = utf8::unchecked::iterator<char const *>( ptr );
484 while( *chr_it.base( ) !=
'\0' ) {
485 auto const cp = *chr_it++;
522 if( cp >= 0x7FU and cp <= 0xFFFFU ) {
524 static_cast<std::uint16_t
>( cp ),
it );
529 static_cast<std::uint16_t
>( 0xD7C0U + ( cp >> 10U ) ),
it );
531 static_cast<std::uint16_t
>( 0xDC00U + ( cp & 0x3FFU ) ),
541 while( *ptr !=
'\0' ) {
544 static_cast<unsigned>( *ptr ) <= 0x7FU ),
545 ErrorReason::InvalidStringHighASCII );
553 template<
bool do_escape =
false,
555 typename OutputIterator,
typename ParseState>
556 [[nodiscard]] constexpr OutputIterator
560 return copy_to_iterator<do_escape, EightBitMode>(
it,
"null" );
562 return copy_to_iterator<do_escape, EightBitMode>(
568 namespace json_details {
569 template<
typename JsonMember,
typename OutputIterator,
571 [[nodiscard]] constexpr OutputIterator
573 parse_to_t
const &value ) {
575 if constexpr( JsonMember::literal_as_string ==
584 if constexpr( JsonMember::literal_as_string ==
591 template<std::size_t idx,
typename JsonMembers,
typename OutputIterator,
594 parse_to_t
const &value ) {
595 if constexpr( idx < std::variant_size<parse_to_t>::value ) {
596 if( value.index( ) != idx ) {
597 to_variant_string<idx + 1, JsonMembers>(
it, value );
600 using element_t =
typename JsonMembers::json_elements;
602 typename pack_element<idx, typename element_t::element_map_t>::type;
603 it = to_daw_json_string<JsonMember>(
605 daw::get_nt<idx>( value ) );
609 template<
typename JsonMember,
typename OutputIterator,
611 [[nodiscard]]
inline constexpr OutputIterator
613 parse_to_t
const &value ) {
615 assert( value.index( ) >= 0 );
616 to_variant_string<0, JsonMember>(
it, value );
620 template<
typename JsonMember,
typename OutputIterator,
622 [[nodiscard]]
inline constexpr OutputIterator
624 OutputIterator
it, parse_to_t
const &value ) {
626 to_variant_string<0, JsonMember>(
it, value );
632 -> decltype( *value );
638 daw::remove_cvref_t<decltype( deref_detect( std::declval<T>( ) ) )>;
640 template<
typename Optional>
642 daw::is_detected<deref_t, Optional>::value;
644 template<
typename JsonMember,
typename OutputIterator,
typename Optional>
645 [[nodiscard]]
inline constexpr OutputIterator
647 Optional
const &value ) {
648 static_assert( is_valid_optional_v<Optional> );
654 if constexpr( json_details::has_op_star_v<Optional> ) {
655 return to_daw_json_string<JsonMember>( tag_type{ },
it, *value );
657 return to_daw_json_string<JsonMember>( tag_type{ },
it, value );
661 template<
typename JsonMember,
typename OutputIterator,
663 [[nodiscard]]
inline OutputIterator
665 parse_to_t
const &value ) {
668 std::is_convertible<parse_to_t,
669 typename JsonMember::parse_to_t>::value,
670 "value must be convertible to specified type in class contract" );
672 if constexpr( std::is_floating_point<
673 typename JsonMember::parse_to_t>::value ) {
674 if( daw::cxmath::is_nan( value ) ) {
675 if constexpr( JsonMember::literal_as_string ==
684 }
else if( daw::cxmath::is_inf( value ) ) {
685 if constexpr( JsonMember::literal_as_string ==
697 if constexpr( JsonMember::literal_as_string ==
701 if constexpr( daw::is_floating_point_v<parse_to_t> ) {
702 static_assert(
sizeof( parse_to_t ) <=
sizeof(
double ) );
703 if constexpr( std::is_same<OutputIterator, char *>::value ) {
710 std::copy( buff, ptr,
it );
717 if constexpr( JsonMember::literal_as_string ==
730 daw::traits::identity<T>>::type;
733 std::array<char[2], 100> result{ };
734 for(
size_t n = 0; n < 100; ++n ) {
736 static_cast<char>( ( n % 10 ) +
static_cast<unsigned char>(
'0' ) );
738 static_cast<char>( ( n / 10 ) +
static_cast<unsigned char>(
'0' ) );
743 template<
typename JsonMember,
typename OutputIterator,
745 [[nodiscard]] constexpr OutputIterator
747 parse_to_t
const &value ) {
750 std::is_convertible<parse_to_t,
751 typename JsonMember::parse_to_t>::value,
752 "value must be convertible to specified type in class contract" );
758 if constexpr( JsonMember::literal_as_string ==
762 if constexpr( std::disjunction<std::is_enum<parse_to_t>,
763 daw::is_integral<parse_to_t>>::value ) {
764 auto v =
static_cast<under_type
>( value );
766 char buff[daw::numeric_limits<under_type>::digits10 + 1]{ };
773 *ptr++ =
static_cast<char>(
'0' -
static_cast<char>( v % 10 ) );
777 if constexpr( JsonMember::literal_as_string ==
788 auto const tmp =
static_cast<std::size_t
>( v % 100 );
795 *ptr++ =
static_cast<char>(
'0' +
static_cast<char>( v ) );
799 while( ptr != buff ) {
807 if constexpr( JsonMember::literal_as_string ==
814 template<
typename JsonMember,
typename OutputIterator,
816 [[nodiscard]] constexpr OutputIterator
818 parse_to_t
const &value ) {
821 std::is_convertible<parse_to_t,
822 typename JsonMember::parse_to_t>::value,
823 "value must be convertible to specified type in class contract" );
829 if constexpr( JsonMember::literal_as_string ==
833 if constexpr( std::disjunction<std::is_enum<parse_to_t>,
834 daw::is_integral<parse_to_t>>::value ) {
835 auto v =
static_cast<under_type
>( value );
837 if( DAW_UNLIKELY( v == 0 ) ) {
841 char buff[daw::numeric_limits<under_type>::digits10 + 1]{ };
844 auto const tmp =
static_cast<std::size_t
>( v % 100 );
851 *ptr++ =
static_cast<char>(
'0' +
static_cast<char>( v ) );
855 while( ptr != buff ) {
864 if constexpr( JsonMember::literal_as_string ==
873 namespace utils_details {
874 template<
typename Integer>
882 template<
typename Integer,
typename OutputIterator>
883 inline constexpr OutputIterator
885 static_assert( daw::is_integral_v<Integer> );
887 if constexpr( daw::is_unsigned_v<Integer> ) {
899 namespace json_details {
900 template<
typename JsonMember,
typename OutputIterator,
902 [[nodiscard]]
inline constexpr OutputIterator
904 OutputIterator
it, parse_to_t
const &value ) {
907 std::is_convertible<parse_to_t,
908 typename JsonMember::parse_to_t>::value,
909 "Value must be convertible to specialized type in "
910 "json_data_contract" );
912 constexpr
EightBitModes eight_bit_mode = JsonMember::eight_bit_mode;
914 if( std::size( value ) > 0U ) {
915 it = utils::copy_to_iterator<false, eight_bit_mode>(
it, value );
921 template<
typename JsonMember,
typename OutputIterator,
923 [[nodiscard]]
inline constexpr OutputIterator
925 OutputIterator
it, parse_to_t
const &value ) {
934 constexpr
EightBitModes eight_bit_mode = JsonMember::eight_bit_mode;
936 it = utils::copy_to_iterator<true, eight_bit_mode>(
it, value );
942 [[nodiscard]]
inline constexpr
bool is_null( std::optional<T>
const &v ) {
943 return not
static_cast<bool>( v );
947 [[nodiscard]]
inline constexpr
bool is_null( T
const & ) {
951 template<
typename JsonMember,
typename OutputIterator,
953 [[nodiscard]] constexpr OutputIterator
955 parse_to_t
const &value ) {
958 std::is_convertible<parse_to_t,
959 typename JsonMember::parse_to_t>::value,
960 "value must be convertible to specified type in class contract" );
971 if( civil.
month < 10 ) {
976 if( civil.
day < 10 ) {
981 if( civil.
hour < 10 ) {
1004 template<
typename JsonMember,
typename OutputIterator,
1005 typename parse_to_t>
1006 [[nodiscard]]
inline constexpr OutputIterator
1008 parse_to_t
const &value ) {
1013 template<
typename JsonMember,
typename OutputIterator,
1014 typename parse_to_t>
1015 [[nodiscard]]
inline constexpr OutputIterator
1017 parse_to_t
const &value ) {
1020 std::is_convertible<parse_to_t,
1021 typename JsonMember::parse_to_t>::value,
1022 "value must be convertible to specified type in class contract" );
1024 if constexpr( has_json_to_json_data_v<parse_to_t> ) {
1027 }
else if constexpr( is_json_map_alias_v<parse_to_t> ) {
1031 static_assert( is_submember_tagged_variant_v<parse_to_t>,
1032 "Could not find appropriate mapping or to_json_data "
1033 "member of json_data_contract" );
1038 template<
typename JsonMember,
typename OutputIterator,
1039 typename parse_to_t>
1040 [[nodiscard]]
inline constexpr OutputIterator
1042 parse_to_t
const &value ) {
1045 std::is_convertible<parse_to_t,
1046 typename JsonMember::parse_to_t>::value,
1047 "value must be convertible to specified type in class contract" );
1049 if constexpr( JsonMember::custom_json_type !=
1052 if constexpr( std::is_invocable_r<
1053 OutputIterator,
typename JsonMember::to_converter_t,
1054 OutputIterator, parse_to_t>::value ) {
1056 it =
typename JsonMember::to_converter_t{ }(
it, value );
1059 it,
typename JsonMember::to_converter_t{ }( value ) );
1065 it,
typename JsonMember::to_converter_t{ }( value ) );
1069 template<
typename JsonMember,
typename OutputIterator,
1070 typename parse_to_t, std::size_t... Is>
1072 parse_to_t
const &value,
1073 std::index_sequence<Is...> ) {
1075 auto const to_daw_json_string_help = [&](
auto Idx,
bool &is_first ) {
1076 constexpr std::size_t index = decltype( Idx )::value;
1088 pack_element::template get<index>( value ) );
1091 bool is_first =
true;
1092 daw::Empty
const expander[]{
1093 ( to_daw_json_string_help( std::integral_constant<std::size_t, Is>{ },
1102 template<
typename JsonMember,
typename OutputIterator,
1103 typename parse_to_t>
1104 [[nodiscard]] constexpr OutputIterator
1106 parse_to_t
const &value ) {
1108 using tuple_t =
typename JsonMember::parse_to_t;
1111 static_assert( is_tuple_v<tuple_t>,
"Expected tuple like type" );
1113 std::is_convertible<parse_to_t, tuple_t>::value,
1114 "value must be convertible to specified type in class contract" );
1117 it = to_daw_json_string_tuple<JsonMember>(
1118 it, value, std::make_index_sequence<element_pack::size>{ } );
1123 template<
typename JsonMember,
typename OutputIterator,
1124 typename parse_to_t>
1125 [[nodiscard]] constexpr OutputIterator
1127 parse_to_t
const &value ) {
1129 using array_t =
typename JsonMember::parse_to_t;
1130 if constexpr( is_container_v<array_t> ) {
1132 std::is_convertible<parse_to_t, array_t>::value,
1133 "value must be convertible to specified type in class contract" );
1137 "This is a special case for pointer like(T*, unique_ptr<T>, "
1138 "shared_ptr<T>) arrays. In the to_json_data it is required to "
1139 "encode the size of the data with the pointer. Will take any "
1140 "Container like type, but std::span like types work too" );
1142 is_container_v<parse_to_t>,
1143 "This is a special case for pointer like(T*, unique_ptr<T>, "
1144 "shared_ptr<T>) arrays. In the to_json_data it is required to "
1145 "encode the size of the data with the pointer. Will take any "
1146 "Container like type, but std::span like types work too" );
1150 if( not std::empty( value ) ) {
1151 auto count = std::size( value ) - 1U;
1152 for(
auto const &v : value ) {
1153 it = to_daw_json_string<typename JsonMember::json_element_t>(
1164 template<
typename JsonMember,
typename OutputIterator,
1165 typename parse_to_t>
1166 [[nodiscard]] constexpr OutputIterator
1168 OutputIterator
it, parse_to_t
const &value ) {
1169 return to_daw_json_string<JsonMember>(
1173 template<
typename Key,
typename Value>
1174 [[maybe_unused]]
inline constexpr Key
const &
1179 template<
typename Key,
typename Value>
1180 [[maybe_unused]]
inline constexpr Value
const &
1185 template<
typename JsonMember,
typename OutputIterator,
1186 typename parse_to_t>
1187 [[nodiscard]] constexpr OutputIterator
1189 OutputIterator
it, parse_to_t
const &value ) {
1192 std::is_convertible<parse_to_t,
1193 typename JsonMember::parse_to_t>::value,
1194 "value must be convertible to specified type in class contract" );
1195 using key_t =
typename JsonMember::json_key_t;
1196 using value_t =
typename JsonMember::json_value_t;
1198 if( not std::empty( value ) ) {
1199 auto count = std::size( value ) - 1U;
1200 for(
auto const &v : value ) {
1218 it = to_daw_json_string<value_t>(
1231 template<
typename JsonMember,
typename OutputIterator,
1232 typename parse_to_t>
1233 [[nodiscard]] constexpr OutputIterator
1235 parse_to_t
const &value ) {
1238 if( not std::empty( value ) ) {
1239 auto count = std::size( value ) - 1U;
1240 for(
auto const &v : value ) {
1241 it = to_daw_json_string<typename JsonMember::json_key_t>(
1245 it = to_daw_json_string<typename JsonMember::json_element_t>(
1257 template<
typename JsonMember,
typename OutputIterator,
typename T>
1258 [[nodiscard]]
inline constexpr OutputIterator
1261 return to_daw_json_string<JsonMember>(
1265 template<std::size_t,
typename JsonMember,
typename ,
1266 typename OutputIterator,
typename TpArgs,
typename Value,
1267 typename VisitedMembers,
1268 std::enable_if_t<not has_dependent_member_v<JsonMember>,
1269 std::nullptr_t> =
nullptr>
1270 inline constexpr
void
1272 TpArgs
const &, Value
const &,
1273 VisitedMembers
const & ) {
1281 template<
typename Needle,
typename... Haystack>
1283 constexpr
auto const names = std::array{ Haystack::name... };
1284 for(
size_t n = 0; n <
sizeof...( Haystack ); ++n ) {
1285 if( Needle::name == names[n] ) {
1292 template<std::size_t pos,
typename JsonMember,
typename NamePack,
1293 typename OutputIterator,
typename TpArgs,
typename Value,
1294 typename VisitedMembers,
1295 std::enable_if_t<has_dependent_member_v<JsonMember>,
1296 std::nullptr_t> =
nullptr>
1299 TpArgs
const &args, Value
const &v,
1300 VisitedMembers &visited_members ) {
1303 "Unsupported data type" );
1306 if( not get<pos>( args ) ) {
1310 constexpr
auto dependent_member_name =
1311 daw::string_view( std::data( dependent_member::name ),
1312 std::size( dependent_member::name ) );
1313 if( daw::algorithm::contains( std::data( visited_members ),
1314 daw::data_end( visited_members ),
1315 dependent_member_name ) ) {
1319 visited_members.push_back( dependent_member_name );
1320 if( not is_first ) {
1325 it = utils::copy_to_iterator<false, EightBitModes::AllowFull>(
1326 it, dependent_member_name );
1328 utils::copy_to_iterator<false, EightBitModes::AllowFull>(
it,
"\":" );
1329 if constexpr( has_switcher_v<JsonMember> ) {
1331 typename JsonMember::switcher{ }( v ) );
1333 constexpr std::size_t dependent_member_pos =
1334 find_names_in_pack<dependent_member>( NamePack{ } );
1336 get<dependent_member_pos>( args ) );
1340 template<std::size_t pos,
typename JsonMember,
typename OutputIterator,
1341 typename Tuple,
typename Value,
typename Visited>
1343 Tuple
const &tp, Value
const &,
1344 Visited &visited_members ) {
1346 std::data( JsonMember::name ), std::size( JsonMember::name ) );
1347 if( daw::algorithm::contains( std::data( visited_members ),
1348 daw::data_end( visited_members ),
1354 "Unsupported data type" );
1361 if( not is_first ) {
1366 it = utils::copy_to_iterator<false, EightBitModes::AllowFull>(
1367 it, JsonMember::name );
1370 utils::copy_to_iterator<false, EightBitModes::AllowFull>(
it,
"\":" );
1375 template<
size_t TupleIdx,
typename JsonMember,
typename OutputIterator,
1376 template<
class...>
class Tuple,
typename... Args>
1379 Tuple<Args...>
const &tp ) {
1383 "Unsupported data type" );
1388 "JSON tagged variant types are not supported when inside an array "
1389 "as an ordered structure" );
1391 if constexpr( is_an_ordered_member_v<JsonMember> ) {
1392 for( ; array_idx < JsonMember::member_index; ++array_idx ) {
1393 if( array_idx > 0 ) {
1402 if( array_idx > 0 ) {
1406 get<TupleIdx>( tp ) );
Definition: daw_json_value.h:316
constexpr std::string_view get_string_view() const
Definition: daw_json_value.h:444
constexpr bool is_null() const
Definition: daw_json_value.h:485
#define daw_json_assert(Bool,...)
Definition: daw_json_assert.h:178
ParseState & tmp
Definition: daw_json_iterator.h:37
Iterator & it
Definition: daw_json_traits.h:231
constexpr ymdhms time_point_to_civil(std::chrono::time_point< Clock, Duration > const &tp)
Definition: daw_json_parse_iso8601_utils.h:274
auto use_stream(std::string_view sv)
Definition: to_daw_json_string.h:200
auto to_string_test(T &&v) -> decltype(to_string(DAW_FWD2(T, v)))
decltype(to_string_test(std::declval< T >())) to_string_result
Definition: to_daw_json_string.h:85
constexpr bool has_to_string_v
Definition: to_daw_json_string.h:93
daw::is_detected< to_string_test::to_string_result, T > has_to_string
Definition: to_daw_json_string.h:90
constexpr auto to_string(std::optional< T > const &v) -> decltype(to_string(*v))
Definition: to_daw_json_string.h:71
constexpr void to_variant_string(OutputIterator &it, parse_to_t const &value)
Definition: to_daw_json_string.h:593
std::bool_constant< JsonType::expected_type==JsonParseTypes::Null > is_json_nullable
Definition: daw_json_parse_common.h:289
constexpr auto digits100
Definition: to_daw_json_string.h:732
daw::remove_cvref_t< decltype(deref_detect(std::declval< T >()))> deref_t
Definition: to_daw_json_string.h:638
OutputIterator to_daw_json_string_tuple(OutputIterator it, parse_to_t const &value, std::index_sequence< Is... >)
Definition: to_daw_json_string.h:1071
constexpr bool has_istream_op_v
Definition: to_daw_json_string.h:118
decltype(from_string(std::declval< daw::tag_t< T > >(), std::declval< std::string_view >())) from_string_test
Definition: to_daw_json_string.h:99
typename json_type_deducer< T, has_json_data_contract_trait_v< T >, json_details::is_a_json_type_v< T >, has_json_link_quick_map_v< T >, is_container_v< T > >::type json_deduced_type
Definition: daw_json_parse_common.h:931
constexpr Value const & json_get_value(std::pair< Key, Value > const &kv)
Definition: to_daw_json_string.h:1181
constexpr OutputIterator member_to_string(template_param< JsonMember >, OutputIterator it, T const &value)
Definition: to_daw_json_string.h:1259
daw::is_detected< is_a_json_tagged_variant_test, T > is_a_json_tagged_variant
Definition: daw_json_traits.h:449
decltype(operator>>(std::declval< T & >(), std::declval< U const & >())) has_rshift_test
Definition: to_daw_json_string.h:111
decltype(operator<<(std::declval< T & >(), std::declval< U const & >())) has_lshift_test
Definition: to_daw_json_string.h:107
constexpr bool has_from_string_v
Definition: to_daw_json_string.h:102
constexpr void to_json_ordered_str(std::size_t &array_idx, OutputIterator &it, Tuple< Args... > const &tp)
Definition: to_daw_json_string.h:1377
std::bool_constant< daw::is_detected_v< json_type_t, T > > is_a_json_type
Definition: daw_json_traits.h:426
typename daw::detected_or_t< T, ordered_member_subtype_test, T > ordered_member_subtype_t
Definition: daw_json_parse_common.h:54
constexpr auto has_value(T const &v) -> std::enable_if_t< is_readable_v< T >, bool >
Definition: daw_json_traits.h:60
constexpr char to_nibble_char(Char c)
Definition: to_daw_json_string.h:329
std::underlying_type< T > base_int_type_impl
Definition: to_daw_json_string.h:725
constexpr bool is_valid_optional_v
Definition: to_daw_json_string.h:641
typename JsonMember::dependent_member dependent_member_t
Definition: daw_json_parse_common.h:961
constexpr void utf32_to_utf8(std::uint32_t cp, OutputIterator &it)
Definition: to_daw_json_string.h:360
typename std::conditional_t< std::is_enum_v< T >, base_int_type_impl< T >, daw::traits::identity< T > >::type base_int_type_t
Definition: to_daw_json_string.h:730
constexpr void dependent_member_to_json_str(bool &, OutputIterator const &, TpArgs const &, Value const &, VisitedMembers const &)
Definition: to_daw_json_string.h:1271
constexpr OutputIterator to_daw_json_string(ParseTag< JsonParseTypes::Null >, OutputIterator it, parse_to_t const &value)
constexpr OutputIterator output_hex(std::uint16_t c, OutputIterator it)
Definition: to_daw_json_string.h:341
constexpr Key const & json_get_key(std::pair< Key, Value > const &kv)
Definition: to_daw_json_string.h:1175
constexpr bool is_null(std::optional< T > const &v)
Definition: to_daw_json_string.h:942
constexpr bool has_ostream_op_v
Definition: to_daw_json_string.h:114
constexpr void to_json_str(bool &is_first, OutputIterator &it, Tuple const &tp, Value const &, Visited &visited_members)
Definition: to_daw_json_string.h:1342
constexpr std::size_t find_names_in_pack(daw::fwd_pack< Haystack... >)
Definition: to_daw_json_string.h:1282
constexpr auto deref_detect(T &&value) -> decltype(*value)
constexpr OutputIterator integer_to_string(OutputIterator it, Integer const &value)
Definition: to_daw_json_string.h:884
constexpr OutputIterator copy_to_iterator(OutputIterator it, Container const &container)
Definition: to_daw_json_string.h:398
EightBitModes
Definition: daw_json_type_options.h:104
constexpr std::string_view to_string(JsonBaseParseTypes pt)
Definition: daw_json_enums.h:50
LiteralAsStringOpt
Definition: daw_json_type_options.h:38
typename json_data_contract< T >::type json_data_contract_trait_t
Definition: daw_json_traits.h:133
std::integral_constant< JsonParseTypes, v > ParseTag
Definition: daw_json_enums.h:106
DAW_ATTRIB_NOINLINE void daw_json_error(ErrorReason reason)
Definition: daw_json_assert.h:39
constexpr OutputIterator real2string(Real const &value, OutputIterator out_it)
Definition: to_daw_json_string.h:46
Definition: daw_from_json.h:22
Definition: daw_json_parse_iso8601_utils.h:263
std::int_least32_t year
Definition: daw_json_parse_iso8601_utils.h:264
std::uint_least32_t second
Definition: daw_json_parse_iso8601_utils.h:269
std::uint_least32_t month
Definition: daw_json_parse_iso8601_utils.h:265
std::uint_least32_t hour
Definition: daw_json_parse_iso8601_utils.h:267
std::uint_least32_t day
Definition: daw_json_parse_iso8601_utils.h:266
std::uint_least32_t minute
Definition: daw_json_parse_iso8601_utils.h:268
std::uint_least32_t millisecond
Definition: daw_json_parse_iso8601_utils.h:270
Definition: to_daw_json_string.h:210
Definition: to_daw_json_string.h:131
static auto use_stream(U const &v)
Definition: to_daw_json_string.h:133
Definition: daw_json_traits.h:632
Definition: daw_json_traits.h:125
Definition: to_daw_json_string.h:1279
Definition: daw_json_value_state.h:56
Allow tuple like types to be used in json_tuple.
Definition: daw_json_traits.h:638
Definition: to_daw_json_string.h:875
static constexpr LiteralAsStringOpt literal_as_string
Definition: to_daw_json_string.h:877
Integer parse_to_t
Definition: to_daw_json_string.h:876
#define DAW_JSON_VER
Definition: version.h:11