19#include <daw/daw_algorithm.h>
20#include <daw/daw_arith_traits.h>
21#include <daw/daw_cpp_feature_check.h>
22#include <daw/daw_cxmath.h>
23#include <daw/daw_likely.h>
24#include <daw/daw_move.h>
25#include <daw/daw_traits.h>
26#include <daw/daw_utility.h>
27#include <daw/daw_visit.h>
28#include <daw/utf8/unchecked.h>
32#include <daw/third_party/dragonbox/dragonbox.h>
42 namespace json_details {
45 constexpr OutputIterator
to_chars( Real
const &value,
46 OutputIterator out_it );
49 namespace json_details::to_strings {
54 [[nodiscard, maybe_unused]]
constexpr auto
65 ->
decltype(
to_string( DAW_FWD2( T, v ) ) );
74 daw::is_detected<to_string_test::to_string_result, T>;
80 namespace json_details {
83 std::declval<daw::tag_t<T>>( ), std::declval<std::string_view>( ) ) );
87 daw::is_detected_v<from_string_test, T>;
89 template<
typename T,
typename U>
91 std::declval<T &>( ), std::declval<U const &>( ) ) );
93 template<
typename T,
typename U>
95 std::declval<T &>( ), std::declval<U const &>( ) ) );
99 daw::is_detected_v<has_lshift_test, std::stringstream, T>;
103 daw::is_detected_v<has_rshift_test, std::stringstream, T>;
118 std::stringstream ss{ };
120 return DAW_MOVE( ss ).str( );
124 [[nodiscard]]
inline constexpr auto operator( )( U
const &value )
const {
125 if constexpr( json_details::is_string_view_like_v<U> ) {
126 return std::string_view( std::data( value ), std::size( value ) );
127 }
else if constexpr( json_details::to_strings::has_to_string_v<U> ) {
130 }
else if constexpr( json_details::has_ostream_op_v<U> ) {
132 }
else if constexpr( std::is_convertible_v<U, std::string_view> ) {
133 return static_cast<std::string_view
>( value );
134 }
else if constexpr( std::is_convertible_v<U, std::string> ) {
135 return static_cast<std::string
>( value );
136 }
else if constexpr( daw::is_arithmetic_v<U> ) {
138 }
else if constexpr( std::is_enum_v<U> ) {
139 return to_string(
static_cast<std::underlying_type_t<U>
>( value ) );
140 }
else if constexpr( json_details::is_dereferenceable_v<U> ) {
141 static_assert( json_details::has_op_bool_v<U>,
142 "default_to_converter cannot work with type" );
145 dereferenced_type> ) {
147 auto const &v = *value;
148 return std::string_view( std::data( v ), std::size( v ) );
150 return std::string_view(
"null", 4 );
152 dereferenced_type> ) {
157 using result_t = DAW_TYPEOF(
to_string( *value ) );
158 return result_t{
"null" };
160 }
else if constexpr( std::is_convertible_v<dereferenced_type,
161 std::string_view> ) {
163 return static_cast<std::string_view
>( value );
165 return std::string_view{
"null" };
166 }
else if constexpr( std::is_convertible_v<dereferenced_type,
169 return static_cast<std::string
>( value );
171 return std::string(
"null" );
176 return std::string(
"null" );
183 namespace from_json_conv_details {
185 [[nodiscard]]
inline auto use_stream( std::string_view sv ) {
186 std::stringstream ss{ };
196 [[nodiscard]]
inline constexpr decltype( auto )
197 operator( )( std::string_view sv )
const {
198 if constexpr( std::disjunction<
199 std::is_same<T, std::string_view>,
200 std::is_same<T, std::optional<std::string_view>>>::
203 }
else if constexpr( json_details::has_from_string_v<T> ) {
204 return from_string( daw::tag<T>, sv );
205 }
else if constexpr( std::is_convertible_v<std::string_view, T> ) {
206 return static_cast<T
>( sv );
207 }
else if constexpr( std::is_convertible_v<std::string, T> ) {
208 return static_cast<T
>(
static_cast<std::string
>( sv ) );
210 static_assert( json_details::has_istream_op_v<T>,
211 "Unsupported type in default to converter. Must "
212 "supply a custom one" );
213 static_assert( std::is_default_constructible_v<T>,
214 "Unsupported type in default to converter. Must "
215 "supply a custom one" );
216 return from_json_conv_details::use_stream<T>( sv );
221 namespace json_details {
222 template<
typename JsonMember,
typename OutputIterator,
226 parse_to_t
const &value );
228 template<
typename JsonMember,
typename OutputIterator,
231 SerializationOptions>
235 parse_to_t
const &value );
237 template<
typename JsonMember,
typename OutputIterator,
239 [[nodiscard]]
constexpr OutputIterator
241 OutputIterator
it, parse_to_t
const &value );
243 template<
typename JsonMember,
typename OutputIterator,
246 SerializationOptions>
250 parse_to_t
const &value );
252 template<
typename JsonMember,
typename OutputIterator,
255 SerializationOptions>
259 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]]
constexpr 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 OutputIterator
it, 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 parse_to_t
const &value );
315 template<
typename JsonMember,
typename OutputIterator,
317 [[nodiscard]]
constexpr OutputIterator
319 parse_to_t
const &value );
321 template<
typename Char>
323 auto const u =
static_cast<unsigned>(
static_cast<unsigned char>( c ) );
326 return static_cast<char>( u +
static_cast<unsigned char>(
'0' ) );
328 return static_cast<char>( ( u - 10U ) +
329 static_cast<unsigned char>(
'A' ) );
333 template<
typename OutputIterator>
335 OutputIterator
it ) {
336 char const nibbles[] = {
'\\',
352 template<
typename OutputIterator>
355 *
it++ =
static_cast<char>( cp );
359 *
it++ =
static_cast<char>( ( cp >> 6U ) | 0b11000000U );
360 *
it++ =
static_cast<char>( ( cp & 0b00111111U ) | 0b10000000U );
363 if( cp <= 0xFFFFU ) {
364 *
it++ =
static_cast<char>( ( cp >> 12U ) | 0b11100000U );
366 static_cast<char>( ( ( cp >> 6U ) & 0b00111111U ) | 0b10000000U );
367 *
it++ =
static_cast<char>( ( cp & 0b00111111U ) | 0b10000000U );
370 if( cp <= 0x10FFFFU ) {
371 *
it++ =
static_cast<char>( ( cp >> 18U ) | 0b11110000U );
373 static_cast<char>( ( ( cp >> 12U ) & 0b00111111U ) | 0b10000000U );
375 static_cast<char>( ( ( cp >> 6U ) & 0b00111111U ) | 0b10000000U );
376 *
it++ =
static_cast<char>( ( cp & 0b00111111U ) | 0b10000000U );
384 template<
bool do_escape =
false,
386 typename OutputIterator,
typename Container,
388 traits::is_container_like_v<daw::remove_cvref_t<Container>>,
389 std::nullptr_t> =
nullptr>
390 [[nodiscard]]
constexpr OutputIterator
392 constexpr bool restrict_high =
394 ( OutputIterator::restricted_string_output ==
396 if constexpr( do_escape ) {
397 using iter = DAW_TYPEOF( std::begin( container ) );
398 using it_t = utf8::unchecked::iterator<iter>;
399 auto first = it_t( std::begin( container ) );
400 auto const last = it_t( std::end( container ) );
401 while( first != last ) {
402 auto const cp = *first++;
438 if constexpr( restrict_high ) {
439 if( cp >= 0x7FU and cp <= 0xFFFFU ) {
441 static_cast<std::uint16_t
>( cp ),
it );
446 static_cast<std::uint16_t
>( 0xD7C0U + ( cp >> 10U ) ),
it );
448 static_cast<std::uint16_t
>( 0xDC00U + ( cp & 0x3FFU ) ),
458 for(
auto c : container ) {
459 if constexpr( restrict_high ) {
461 static_cast<unsigned char>( c ) <= 0x7FU ),
462 ErrorReason::InvalidStringHighASCII );
470 template<
bool do_escape =
false,
472 typename OutputIterator>
473 [[nodiscard]]
constexpr OutputIterator
475 if( ptr ==
nullptr ) {
478 constexpr bool restrict_high =
480 ( OutputIterator::restricted_string_output ==
483 if constexpr( do_escape ) {
484 auto chr_it = utf8::unchecked::iterator<char const *>( ptr );
485 while( *chr_it.base( ) !=
'\0' ) {
486 auto const cp = *chr_it++;
522 if constexpr( restrict_high ) {
523 if( cp >= 0x7FU and cp <= 0xFFFFU ) {
525 static_cast<std::uint16_t
>( cp ),
it );
530 static_cast<std::uint16_t
>( 0xD7C0U + ( cp >> 10U ) ),
it );
532 static_cast<std::uint16_t
>( 0xDC00U + ( cp & 0x3FFU ) ),
542 while( *ptr !=
'\0' ) {
543 if constexpr( restrict_high ) {
545 static_cast<unsigned>( *ptr ) <= 0x7FU ),
546 ErrorReason::InvalidStringHighASCII );
554 template<
bool do_escape =
false,
556 typename OutputIterator,
typename ParseState>
557 [[nodiscard]]
constexpr OutputIterator
561 return copy_to_iterator<do_escape, EightBitMode>(
it,
"null" );
563 return copy_to_iterator<do_escape, EightBitMode>(
569 namespace json_details {
570 template<
typename JsonMember,
typename OutputIterator,
572 [[nodiscard]]
constexpr OutputIterator
574 parse_to_t
const &value ) {
576 if constexpr( JsonMember::literal_as_string ==
585 if constexpr( JsonMember::literal_as_string ==
592 template<std::size_t idx,
typename JsonMembers,
typename OutputIterator,
595 parse_to_t
const &value ) {
596 if constexpr( idx < std::variant_size<parse_to_t>::value ) {
597 if( value.index( ) != idx ) {
598 to_variant_string<idx + 1, JsonMembers>(
it, value );
601 using element_t =
typename JsonMembers::json_elements;
603 typename pack_element<idx, typename element_t::element_map_t>::type;
604 it = to_daw_json_string<JsonMember>(
606 daw::get_nt<idx>( value ) );
610 template<
typename JsonMember,
typename OutputIterator,
612 [[nodiscard]]
inline constexpr OutputIterator
614 parse_to_t
const &value ) {
616 assert( value.index( ) >= 0 );
617 to_variant_string<0, JsonMember>(
it, value );
621 template<
typename JsonMember,
typename OutputIterator,
623 [[nodiscard]]
inline constexpr OutputIterator
625 OutputIterator
it, parse_to_t
const &value ) {
627 to_variant_string<0, JsonMember>(
it, value );
631 template<
typename JsonMember,
typename OutputIterator,
633 [[nodiscard]]
inline constexpr OutputIterator
635 OutputIterator
it, parse_to_t
const &value ) {
637 to_variant_string<0, JsonMember>(
it, value );
641 template<
typename JsonMember,
typename OutputIterator,
typename Optional>
642 [[nodiscard]]
inline constexpr OutputIterator
644 Optional
const &value ) {
645 static_assert( is_dereferenceable_v<Optional> );
651 if constexpr( json_details::has_op_star_v<Optional> ) {
652 return to_daw_json_string<JsonMember>( tag_type{ },
it, *value );
654 return to_daw_json_string<JsonMember>( tag_type{ },
it, value );
658 template<
typename JsonMember,
typename OutputIterator,
660 [[nodiscard]]
constexpr OutputIterator
662 parse_to_t
const &value ) {
665 std::is_convertible<parse_to_t,
666 typename JsonMember::parse_to_t>::value,
667 "value must be convertible to specified type in class contract" );
669 if constexpr( std::is_floating_point<
670 typename JsonMember::parse_to_t>::value ) {
671 if( daw::cxmath::is_nan( value ) ) {
672 if constexpr( JsonMember::literal_as_string ==
674 JsonMember::allow_number_errors ==
676 JsonMember::allow_number_errors ==
685 }
else if( daw::cxmath::is_inf( value ) ) {
686 if constexpr( JsonMember::literal_as_string ==
688 JsonMember::allow_number_errors ==
690 JsonMember::allow_number_errors ==
705 if constexpr( JsonMember::literal_as_string ==
709 if constexpr( daw::is_floating_point_v<parse_to_t> ) {
710 static_assert(
sizeof( parse_to_t ) <=
sizeof(
double ) );
711 if constexpr(
it.is_pointer ) {
713 to_chars<JsonMember::fp_output_format>( value,
it.get( ) ) );
718 ptr = to_chars<JsonMember::fp_output_format>( value, ptr );
719 std::copy( buff, ptr,
it );
726 if constexpr( JsonMember::literal_as_string ==
739 daw::traits::identity<T>>::type;
742 std::array<char[2], 100> result{ };
743 for(
size_t n = 0;
n < 100; ++
n ) {
745 static_cast<char>( (
n % 10 ) +
static_cast<unsigned char>(
'0' ) );
747 static_cast<char>( (
n / 10 ) +
static_cast<unsigned char>(
'0' ) );
752 template<
typename JsonMember,
typename OutputIterator,
754 [[nodiscard]]
constexpr OutputIterator
756 parse_to_t
const &value ) {
759 std::is_convertible<parse_to_t,
760 typename JsonMember::parse_to_t>::value,
761 "value must be convertible to specified type in class contract" );
767 if constexpr( JsonMember::literal_as_string ==
771 if constexpr( std::disjunction<std::is_enum<parse_to_t>,
772 daw::is_integral<parse_to_t>>::value ) {
773 auto v =
static_cast<under_type
>( value );
775 char buff[daw::numeric_limits<under_type>::digits10 + 1]{ };
782 *ptr++ =
static_cast<char>(
'0' -
static_cast<char>( v % 10 ) );
786 if constexpr( JsonMember::literal_as_string ==
797 auto const tmp =
static_cast<std::size_t
>( v % 100 );
804 *ptr++ =
static_cast<char>(
'0' +
static_cast<char>( v ) );
808 while( ptr != buff ) {
816 if constexpr( JsonMember::literal_as_string ==
823 template<
typename JsonMember,
typename OutputIterator,
825 [[nodiscard]]
constexpr OutputIterator
827 parse_to_t
const &value ) {
830 std::is_convertible<parse_to_t,
831 typename JsonMember::parse_to_t>::value,
832 "value must be convertible to specified type in class contract" );
838 if constexpr( JsonMember::literal_as_string ==
842 if constexpr( std::disjunction<std::is_enum<parse_to_t>,
843 daw::is_integral<parse_to_t>>::value ) {
844 auto v =
static_cast<under_type
>( value );
846 if( DAW_UNLIKELY( v == 0 ) ) {
850 char buff[daw::numeric_limits<under_type>::digits10 + 1]{ };
853 auto const tmp =
static_cast<std::size_t
>( v % 100 );
860 *ptr++ =
static_cast<char>(
'0' +
static_cast<char>( v ) );
864 while( ptr != buff ) {
873 if constexpr( JsonMember::literal_as_string ==
882 namespace utils_details {
883 template<
typename Integer>
891 template<
typename Integer,
typename OutputIterator>
892 inline constexpr OutputIterator
894 static_assert( daw::is_integral_v<Integer> );
896 if constexpr( daw::is_unsigned_v<Integer> ) {
908 namespace json_details {
909 template<
typename JsonMember,
typename OutputIterator,
911 [[nodiscard]]
inline constexpr OutputIterator
913 OutputIterator
it, parse_to_t
const &value ) {
916 std::is_convertible<parse_to_t,
917 typename JsonMember::parse_to_t>::value,
918 "Value must be convertible to specialized type in "
919 "json_data_contract" );
921 constexpr EightBitModes eight_bit_mode = JsonMember::eight_bit_mode;
923 if( std::size( value ) > 0U ) {
924 it = utils::copy_to_iterator<false, eight_bit_mode>(
it, value );
930 template<
typename JsonMember,
typename OutputIterator,
932 [[nodiscard]]
inline constexpr OutputIterator
934 OutputIterator
it, parse_to_t
const &value ) {
943 constexpr EightBitModes eight_bit_mode = JsonMember::eight_bit_mode;
945 it = utils::copy_to_iterator<true, eight_bit_mode>(
it, value );
951 [[nodiscard]]
inline constexpr bool is_null( std::optional<T>
const &v ) {
952 return not
static_cast<bool>( v );
956 [[nodiscard]]
inline constexpr bool is_null( T
const & ) {
960 template<
typename JsonMember,
typename OutputIterator,
962 [[nodiscard]]
constexpr OutputIterator
964 parse_to_t
const &value ) {
967 std::is_convertible<parse_to_t,
968 typename JsonMember::parse_to_t>::value,
969 "value must be convertible to specified type in class contract" );
980 if( civil.
month < 10 ) {
985 if( civil.
day < 10 ) {
990 if( civil.
hour < 10 ) {
1000 if( civil.
second < 10 ) {
1013 template<
typename JsonMember,
typename OutputIterator,
1014 typename parse_to_t>
1015 [[nodiscard]]
inline constexpr OutputIterator
1017 parse_to_t
const &value ) {
1022 template<
typename JsonMember,
typename OutputIterator,
1023 typename parse_to_t>
1024 [[nodiscard]]
inline constexpr OutputIterator
1026 parse_to_t
const &value ) {
1029 std::is_convertible<parse_to_t,
1030 typename JsonMember::parse_to_t>::value,
1031 "value must be convertible to specified type in class contract" );
1033 if constexpr( has_json_to_json_data_v<parse_to_t> ) {
1036 }
else if constexpr( is_json_map_alias_v<parse_to_t> ) {
1040 static_assert( is_submember_tagged_variant_v<parse_to_t>,
1041 "Could not find appropriate mapping or to_json_data "
1042 "member of json_data_contract" );
1047 template<
typename JsonMember,
typename OutputIterator,
1048 typename parse_to_t>
1049 [[nodiscard]]
inline constexpr OutputIterator
1051 parse_to_t
const &value ) {
1054 std::is_convertible<parse_to_t,
1055 typename JsonMember::parse_to_t>::value,
1056 "value must be convertible to specified type in class contract" );
1058 if constexpr( JsonMember::custom_json_type !=
1061 if constexpr( std::is_invocable_r<
1062 OutputIterator,
typename JsonMember::to_converter_t,
1063 OutputIterator, parse_to_t>::value ) {
1065 it =
typename JsonMember::to_converter_t{ }(
it, value );
1068 it,
typename JsonMember::to_converter_t{ }( value ) );
1074 it,
typename JsonMember::to_converter_t{ }( value ) );
1078 template<
typename JsonMember,
typename OutputIterator,
1084 parse_to_t
const &value, std::index_sequence<Is...> ) {
1086 auto const to_daw_json_string_help = [&](
auto Idx ) {
1087 using index = daw::remove_cvref_t<
decltype( Idx )>;
1089 using T = std::tuple_element_t<index::value,
1090 typename JsonMember::sub_member_list>;
1092 it = to_daw_json_string<T>(
1094 pack_element::template get<index::value>( value ) );
1095 if constexpr( index::value + 1 <
sizeof...( Is ) ) {
1100 (void)to_daw_json_string_help;
1102 daw::Empty
const expander[]{
1103 ( to_daw_json_string_help( daw::constant<Is>{ } ), daw::Empty{ } )...,
1110 template<
typename JsonMember,
typename OutputIterator,
1113 SerializationOptions>
1117 parse_to_t
const &value ) {
1119 using tuple_t =
typename JsonMember::parse_to_t;
1122 static_assert( is_tuple_v<tuple_t>,
"Expected tuple like type" );
1124 std::is_convertible<parse_to_t, tuple_t>::value,
1125 "value must be convertible to specified type in class contract" );
1130 it = to_daw_json_string_tuple<JsonMember>(
1131 it, value, std::make_index_sequence<element_pack::size>{ } );
1133 if constexpr( element_pack::size > 0 ) {
1134 if constexpr( element_pack::size > 0 and
1144 template<
typename JsonMember,
typename OutputIterator,
1147 SerializationOptions>
1151 parse_to_t
const &value ) {
1153 using array_t =
typename JsonMember::parse_to_t;
1154 if constexpr( is_container_v<array_t> ) {
1156 std::is_convertible<parse_to_t, array_t>::value,
1157 "value must be convertible to specified type in class contract" );
1161 "This is a special case for pointer like(T*, unique_ptr<T>, "
1162 "shared_ptr<T>) arrays. In the to_json_data it is required to "
1163 "encode the size of the data with the pointer. Will take any "
1164 "Container like type, but std::span like types work too" );
1166 is_container_v<parse_to_t>,
1167 "This is a special case for pointer like(T*, unique_ptr<T>, "
1168 "shared_ptr<T>) arrays. In the to_json_data it is required to "
1169 "encode the size of the data with the pointer. Will take any "
1170 "Container like type, but std::span like types work too" );
1175 auto first = std::begin( value );
1176 auto last = std::end( value );
1177 bool const has_elements = first != last;
1178 while( first != last ) {
1180 it = to_daw_json_string<typename JsonMember::json_element_t>(
1184 if( first != last ) {
1190 if( has_elements ) {
1194 if( has_elements ) {
1201 template<
typename JsonMember,
typename OutputIterator,
1202 typename parse_to_t>
1203 [[nodiscard]]
constexpr OutputIterator
1205 OutputIterator
it, parse_to_t
const &value ) {
1206 return to_daw_json_string<JsonMember>(
1210 template<
typename Key,
typename Value>
1211 [[maybe_unused]]
inline constexpr Key
const &
1216 template<
typename Key,
typename Value>
1217 [[maybe_unused]]
inline constexpr Value
const &
1222 template<
typename JsonMember,
typename OutputIterator,
1229 parse_to_t
const &value ) {
1232 std::is_convertible<parse_to_t,
1233 typename JsonMember::parse_to_t>::value,
1234 "value must be convertible to specified type in class contract" );
1235 using key_t =
typename JsonMember::json_key_t;
1236 using value_t =
typename JsonMember::json_value_t;
1239 auto first = std::begin( value );
1240 auto last = std::end( value );
1241 bool const has_elements = first != last;
1242 while( first != last ) {
1271 if( has_elements ) {
1278 if( first != last ) {
1284 if( has_elements ) {
1288 if( has_elements ) {
1295 template<
typename JsonMember,
typename OutputIterator,
1298 SerializationOptions>
1302 parse_to_t
const &value ) {
1306 auto first = std::begin( value );
1307 auto last = std::end( value );
1308 bool const has_elements = first != last;
1309 while( first != last ) {
1310 auto const &v = *first;
1312 it = to_daw_json_string<typename JsonMember::json_key_t>(
1317 it = to_daw_json_string<typename JsonMember::json_element_t>(
1321 if( first != last ) {
1327 if( has_elements ) {
1331 if( has_elements ) {
1338 template<
typename JsonMember,
typename OutputIterator,
typename T>
1339 [[nodiscard]]
inline constexpr OutputIterator
1342 return to_daw_json_string<JsonMember>(
1351 template<
typename Name>
1353#ifdef DAW_USE_EXCEPTIONS
1360 template<
typename,
typename...>
1363 template<
typename Needle,
typename... Haystack>
1367 static_assert( ( ( Haystack::name == Needle::name ) or ... ),
1368 "Name must exist" );
1369 constexpr std::array
const names = { Haystack::name... };
1371 for( ;
n <
sizeof...( Haystack ); ++
n ) {
1372 if( Needle::name == names[
n] ) {
1376 if(
n >=
sizeof...( Haystack ) ) {
1377 missing_required_mapping_error<Needle>( );
1382 static constexpr std::size_t value = find_position( );
1385 template<
typename Needle,
typename... Haystack>
1389 template<std::size_t,
typename JsonMember,
typename ,
1390 typename OutputIterator,
typename TpArgs,
typename Value,
1391 typename VisitedMembers,
1392 std::enable_if_t<not has_dependent_member_v<JsonMember>,
1393 std::nullptr_t> =
nullptr>
1394 DAW_ATTRIB_INLINE
inline constexpr void
1396 TpArgs
const &, Value
const &,
1397 VisitedMembers
const & ) {
1402 template<std::size_t pos,
typename JsonMember,
typename NamePack,
1404 typename TpArgs,
typename Value,
typename VisitedMembers,
1405 std::enable_if_t<has_dependent_member_v<JsonMember>,
1406 std::nullptr_t> =
nullptr>
1410 TpArgs
const &args, Value
const &v, VisitedMembers &visited_members ) {
1415 "Unsupported data type" );
1418 if( not get<pos>( args ) ) {
1422 if( daw::algorithm::contains( std::data( visited_members ),
1423 daw::data_end( visited_members ),
1424 dependent_member::name ) ) {
1428 visited_members.push_back( dependent_member::name );
1429 if( not is_first ) {
1435 it = utils::copy_to_iterator<false, EightBitModes::AllowFull>(
1436 it, dependent_member::name );
1441 if constexpr( has_switcher_v<JsonMember> ) {
1443 typename JsonMember::switcher{ }( v ) );
1445 constexpr auto idx = find_names_in_pack_v<dependent_member, NamePack>;
1452 template<std::size_t pos,
typename JsonMember,
typename OutputIterator,
1454 typename Value,
typename Visited>
1458 Tuple
const &tp, Value
const &, Visited &visited_members ) {
1460 std::data( JsonMember::name ), std::size( JsonMember::name ) );
1461 if( daw::algorithm::contains( std::data( visited_members ),
1462 daw::data_end( visited_members ),
1468 "Unsupported data type" );
1475 if( not is_first ) {
1481 it = utils::copy_to_iterator<false, EightBitModes::AllowFull>(
1482 it, JsonMember::name );
1490 template<
size_t TupleIdx,
typename JsonMember,
typename OutputIterator,
1494 std::size_t &array_idx, std::size_t array_size,
1496 Tuple<Args...>
const &tp ) {
1500 "Unsupported data type" );
1505 "JSON tagged variant types are not supported when inside an array "
1506 "as an ordered structure" );
1508 if constexpr( is_an_ordered_member_v<JsonMember> ) {
1509 for( ; array_idx < JsonMember::member_index; ++array_idx ) {
1520 get<TupleIdx>( tp ) );
1522 if( array_idx < array_size ) {
1531 OutputIterator out_it ) {
1532 daw::jkj::dragonbox::unsigned_fp_t<Real> dec =
1533 daw::jkj::dragonbox::to_decimal(
1534 value, daw::jkj::dragonbox::policy::sign::ignore );
1537 daw::jkj::dragonbox::to_chars_detail::decimal_length(
1540 auto whole_dig =
static_cast<std::int32_t
>( digits ) + dec.exponent;
1542 auto const br = [&] {
1543 if constexpr( std::is_same_v<Real, float> ) {
1544 return daw::jkj::dragonbox::ieee754_bits( value );
1546 return daw::jkj::dragonbox::ieee754_bits(
1547 static_cast<double>( value ) );
1550 if( dec.significand == 0 ) {
1551 if( br.is_negative( ) ) {
1561 if( ( whole_dig < -4 ) | ( whole_dig > 6 ) ) {
1566 if( br.is_negative( ) ) {
1569 if( dec.significand == 0 ) {
1573 if( dec.exponent < 0 ) {
1575 if( whole_dig < 0 ) {
1581 }
while( whole_dig < 0 );
1587 daw::cxmath::pow10(
static_cast<std::size_t
>( -dec.exponent ) );
1588 auto const p1val = dec.significand / p1pow;
1594 auto const p2val = dec.significand - ( p1val * p1pow );
1599 while( dec.exponent > 0 ) {
Definition: daw_json_value.h:320
constexpr std::string_view get_string_view() const
Definition: daw_json_value.h:452
constexpr bool is_null() const
Definition: daw_json_value.h:493
#define daw_json_assert(Bool,...)
Definition: daw_json_assert.h:179
auto operator<<(std::ostream &os, T const &value) -> std::enable_if_t< daw::json::json_details::is_opted_into_json_iostreams_v< T >, std::ostream & >
Definition: daw_json_iostream.h:43
ParseState & tmp
Definition: daw_json_iterator.h:37
Iterator & it
Definition: daw_json_traits.h:251
constexpr ymdhms time_point_to_civil(std::chrono::time_point< Clock, Duration > const &tp)
Definition: daw_json_parse_iso8601_utils.h:283
auto use_stream(std::string_view sv)
Definition: to_daw_json_string.h:185
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:69
constexpr bool has_to_string_v
Definition: to_daw_json_string.h:77
daw::is_detected< to_string_test::to_string_result, T > has_to_string
Definition: to_daw_json_string.h:74
constexpr auto to_string(std::optional< T > const &v) -> decltype(to_string(*v))
Definition: to_daw_json_string.h:55
constexpr void to_variant_string(OutputIterator &it, parse_to_t const &value)
Definition: to_daw_json_string.h:594
constexpr DAW_ATTRIB_INLINE void dependent_member_to_json_str(bool &, OutputIterator const &, TpArgs const &, Value const &, VisitedMembers const &)
Definition: to_daw_json_string.h:1395
std::bool_constant< JsonType::expected_type==JsonParseTypes::Null > is_json_nullable
Definition: daw_json_parse_common.h:284
serialization_policy< OutputIterator, SerializationOptions > to_daw_json_string_tuple(serialization_policy< OutputIterator, SerializationOptions > it, parse_to_t const &value, std::index_sequence< Is... >)
Definition: to_daw_json_string.h:1082
constexpr auto digits100
Definition: to_daw_json_string.h:741
constexpr bool has_istream_op_v
Definition: to_daw_json_string.h:102
decltype(from_string(std::declval< daw::tag_t< T > >(), std::declval< std::string_view >())) from_string_test
Definition: to_daw_json_string.h:83
typename deref_t_impl::deref_type_impl< T >::type dereferenced_t
Definition: daw_json_traits.h:745
constexpr OutputIterator member_to_string(template_param< JsonMember >, OutputIterator it, T const &value)
Definition: to_daw_json_string.h:1340
daw::is_detected< is_a_json_tagged_variant_test, T > is_a_json_tagged_variant
Definition: daw_json_traits.h:472
decltype(operator>>(std::declval< T & >(), std::declval< U const & >())) has_rshift_test
Definition: to_daw_json_string.h:95
decltype(operator<<(std::declval< T & >(), std::declval< U const & >())) has_lshift_test
Definition: to_daw_json_string.h:91
constexpr bool has_from_string_v
Definition: to_daw_json_string.h:86
std::bool_constant< daw::is_detected_v< json_type_t, T > > is_a_json_type
Definition: daw_json_traits.h:446
typename daw::detected_or_t< T, ordered_member_subtype_test, T > ordered_member_subtype_t
Definition: daw_json_parse_common.h:51
constexpr void to_json_ordered_str(std::size_t &array_idx, std::size_t array_size, serialization_policy< OutputIterator, SerializerOptions > &it, Tuple< Args... > const &tp)
Definition: to_daw_json_string.h:1493
constexpr auto has_value(T const &v) -> std::enable_if_t< is_readable_v< T >, bool >
Definition: daw_json_traits.h:62
constexpr char to_nibble_char(Char c)
Definition: to_daw_json_string.h:322
std::underlying_type< T > base_int_type_impl
Definition: to_daw_json_string.h:734
typename JsonMember::dependent_member dependent_member_t
Definition: daw_json_parse_common.h:995
std::uint32_t json_options_t
Definition: daw_json_option_bits.h:23
constexpr Key const & json_get_key(std::pair< Key, Value > const &kv)
Definition: to_daw_json_string.h:1212
constexpr Value const & json_get_value(std::pair< Key, Value > const &kv)
Definition: to_daw_json_string.h:1218
constexpr void utf32_to_utf8(std::uint32_t cp, OutputIterator &it)
Definition: to_daw_json_string.h:353
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:739
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:334
missing_required_mapping_for< Name > missing_required_mapping_error()
Definition: to_daw_json_string.h:1352
constexpr void to_json_str(bool &is_first, serialization_policy< OutputIterator, SerializationOptions > &it, Tuple const &tp, Value const &, Visited &visited_members)
Definition: to_daw_json_string.h:1455
constexpr bool is_null(std::optional< T > const &v)
Definition: to_daw_json_string.h:951
constexpr bool has_ostream_op_v
Definition: to_daw_json_string.h:98
constexpr OutputIterator to_chars(Real const &value, OutputIterator out_it)
Definition: to_daw_json_string.h:1530
constexpr bool is_string_view_like_v
Definition: daw_json_traits.h:531
static constexpr std::size_t find_names_in_pack_v
Definition: to_daw_json_string.h:1386
constexpr OutputIterator integer_to_string(OutputIterator it, Integer const &value)
Definition: to_daw_json_string.h:893
constexpr OutputIterator copy_to_iterator(OutputIterator it, Container const &container)
Definition: to_daw_json_string.h:391
EightBitModes
Definition: daw_json_type_options.h:143
@ Tuple
A variant type where the Switcher is based on a submember of the class being parsed.
constexpr std::string_view to_string(JsonBaseParseTypes pt)
Definition: daw_json_enums.h:63
daw::constant< v > ParseTag
Definition: daw_json_enums.h:119
constexpr decltype(auto) get(basic_json_pair< ParseState > const &parse_state)
Definition: daw_json_value.h:49
LiteralAsStringOpt
Definition: daw_json_type_options.h:38
typename json_data_contract< T >::type json_data_contract_trait_t
Definition: daw_json_traits.h:135
DAW_ATTRIB_NOINLINE void daw_json_error(ErrorReason reason)
Definition: daw_json_assert.h:39
FPOutputFormat
Definition: daw_json_type_options.h:83
Definition: daw_from_json.h:22
Definition: daw_from_json.h:22
Definition: daw_json_parse_iso8601_utils.h:272
std::int_least32_t year
Definition: daw_json_parse_iso8601_utils.h:273
std::uint_least32_t second
Definition: daw_json_parse_iso8601_utils.h:278
std::uint_least32_t month
Definition: daw_json_parse_iso8601_utils.h:274
std::uint_least32_t hour
Definition: daw_json_parse_iso8601_utils.h:276
std::uint_least32_t day
Definition: daw_json_parse_iso8601_utils.h:275
std::uint_least32_t minute
Definition: daw_json_parse_iso8601_utils.h:277
std::uint_least32_t millisecond
Definition: daw_json_parse_iso8601_utils.h:279
Definition: to_daw_json_string.h:195
Definition: to_daw_json_string.h:115
static auto use_stream(U const &v)
Definition: to_daw_json_string.h:117
Definition: daw_json_traits.h:667
Definition: daw_json_traits.h:127
static constexpr std::size_t find_position()
Definition: to_daw_json_string.h:1366
Definition: to_daw_json_string.h:1361
Definition: to_daw_json_string.h:1347
Definition: daw_json_value_state.h:57
Definition: daw_json_serialize_policy.h:47
Allow tuple like types to be used in json_tuple.
Definition: daw_json_traits.h:672
Definition: to_daw_json_string.h:884
static constexpr LiteralAsStringOpt literal_as_string
Definition: to_daw_json_string.h:886
Integer parse_to_t
Definition: to_daw_json_string.h:885
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition: version.h:16