30 #ifndef INCLUDE_NLOHMANN_JSON_HPP_ 31 #define INCLUDE_NLOHMANN_JSON_HPP_ 33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 6
35 #define NLOHMANN_JSON_VERSION_PATCH 1
42 #include <initializer_list> 62 #include <forward_list> 67 #include <type_traits> 68 #include <unordered_map> 92 std::size_t chars_read_total = 0;
94 std::size_t chars_read_current_line = 0;
96 std::size_t lines_read = 0;
99 constexpr operator size_t()
const 101 return chars_read_total;
145 class exception :
public std::exception
149 const char* what()
const noexcept override
158 exception(
int id_,
const char* what_arg) : id(id_), m(what_arg) {}
160 static std::string name(
const std::string& ename,
int id_)
162 return "[json.exception." + ename +
"." + std::to_string(id_) +
"] ";
167 std::runtime_error m;
214 class parse_error :
public exception
226 static parse_error create(
int id_,
const position_t& pos,
const std::string& what_arg)
228 std::string w = exception::name(
"parse_error", id_) +
"parse error" +
229 position_string(pos) +
": " + what_arg;
230 return parse_error(id_, pos.chars_read_total, w.c_str());
233 static parse_error create(
int id_, std::size_t byte_,
const std::string& what_arg)
235 std::string w = exception::name(
"parse_error", id_) +
"parse error" +
236 (byte_ != 0 ? (
" at byte " + std::to_string(byte_)) :
"") +
238 return parse_error(id_, byte_, w.c_str());
250 const std::size_t byte;
253 parse_error(
int id_, std::size_t byte_,
const char* what_arg)
254 : exception(id_, what_arg), byte(byte_) {}
256 static std::string position_string(
const position_t& pos)
258 return " at line " + std::to_string(pos.lines_read + 1) +
259 ", column " + std::to_string(pos.chars_read_current_line);
300 class invalid_iterator :
public exception
303 static invalid_iterator create(
int id_,
const std::string& what_arg)
305 std::string w = exception::name(
"invalid_iterator", id_) + what_arg;
306 return invalid_iterator(id_, w.c_str());
310 invalid_iterator(
int id_,
const char* what_arg)
311 : exception(id_, what_arg) {}
353 class type_error :
public exception
356 static type_error create(
int id_,
const std::string& what_arg)
358 std::string w = exception::name(
"type_error", id_) + what_arg;
359 return type_error(id_, w.c_str());
363 type_error(
int id_,
const char* what_arg) : exception(id_, what_arg) {}
399 class out_of_range :
public exception
402 static out_of_range create(
int id_,
const std::string& what_arg)
404 std::string w = exception::name(
"out_of_range", id_) + what_arg;
405 return out_of_range(id_, w.c_str());
409 out_of_range(
int id_,
const char* what_arg) : exception(id_, what_arg) {}
436 class other_error :
public exception
439 static other_error create(
int id_,
const std::string& what_arg)
441 std::string w = exception::name(
"other_error", id_) + what_arg;
442 return other_error(id_, w.c_str());
446 other_error(
int id_,
const char* what_arg) : exception(id_, what_arg) {}
460 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) 461 #if defined(__clang__
) 462 #if (__clang_major__
* 10000
+ __clang_minor__
* 100
+ __clang_patchlevel__
) < 30400
463 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" 465 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) 466 #if (__GNUC__ * 10000
+ __GNUC_MINOR__ * 100
+ __GNUC_PATCHLEVEL__) < 40800
467 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" 473 #if defined(__clang__
) || defined(__GNUC__
) || defined(__GNUG__
) 474 #pragma GCC diagnostic push 475 #pragma GCC diagnostic ignored "-Wfloat-equal" 479 #if defined(__clang__
) 480 #pragma GCC diagnostic push 481 #pragma GCC diagnostic ignored "-Wdocumentation" 485 #if defined(__clang__
) || defined(__GNUC__
) || defined(__GNUG__
) 486 #define JSON_DEPRECATED __attribute__((deprecated)) 487 #elif defined(_MSC_VER) 488 #define JSON_DEPRECATED __declspec(deprecated) 490 #define JSON_DEPRECATED 494 #if defined(__has_cpp_attribute
) 495 #if __has_cpp_attribute
(nodiscard) 496 #define JSON_NODISCARD [[nodiscard]] 497 #elif __has_cpp_attribute(gnu::warn_unused_result) 498 #define JSON_NODISCARD [[gnu::warn_unused_result]] 500 #define JSON_NODISCARD 503 #define JSON_NODISCARD 507 #if (defined(__cpp_exceptions
) || defined(__EXCEPTIONS
) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) 508 #define JSON_THROW(exception) throw exception 510 #define JSON_CATCH(exception) catch(exception) 511 #define JSON_INTERNAL_CATCH(exception) catch(exception) 514 #define JSON_THROW(exception) std::abort() 515 #define JSON_TRY if(true) 516 #define JSON_CATCH(exception) if(false) 517 #define JSON_INTERNAL_CATCH(exception) if(false) 521 #if defined(JSON_THROW_USER) 523 #define JSON_THROW JSON_THROW_USER 525 #if defined(JSON_TRY_USER) 527 #define JSON_TRY JSON_TRY_USER 529 #if defined(JSON_CATCH_USER) 531 #define JSON_CATCH JSON_CATCH_USER 532 #undef JSON_INTERNAL_CATCH 533 #define JSON_INTERNAL_CATCH JSON_CATCH_USER 535 #if defined(JSON_INTERNAL_CATCH_USER) 536 #undef JSON_INTERNAL_CATCH 537 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER 541 #if defined(__clang__
) || defined(__GNUC__
) || defined(__GNUG__
) 542 #define JSON_LIKELY(x) __builtin_expect(x, 1
) 543 #define JSON_UNLIKELY(x) __builtin_expect(x, 0
) 545 #define JSON_LIKELY(x) x 546 #define JSON_UNLIKELY(x) x 550 #if (defined(__cplusplus
) && __cplusplus
>= 201703L
) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1
) 551 #define JSON_HAS_CPP_17 552 #define JSON_HAS_CPP_14 553 #elif (defined(__cplusplus
) && __cplusplus
>= 201402L
) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1
) 554 #define JSON_HAS_CPP_14 562 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) 563 template<typename BasicJsonType> 564 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) 566 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); 567 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; 568 auto it = std::find_if(std::begin(m), std::end(m), 569 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool 571 return ej_pair.first == e; 573 j = ((it != std::end(m)) ? it : std::begin(m))->second; 575 template<typename BasicJsonType> 576 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) 578 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); 579 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; 580 auto it = std::find_if(std::begin(m), std::end(m), 581 [j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool 583 return ej_pair.second == j; 585 e = ((it != std::end(m)) ? it : std::begin(m))->first; 591 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION 592 template<template<typename, typename, typename...> class ObjectType, 593 template<typename, typename...> class ArrayType, 594 class StringType, class BooleanType, class NumberIntegerType, 595 class NumberUnsignedType, class NumberFloatType, 596 template<typename> class AllocatorType, 597 template<typename, typename = void> class JSONSerializer> 599 #define NLOHMANN_BASIC_JSON_TPL 600 basic_json<ObjectType, ArrayType, StringType, BooleanType, 601 NumberIntegerType, NumberUnsignedType, NumberFloatType, 602 AllocatorType, JSONSerializer> 609 #include <type_traits> 616 template<
bool B,
typename T =
void>
617 using enable_if_t =
typename std::enable_if<B, T>::type;
620 using uncvref_t =
typename std::remove_cv<
typename std::remove_reference<T>::type>::type;
624 template<std::size_t... Ints>
625 struct index_sequence
627 using type = index_sequence;
628 using value_type = std::size_t;
629 static constexpr std::size_t size()
noexcept 631 return sizeof...(Ints);
635 template<
class Sequence1,
class Sequence2>
636 struct merge_and_renumber;
638 template<std::size_t... I1, std::size_t... I2>
639 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
640 : index_sequence < I1..., (
sizeof...(I1) + I2)... > {};
642 template<std::size_t N>
643 struct make_index_sequence
644 : merge_and_renumber <
typename make_index_sequence < N / 2 >::type,
645 typename make_index_sequence < N - N / 2 >::type > {};
647 template<>
struct make_index_sequence<0> : index_sequence<> {};
648 template<>
struct make_index_sequence<1> : index_sequence<0> {};
650 template<
typename... Ts>
651 using index_sequence_for = make_index_sequence<
sizeof...(Ts)>;
654 template<
unsigned N>
struct priority_tag : priority_tag < N - 1 > {};
655 template<>
struct priority_tag<0> {};
661 static constexpr T value{};
665 constexpr T static_const<T>::value;
674 #include <type_traits> 689 template <
typename ...Ts>
struct make_void
693 template <
typename ...Ts>
using void_t =
typename make_void<Ts...>::type;
704 template <
typename It,
typename =
void>
705 struct iterator_types {};
707 template <
typename It>
708 struct iterator_types <
710 void_t<
typename It::difference_type,
typename It::value_type,
typename It::pointer,
711 typename It::reference,
typename It::iterator_category >>
713 using difference_type =
typename It::difference_type;
714 using value_type =
typename It::value_type;
715 using pointer =
typename It::pointer;
716 using reference =
typename It::reference;
717 using iterator_category =
typename It::iterator_category;
722 template <
typename T,
typename =
void>
723 struct iterator_traits
727 template <
typename T>
728 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
733 template <
typename T>
734 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
736 using iterator_category = std::random_access_iterator_tag;
737 using value_type = T;
738 using difference_type = ptrdiff_t;
740 using reference = T&;
752 #include <type_traits> 765 ~nonesuch() =
delete;
766 nonesuch(nonesuch
const&) =
delete;
767 nonesuch(nonesuch
const&&) =
delete;
768 void operator=(nonesuch
const&) =
delete;
769 void operator=(nonesuch&&) =
delete;
772 template <
class Default,
774 template <
class...>
class Op,
778 using value_t = std::false_type;
779 using type = Default;
782 template <
class Default,
template <
class...>
class Op,
class... Args>
783 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
785 using value_t = std::true_type;
786 using type = Op<Args...>;
789 template <
template <
class...>
class Op,
class... Args>
790 using is_detected =
typename detector<nonesuch,
void, Op, Args...>::value_t;
792 template <
template <
class...>
class Op,
class... Args>
793 using detected_t =
typename detector<nonesuch,
void, Op, Args...>::type;
795 template <
class Default,
template <
class...>
class Op,
class... Args>
796 using detected_or = detector<Default,
void, Op, Args...>;
798 template <
class Default,
template <
class...>
class Op,
class... Args>
799 using detected_or_t =
typename detected_or<Default, Op, Args...>::type;
801 template <
class Expected,
template <
class...>
class Op,
class... Args>
802 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
804 template <
class To,
template <
class...>
class Op,
class... Args>
805 using is_detected_convertible =
806 std::is_convertible<detected_t<Op, Args...>, To>;
811 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ 812 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_ 834 template<
typename T =
void,
typename SFINAE =
void>
835 struct adl_serializer;
837 template<
template<
typename U,
typename V,
typename... Args>
class ObjectType =
839 template<
typename U,
typename... Args>
class ArrayType = std::vector,
840 class StringType = std::string,
class BooleanType =
bool,
841 class NumberIntegerType = std::int64_t,
842 class NumberUnsignedType = std::uint64_t,
843 class NumberFloatType =
double,
844 template<
typename U>
class AllocatorType = std::allocator,
845 template<
typename T,
typename SFINAE =
void>
class JSONSerializer =
860 template<
typename BasicJsonType>
871 using json = basic_json<>;
902 template<
typename>
struct is_basic_json : std::false_type {};
911 template <
typename T>
912 using mapped_type_t =
typename T::mapped_type;
914 template <
typename T>
915 using key_type_t =
typename T::key_type;
917 template <
typename T>
918 using value_type_t =
typename T::value_type;
920 template <
typename T>
921 using difference_type_t =
typename T::difference_type;
923 template <
typename T>
924 using pointer_t =
typename T::pointer;
926 template <
typename T>
927 using reference_t =
typename T::reference;
929 template <
typename T>
930 using iterator_category_t =
typename T::iterator_category;
932 template <
typename T>
933 using iterator_t =
typename T::iterator;
935 template <
typename T,
typename... Args>
936 using to_json_function =
decltype(T::to_json(std::declval<Args>()...));
938 template <
typename T,
typename... Args>
939 using from_json_function =
decltype(T::from_json(std::declval<Args>()...));
941 template <
typename T,
typename U>
942 using get_template_function =
decltype(std::declval<T>().
template get<U>());
945 template <
typename BasicJsonType,
typename T,
typename =
void>
946 struct has_from_json : std::false_type {};
948 template <
typename BasicJsonType,
typename T>
949 struct has_from_json<BasicJsonType, T,
950 enable_if_t<
not is_basic_json<T>::value>>
952 using serializer =
typename BasicJsonType::
template json_serializer<T,
void>;
954 static constexpr bool value =
955 is_detected_exact<
void, from_json_function, serializer,
956 const BasicJsonType&, T&>::value;
961 template <
typename BasicJsonType,
typename T,
typename =
void>
962 struct has_non_default_from_json : std::false_type {};
964 template<
typename BasicJsonType,
typename T>
965 struct has_non_default_from_json<BasicJsonType, T, enable_if_t<
not is_basic_json<T>::value>>
967 using serializer =
typename BasicJsonType::
template json_serializer<T,
void>;
969 static constexpr bool value =
970 is_detected_exact<T, from_json_function, serializer,
971 const BasicJsonType&>::value;
976 template <
typename BasicJsonType,
typename T,
typename =
void>
977 struct has_to_json : std::false_type {};
979 template <
typename BasicJsonType,
typename T>
980 struct has_to_json<BasicJsonType, T, enable_if_t<
not is_basic_json<T>::value>>
982 using serializer =
typename BasicJsonType::
template json_serializer<T,
void>;
984 static constexpr bool value =
985 is_detected_exact<
void, to_json_function, serializer, BasicJsonType&,
994 template <
typename T,
typename =
void>
995 struct is_iterator_traits : std::false_type {};
997 template <
typename T>
998 struct is_iterator_traits<iterator_traits<T>>
1001 using traits = iterator_traits<T>;
1004 static constexpr auto value =
1005 is_detected<value_type_t, traits>::value &&
1006 is_detected<difference_type_t, traits>::value &&
1007 is_detected<pointer_t, traits>::value &&
1008 is_detected<iterator_category_t, traits>::value &&
1009 is_detected<reference_t, traits>::value;
1014 template <
typename T,
typename =
void>
1015 struct is_complete_type : std::false_type {};
1017 template <
typename T>
1018 struct is_complete_type<T,
decltype(
void(
sizeof(T)))> : std::true_type {};
1020 template <
typename BasicJsonType,
typename CompatibleObjectType,
1022 struct is_compatible_object_type_impl : std::false_type {};
1024 template <
typename BasicJsonType,
typename CompatibleObjectType>
1025 struct is_compatible_object_type_impl <
1026 BasicJsonType, CompatibleObjectType,
1027 enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value
and 1028 is_detected<key_type_t, CompatibleObjectType>::value >>
1031 using object_t =
typename BasicJsonType::object_t;
1034 static constexpr bool value =
1035 std::is_constructible<
typename object_t::key_type,
1036 typename CompatibleObjectType::key_type>::value
and 1037 std::is_constructible<
typename object_t::mapped_type,
1038 typename CompatibleObjectType::mapped_type>::value;
1041 template <
typename BasicJsonType,
typename CompatibleObjectType>
1042 struct is_compatible_object_type
1043 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
1045 template <
typename BasicJsonType,
typename ConstructibleObjectType,
1047 struct is_constructible_object_type_impl : std::false_type {};
1049 template <
typename BasicJsonType,
typename ConstructibleObjectType>
1050 struct is_constructible_object_type_impl <
1051 BasicJsonType, ConstructibleObjectType,
1052 enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value
and 1053 is_detected<key_type_t, ConstructibleObjectType>::value >>
1055 using object_t =
typename BasicJsonType::object_t;
1057 static constexpr bool value =
1058 (std::is_constructible<
typename ConstructibleObjectType::key_type,
typename object_t::key_type>::value
and 1059 std::is_same<
typename object_t::mapped_type,
typename ConstructibleObjectType::mapped_type>::value)
or 1060 (has_from_json<BasicJsonType,
typename ConstructibleObjectType::mapped_type>::value
or 1061 has_non_default_from_json<BasicJsonType,
typename ConstructibleObjectType::mapped_type >::value);
1064 template <
typename BasicJsonType,
typename ConstructibleObjectType>
1065 struct is_constructible_object_type
1066 : is_constructible_object_type_impl<BasicJsonType,
1067 ConstructibleObjectType> {};
1069 template <
typename BasicJsonType,
typename CompatibleStringType,
1071 struct is_compatible_string_type_impl : std::false_type {};
1073 template <
typename BasicJsonType,
typename CompatibleStringType>
1074 struct is_compatible_string_type_impl <
1075 BasicJsonType, CompatibleStringType,
1076 enable_if_t<is_detected_exact<
typename BasicJsonType::string_t::value_type,
1077 value_type_t, CompatibleStringType>::value >>
1079 static constexpr auto value =
1080 std::is_constructible<
typename BasicJsonType::string_t, CompatibleStringType>::value;
1083 template <
typename BasicJsonType,
typename ConstructibleStringType>
1084 struct is_compatible_string_type
1085 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
1087 template <
typename BasicJsonType,
typename ConstructibleStringType,
1089 struct is_constructible_string_type_impl : std::false_type {};
1091 template <
typename BasicJsonType,
typename ConstructibleStringType>
1092 struct is_constructible_string_type_impl <
1093 BasicJsonType, ConstructibleStringType,
1094 enable_if_t<is_detected_exact<
typename BasicJsonType::string_t::value_type,
1095 value_type_t, ConstructibleStringType>::value >>
1097 static constexpr auto value =
1098 std::is_constructible<ConstructibleStringType,
1099 typename BasicJsonType::string_t>::value;
1102 template <
typename BasicJsonType,
typename ConstructibleStringType>
1103 struct is_constructible_string_type
1104 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
1106 template <
typename BasicJsonType,
typename CompatibleArrayType,
typename =
void>
1107 struct is_compatible_array_type_impl : std::false_type {};
1109 template <
typename BasicJsonType,
typename CompatibleArrayType>
1110 struct is_compatible_array_type_impl <
1111 BasicJsonType, CompatibleArrayType,
1112 enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value
and 1113 is_detected<iterator_t, CompatibleArrayType>::value
and 1117 not is_iterator_traits<
1118 iterator_traits<CompatibleArrayType>>::value >>
1120 static constexpr bool value =
1121 std::is_constructible<BasicJsonType,
1122 typename CompatibleArrayType::value_type>::value;
1125 template <
typename BasicJsonType,
typename CompatibleArrayType>
1126 struct is_compatible_array_type
1127 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
1129 template <
typename BasicJsonType,
typename ConstructibleArrayType,
typename =
void>
1130 struct is_constructible_array_type_impl : std::false_type {};
1132 template <
typename BasicJsonType,
typename ConstructibleArrayType>
1133 struct is_constructible_array_type_impl <
1134 BasicJsonType, ConstructibleArrayType,
1135 enable_if_t<std::is_same<ConstructibleArrayType,
1136 typename BasicJsonType::value_type>::value >>
1137 : std::true_type {};
1139 template <
typename BasicJsonType,
typename ConstructibleArrayType>
1140 struct is_constructible_array_type_impl <
1141 BasicJsonType, ConstructibleArrayType,
1142 enable_if_t<
not std::is_same<ConstructibleArrayType,
1143 typename BasicJsonType::value_type>::value
and 1144 is_detected<value_type_t, ConstructibleArrayType>::value
and 1145 is_detected<iterator_t, ConstructibleArrayType>::value
and 1147 detected_t<value_type_t, ConstructibleArrayType>>::value >>
1149 static constexpr bool value =
1154 not is_iterator_traits <
1155 iterator_traits<ConstructibleArrayType >>::value
and 1157 (std::is_same<
typename ConstructibleArrayType::value_type,
typename BasicJsonType::array_t::value_type>::value
or 1158 has_from_json<BasicJsonType,
1159 typename ConstructibleArrayType::value_type>::value
or 1160 has_non_default_from_json <
1161 BasicJsonType,
typename ConstructibleArrayType::value_type >::value);
1164 template <
typename BasicJsonType,
typename ConstructibleArrayType>
1165 struct is_constructible_array_type
1166 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
1168 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType,
1170 struct is_compatible_integer_type_impl : std::false_type {};
1172 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType>
1173 struct is_compatible_integer_type_impl <
1174 RealIntegerType, CompatibleNumberIntegerType,
1175 enable_if_t<std::is_integral<RealIntegerType>::value
and 1176 std::is_integral<CompatibleNumberIntegerType>::value
and 1177 not std::is_same<
bool, CompatibleNumberIntegerType>::value >>
1180 using RealLimits = std::numeric_limits<RealIntegerType>;
1181 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
1183 static constexpr auto value =
1184 std::is_constructible<RealIntegerType,
1185 CompatibleNumberIntegerType>::value
and 1186 CompatibleLimits::is_integer
and 1187 RealLimits::is_signed == CompatibleLimits::is_signed;
1190 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType>
1191 struct is_compatible_integer_type
1192 : is_compatible_integer_type_impl<RealIntegerType,
1193 CompatibleNumberIntegerType> {};
1195 template <
typename BasicJsonType,
typename CompatibleType,
typename =
void>
1196 struct is_compatible_type_impl: std::false_type {};
1198 template <
typename BasicJsonType,
typename CompatibleType>
1199 struct is_compatible_type_impl <
1200 BasicJsonType, CompatibleType,
1201 enable_if_t<is_complete_type<CompatibleType>::value >>
1203 static constexpr bool value =
1204 has_to_json<BasicJsonType, CompatibleType>::value;
1207 template <
typename BasicJsonType,
typename CompatibleType>
1208 struct is_compatible_type
1209 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
1254 enum class value_t : std::uint8_t
1277 inline bool operator<(
const value_t lhs,
const value_t rhs)
noexcept 1279 static constexpr std::array<std::uint8_t, 8> order = {{
1285 const auto l_index =
static_cast<std::size_t>(lhs);
1286 const auto r_index =
static_cast<std::size_t>(rhs);
1287 return l_index < order.size()
and r_index < order.size()
and order[l_index] < order[r_index];
1297 template<
typename BasicJsonType>
1298 void from_json(
const BasicJsonType& j,
typename std::nullptr_t& n)
1302 JSON_THROW(type_error::create(302,
"type must be null, but is " + std::string(j.type_name())));
1308 template<
typename BasicJsonType,
typename ArithmeticType,
1309 enable_if_t<std::is_arithmetic<ArithmeticType>::value
and 1310 not std::is_same<ArithmeticType,
typename BasicJsonType::boolean_t>::value,
1312 void get_arithmetic_value(
const BasicJsonType& j, ArithmeticType& val)
1314 switch (
static_cast<value_t>(j))
1316 case value_t::number_unsigned:
1318 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_unsigned_t*>());
1321 case value_t::number_integer:
1323 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_integer_t*>());
1326 case value_t::number_float:
1328 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_float_t*>());
1333 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
1337 template<
typename BasicJsonType>
1338 void from_json(
const BasicJsonType& j,
typename BasicJsonType::boolean_t& b)
1342 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(j.type_name())));
1344 b = *j.
template get_ptr<
const typename BasicJsonType::boolean_t*>();
1347 template<
typename BasicJsonType>
1348 void from_json(
const BasicJsonType& j,
typename BasicJsonType::string_t& s)
1352 JSON_THROW(type_error::create(302,
"type must be string, but is " + std::string(j.type_name())));
1354 s = *j.
template get_ptr<
const typename BasicJsonType::string_t*>();
1358 typename BasicJsonType,
typename ConstructibleStringType,
1360 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value
and 1361 not std::is_same<
typename BasicJsonType::string_t,
1362 ConstructibleStringType>::value,
1364 void from_json(
const BasicJsonType& j, ConstructibleStringType& s)
1368 JSON_THROW(type_error::create(302,
"type must be string, but is " + std::string(j.type_name())));
1371 s = *j.
template get_ptr<
const typename BasicJsonType::string_t*>();
1374 template<
typename BasicJsonType>
1375 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_float_t& val)
1377 get_arithmetic_value(j, val);
1380 template<
typename BasicJsonType>
1381 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_unsigned_t& val)
1383 get_arithmetic_value(j, val);
1386 template<
typename BasicJsonType>
1387 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_integer_t& val)
1389 get_arithmetic_value(j, val);
1392 template<
typename BasicJsonType,
typename EnumType,
1393 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
1394 void from_json(
const BasicJsonType& j, EnumType& e)
1396 typename std::underlying_type<EnumType>::type val;
1397 get_arithmetic_value(j, val);
1398 e =
static_cast<EnumType>(val);
1402 template<
typename BasicJsonType,
typename T,
typename Allocator,
1403 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1404 void from_json(
const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1408 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1410 std::transform(j.rbegin(), j.rend(),
1411 std::front_inserter(l), [](
const BasicJsonType & i)
1413 return i.
template get<T>();
1418 template<
typename BasicJsonType,
typename T,
1419 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1420 void from_json(
const BasicJsonType& j, std::valarray<T>& l)
1424 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1427 std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1430 template<
typename BasicJsonType>
1431 void from_json_array_impl(
const BasicJsonType& j,
typename BasicJsonType::array_t& arr, priority_tag<3> )
1433 arr = *j.
template get_ptr<
const typename BasicJsonType::array_t*>();
1436 template <
typename BasicJsonType,
typename T, std::size_t N>
1437 auto from_json_array_impl(
const BasicJsonType& j, std::array<T, N>& arr,
1439 ->
decltype(j.
template get<T>(),
void())
1441 for (std::size_t i = 0; i < N; ++i)
1443 arr[i] = j.at(i).
template get<T>();
1447 template<
typename BasicJsonType,
typename ConstructibleArrayType>
1448 auto from_json_array_impl(
const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> )
1450 arr.reserve(std::declval<
typename ConstructibleArrayType::size_type>()),
1451 j.
template get<
typename ConstructibleArrayType::value_type>(),
1456 arr.reserve(j.size());
1457 std::transform(j.begin(), j.end(),
1458 std::inserter(arr, end(arr)), [](
const BasicJsonType & i)
1462 return i.
template get<
typename ConstructibleArrayType::value_type>();
1466 template <
typename BasicJsonType,
typename ConstructibleArrayType>
1467 void from_json_array_impl(
const BasicJsonType& j, ConstructibleArrayType& arr,
1473 j.begin(), j.end(), std::inserter(arr, end(arr)),
1474 [](
const BasicJsonType & i)
1478 return i.
template get<
typename ConstructibleArrayType::value_type>();
1482 template <
typename BasicJsonType,
typename ConstructibleArrayType,
1484 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value
and 1485 not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value
and 1486 not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value
and 1487 not is_basic_json<ConstructibleArrayType>::value,
1490 auto from_json(
const BasicJsonType& j, ConstructibleArrayType& arr)
1491 ->
decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
1492 j.
template get<
typename ConstructibleArrayType::value_type>(),
1497 JSON_THROW(type_error::create(302,
"type must be array, but is " +
1498 std::string(j.type_name())));
1501 from_json_array_impl(j, arr, priority_tag<3> {});
1504 template<
typename BasicJsonType,
typename ConstructibleObjectType,
1505 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value,
int> = 0>
1506 void from_json(
const BasicJsonType& j, ConstructibleObjectType& obj)
1510 JSON_THROW(type_error::create(302,
"type must be object, but is " + std::string(j.type_name())));
1513 auto inner_object = j.
template get_ptr<
const typename BasicJsonType::object_t*>();
1514 using value_type =
typename ConstructibleObjectType::value_type;
1516 inner_object->begin(), inner_object->end(),
1517 std::inserter(obj, obj.begin()),
1518 [](
typename BasicJsonType::object_t::value_type
const & p)
1520 return value_type(p.first, p.second.
template get<
typename ConstructibleObjectType::mapped_type>());
1528 template<
typename BasicJsonType,
typename ArithmeticType,
1530 std::is_arithmetic<ArithmeticType>::value
and 1531 not std::is_same<ArithmeticType,
typename BasicJsonType::number_unsigned_t>::value
and 1532 not std::is_same<ArithmeticType,
typename BasicJsonType::number_integer_t>::value
and 1533 not std::is_same<ArithmeticType,
typename BasicJsonType::number_float_t>::value
and 1534 not std::is_same<ArithmeticType,
typename BasicJsonType::boolean_t>::value,
1536 void from_json(
const BasicJsonType& j, ArithmeticType& val)
1538 switch (
static_cast<value_t>(j))
1540 case value_t::number_unsigned:
1542 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_unsigned_t*>());
1545 case value_t::number_integer:
1547 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_integer_t*>());
1550 case value_t::number_float:
1552 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_float_t*>());
1555 case value_t::boolean:
1557 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::boolean_t*>());
1562 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
1566 template<
typename BasicJsonType,
typename A1,
typename A2>
1567 void from_json(
const BasicJsonType& j, std::pair<A1, A2>& p)
1569 p = {j.at(0).
template get<A1>(), j.at(1).
template get<A2>()};
1572 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1573 void from_json_tuple_impl(
const BasicJsonType& j, Tuple& t, index_sequence<Idx...> )
1575 t = std::make_tuple(j.at(Idx).
template get<
typename std::tuple_element<Idx, Tuple>::type>()...);
1578 template<
typename BasicJsonType,
typename... Args>
1579 void from_json(
const BasicJsonType& j, std::tuple<Args...>& t)
1581 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1584 template <
typename BasicJsonType,
typename Key,
typename Value,
typename Compare,
typename Allocator,
1585 typename = enable_if_t<
not std::is_constructible<
1586 typename BasicJsonType::string_t, Key>::value>>
1587 void from_json(
const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
1591 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1593 for (
const auto& p : j)
1597 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(p.type_name())));
1599 m.emplace(p.at(0).
template get<Key>(), p.at(1).
template get<Value>());
1603 template <
typename BasicJsonType,
typename Key,
typename Value,
typename Hash,
typename KeyEqual,
typename Allocator,
1604 typename = enable_if_t<
not std::is_constructible<
1605 typename BasicJsonType::string_t, Key>::value>>
1606 void from_json(
const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
1610 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1612 for (
const auto& p : j)
1616 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(p.type_name())));
1618 m.emplace(p.at(0).
template get<Key>(), p.at(1).
template get<Value>());
1624 template<
typename BasicJsonType,
typename T>
1625 auto operator()(
const BasicJsonType& j, T& val)
const 1626 noexcept(
noexcept(from_json(j, val)))
1627 ->
decltype(from_json(j, val),
void())
1629 return from_json(j, val);
1639 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
1646 #include <algorithm> 1651 #include <type_traits> 1673 template <
typename IteratorType>
class iteration_proxy_value
1676 using difference_type = std::ptrdiff_t;
1677 using value_type = iteration_proxy_value;
1678 using pointer = value_type * ;
1679 using reference = value_type & ;
1680 using iterator_category = std::input_iterator_tag;
1684 IteratorType anchor;
1686 std::size_t array_index = 0;
1688 mutable std::size_t array_index_last = 0;
1690 mutable std::string array_index_str =
"0";
1692 const std::string empty_str =
"";
1695 explicit iteration_proxy_value(IteratorType it)
noexcept : anchor(it) {}
1698 iteration_proxy_value& operator*()
1704 iteration_proxy_value& operator++()
1713 bool operator==(
const iteration_proxy_value& o)
const 1715 return anchor == o.anchor;
1719 bool operator!=(
const iteration_proxy_value& o)
const 1721 return anchor != o.anchor;
1725 const std::string& key()
const 1727 assert(anchor.m_object !=
nullptr);
1729 switch (anchor.m_object->type())
1732 case value_t::array:
1734 if (array_index != array_index_last)
1736 array_index_str = std::to_string(array_index);
1737 array_index_last = array_index;
1739 return array_index_str;
1743 case value_t::object:
1744 return anchor.key();
1753 typename IteratorType::reference value()
const 1755 return anchor.value();
1760 template<
typename IteratorType>
class iteration_proxy
1764 typename IteratorType::reference container;
1768 explicit iteration_proxy(
typename IteratorType::reference cont)
noexcept 1769 : container(cont) {}
1772 iteration_proxy_value<IteratorType> begin()
noexcept 1774 return iteration_proxy_value<IteratorType>(container.begin());
1778 iteration_proxy_value<IteratorType> end()
noexcept 1780 return iteration_proxy_value<IteratorType>(container.end());
1786 template <std::size_t N,
typename IteratorType, enable_if_t<N == 0,
int> = 0>
1787 auto get(
const nlohmann::detail::iteration_proxy_value<IteratorType>& i) ->
decltype(i.key())
1794 template <std::size_t N,
typename IteratorType, enable_if_t<N == 1,
int> = 0>
1795 auto get(
const nlohmann::detail::iteration_proxy_value<IteratorType>& i) ->
decltype(i.value())
1808 #if defined(__clang__
) 1810 #pragma clang diagnostic push 1811 #pragma clang diagnostic ignored "-Wmismatched-tags" 1813 template <
typename IteratorType>
1814 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
1815 :
public std::integral_constant<std::size_t, 2> {};
1817 template <std::size_t N,
typename IteratorType>
1818 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
1821 using type =
decltype(
1822 get<N>(std::declval <
1823 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
1825 #if defined(__clang__
) 1826 #pragma clang diagnostic pop 1845 template<value_t>
struct external_constructor;
1848 struct external_constructor<value_t::boolean>
1850 template<
typename BasicJsonType>
1851 static void construct(BasicJsonType& j,
typename BasicJsonType::boolean_t b)
noexcept 1853 j.m_type = value_t::boolean;
1855 j.assert_invariant();
1860 struct external_constructor<value_t::string>
1862 template<
typename BasicJsonType>
1863 static void construct(BasicJsonType& j,
const typename BasicJsonType::string_t& s)
1865 j.m_type = value_t::string;
1867 j.assert_invariant();
1870 template<
typename BasicJsonType>
1871 static void construct(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
1873 j.m_type = value_t::string;
1874 j.m_value = std::move(s);
1875 j.assert_invariant();
1878 template<
typename BasicJsonType,
typename CompatibleStringType,
1879 enable_if_t<
not std::is_same<CompatibleStringType,
typename BasicJsonType::string_t>::value,
1881 static void construct(BasicJsonType& j,
const CompatibleStringType& str)
1883 j.m_type = value_t::string;
1884 j.m_value.string = j.
template create<
typename BasicJsonType::string_t>(str);
1885 j.assert_invariant();
1890 struct external_constructor<value_t::number_float>
1892 template<
typename BasicJsonType>
1893 static void construct(BasicJsonType& j,
typename BasicJsonType::number_float_t val)
noexcept 1895 j.m_type = value_t::number_float;
1897 j.assert_invariant();
1902 struct external_constructor<value_t::number_unsigned>
1904 template<
typename BasicJsonType>
1905 static void construct(BasicJsonType& j,
typename BasicJsonType::number_unsigned_t val)
noexcept 1907 j.m_type = value_t::number_unsigned;
1909 j.assert_invariant();
1914 struct external_constructor<value_t::number_integer>
1916 template<
typename BasicJsonType>
1917 static void construct(BasicJsonType& j,
typename BasicJsonType::number_integer_t val)
noexcept 1919 j.m_type = value_t::number_integer;
1921 j.assert_invariant();
1926 struct external_constructor<value_t::array>
1928 template<
typename BasicJsonType>
1929 static void construct(BasicJsonType& j,
const typename BasicJsonType::array_t& arr)
1931 j.m_type = value_t::array;
1933 j.assert_invariant();
1936 template<
typename BasicJsonType>
1937 static void construct(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
1939 j.m_type = value_t::array;
1940 j.m_value = std::move(arr);
1941 j.assert_invariant();
1944 template<
typename BasicJsonType,
typename CompatibleArrayType,
1945 enable_if_t<
not std::is_same<CompatibleArrayType,
typename BasicJsonType::array_t>::value,
1947 static void construct(BasicJsonType& j,
const CompatibleArrayType& arr)
1951 j.m_type = value_t::array;
1952 j.m_value.array = j.
template create<
typename BasicJsonType::array_t>(begin(arr), end(arr));
1953 j.assert_invariant();
1956 template<
typename BasicJsonType>
1957 static void construct(BasicJsonType& j,
const std::vector<
bool>& arr)
1959 j.m_type = value_t::array;
1960 j.m_value = value_t::array;
1961 j.m_value.array->reserve(arr.size());
1962 for (
const bool x : arr)
1964 j.m_value.array->push_back(x);
1966 j.assert_invariant();
1969 template<
typename BasicJsonType,
typename T,
1970 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
1971 static void construct(BasicJsonType& j,
const std::valarray<T>& arr)
1973 j.m_type = value_t::array;
1974 j.m_value = value_t::array;
1975 j.m_value.array->resize(arr.size());
1976 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
1977 j.assert_invariant();
1982 struct external_constructor<value_t::object>
1984 template<
typename BasicJsonType>
1985 static void construct(BasicJsonType& j,
const typename BasicJsonType::object_t& obj)
1987 j.m_type = value_t::object;
1989 j.assert_invariant();
1992 template<
typename BasicJsonType>
1993 static void construct(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
1995 j.m_type = value_t::object;
1996 j.m_value = std::move(obj);
1997 j.assert_invariant();
2000 template<
typename BasicJsonType,
typename CompatibleObjectType,
2001 enable_if_t<
not std::is_same<CompatibleObjectType,
typename BasicJsonType::object_t>::value,
int> = 0>
2002 static void construct(BasicJsonType& j,
const CompatibleObjectType& obj)
2007 j.m_type = value_t::object;
2008 j.m_value.object = j.
template create<
typename BasicJsonType::object_t>(begin(obj), end(obj));
2009 j.assert_invariant();
2017 template<
typename BasicJsonType,
typename T,
2018 enable_if_t<std::is_same<T,
typename BasicJsonType::boolean_t>::value,
int> = 0>
2019 void to_json(BasicJsonType& j, T b)
noexcept 2021 external_constructor<value_t::boolean>::construct(j, b);
2024 template<
typename BasicJsonType,
typename CompatibleString,
2025 enable_if_t<std::is_constructible<
typename BasicJsonType::string_t, CompatibleString>::value,
int> = 0>
2026 void to_json(BasicJsonType& j,
const CompatibleString& s)
2028 external_constructor<value_t::string>::construct(j, s);
2031 template<
typename BasicJsonType>
2032 void to_json(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
2034 external_constructor<value_t::string>::construct(j, std::move(s));
2037 template<
typename BasicJsonType,
typename FloatType,
2038 enable_if_t<std::is_floating_point<FloatType>::value,
int> = 0>
2039 void to_json(BasicJsonType& j, FloatType val)
noexcept 2041 external_constructor<value_t::number_float>::construct(j,
static_cast<
typename BasicJsonType::number_float_t>(val));
2044 template<
typename BasicJsonType,
typename CompatibleNumberUnsignedType,
2045 enable_if_t<is_compatible_integer_type<
typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value,
int> = 0>
2046 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val)
noexcept 2048 external_constructor<value_t::number_unsigned>::construct(j,
static_cast<
typename BasicJsonType::number_unsigned_t>(val));
2051 template<
typename BasicJsonType,
typename CompatibleNumberIntegerType,
2052 enable_if_t<is_compatible_integer_type<
typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value,
int> = 0>
2053 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val)
noexcept 2055 external_constructor<value_t::number_integer>::construct(j,
static_cast<
typename BasicJsonType::number_integer_t>(val));
2058 template<
typename BasicJsonType,
typename EnumType,
2059 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
2060 void to_json(BasicJsonType& j, EnumType e)
noexcept 2062 using underlying_type =
typename std::underlying_type<EnumType>::type;
2063 external_constructor<value_t::number_integer>::construct(j,
static_cast<underlying_type>(e));
2066 template<
typename BasicJsonType>
2067 void to_json(BasicJsonType& j,
const std::vector<
bool>& e)
2069 external_constructor<value_t::array>::construct(j, e);
2072 template <
typename BasicJsonType,
typename CompatibleArrayType,
2073 enable_if_t<is_compatible_array_type<BasicJsonType,
2074 CompatibleArrayType>::value
and 2075 not is_compatible_object_type<
2076 BasicJsonType, CompatibleArrayType>::value
and 2077 not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value
and 2078 not is_basic_json<CompatibleArrayType>::value,
2080 void to_json(BasicJsonType& j,
const CompatibleArrayType& arr)
2082 external_constructor<value_t::array>::construct(j, arr);
2085 template<
typename BasicJsonType,
typename T,
2086 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
2087 void to_json(BasicJsonType& j,
const std::valarray<T>& arr)
2089 external_constructor<value_t::array>::construct(j, std::move(arr));
2092 template<
typename BasicJsonType>
2093 void to_json(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
2095 external_constructor<value_t::array>::construct(j, std::move(arr));
2098 template<
typename BasicJsonType,
typename CompatibleObjectType,
2099 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value
and not is_basic_json<CompatibleObjectType>::value,
int> = 0>
2100 void to_json(BasicJsonType& j,
const CompatibleObjectType& obj)
2102 external_constructor<value_t::object>::construct(j, obj);
2105 template<
typename BasicJsonType>
2106 void to_json(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
2108 external_constructor<value_t::object>::construct(j, std::move(obj));
2112 typename BasicJsonType,
typename T, std::size_t N,
2113 enable_if_t<
not std::is_constructible<
typename BasicJsonType::string_t,
2114 const T(&)[N]>::value,
2116 void to_json(BasicJsonType& j,
const T(&arr)[N])
2118 external_constructor<value_t::array>::construct(j, arr);
2121 template<
typename BasicJsonType,
typename... Args>
2122 void to_json(BasicJsonType& j,
const std::pair<Args...>& p)
2124 j = { p.first, p.second };
2128 template <
typename BasicJsonType,
typename T,
2129 enable_if_t<std::is_same<T, iteration_proxy_value<
typename BasicJsonType::iterator>>::value,
int> = 0>
2130 void to_json(BasicJsonType& j,
const T& b)
2132 j = { {b.key(), b.value()} };
2135 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
2136 void to_json_tuple_impl(BasicJsonType& j,
const Tuple& t, index_sequence<Idx...> )
2138 j = { std::get<Idx>(t)... };
2141 template<
typename BasicJsonType,
typename... Args>
2142 void to_json(BasicJsonType& j,
const std::tuple<Args...>& t)
2144 to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
2149 template<
typename BasicJsonType,
typename T>
2150 auto operator()(BasicJsonType& j, T&& val)
const noexcept(
noexcept(to_json(j, std::forward<T>(val))))
2151 ->
decltype(to_json(j, std::forward<T>(val)),
void())
2153 return to_json(j, std::forward<T>(val));
2161 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
2169 template<
typename,
typename>
2170 struct adl_serializer
2181 template<
typename BasicJsonType,
typename ValueType>
2182 static auto from_json(BasicJsonType&& j, ValueType& val)
noexcept(
2183 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
2184 ->
decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val),
void())
2186 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
2198 template <
typename BasicJsonType,
typename ValueType>
2199 static auto to_json(BasicJsonType& j, ValueType&& val)
noexcept(
2200 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
2201 ->
decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)),
void())
2203 ::nlohmann::to_json(j, std::forward<ValueType>(val));
2218 #include <algorithm> 2246 #include <type_traits> 2259 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
2276 struct input_adapter_protocol
2279 virtual std::char_traits<
char>::int_type get_character() = 0;
2280 virtual ~input_adapter_protocol() =
default;
2284 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
2290 class file_input_adapter :
public input_adapter_protocol
2293 explicit file_input_adapter(std::FILE* f)
noexcept 2298 file_input_adapter(
const file_input_adapter&) =
delete;
2299 file_input_adapter(file_input_adapter&&) =
default;
2300 file_input_adapter& operator=(
const file_input_adapter&) =
delete;
2301 file_input_adapter& operator=(file_input_adapter&&) =
default;
2302 ~file_input_adapter() override =
default;
2304 std::char_traits<
char>::int_type get_character()
noexcept override
2306 return std::fgetc(m_file);
2324 class input_stream_adapter :
public input_adapter_protocol
2327 ~input_stream_adapter() override
2331 is.clear(is.rdstate() & std::ios::eofbit);
2334 explicit input_stream_adapter(std::istream& i)
2335 : is(i), sb(*i.rdbuf())
2339 input_stream_adapter(
const input_stream_adapter&) =
delete;
2340 input_stream_adapter& operator=(input_stream_adapter&) =
delete;
2341 input_stream_adapter(input_stream_adapter&&) =
delete;
2342 input_stream_adapter& operator=(input_stream_adapter&&) =
delete;
2347 std::char_traits<
char>::int_type get_character() override
2349 auto res = sb.sbumpc();
2353 is.clear(is.rdstate() | std::ios::eofbit);
2365 class input_buffer_adapter :
public input_adapter_protocol
2368 input_buffer_adapter(
const char* b,
const std::size_t l)
noexcept 2369 : cursor(b), limit(b + l)
2373 input_buffer_adapter(
const input_buffer_adapter&) =
delete;
2374 input_buffer_adapter& operator=(input_buffer_adapter&) =
delete;
2375 input_buffer_adapter(input_buffer_adapter&&) =
delete;
2376 input_buffer_adapter& operator=(input_buffer_adapter&&) =
delete;
2377 ~input_buffer_adapter() override =
default;
2379 std::char_traits<
char>::int_type get_character()
noexcept override
2383 return std::char_traits<
char>::to_int_type(*(cursor++));
2386 return std::char_traits<
char>::eof();
2393 const char*
const limit;
2396 template<
typename WideStringType, size_t T>
2397 struct wide_string_input_helper
2400 static void fill_buffer(
const WideStringType& str,
2401 size_t& current_wchar,
2402 std::array<std::char_traits<
char>::int_type, 4>& utf8_bytes,
2403 size_t& utf8_bytes_index,
2404 size_t& utf8_bytes_filled)
2406 utf8_bytes_index = 0;
2408 if (current_wchar == str.size())
2410 utf8_bytes[0] = std::char_traits<
char>::eof();
2411 utf8_bytes_filled = 1;
2416 const auto wc =
static_cast<
unsigned int>(str[current_wchar++]);
2421 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(wc);
2422 utf8_bytes_filled = 1;
2424 else if (wc <= 0x7FF)
2426 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(0xC0u | ((wc >> 6u) & 0x1Fu));
2427 utf8_bytes[1] =
static_cast<std::char_traits<
char>::int_type>(0x80u | (wc & 0x3Fu));
2428 utf8_bytes_filled = 2;
2430 else if (wc <= 0xFFFF)
2432 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(0xE0u | ((wc >> 12u) & 0x0Fu));
2433 utf8_bytes[1] =
static_cast<std::char_traits<
char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2434 utf8_bytes[2] =
static_cast<std::char_traits<
char>::int_type>(0x80u | (wc & 0x3Fu));
2435 utf8_bytes_filled = 3;
2437 else if (wc <= 0x10FFFF)
2439 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(0xF0u | ((wc >> 18u) & 0x07u));
2440 utf8_bytes[1] =
static_cast<std::char_traits<
char>::int_type>(0x80u | ((wc >> 12u) & 0x3Fu));
2441 utf8_bytes[2] =
static_cast<std::char_traits<
char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2442 utf8_bytes[3] =
static_cast<std::char_traits<
char>::int_type>(0x80u | (wc & 0x3Fu));
2443 utf8_bytes_filled = 4;
2448 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(wc);
2449 utf8_bytes_filled = 1;
2455 template<
typename WideStringType>
2456 struct wide_string_input_helper<WideStringType, 2>
2459 static void fill_buffer(
const WideStringType& str,
2460 size_t& current_wchar,
2461 std::array<std::char_traits<
char>::int_type, 4>& utf8_bytes,
2462 size_t& utf8_bytes_index,
2463 size_t& utf8_bytes_filled)
2465 utf8_bytes_index = 0;
2467 if (current_wchar == str.size())
2469 utf8_bytes[0] = std::char_traits<
char>::eof();
2470 utf8_bytes_filled = 1;
2475 const auto wc =
static_cast<
unsigned int>(str[current_wchar++]);
2480 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(wc);
2481 utf8_bytes_filled = 1;
2483 else if (wc <= 0x7FF)
2485 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(0xC0u | ((wc >> 6u)));
2486 utf8_bytes[1] =
static_cast<std::char_traits<
char>::int_type>(0x80u | (wc & 0x3Fu));
2487 utf8_bytes_filled = 2;
2489 else if (0xD800 > wc
or wc >= 0xE000)
2491 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(0xE0u | ((wc >> 12u)));
2492 utf8_bytes[1] =
static_cast<std::char_traits<
char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2493 utf8_bytes[2] =
static_cast<std::char_traits<
char>::int_type>(0x80u | (wc & 0x3Fu));
2494 utf8_bytes_filled = 3;
2498 if (current_wchar < str.size())
2500 const auto wc2 =
static_cast<
unsigned int>(str[current_wchar++]);
2501 const auto charcode = 0x10000u + (((wc & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
2502 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(0xF0u | (charcode >> 18u));
2503 utf8_bytes[1] =
static_cast<std::char_traits<
char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
2504 utf8_bytes[2] =
static_cast<std::char_traits<
char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
2505 utf8_bytes[3] =
static_cast<std::char_traits<
char>::int_type>(0x80u | (charcode & 0x3Fu));
2506 utf8_bytes_filled = 4;
2512 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(wc);
2513 utf8_bytes_filled = 1;
2520 template<
typename WideStringType>
2521 class wide_string_input_adapter :
public input_adapter_protocol
2524 explicit wide_string_input_adapter(
const WideStringType& w)
noexcept 2528 std::char_traits<
char>::int_type get_character()
noexcept override
2531 if (utf8_bytes_index == utf8_bytes_filled)
2533 fill_buffer<
sizeof(
typename WideStringType::value_type)>();
2535 assert(utf8_bytes_filled > 0);
2536 assert(utf8_bytes_index == 0);
2540 assert(utf8_bytes_filled > 0);
2541 assert(utf8_bytes_index < utf8_bytes_filled);
2542 return utf8_bytes[utf8_bytes_index++];
2549 wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
2553 const WideStringType& str;
2556 std::size_t current_wchar = 0;
2559 std::array<std::char_traits<
char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
2562 std::size_t utf8_bytes_index = 0;
2564 std::size_t utf8_bytes_filled = 0;
2571 input_adapter(std::FILE* file)
2572 : ia(std::make_shared<file_input_adapter>(file)) {}
2574 input_adapter(std::istream& i)
2575 : ia(std::make_shared<input_stream_adapter>(i)) {}
2578 input_adapter(std::istream&& i)
2579 : ia(std::make_shared<input_stream_adapter>(i)) {}
2581 input_adapter(
const std::wstring& ws)
2582 : ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {}
2584 input_adapter(
const std::u16string& ws)
2585 : ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {}
2587 input_adapter(
const std::u32string& ws)
2588 : ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {}
2591 template<
typename CharT,
2592 typename std::enable_if<
2593 std::is_pointer<CharT>::value
and 2594 std::is_integral<
typename std::remove_pointer<CharT>::type>::value
and 2595 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
2597 input_adapter(CharT b, std::size_t l)
2598 : ia(std::make_shared<input_buffer_adapter>(
reinterpret_cast<
const char*>(b), l)) {}
2603 template<
typename CharT,
2604 typename std::enable_if<
2605 std::is_pointer<CharT>::value
and 2606 std::is_integral<
typename std::remove_pointer<CharT>::type>::value
and 2607 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
2609 input_adapter(CharT b)
2610 : input_adapter(
reinterpret_cast<
const char*>(b),
2611 std::strlen(
reinterpret_cast<
const char*>(b))) {}
2614 template<
class IteratorType,
2615 typename std::enable_if<
2616 std::is_same<
typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
2618 input_adapter(IteratorType first, IteratorType last)
2623 const auto is_contiguous = std::accumulate(
2624 first, last, std::pair<
bool,
int>(
true, 0),
2625 [&first](std::pair<
bool,
int> res,
decltype(*first) val)
2627 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
2630 assert(is_contiguous);
2635 sizeof(
typename iterator_traits<IteratorType>::value_type) == 1,
2636 "each element in the iterator range must have the size of 1 byte");
2638 const auto len =
static_cast<size_t>(std::distance(first, last));
2642 ia = std::make_shared<input_buffer_adapter>(
reinterpret_cast<
const char*>(&(*first)), len);
2647 ia = std::make_shared<input_buffer_adapter>(
nullptr, len);
2652 template<
class T, std::size_t N>
2653 input_adapter(T (&array)[N])
2654 : input_adapter(std::begin(array), std::end(array)) {}
2657 template<
class ContiguousContainer,
typename 2658 std::enable_if<
not std::is_pointer<ContiguousContainer>::value
and 2659 std::is_base_of<std::random_access_iterator_tag,
typename iterator_traits<
decltype(std::begin(std::declval<ContiguousContainer
const>()))>::iterator_category>::value,
2661 input_adapter(
const ContiguousContainer& c)
2662 : input_adapter(std::begin(c), std::end(c)) {}
2664 operator input_adapter_t()
2671 input_adapter_t ia =
nullptr;
2701 template<
typename BasicJsonType>
2705 using number_integer_t =
typename BasicJsonType::number_integer_t;
2707 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
2709 using number_float_t =
typename BasicJsonType::number_float_t;
2711 using string_t =
typename BasicJsonType::string_t;
2717 virtual bool null() = 0;
2724 virtual bool boolean(
bool val) = 0;
2731 virtual bool number_integer(number_integer_t val) = 0;
2738 virtual bool number_unsigned(number_unsigned_t val) = 0;
2746 virtual bool number_float(number_float_t val,
const string_t& s) = 0;
2754 virtual bool string(string_t& val) = 0;
2762 virtual bool start_object(std::size_t elements) = 0;
2770 virtual bool key(string_t& val) = 0;
2776 virtual bool end_object() = 0;
2784 virtual bool start_array(std::size_t elements) = 0;
2790 virtual bool end_array() = 0;
2799 virtual bool parse_error(std::size_t position,
2800 const std::string& last_token,
2801 const detail::exception& ex) = 0;
2803 virtual ~json_sax() =
default;
2822 template<
typename BasicJsonType>
2823 class json_sax_dom_parser
2826 using number_integer_t =
typename BasicJsonType::number_integer_t;
2827 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
2828 using number_float_t =
typename BasicJsonType::number_float_t;
2829 using string_t =
typename BasicJsonType::string_t;
2836 explicit json_sax_dom_parser(BasicJsonType& r,
const bool allow_exceptions_ =
true)
2837 : root(r), allow_exceptions(allow_exceptions_)
2841 json_sax_dom_parser(
const json_sax_dom_parser&) =
delete;
2842 json_sax_dom_parser(json_sax_dom_parser&&) =
default;
2843 json_sax_dom_parser& operator=(
const json_sax_dom_parser&) =
delete;
2844 json_sax_dom_parser& operator=(json_sax_dom_parser&&) =
default;
2845 ~json_sax_dom_parser() =
default;
2849 handle_value(
nullptr);
2853 bool boolean(
bool val)
2859 bool number_integer(number_integer_t val)
2865 bool number_unsigned(number_unsigned_t val)
2871 bool number_float(number_float_t val,
const string_t& )
2877 bool string(string_t& val)
2883 bool start_object(std::size_t len)
2885 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
2887 if (
JSON_UNLIKELY(len != std::size_t(-1)
and len > ref_stack.back()->max_size()))
2890 "excessive object size: " + std::to_string(len)));
2896 bool key(string_t& val)
2899 object_element = &(ref_stack.back()->m_value.object->operator[](val));
2905 ref_stack.pop_back();
2909 bool start_array(std::size_t len)
2911 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
2913 if (
JSON_UNLIKELY(len != std::size_t(-1)
and len > ref_stack.back()->max_size()))
2916 "excessive array size: " + std::to_string(len)));
2924 ref_stack.pop_back();
2928 bool parse_error(std::size_t ,
const std::string& ,
2929 const detail::exception& ex)
2932 if (allow_exceptions)
2935 switch ((ex.id / 100) % 100)
2938 JSON_THROW(*
static_cast<
const detail::parse_error*>(&ex));
2940 JSON_THROW(*
static_cast<
const detail::out_of_range*>(&ex));
2943 JSON_THROW(*
static_cast<
const detail::invalid_iterator*>(&ex));
2945 JSON_THROW(*
static_cast<
const detail::type_error*>(&ex));
2947 JSON_THROW(*
static_cast<
const detail::other_error*>(&ex));
2956 constexpr bool is_errored()
const 2968 template<
typename Value>
2969 BasicJsonType* handle_value(Value&& v)
2971 if (ref_stack.empty())
2973 root = BasicJsonType(std::forward<Value>(v));
2977 assert(ref_stack.back()->is_array()
or ref_stack.back()->is_object());
2979 if (ref_stack.back()->is_array())
2981 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
2982 return &(ref_stack.back()->m_value.array->back());
2985 assert(ref_stack.back()->is_object());
2986 assert(object_element);
2987 *object_element = BasicJsonType(std::forward<Value>(v));
2988 return object_element;
2992 BasicJsonType& root;
2994 std::vector<BasicJsonType*> ref_stack {};
2996 BasicJsonType* object_element =
nullptr;
2998 bool errored =
false;
3000 const bool allow_exceptions =
true;
3003 template<
typename BasicJsonType>
3004 class json_sax_dom_callback_parser
3007 using number_integer_t =
typename BasicJsonType::number_integer_t;
3008 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
3009 using number_float_t =
typename BasicJsonType::number_float_t;
3010 using string_t =
typename BasicJsonType::string_t;
3011 using parser_callback_t =
typename BasicJsonType::parser_callback_t;
3012 using parse_event_t =
typename BasicJsonType::parse_event_t;
3014 json_sax_dom_callback_parser(BasicJsonType& r,
3015 const parser_callback_t cb,
3016 const bool allow_exceptions_ =
true)
3017 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
3019 keep_stack.push_back(
true);
3023 json_sax_dom_callback_parser(
const json_sax_dom_callback_parser&) =
delete;
3024 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) =
default;
3025 json_sax_dom_callback_parser& operator=(
const json_sax_dom_callback_parser&) =
delete;
3026 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) =
default;
3027 ~json_sax_dom_callback_parser() =
default;
3031 handle_value(
nullptr);
3035 bool boolean(
bool val)
3041 bool number_integer(number_integer_t val)
3047 bool number_unsigned(number_unsigned_t val)
3053 bool number_float(number_float_t val,
const string_t& )
3059 bool string(string_t& val)
3065 bool start_object(std::size_t len)
3068 const bool keep = callback(
static_cast<
int>(ref_stack.size()), parse_event_t::object_start, discarded);
3069 keep_stack.push_back(keep);
3071 auto val = handle_value(BasicJsonType::value_t::object,
true);
3072 ref_stack.push_back(val.second);
3075 if (ref_stack.back()
and JSON_UNLIKELY(len != std::size_t(-1)
and len > ref_stack.back()->max_size()))
3077 JSON_THROW(out_of_range::create(408,
"excessive object size: " + std::to_string(len)));
3083 bool key(string_t& val)
3085 BasicJsonType k = BasicJsonType(val);
3088 const bool keep = callback(
static_cast<
int>(ref_stack.size()), parse_event_t::key, k);
3089 key_keep_stack.push_back(keep);
3092 if (keep
and ref_stack.back())
3094 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
3102 if (ref_stack.back()
and not callback(
static_cast<
int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
3105 *ref_stack.back() = discarded;
3108 assert(
not ref_stack.empty());
3109 assert(
not keep_stack.empty());
3110 ref_stack.pop_back();
3111 keep_stack.pop_back();
3113 if (
not ref_stack.empty()
and ref_stack.back()
and ref_stack.back()->is_object())
3116 for (
auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
3118 if (it->is_discarded())
3120 ref_stack.back()->erase(it);
3129 bool start_array(std::size_t len)
3131 const bool keep = callback(
static_cast<
int>(ref_stack.size()), parse_event_t::array_start, discarded);
3132 keep_stack.push_back(keep);
3134 auto val = handle_value(BasicJsonType::value_t::array,
true);
3135 ref_stack.push_back(val.second);
3138 if (ref_stack.back()
and JSON_UNLIKELY(len != std::size_t(-1)
and len > ref_stack.back()->max_size()))
3140 JSON_THROW(out_of_range::create(408,
"excessive array size: " + std::to_string(len)));
3150 if (ref_stack.back())
3152 keep = callback(
static_cast<
int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
3156 *ref_stack.back() = discarded;
3160 assert(
not ref_stack.empty());
3161 assert(
not keep_stack.empty());
3162 ref_stack.pop_back();
3163 keep_stack.pop_back();
3166 if (
not keep
and not ref_stack.empty()
and ref_stack.back()->is_array())
3168 ref_stack.back()->m_value.array->pop_back();
3174 bool parse_error(std::size_t ,
const std::string& ,
3175 const detail::exception& ex)
3178 if (allow_exceptions)
3181 switch ((ex.id / 100) % 100)
3184 JSON_THROW(*
static_cast<
const detail::parse_error*>(&ex));
3186 JSON_THROW(*
static_cast<
const detail::out_of_range*>(&ex));
3189 JSON_THROW(*
static_cast<
const detail::invalid_iterator*>(&ex));
3191 JSON_THROW(*
static_cast<
const detail::type_error*>(&ex));
3193 JSON_THROW(*
static_cast<
const detail::other_error*>(&ex));
3202 constexpr bool is_errored()
const 3223 template<
typename Value>
3224 std::pair<
bool, BasicJsonType*> handle_value(Value&& v,
const bool skip_callback =
false)
3226 assert(
not keep_stack.empty());
3230 if (
not keep_stack.back())
3232 return {
false,
nullptr};
3236 auto value = BasicJsonType(std::forward<Value>(v));
3239 const bool keep = skip_callback
or callback(
static_cast<
int>(ref_stack.size()), parse_event_t::value, value);
3244 return {
false,
nullptr};
3247 if (ref_stack.empty())
3249 root = std::move(value);
3250 return {
true, &root};
3255 if (
not ref_stack.back())
3257 return {
false,
nullptr};
3261 assert(ref_stack.back()->is_array()
or ref_stack.back()->is_object());
3264 if (ref_stack.back()->is_array())
3266 ref_stack.back()->m_value.array->push_back(std::move(value));
3267 return {
true, &(ref_stack.back()->m_value.array->back())};
3271 assert(ref_stack.back()->is_object());
3273 assert(
not key_keep_stack.empty());
3274 const bool store_element = key_keep_stack.back();
3275 key_keep_stack.pop_back();
3277 if (
not store_element)
3279 return {
false,
nullptr};
3282 assert(object_element);
3283 *object_element = std::move(value);
3284 return {
true, object_element};
3288 BasicJsonType& root;
3290 std::vector<BasicJsonType*> ref_stack {};
3292 std::vector<
bool> keep_stack {};
3294 std::vector<
bool> key_keep_stack {};
3296 BasicJsonType* object_element =
nullptr;
3298 bool errored =
false;
3300 const parser_callback_t callback =
nullptr;
3302 const bool allow_exceptions =
true;
3304 BasicJsonType discarded = BasicJsonType::value_t::discarded;
3307 template<
typename BasicJsonType>
3308 class json_sax_acceptor
3311 using number_integer_t =
typename BasicJsonType::number_integer_t;
3312 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
3313 using number_float_t =
typename BasicJsonType::number_float_t;
3314 using string_t =
typename BasicJsonType::string_t;
3326 bool number_integer(number_integer_t )
3331 bool number_unsigned(number_unsigned_t )
3336 bool number_float(number_float_t ,
const string_t& )
3341 bool string(string_t& )
3346 bool start_object(std::size_t = std::size_t(-1))
3351 bool key(string_t& )
3361 bool start_array(std::size_t = std::size_t(-1))
3371 bool parse_error(std::size_t ,
const std::string& ,
const detail::exception& )
3398 template <
typename T>
3399 using null_function_t =
decltype(std::declval<T&>().null());
3401 template <
typename T>
3402 using boolean_function_t =
3403 decltype(std::declval<T&>().boolean(std::declval<
bool>()));
3405 template <
typename T,
typename Integer>
3406 using number_integer_function_t =
3407 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
3409 template <
typename T,
typename Unsigned>
3410 using number_unsigned_function_t =
3411 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
3413 template <
typename T,
typename Float,
typename String>
3414 using number_float_function_t =
decltype(std::declval<T&>().number_float(
3415 std::declval<Float>(), std::declval<
const String&>()));
3417 template <
typename T,
typename String>
3418 using string_function_t =
3419 decltype(std::declval<T&>().string(std::declval<String&>()));
3421 template <
typename T>
3422 using start_object_function_t =
3423 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
3425 template <
typename T,
typename String>
3426 using key_function_t =
3427 decltype(std::declval<T&>().key(std::declval<String&>()));
3429 template <
typename T>
3430 using end_object_function_t =
decltype(std::declval<T&>().end_object());
3432 template <
typename T>
3433 using start_array_function_t =
3434 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
3436 template <
typename T>
3437 using end_array_function_t =
decltype(std::declval<T&>().end_array());
3439 template <
typename T,
typename Exception>
3440 using parse_error_function_t =
decltype(std::declval<T&>().parse_error(
3441 std::declval<std::size_t>(), std::declval<
const std::string&>(),
3442 std::declval<
const Exception&>()));
3444 template <
typename SAX,
typename BasicJsonType>
3448 static_assert(is_basic_json<BasicJsonType>::value,
3449 "BasicJsonType must be of type basic_json<...>");
3451 using number_integer_t =
typename BasicJsonType::number_integer_t;
3452 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
3453 using number_float_t =
typename BasicJsonType::number_float_t;
3454 using string_t =
typename BasicJsonType::string_t;
3455 using exception_t =
typename BasicJsonType::exception;
3458 static constexpr bool value =
3459 is_detected_exact<
bool, null_function_t, SAX>::value &&
3460 is_detected_exact<
bool, boolean_function_t, SAX>::value &&
3461 is_detected_exact<
bool, number_integer_function_t, SAX,
3462 number_integer_t>::value &&
3463 is_detected_exact<
bool, number_unsigned_function_t, SAX,
3464 number_unsigned_t>::value &&
3465 is_detected_exact<
bool, number_float_function_t, SAX, number_float_t,
3467 is_detected_exact<
bool, string_function_t, SAX, string_t>::value &&
3468 is_detected_exact<
bool, start_object_function_t, SAX>::value &&
3469 is_detected_exact<
bool, key_function_t, SAX, string_t>::value &&
3470 is_detected_exact<
bool, end_object_function_t, SAX>::value &&
3471 is_detected_exact<
bool, start_array_function_t, SAX>::value &&
3472 is_detected_exact<
bool, end_array_function_t, SAX>::value &&
3473 is_detected_exact<
bool, parse_error_function_t, SAX, exception_t>::value;
3476 template <
typename SAX,
typename BasicJsonType>
3477 struct is_sax_static_asserts
3480 static_assert(is_basic_json<BasicJsonType>::value,
3481 "BasicJsonType must be of type basic_json<...>");
3483 using number_integer_t =
typename BasicJsonType::number_integer_t;
3484 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
3485 using number_float_t =
typename BasicJsonType::number_float_t;
3486 using string_t =
typename BasicJsonType::string_t;
3487 using exception_t =
typename BasicJsonType::exception;
3490 static_assert(is_detected_exact<
bool, null_function_t, SAX>::value,
3491 "Missing/invalid function: bool null()");
3492 static_assert(is_detected_exact<
bool, boolean_function_t, SAX>::value,
3493 "Missing/invalid function: bool boolean(bool)");
3494 static_assert(is_detected_exact<
bool, boolean_function_t, SAX>::value,
3495 "Missing/invalid function: bool boolean(bool)");
3497 is_detected_exact<
bool, number_integer_function_t, SAX,
3498 number_integer_t>::value,
3499 "Missing/invalid function: bool number_integer(number_integer_t)");
3501 is_detected_exact<
bool, number_unsigned_function_t, SAX,
3502 number_unsigned_t>::value,
3503 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
3504 static_assert(is_detected_exact<
bool, number_float_function_t, SAX,
3505 number_float_t, string_t>::value,
3506 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
3508 is_detected_exact<
bool, string_function_t, SAX, string_t>::value,
3509 "Missing/invalid function: bool string(string_t&)");
3510 static_assert(is_detected_exact<
bool, start_object_function_t, SAX>::value,
3511 "Missing/invalid function: bool start_object(std::size_t)");
3512 static_assert(is_detected_exact<
bool, key_function_t, SAX, string_t>::value,
3513 "Missing/invalid function: bool key(string_t&)");
3514 static_assert(is_detected_exact<
bool, end_object_function_t, SAX>::value,
3515 "Missing/invalid function: bool end_object()");
3516 static_assert(is_detected_exact<
bool, start_array_function_t, SAX>::value,
3517 "Missing/invalid function: bool start_array(std::size_t)");
3518 static_assert(is_detected_exact<
bool, end_array_function_t, SAX>::value,
3519 "Missing/invalid function: bool end_array()");
3521 is_detected_exact<
bool, parse_error_function_t, SAX, exception_t>::value,
3522 "Missing/invalid function: bool parse_error(std::size_t, const " 3523 "std::string&, const exception&)");
3542 template<
typename BasicJsonType,
typename SAX = json_sax_dom_parser<BasicJsonType>>
3545 using number_integer_t =
typename BasicJsonType::number_integer_t;
3546 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
3547 using number_float_t =
typename BasicJsonType::number_float_t;
3548 using string_t =
typename BasicJsonType::string_t;
3549 using json_sax_t = SAX;
3557 explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
3559 (
void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
3564 binary_reader(
const binary_reader&) =
delete;
3565 binary_reader(binary_reader&&) =
default;
3566 binary_reader& operator=(
const binary_reader&) =
delete;
3567 binary_reader& operator=(binary_reader&&) =
default;
3568 ~binary_reader() =
default;
3577 bool sax_parse(
const input_format_t format,
3579 const bool strict =
true)
3582 bool result =
false;
3586 case input_format_t::bson:
3587 result = parse_bson_internal();
3590 case input_format_t::cbor:
3591 result = parse_cbor_internal();
3594 case input_format_t::msgpack:
3595 result = parse_msgpack_internal();
3598 case input_format_t::ubjson:
3599 result = parse_ubjson_internal();
3607 if (result
and strict)
3609 if (format == input_format_t::ubjson)
3618 if (
JSON_UNLIKELY(current != std::char_traits<
char>::eof()))
3620 return sax->parse_error(chars_read, get_token_string(),
3621 parse_error::create(110, chars_read, exception_message(format,
"expected end of input; last byte: 0x" + get_token_string(),
"value")));
3635 static constexpr bool little_endianess(
int num = 1)
noexcept 3637 return *
reinterpret_cast<
char*>(&num) == 1;
3649 bool parse_bson_internal()
3651 std::int32_t document_size;
3652 get_number<std::int32_t,
true>(input_format_t::bson, document_size);
3664 return sax->end_object();
3674 bool get_bson_cstr(string_t& result)
3676 auto out = std::back_inserter(result);
3680 if (
JSON_UNLIKELY(
not unexpect_eof(input_format_t::bson,
"cstring")))
3684 if (current == 0x00)
3688 *out++ =
static_cast<
char>(current);
3705 template<
typename NumberType>
3706 bool get_bson_string(
const NumberType len, string_t& result)
3710 auto last_token = get_token_string();
3711 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson,
"string length must be at least 1, is " + std::to_string(len),
"string")));
3714 return get_string(input_format_t::bson, len -
static_cast<NumberType>(1), result)
and get() != std::char_traits<
char>::eof();
3727 bool parse_bson_element_internal(
const int element_type,
3728 const std::size_t element_type_parse_position)
3730 switch (element_type)
3735 return get_number<
double,
true>(input_format_t::bson, number)
and sax->number_float(
static_cast<number_float_t>(number),
"");
3742 return get_number<std::int32_t,
true>(input_format_t::bson, len)
and get_bson_string(len, value)
and sax->string(value);
3747 return parse_bson_internal();
3752 return parse_bson_array();
3757 return sax->boolean(get() != 0);
3768 return get_number<std::int32_t,
true>(input_format_t::bson, value)
and sax->number_integer(value);
3774 return get_number<std::int64_t,
true>(input_format_t::bson, value)
and sax->number_integer(value);
3779 std::array<
char, 3> cr{{}};
3780 (std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<
unsigned char>(element_type));
3781 return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position,
"Unsupported BSON record type 0x" + std::string(cr.data())));
3798 bool parse_bson_element_list(
const bool is_array)
3801 while (
int element_type = get())
3803 if (
JSON_UNLIKELY(
not unexpect_eof(input_format_t::bson,
"element list")))
3808 const std::size_t element_type_parse_position = chars_read;
3814 if (
not is_array
and not sax->key(key))
3819 if (
JSON_UNLIKELY(
not parse_bson_element_internal(element_type, element_type_parse_position)))
3835 bool parse_bson_array()
3837 std::int32_t document_size;
3838 get_number<std::int32_t,
true>(input_format_t::bson, document_size);
3850 return sax->end_array();
3864 bool parse_cbor_internal(
const bool get_char =
true)
3866 switch (get_char ? get() : current)
3869 case std::char_traits<
char>::eof():
3870 return unexpect_eof(input_format_t::cbor,
"value");
3897 return sax->number_unsigned(
static_cast<number_unsigned_t>(current));
3901 std::uint8_t number;
3902 return get_number(input_format_t::cbor, number)
and sax->number_unsigned(number);
3907 std::uint16_t number;
3908 return get_number(input_format_t::cbor, number)
and sax->number_unsigned(number);
3913 std::uint32_t number;
3914 return get_number(input_format_t::cbor, number)
and sax->number_unsigned(number);
3919 std::uint64_t number;
3920 return get_number(input_format_t::cbor, number)
and sax->number_unsigned(number);
3948 return sax->number_integer(
static_cast<std::int8_t>(0x20 - 1 - current));
3952 std::uint8_t number;
3953 return get_number(input_format_t::cbor, number)
and sax->number_integer(
static_cast<number_integer_t>(-1) - number);
3958 std::uint16_t number;
3959 return get_number(input_format_t::cbor, number)
and sax->number_integer(
static_cast<number_integer_t>(-1) - number);
3964 std::uint32_t number;
3965 return get_number(input_format_t::cbor, number)
and sax->number_integer(
static_cast<number_integer_t>(-1) - number);
3970 std::uint64_t number;
3971 return get_number(input_format_t::cbor, number)
and sax->number_integer(
static_cast<number_integer_t>(-1)
3972 -
static_cast<number_integer_t>(number));
4007 return get_cbor_string(s)
and sax->string(s);
4035 return get_cbor_array(
static_cast<std::size_t>(
static_cast<
unsigned int>(current) & 0x1Fu));
4040 return get_number(input_format_t::cbor, len)
and get_cbor_array(
static_cast<std::size_t>(len));
4046 return get_number(input_format_t::cbor, len)
and get_cbor_array(
static_cast<std::size_t>(len));
4052 return get_number(input_format_t::cbor, len)
and get_cbor_array(
static_cast<std::size_t>(len));
4058 return get_number(input_format_t::cbor, len)
and get_cbor_array(
static_cast<std::size_t>(len));
4062 return get_cbor_array(std::size_t(-1));
4089 return get_cbor_object(
static_cast<std::size_t>(
static_cast<
unsigned int>(current) & 0x1Fu));
4094 return get_number(input_format_t::cbor, len)
and get_cbor_object(
static_cast<std::size_t>(len));
4100 return get_number(input_format_t::cbor, len)
and get_cbor_object(
static_cast<std::size_t>(len));
4106 return get_number(input_format_t::cbor, len)
and get_cbor_object(
static_cast<std::size_t>(len));
4112 return get_number(input_format_t::cbor, len)
and get_cbor_object(
static_cast<std::size_t>(len));
4116 return get_cbor_object(std::size_t(-1));
4119 return sax->boolean(
false);
4122 return sax->boolean(
true);
4129 const int byte1_raw = get();
4130 if (
JSON_UNLIKELY(
not unexpect_eof(input_format_t::cbor,
"number")))
4134 const int byte2_raw = get();
4135 if (
JSON_UNLIKELY(
not unexpect_eof(input_format_t::cbor,
"number")))
4140 const auto byte1 =
static_cast<
unsigned char>(byte1_raw);
4141 const auto byte2 =
static_cast<
unsigned char>(byte2_raw);
4151 const auto half =
static_cast<
unsigned int>((byte1 << 8u) + byte2);
4152 const double val = [&half]
4154 const int exp = (half >> 10u) & 0x1Fu;
4155 const unsigned int mant = half & 0x3FFu;
4156 assert(0 <= exp
and exp <= 32);
4157 assert(0 <= mant
and mant <= 1024);
4161 return std::ldexp(mant, -24);
4164 ? std::numeric_limits<
double>::infinity()
4165 : std::numeric_limits<
double>::quiet_NaN();
4167 return std::ldexp(mant + 1024, exp - 25);
4170 return sax->number_float((half & 0x8000u) != 0
4171 ?
static_cast<number_float_t>(-val)
4172 :
static_cast<number_float_t>(val),
"");
4178 return get_number(input_format_t::cbor, number)
and sax->number_float(
static_cast<number_float_t>(number),
"");
4184 return get_number(input_format_t::cbor, number)
and sax->number_float(
static_cast<number_float_t>(number),
"");
4189 auto last_token = get_token_string();
4190 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor,
"invalid byte: 0x" + last_token,
"value")));
4206 bool get_cbor_string(string_t& result)
4208 if (
JSON_UNLIKELY(
not unexpect_eof(input_format_t::cbor,
"string")))
4241 return get_string(input_format_t::cbor,
static_cast<
unsigned int>(current) & 0x1Fu, result);
4247 return get_number(input_format_t::cbor, len)
and get_string(input_format_t::cbor, len, result);
4253 return get_number(input_format_t::cbor, len)
and get_string(input_format_t::cbor, len, result);
4259 return get_number(input_format_t::cbor, len)
and get_string(input_format_t::cbor, len, result);
4265 return get_number(input_format_t::cbor, len)
and get_string(input_format_t::cbor, len, result);
4270 while (get() != 0xFF)
4273 if (
not get_cbor_string(chunk))
4277 result.append(chunk);
4284 auto last_token = get_token_string();
4285 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor,
"expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token,
"string")));
4295 bool get_cbor_array(
const std::size_t len)
4302 if (len != std::size_t(-1))
4304 for (std::size_t i = 0; i < len; ++i)
4314 while (get() != 0xFF)
4323 return sax->end_array();
4331 bool get_cbor_object(
const std::size_t len)
4339 if (len != std::size_t(-1))
4341 for (std::size_t i = 0; i < len; ++i)
4344 if (
JSON_UNLIKELY(
not get_cbor_string(key)
or not sax->key(key)))
4358 while (get() != 0xFF)
4360 if (
JSON_UNLIKELY(
not get_cbor_string(key)
or not sax->key(key)))
4373 return sax->end_object();
4383 bool parse_msgpack_internal()
4388 case std::char_traits<
char>::eof():
4389 return unexpect_eof(input_format_t::msgpack,
"value");
4520 return sax->number_unsigned(
static_cast<number_unsigned_t>(current));
4539 return get_msgpack_object(
static_cast<std::size_t>(
static_cast<
unsigned int>(current) & 0x0Fu));
4558 return get_msgpack_array(
static_cast<std::size_t>(
static_cast<
unsigned int>(current) & 0x0Fu));
4595 return get_msgpack_string(s)
and sax->string(s);
4602 return sax->boolean(
false);
4605 return sax->boolean(
true);
4610 return get_number(input_format_t::msgpack, number)
and sax->number_float(
static_cast<number_float_t>(number),
"");
4616 return get_number(input_format_t::msgpack, number)
and sax->number_float(
static_cast<number_float_t>(number),
"");
4621 std::uint8_t number;
4622 return get_number(input_format_t::msgpack, number)
and sax->number_unsigned(number);
4627 std::uint16_t number;
4628 return get_number(input_format_t::msgpack, number)
and sax->number_unsigned(number);
4633 std::uint32_t number;
4634 return get_number(input_format_t::msgpack, number)
and sax->number_unsigned(number);
4639 std::uint64_t number;
4640 return get_number(input_format_t::msgpack, number)
and sax->number_unsigned(number);
4646 return get_number(input_format_t::msgpack, number)
and sax->number_integer(number);
4651 std::int16_t number;
4652 return get_number(input_format_t::msgpack, number)
and sax->number_integer(number);
4657 std::int32_t number;
4658 return get_number(input_format_t::msgpack, number)
and sax->number_integer(number);
4663 std::int64_t number;
4664 return get_number(input_format_t::msgpack, number)
and sax->number_integer(number);
4672 return get_msgpack_string(s)
and sax->string(s);
4678 return get_number(input_format_t::msgpack, len)
and get_msgpack_array(
static_cast<std::size_t>(len));
4684 return get_number(input_format_t::msgpack, len)
and get_msgpack_array(
static_cast<std::size_t>(len));
4690 return get_number(input_format_t::msgpack, len)
and get_msgpack_object(
static_cast<std::size_t>(len));
4696 return get_number(input_format_t::msgpack, len)
and get_msgpack_object(
static_cast<std::size_t>(len));
4732 return sax->number_integer(
static_cast<std::int8_t>(current));
4736 auto last_token = get_token_string();
4737 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack,
"invalid byte: 0x" + last_token,
"value")));
4752 bool get_msgpack_string(string_t& result)
4754 if (
JSON_UNLIKELY(
not unexpect_eof(input_format_t::msgpack,
"string")))
4795 return get_string(input_format_t::msgpack,
static_cast<
unsigned int>(current) & 0x1Fu, result);
4801 return get_number(input_format_t::msgpack, len)
and get_string(input_format_t::msgpack, len, result);
4807 return get_number(input_format_t::msgpack, len)
and get_string(input_format_t::msgpack, len, result);
4813 return get_number(input_format_t::msgpack, len)
and get_string(input_format_t::msgpack, len, result);
4818 auto last_token = get_token_string();
4819 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack,
"expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token,
"string")));
4828 bool get_msgpack_array(
const std::size_t len)
4835 for (std::size_t i = 0; i < len; ++i)
4843 return sax->end_array();
4850 bool get_msgpack_object(
const std::size_t len)
4858 for (std::size_t i = 0; i < len; ++i)
4861 if (
JSON_UNLIKELY(
not get_msgpack_string(key)
or not sax->key(key)))
4873 return sax->end_object();
4887 bool parse_ubjson_internal(
const bool get_char =
true)
4889 return get_ubjson_value(get_char ? get_ignore_noop() : current);
4906 bool get_ubjson_string(string_t& result,
const bool get_char =
true)
4913 if (
JSON_UNLIKELY(
not unexpect_eof(input_format_t::ubjson,
"value")))
4923 return get_number(input_format_t::ubjson, len)
and get_string(input_format_t::ubjson, len, result);
4929 return get_number(input_format_t::ubjson, len)
and get_string(input_format_t::ubjson, len, result);
4935 return get_number(input_format_t::ubjson, len)
and get_string(input_format_t::ubjson, len, result);
4941 return get_number(input_format_t::ubjson, len)
and get_string(input_format_t::ubjson, len, result);
4947 return get_number(input_format_t::ubjson, len)
and get_string(input_format_t::ubjson, len, result);
4951 auto last_token = get_token_string();
4952 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson,
"expected length type specification (U, i, I, l, L); last byte: 0x" + last_token,
"string")));
4960 bool get_ubjson_size_value(std::size_t& result)
4962 switch (get_ignore_noop())
4966 std::uint8_t number;
4967 if (
JSON_UNLIKELY(
not get_number(input_format_t::ubjson, number)))
4971 result =
static_cast<std::size_t>(number);
4978 if (
JSON_UNLIKELY(
not get_number(input_format_t::ubjson, number)))
4982 result =
static_cast<std::size_t>(number);
4988 std::int16_t number;
4989 if (
JSON_UNLIKELY(
not get_number(input_format_t::ubjson, number)))
4993 result =
static_cast<std::size_t>(number);
4999 std::int32_t number;
5000 if (
JSON_UNLIKELY(
not get_number(input_format_t::ubjson, number)))
5004 result =
static_cast<std::size_t>(number);
5010 std::int64_t number;
5011 if (
JSON_UNLIKELY(
not get_number(input_format_t::ubjson, number)))
5015 result =
static_cast<std::size_t>(number);
5021 auto last_token = get_token_string();
5022 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson,
"expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token,
"size")));
5037 bool get_ubjson_size_type(std::pair<std::size_t,
int>& result)
5039 result.first = string_t::npos;
5046 result.second = get();
5047 if (
JSON_UNLIKELY(
not unexpect_eof(input_format_t::ubjson,
"type")))
5055 if (
JSON_UNLIKELY(
not unexpect_eof(input_format_t::ubjson,
"value")))
5059 auto last_token = get_token_string();
5060 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson,
"expected '#' after type information; last byte: 0x" + last_token,
"size")));
5063 return get_ubjson_size_value(result.first);
5068 return get_ubjson_size_value(result.first);
5078 bool get_ubjson_value(
const int prefix)
5082 case std::char_traits<
char>::eof():
5083 return unexpect_eof(input_format_t::ubjson,
"value");
5086 return sax->boolean(
true);
5088 return sax->boolean(
false);
5095 std::uint8_t number;
5096 return get_number(input_format_t::ubjson, number)
and sax->number_unsigned(number);
5102 return get_number(input_format_t::ubjson, number)
and sax->number_integer(number);
5107 std::int16_t number;
5108 return get_number(input_format_t::ubjson, number)
and sax->number_integer(number);
5113 std::int32_t number;
5114 return get_number(input_format_t::ubjson, number)
and sax->number_integer(number);
5119 std::int64_t number;
5120 return get_number(input_format_t::ubjson, number)
and sax->number_integer(number);
5126 return get_number(input_format_t::ubjson, number)
and sax->number_float(
static_cast<number_float_t>(number),
"");
5132 return get_number(input_format_t::ubjson, number)
and sax->number_float(
static_cast<number_float_t>(number),
"");
5138 if (
JSON_UNLIKELY(
not unexpect_eof(input_format_t::ubjson,
"char")))
5144 auto last_token = get_token_string();
5145 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson,
"byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token,
"char")));
5147 string_t s(1,
static_cast<
char>(current));
5148 return sax->string(s);
5154 return get_ubjson_string(s)
and sax->string(s);
5158 return get_ubjson_array();
5161 return get_ubjson_object();
5165 auto last_token = get_token_string();
5166 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson,
"invalid byte: 0x" + last_token,
"value")));
5174 bool get_ubjson_array()
5176 std::pair<std::size_t,
int> size_and_type;
5182 if (size_and_type.first != string_t::npos)
5184 if (
JSON_UNLIKELY(
not sax->start_array(size_and_type.first)))
5189 if (size_and_type.second != 0)
5191 if (size_and_type.second !=
'N')
5193 for (std::size_t i = 0; i < size_and_type.first; ++i)
5195 if (
JSON_UNLIKELY(
not get_ubjson_value(size_and_type.second)))
5204 for (std::size_t i = 0; i < size_and_type.first; ++i)
5220 while (current !=
']')
5230 return sax->end_array();
5236 bool get_ubjson_object()
5238 std::pair<std::size_t,
int> size_and_type;
5245 if (size_and_type.first != string_t::npos)
5247 if (
JSON_UNLIKELY(
not sax->start_object(size_and_type.first)))
5252 if (size_and_type.second != 0)
5254 for (std::size_t i = 0; i < size_and_type.first; ++i)
5256 if (
JSON_UNLIKELY(
not get_ubjson_string(key)
or not sax->key(key)))
5260 if (
JSON_UNLIKELY(
not get_ubjson_value(size_and_type.second)))
5269 for (std::size_t i = 0; i < size_and_type.first; ++i)
5271 if (
JSON_UNLIKELY(
not get_ubjson_string(key)
or not sax->key(key)))
5290 while (current !=
'}')
5292 if (
JSON_UNLIKELY(
not get_ubjson_string(key,
false)
or not sax->key(key)))
5305 return sax->end_object();
5324 return current = ia->get_character();
5330 int get_ignore_noop()
5336 while (current ==
'N');
5354 template<
typename NumberType,
bool InputIsLittleEndian =
false>
5355 bool get_number(
const input_format_t format, NumberType& result)
5358 std::array<std::uint8_t,
sizeof(NumberType)> vec;
5359 for (std::size_t i = 0; i <
sizeof(NumberType); ++i)
5368 if (is_little_endian != InputIsLittleEndian)
5370 vec[
sizeof(NumberType) - i - 1] =
static_cast<std::uint8_t>(current);
5374 vec[i] =
static_cast<std::uint8_t>(current);
5379 std::memcpy(&result, vec.data(),
sizeof(NumberType));
5397 template<
typename NumberType>
5398 bool get_string(
const input_format_t format,
5399 const NumberType len,
5402 bool success =
true;
5403 std::generate_n(std::back_inserter(result), len, [
this, &success, &format]()
5410 return static_cast<
char>(current);
5420 bool unexpect_eof(
const input_format_t format,
const char* context)
const 5422 if (
JSON_UNLIKELY(current == std::char_traits<
char>::eof()))
5424 return sax->parse_error(chars_read,
"<end of file>",
5425 parse_error::create(110, chars_read, exception_message(format,
"unexpected end of input", context)));
5433 std::string get_token_string()
const 5435 std::array<
char, 3> cr{{}};
5436 (std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<
unsigned char>(current));
5437 return std::string{cr.data()};
5446 std::string exception_message(
const input_format_t format,
5447 const std::string& detail,
5448 const std::string& context)
const 5450 std::string error_msg =
"syntax error while parsing ";
5454 case input_format_t::cbor:
5455 error_msg +=
"CBOR";
5458 case input_format_t::msgpack:
5459 error_msg +=
"MessagePack";
5462 case input_format_t::ubjson:
5463 error_msg +=
"UBJSON";
5466 case input_format_t::bson:
5467 error_msg +=
"BSON";
5474 return error_msg +
" " + context +
": " + detail;
5479 input_adapter_t ia =
nullptr;
5482 int current = std::char_traits<
char>::eof();
5485 std::size_t chars_read = 0;
5488 const bool is_little_endian = little_endianess();
5491 json_sax_t* sax =
nullptr;
5506 #include <initializer_list> 5531 template<
typename BasicJsonType>
5534 using number_integer_t =
typename BasicJsonType::number_integer_t;
5535 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
5536 using number_float_t =
typename BasicJsonType::number_float_t;
5537 using string_t =
typename BasicJsonType::string_t;
5541 enum class token_type
5563 static const char* token_type_name(
const token_type t)
noexcept 5567 case token_type::uninitialized:
5568 return "<uninitialized>";
5569 case token_type::literal_true:
5570 return "true literal";
5571 case token_type::literal_false:
5572 return "false literal";
5573 case token_type::literal_null:
5574 return "null literal";
5575 case token_type::value_string:
5576 return "string literal";
5577 case lexer::token_type::value_unsigned:
5578 case lexer::token_type::value_integer:
5579 case lexer::token_type::value_float:
5580 return "number literal";
5581 case token_type::begin_array:
5583 case token_type::begin_object:
5585 case token_type::end_array:
5587 case token_type::end_object:
5589 case token_type::name_separator:
5591 case token_type::value_separator:
5593 case token_type::parse_error:
5594 return "<parse error>";
5595 case token_type::end_of_input:
5596 return "end of input";
5597 case token_type::literal_or_value:
5598 return "'[', '{', or a literal";
5601 return "unknown token";
5606 explicit lexer(detail::input_adapter_t&& adapter)
5607 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
5610 lexer(
const lexer&) =
delete;
5611 lexer(lexer&&) =
delete;
5612 lexer& operator=(lexer&) =
delete;
5613 lexer& operator=(lexer&&) =
delete;
5622 static char get_decimal_point()
noexcept 5624 const auto loc = localeconv();
5625 assert(loc !=
nullptr);
5626 return (loc->decimal_point ==
nullptr) ?
'.' : *(loc->decimal_point);
5651 assert(current ==
'u');
5654 const auto factors = { 12u, 8u, 4u, 0u };
5655 for (
const auto factor : factors)
5659 if (current >=
'0' and current <=
'9')
5661 codepoint +=
static_cast<
int>((
static_cast<
unsigned int>(current) - 0x30u) << factor);
5663 else if (current >=
'A' and current <=
'F')
5665 codepoint +=
static_cast<
int>((
static_cast<
unsigned int>(current) - 0x37u) << factor);
5667 else if (current >=
'a' and current <=
'f')
5669 codepoint +=
static_cast<
int>((
static_cast<
unsigned int>(current) - 0x57u) << factor);
5677 assert(0x0000 <= codepoint
and codepoint <= 0xFFFF);
5696 bool next_byte_in_range(std::initializer_list<
int> ranges)
5698 assert(ranges.size() == 2
or ranges.size() == 4
or ranges.size() == 6);
5701 for (
auto range = ranges.begin(); range != ranges.end(); ++range)
5704 if (
JSON_LIKELY(*range <= current
and current <= *(++range)))
5710 error_message =
"invalid string: ill-formed UTF-8 byte";
5733 token_type scan_string()
5739 assert(current ==
'\"');
5747 case std::char_traits<
char>::eof():
5749 error_message =
"invalid string: missing closing quote";
5750 return token_type::parse_error;
5756 return token_type::value_string;
5800 const int codepoint1 = get_codepoint();
5801 int codepoint = codepoint1;
5805 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
5806 return token_type::parse_error;
5810 if (0xD800 <= codepoint1
and codepoint1 <= 0xDBFF)
5815 const int codepoint2 = get_codepoint();
5819 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
5820 return token_type::parse_error;
5824 if (
JSON_LIKELY(0xDC00 <= codepoint2
and codepoint2 <= 0xDFFF))
5827 codepoint =
static_cast<
int>(
5829 (
static_cast<
unsigned int>(codepoint1) << 10u)
5831 +
static_cast<
unsigned int>(codepoint2)
5839 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
5840 return token_type::parse_error;
5845 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
5846 return token_type::parse_error;
5851 if (
JSON_UNLIKELY(0xDC00 <= codepoint1
and codepoint1 <= 0xDFFF))
5853 error_message =
"invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
5854 return token_type::parse_error;
5859 assert(0x00 <= codepoint
and codepoint <= 0x10FFFF);
5862 if (codepoint < 0x80)
5867 else if (codepoint <= 0x7FF)
5870 add(
static_cast<
int>(0xC0u | (
static_cast<
unsigned int>(codepoint) >> 6u)));
5871 add(
static_cast<
int>(0x80u | (
static_cast<
unsigned int>(codepoint) & 0x3Fu)));
5873 else if (codepoint <= 0xFFFF)
5876 add(
static_cast<
int>(0xE0u | (
static_cast<
unsigned int>(codepoint) >> 12u)));
5877 add(
static_cast<
int>(0x80u | ((
static_cast<
unsigned int>(codepoint) >> 6u) & 0x3Fu)));
5878 add(
static_cast<
int>(0x80u | (
static_cast<
unsigned int>(codepoint) & 0x3Fu)));
5883 add(
static_cast<
int>(0xF0u | (
static_cast<
unsigned int>(codepoint) >> 18u)));
5884 add(
static_cast<
int>(0x80u | ((
static_cast<
unsigned int>(codepoint) >> 12u) & 0x3Fu)));
5885 add(
static_cast<
int>(0x80u | ((
static_cast<
unsigned int>(codepoint) >> 6u) & 0x3Fu)));
5886 add(
static_cast<
int>(0x80u | (
static_cast<
unsigned int>(codepoint) & 0x3Fu)));
5894 error_message =
"invalid string: forbidden character after backslash";
5895 return token_type::parse_error;
5904 error_message =
"invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
5905 return token_type::parse_error;
5910 error_message =
"invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
5911 return token_type::parse_error;
5916 error_message =
"invalid string: control character U+0002 (STX) must be escaped to \\u0002";
5917 return token_type::parse_error;
5922 error_message =
"invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
5923 return token_type::parse_error;
5928 error_message =
"invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
5929 return token_type::parse_error;
5934 error_message =
"invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
5935 return token_type::parse_error;
5940 error_message =
"invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
5941 return token_type::parse_error;
5946 error_message =
"invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
5947 return token_type::parse_error;
5952 error_message =
"invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
5953 return token_type::parse_error;
5958 error_message =
"invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
5959 return token_type::parse_error;
5964 error_message =
"invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
5965 return token_type::parse_error;
5970 error_message =
"invalid string: control character U+000B (VT) must be escaped to \\u000B";
5971 return token_type::parse_error;
5976 error_message =
"invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
5977 return token_type::parse_error;
5982 error_message =
"invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
5983 return token_type::parse_error;
5988 error_message =
"invalid string: control character U+000E (SO) must be escaped to \\u000E";
5989 return token_type::parse_error;
5994 error_message =
"invalid string: control character U+000F (SI) must be escaped to \\u000F";
5995 return token_type::parse_error;
6000 error_message =
"invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
6001 return token_type::parse_error;
6006 error_message =
"invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
6007 return token_type::parse_error;
6012 error_message =
"invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
6013 return token_type::parse_error;
6018 error_message =
"invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
6019 return token_type::parse_error;
6024 error_message =
"invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
6025 return token_type::parse_error;
6030 error_message =
"invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
6031 return token_type::parse_error;
6036 error_message =
"invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
6037 return token_type::parse_error;
6042 error_message =
"invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
6043 return token_type::parse_error;
6048 error_message =
"invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
6049 return token_type::parse_error;
6054 error_message =
"invalid string: control character U+0019 (EM) must be escaped to \\u0019";
6055 return token_type::parse_error;
6060 error_message =
"invalid string: control character U+001A (SUB) must be escaped to \\u001A";
6061 return token_type::parse_error;
6066 error_message =
"invalid string: control character U+001B (ESC) must be escaped to \\u001B";
6067 return token_type::parse_error;
6072 error_message =
"invalid string: control character U+001C (FS) must be escaped to \\u001C";
6073 return token_type::parse_error;
6078 error_message =
"invalid string: control character U+001D (GS) must be escaped to \\u001D";
6079 return token_type::parse_error;
6084 error_message =
"invalid string: control character U+001E (RS) must be escaped to \\u001E";
6085 return token_type::parse_error;
6090 error_message =
"invalid string: control character U+001F (US) must be escaped to \\u001F";
6091 return token_type::parse_error;
6228 return token_type::parse_error;
6236 if (
JSON_UNLIKELY(
not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
6238 return token_type::parse_error;
6260 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
6262 return token_type::parse_error;
6270 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
6272 return token_type::parse_error;
6280 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6282 return token_type::parse_error;
6292 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6294 return token_type::parse_error;
6302 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
6304 return token_type::parse_error;
6312 error_message =
"invalid string: ill-formed UTF-8 byte";
6313 return token_type::parse_error;
6319 static void strtof(
float& f,
const char* str,
char** endptr)
noexcept 6321 f = std::strtof(str, endptr);
6324 static void strtof(
double& f,
const char* str,
char** endptr)
noexcept 6326 f = std::strtod(str, endptr);
6329 static void strtof(
long double& f,
const char* str,
char** endptr)
noexcept 6331 f = std::strtold(str, endptr);
6374 token_type scan_number()
6381 token_type number_type = token_type::value_unsigned;
6389 goto scan_number_minus;
6395 goto scan_number_zero;
6409 goto scan_number_any1;
6419 number_type = token_type::value_integer;
6425 goto scan_number_zero;
6439 goto scan_number_any1;
6444 error_message =
"invalid number; expected digit after '-'";
6445 return token_type::parse_error;
6455 add(decimal_point_char);
6456 goto scan_number_decimal1;
6463 goto scan_number_exponent;
6467 goto scan_number_done;
6486 goto scan_number_any1;
6491 add(decimal_point_char);
6492 goto scan_number_decimal1;
6499 goto scan_number_exponent;
6503 goto scan_number_done;
6506 scan_number_decimal1:
6508 number_type = token_type::value_float;
6523 goto scan_number_decimal2;
6528 error_message =
"invalid number; expected digit after '.'";
6529 return token_type::parse_error;
6533 scan_number_decimal2:
6549 goto scan_number_decimal2;
6556 goto scan_number_exponent;
6560 goto scan_number_done;
6563 scan_number_exponent:
6565 number_type = token_type::value_float;
6572 goto scan_number_sign;
6587 goto scan_number_any2;
6593 "invalid number; expected '+', '-', or digit after exponent";
6594 return token_type::parse_error;
6614 goto scan_number_any2;
6619 error_message =
"invalid number; expected digit after exponent sign";
6620 return token_type::parse_error;
6640 goto scan_number_any2;
6644 goto scan_number_done;
6652 char* endptr =
nullptr;
6656 if (number_type == token_type::value_unsigned)
6658 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
6661 assert(endptr == token_buffer.data() + token_buffer.size());
6665 value_unsigned =
static_cast<number_unsigned_t>(x);
6666 if (value_unsigned == x)
6668 return token_type::value_unsigned;
6672 else if (number_type == token_type::value_integer)
6674 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
6677 assert(endptr == token_buffer.data() + token_buffer.size());
6681 value_integer =
static_cast<number_integer_t>(x);
6682 if (value_integer == x)
6684 return token_type::value_integer;
6691 strtof(value_float, token_buffer.data(), &endptr);
6694 assert(endptr == token_buffer.data() + token_buffer.size());
6696 return token_type::value_float;
6704 token_type scan_literal(
const char* literal_text,
const std::size_t length,
6705 token_type return_type)
6707 assert(current == literal_text[0]);
6708 for (std::size_t i = 1; i < length; ++i)
6712 error_message =
"invalid literal";
6713 return token_type::parse_error;
6724 void reset()
noexcept 6726 token_buffer.clear();
6727 token_string.clear();
6728 token_string.push_back(std::char_traits<
char>::to_char_type(current));
6741 std::char_traits<
char>::int_type get()
6743 ++position.chars_read_total;
6744 ++position.chars_read_current_line;
6753 current = ia->get_character();
6756 if (
JSON_LIKELY(current != std::char_traits<
char>::eof()))
6758 token_string.push_back(std::char_traits<
char>::to_char_type(current));
6761 if (current ==
'\n')
6763 ++position.lines_read;
6764 position.chars_read_current_line = 0;
6782 --position.chars_read_total;
6785 if (position.chars_read_current_line == 0)
6787 if (position.lines_read > 0)
6789 --position.lines_read;
6794 --position.chars_read_current_line;
6797 if (
JSON_LIKELY(current != std::char_traits<
char>::eof()))
6799 assert(
not token_string.empty());
6800 token_string.pop_back();
6807 token_buffer.push_back(std::char_traits<
char>::to_char_type(c));
6816 constexpr number_integer_t get_number_integer()
const noexcept 6818 return value_integer;
6822 constexpr number_unsigned_t get_number_unsigned()
const noexcept 6824 return value_unsigned;
6828 constexpr number_float_t get_number_float()
const noexcept 6834 string_t& get_string()
6836 return token_buffer;
6844 constexpr position_t get_position()
const noexcept 6852 std::string get_token_string()
const 6856 for (
const auto c : token_string)
6858 if (
'\x00' <= c
and c <=
'\x1F')
6861 std::array<
char, 9> cs{{}};
6862 (std::snprintf)(cs.data(), cs.size(),
"<U+%.4X>",
static_cast<
unsigned char>(c));
6863 result += cs.data();
6868 result.push_back(c);
6876 constexpr const char* get_error_message()
const noexcept 6878 return error_message;
6894 return get() == 0xBB
and get() == 0xBF;
6906 if (position.chars_read_total == 0
and not skip_bom())
6908 error_message =
"invalid BOM; must be 0xEF 0xBB 0xBF if given";
6909 return token_type::parse_error;
6917 while (current ==
' ' or current ==
'\t' or current ==
'\n' or current ==
'\r');
6923 return token_type::begin_array;
6925 return token_type::end_array;
6927 return token_type::begin_object;
6929 return token_type::end_object;
6931 return token_type::name_separator;
6933 return token_type::value_separator;
6937 return scan_literal(
"true", 4, token_type::literal_true);
6939 return scan_literal(
"false", 5, token_type::literal_false);
6941 return scan_literal(
"null", 4, token_type::literal_null);
6945 return scan_string();
6959 return scan_number();
6964 case std::char_traits<
char>::eof():
6965 return token_type::end_of_input;
6969 error_message =
"invalid literal";
6970 return token_type::parse_error;
6976 detail::input_adapter_t ia =
nullptr;
6979 std::char_traits<
char>::int_type current = std::char_traits<
char>::eof();
6982 bool next_unget =
false;
6985 position_t position {};
6988 std::vector<
char> token_string {};
6991 string_t token_buffer {};
6994 const char* error_message =
"";
6997 number_integer_t value_integer = 0;
6998 number_unsigned_t value_unsigned = 0;
6999 number_float_t value_float = 0;
7002 const char decimal_point_char =
'.';
7013 #include <functional> 7046 template<
typename BasicJsonType>
7049 using number_integer_t =
typename BasicJsonType::number_integer_t;
7050 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
7051 using number_float_t =
typename BasicJsonType::number_float_t;
7052 using string_t =
typename BasicJsonType::string_t;
7053 using lexer_t = lexer<BasicJsonType>;
7054 using token_type =
typename lexer_t::token_type;
7057 enum class parse_event_t : uint8_t
7073 using parser_callback_t =
7074 std::function<
bool(
int depth, parse_event_t event, BasicJsonType& parsed)>;
7077 explicit parser(detail::input_adapter_t&& adapter,
7078 const parser_callback_t cb =
nullptr,
7079 const bool allow_exceptions_ =
true)
7080 : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
7096 void parse(
const bool strict, BasicJsonType& result)
7100 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
7101 sax_parse_internal(&sdp);
7102 result.assert_invariant();
7105 if (strict
and (get_token() != token_type::end_of_input))
7107 sdp.parse_error(m_lexer.get_position(),
7108 m_lexer.get_token_string(),
7109 parse_error::create(101, m_lexer.get_position(),
7110 exception_message(token_type::end_of_input,
"value")));
7114 if (sdp.is_errored())
7116 result = value_t::discarded;
7122 if (result.is_discarded())
7129 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
7130 sax_parse_internal(&sdp);
7131 result.assert_invariant();
7134 if (strict
and (get_token() != token_type::end_of_input))
7136 sdp.parse_error(m_lexer.get_position(),
7137 m_lexer.get_token_string(),
7138 parse_error::create(101, m_lexer.get_position(),
7139 exception_message(token_type::end_of_input,
"value")));
7143 if (sdp.is_errored())
7145 result = value_t::discarded;
7157 bool accept(
const bool strict =
true)
7159 json_sax_acceptor<BasicJsonType> sax_acceptor;
7160 return sax_parse(&sax_acceptor, strict);
7163 template <
typename SAX>
7164 bool sax_parse(SAX* sax,
const bool strict =
true)
7166 (
void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
7167 const bool result = sax_parse_internal(sax);
7170 if (result
and strict
and (get_token() != token_type::end_of_input))
7172 return sax->parse_error(m_lexer.get_position(),
7173 m_lexer.get_token_string(),
7174 parse_error::create(101, m_lexer.get_position(),
7175 exception_message(token_type::end_of_input,
"value")));
7182 template <
typename SAX>
7183 bool sax_parse_internal(SAX* sax)
7187 std::vector<
bool> states;
7189 bool skip_to_state_evaluation =
false;
7193 if (
not skip_to_state_evaluation)
7198 case token_type::begin_object:
7206 if (get_token() == token_type::end_object)
7218 return sax->parse_error(m_lexer.get_position(),
7219 m_lexer.get_token_string(),
7220 parse_error::create(101, m_lexer.get_position(),
7221 exception_message(token_type::value_string,
"object key")));
7229 if (
JSON_UNLIKELY(get_token() != token_type::name_separator))
7231 return sax->parse_error(m_lexer.get_position(),
7232 m_lexer.get_token_string(),
7233 parse_error::create(101, m_lexer.get_position(),
7234 exception_message(token_type::name_separator,
"object separator")));
7238 states.push_back(
false);
7245 case token_type::begin_array:
7253 if (get_token() == token_type::end_array)
7263 states.push_back(
true);
7269 case token_type::value_float:
7271 const auto res = m_lexer.get_number_float();
7275 return sax->parse_error(m_lexer.get_position(),
7276 m_lexer.get_token_string(),
7277 out_of_range::create(406,
"number overflow parsing '" + m_lexer.get_token_string() +
"'"));
7280 if (
JSON_UNLIKELY(
not sax->number_float(res, m_lexer.get_string())))
7288 case token_type::literal_false:
7297 case token_type::literal_null:
7306 case token_type::literal_true:
7315 case token_type::value_integer:
7317 if (
JSON_UNLIKELY(
not sax->number_integer(m_lexer.get_number_integer())))
7324 case token_type::value_string:
7333 case token_type::value_unsigned:
7335 if (
JSON_UNLIKELY(
not sax->number_unsigned(m_lexer.get_number_unsigned())))
7342 case token_type::parse_error:
7345 return sax->parse_error(m_lexer.get_position(),
7346 m_lexer.get_token_string(),
7347 parse_error::create(101, m_lexer.get_position(),
7348 exception_message(token_type::uninitialized,
"value")));
7353 return sax->parse_error(m_lexer.get_position(),
7354 m_lexer.get_token_string(),
7355 parse_error::create(101, m_lexer.get_position(),
7356 exception_message(token_type::literal_or_value,
"value")));
7362 skip_to_state_evaluation =
false;
7375 if (get_token() == token_type::value_separator)
7383 if (
JSON_LIKELY(last_token == token_type::end_array))
7394 assert(
not states.empty());
7396 skip_to_state_evaluation =
true;
7400 return sax->parse_error(m_lexer.get_position(),
7401 m_lexer.get_token_string(),
7402 parse_error::create(101, m_lexer.get_position(),
7403 exception_message(token_type::end_array,
"array")));
7408 if (get_token() == token_type::value_separator)
7413 return sax->parse_error(m_lexer.get_position(),
7414 m_lexer.get_token_string(),
7415 parse_error::create(101, m_lexer.get_position(),
7416 exception_message(token_type::value_string,
"object key")));
7425 if (
JSON_UNLIKELY(get_token() != token_type::name_separator))
7427 return sax->parse_error(m_lexer.get_position(),
7428 m_lexer.get_token_string(),
7429 parse_error::create(101, m_lexer.get_position(),
7430 exception_message(token_type::name_separator,
"object separator")));
7439 if (
JSON_LIKELY(last_token == token_type::end_object))
7450 assert(
not states.empty());
7452 skip_to_state_evaluation =
true;
7456 return sax->parse_error(m_lexer.get_position(),
7457 m_lexer.get_token_string(),
7458 parse_error::create(101, m_lexer.get_position(),
7459 exception_message(token_type::end_object,
"object")));
7465 token_type get_token()
7467 return last_token = m_lexer.scan();
7470 std::string exception_message(
const token_type expected,
const std::string& context)
7472 std::string error_msg =
"syntax error ";
7474 if (
not context.empty())
7476 error_msg +=
"while parsing " + context +
" ";
7481 if (last_token == token_type::parse_error)
7483 error_msg += std::string(m_lexer.get_error_message()) +
"; last read: '" +
7484 m_lexer.get_token_string() +
"'";
7488 error_msg +=
"unexpected " + std::string(lexer_t::token_type_name(last_token));
7491 if (expected != token_type::uninitialized)
7493 error_msg +=
"; expected " + std::string(lexer_t::token_type_name(expected));
7501 const parser_callback_t callback =
nullptr;
7503 token_type last_token = token_type::uninitialized;
7507 const bool allow_exceptions =
true;
7534 class primitive_iterator_t
7537 using difference_type = std::ptrdiff_t;
7538 static constexpr difference_type begin_value = 0;
7539 static constexpr difference_type end_value = begin_value + 1;
7542 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
7545 constexpr difference_type get_value()
const noexcept 7551 void set_begin()
noexcept 7557 void set_end()
noexcept 7563 constexpr bool is_begin()
const noexcept 7565 return m_it == begin_value;
7569 constexpr bool is_end()
const noexcept 7571 return m_it == end_value;
7574 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs)
noexcept 7576 return lhs.m_it == rhs.m_it;
7579 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs)
noexcept 7581 return lhs.m_it < rhs.m_it;
7584 primitive_iterator_t operator+(difference_type n)
noexcept 7586 auto result = *
this;
7591 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs)
noexcept 7593 return lhs.m_it - rhs.m_it;
7596 primitive_iterator_t& operator++()
noexcept 7602 primitive_iterator_t
const operator++(
int)
noexcept 7604 auto result = *
this;
7609 primitive_iterator_t& operator--()
noexcept 7615 primitive_iterator_t
const operator--(
int)
noexcept 7617 auto result = *
this;
7622 primitive_iterator_t& operator+=(difference_type n)
noexcept 7628 primitive_iterator_t& operator-=(difference_type n)
noexcept 7648 template<
typename BasicJsonType>
struct internal_iterator
7651 typename BasicJsonType::object_t::iterator object_iterator {};
7653 typename BasicJsonType::array_t::iterator array_iterator {};
7655 primitive_iterator_t primitive_iterator {};
7665 #include <type_traits> 7687 template<
typename IteratorType>
class iteration_proxy;
7688 template<
typename IteratorType>
class iteration_proxy_value;
7706 template<
typename BasicJsonType>
7710 friend iter_impl<
typename std::conditional<std::is_const<BasicJsonType>::value,
typename std::remove_const<BasicJsonType>::type,
const BasicJsonType>::type>;
7711 friend BasicJsonType;
7712 friend iteration_proxy<iter_impl>;
7713 friend iteration_proxy_value<iter_impl>;
7715 using object_t =
typename BasicJsonType::object_t;
7716 using array_t =
typename BasicJsonType::array_t;
7718 static_assert(is_basic_json<
typename std::remove_const<BasicJsonType>::type>::value,
7719 "iter_impl only accepts (const) basic_json");
7728 using iterator_category = std::bidirectional_iterator_tag;
7731 using value_type =
typename BasicJsonType::value_type;
7733 using difference_type =
typename BasicJsonType::difference_type;
7735 using pointer =
typename std::conditional<std::is_const<BasicJsonType>::value,
7736 typename BasicJsonType::const_pointer,
7737 typename BasicJsonType::pointer>::type;
7740 typename std::conditional<std::is_const<BasicJsonType>::value,
7741 typename BasicJsonType::const_reference,
7742 typename BasicJsonType::reference>::type;
7745 iter_impl() =
default;
7753 explicit iter_impl(pointer object)
noexcept : m_object(object)
7755 assert(m_object !=
nullptr);
7757 switch (m_object->m_type)
7759 case value_t::object:
7761 m_it.object_iterator =
typename object_t::iterator();
7765 case value_t::array:
7767 m_it.array_iterator =
typename array_t::iterator();
7773 m_it.primitive_iterator = primitive_iterator_t();
7793 iter_impl(
const iter_impl<
typename std::remove_const<BasicJsonType>::type>& other)
noexcept 7794 : m_object(other.m_object), m_it(other.m_it) {}
7802 iter_impl& operator=(
const iter_impl<
typename std::remove_const<BasicJsonType>::type>& other)
noexcept 7804 m_object = other.m_object;
7814 void set_begin()
noexcept 7816 assert(m_object !=
nullptr);
7818 switch (m_object->m_type)
7820 case value_t::object:
7822 m_it.object_iterator = m_object->m_value.object->begin();
7826 case value_t::array:
7828 m_it.array_iterator = m_object->m_value.array->begin();
7835 m_it.primitive_iterator.set_end();
7841 m_it.primitive_iterator.set_begin();
7851 void set_end()
noexcept 7853 assert(m_object !=
nullptr);
7855 switch (m_object->m_type)
7857 case value_t::object:
7859 m_it.object_iterator = m_object->m_value.object->end();
7863 case value_t::array:
7865 m_it.array_iterator = m_object->m_value.array->end();
7871 m_it.primitive_iterator.set_end();
7882 reference operator*()
const 7884 assert(m_object !=
nullptr);
7886 switch (m_object->m_type)
7888 case value_t::object:
7890 assert(m_it.object_iterator != m_object->m_value.object->end());
7891 return m_it.object_iterator->second;
7894 case value_t::array:
7896 assert(m_it.array_iterator != m_object->m_value.array->end());
7897 return *m_it.array_iterator;
7901 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
7905 if (
JSON_LIKELY(m_it.primitive_iterator.is_begin()))
7910 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
7919 pointer operator->()
const 7921 assert(m_object !=
nullptr);
7923 switch (m_object->m_type)
7925 case value_t::object:
7927 assert(m_it.object_iterator != m_object->m_value.object->end());
7928 return &(m_it.object_iterator->second);
7931 case value_t::array:
7933 assert(m_it.array_iterator != m_object->m_value.array->end());
7934 return &*m_it.array_iterator;
7939 if (
JSON_LIKELY(m_it.primitive_iterator.is_begin()))
7944 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
7953 iter_impl
const operator++(
int)
7955 auto result = *
this;
7964 iter_impl& operator++()
7966 assert(m_object !=
nullptr);
7968 switch (m_object->m_type)
7970 case value_t::object:
7972 std::advance(m_it.object_iterator, 1);
7976 case value_t::array:
7978 std::advance(m_it.array_iterator, 1);
7984 ++m_it.primitive_iterator;
7996 iter_impl
const operator--(
int)
7998 auto result = *
this;
8007 iter_impl& operator--()
8009 assert(m_object !=
nullptr);
8011 switch (m_object->m_type)
8013 case value_t::object:
8015 std::advance(m_it.object_iterator, -1);
8019 case value_t::array:
8021 std::advance(m_it.array_iterator, -1);
8027 --m_it.primitive_iterator;
8039 bool operator==(
const iter_impl& other)
const 8044 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
8047 assert(m_object !=
nullptr);
8049 switch (m_object->m_type)
8051 case value_t::object:
8052 return (m_it.object_iterator == other.m_it.object_iterator);
8054 case value_t::array:
8055 return (m_it.array_iterator == other.m_it.array_iterator);
8058 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
8066 bool operator!=(
const iter_impl& other)
const 8068 return not operator==(other);
8075 bool operator<(
const iter_impl& other)
const 8080 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
8083 assert(m_object !=
nullptr);
8085 switch (m_object->m_type)
8087 case value_t::object:
8088 JSON_THROW(invalid_iterator::create(213,
"cannot compare order of object iterators"));
8090 case value_t::array:
8091 return (m_it.array_iterator < other.m_it.array_iterator);
8094 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
8102 bool operator<=(
const iter_impl& other)
const 8104 return not other.operator < (*
this);
8111 bool operator>(
const iter_impl& other)
const 8113 return not operator<=(other);
8120 bool operator>=(
const iter_impl& other)
const 8122 return not operator<(other);
8129 iter_impl& operator+=(difference_type i)
8131 assert(m_object !=
nullptr);
8133 switch (m_object->m_type)
8135 case value_t::object:
8136 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
8138 case value_t::array:
8140 std::advance(m_it.array_iterator, i);
8146 m_it.primitive_iterator += i;
8158 iter_impl& operator-=(difference_type i)
8160 return operator+=(-i);
8167 iter_impl operator+(difference_type i)
const 8169 auto result = *
this;
8178 friend iter_impl operator+(difference_type i,
const iter_impl& it)
8189 iter_impl operator-(difference_type i)
const 8191 auto result = *
this;
8200 difference_type operator-(
const iter_impl& other)
const 8202 assert(m_object !=
nullptr);
8204 switch (m_object->m_type)
8206 case value_t::object:
8207 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
8209 case value_t::array:
8210 return m_it.array_iterator - other.m_it.array_iterator;
8213 return m_it.primitive_iterator - other.m_it.primitive_iterator;
8221 reference operator[](difference_type n)
const 8223 assert(m_object !=
nullptr);
8225 switch (m_object->m_type)
8227 case value_t::object:
8228 JSON_THROW(invalid_iterator::create(208,
"cannot use operator[] for object iterators"));
8230 case value_t::array:
8231 return *std::next(m_it.array_iterator, n);
8234 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
8238 if (
JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
8243 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
8252 const typename object_t::key_type& key()
const 8254 assert(m_object !=
nullptr);
8258 return m_it.object_iterator->first;
8261 JSON_THROW(invalid_iterator::create(207,
"cannot use key() for non-object iterators"));
8268 reference value()
const 8275 pointer m_object =
nullptr;
8277 internal_iterator<
typename std::remove_const<BasicJsonType>::type> m_it {};
8317 template<
typename Base>
8318 class json_reverse_iterator :
public std::reverse_iterator<Base>
8321 using difference_type = std::ptrdiff_t;
8323 using base_iterator = std::reverse_iterator<Base>;
8325 using reference =
typename Base::reference;
8328 explicit json_reverse_iterator(
const typename base_iterator::iterator_type& it)
noexcept 8329 : base_iterator(it) {}
8332 explicit json_reverse_iterator(
const base_iterator& it)
noexcept : base_iterator(it) {}
8335 json_reverse_iterator
const operator++(
int)
8337 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
8341 json_reverse_iterator& operator++()
8343 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
8347 json_reverse_iterator
const operator--(
int)
8349 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
8353 json_reverse_iterator& operator--()
8355 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
8359 json_reverse_iterator& operator+=(difference_type i)
8361 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
8365 json_reverse_iterator operator+(difference_type i)
const 8367 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
8371 json_reverse_iterator operator-(difference_type i)
const 8373 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
8377 difference_type operator-(
const json_reverse_iterator& other)
const 8379 return base_iterator(*
this) - base_iterator(other);
8383 reference operator[](difference_type n)
const 8385 return *(
this->operator+(n));
8389 auto key()
const ->
decltype(std::declval<Base>().key())
8391 auto it = --
this->base();
8396 reference value()
const 8398 auto it = --
this->base();
8399 return it.operator * ();
8410 #include <algorithm> 8426 template<
typename BasicJsonType>
8431 friend class basic_json;
8455 explicit json_pointer(
const std::string& s =
"")
8456 : reference_tokens(split(s))
8473 std::string to_string()
const 8475 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
8477 [](
const std::string & a,
const std::string & b)
8479 return a +
"/" + escape(b);
8484 operator std::string()
const 8505 json_pointer& operator/=(
const json_pointer& ptr)
8507 reference_tokens.insert(reference_tokens.end(),
8508 ptr.reference_tokens.begin(),
8509 ptr.reference_tokens.end());
8529 json_pointer& operator/=(std::string token)
8531 push_back(std::move(token));
8551 json_pointer& operator/=(std::size_t array_index)
8553 return *
this /= std::to_string(array_index);
8571 friend json_pointer operator/(
const json_pointer& lhs,
8572 const json_pointer& rhs)
8574 return json_pointer(lhs) /= rhs;
8592 friend json_pointer operator/(
const json_pointer& ptr, std::string token)
8594 return json_pointer(ptr) /= std::move(token);
8612 friend json_pointer operator/(
const json_pointer& ptr, std::size_t array_index)
8614 return json_pointer(ptr) /= array_index;
8630 json_pointer parent_pointer()
const 8637 json_pointer res = *
this;
8659 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
8662 reference_tokens.pop_back();
8679 const std::string& back()
8683 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
8686 return reference_tokens.back();
8701 void push_back(
const std::string& token)
8703 reference_tokens.push_back(token);
8707 void push_back(std::string&& token)
8709 reference_tokens.push_back(std::move(token));
8726 bool empty()
const noexcept 8728 return reference_tokens.empty();
8739 static int array_index(
const std::string& s)
8741 std::size_t processed_chars = 0;
8742 const int res = std::stoi(s, &processed_chars);
8747 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + s +
"'"));
8753 json_pointer top()
const 8757 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
8760 json_pointer result = *
this;
8761 result.reference_tokens = {reference_tokens[0]};
8773 BasicJsonType& get_and_create(BasicJsonType& j)
const 8775 using size_type =
typename BasicJsonType::size_type;
8780 for (
const auto& reference_token : reference_tokens)
8782 switch (result->m_type)
8784 case detail::value_t::null:
8786 if (reference_token ==
"0")
8789 result = &result->operator[](0);
8794 result = &result->operator[](reference_token);
8799 case detail::value_t::object:
8802 result = &result->operator[](reference_token);
8806 case detail::value_t::array:
8811 result = &result->operator[](
static_cast<size_type>(array_index(reference_token)));
8815 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
8827 JSON_THROW(detail::type_error::create(313,
"invalid value to unflatten"));
8853 BasicJsonType& get_unchecked(BasicJsonType* ptr)
const 8855 using size_type =
typename BasicJsonType::size_type;
8856 for (
const auto& reference_token : reference_tokens)
8859 if (ptr->m_type == detail::value_t::null)
8863 std::all_of(reference_token.begin(), reference_token.end(),
8866 return x >=
'0' and x <=
'9';
8870 *ptr = (nums
or reference_token ==
"-")
8871 ? detail::value_t::array
8872 : detail::value_t::object;
8875 switch (ptr->m_type)
8877 case detail::value_t::object:
8880 ptr = &ptr->operator[](reference_token);
8884 case detail::value_t::array:
8887 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
8889 JSON_THROW(detail::parse_error::create(106, 0,
8890 "array index '" + reference_token +
8891 "' must not begin with '0'"));
8894 if (reference_token ==
"-")
8897 ptr = &ptr->operator[](ptr->m_value.array->size());
8904 ptr = &ptr->operator[](
8905 static_cast<size_type>(array_index(reference_token)));
8909 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
8916 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
8929 BasicJsonType& get_checked(BasicJsonType* ptr)
const 8931 using size_type =
typename BasicJsonType::size_type;
8932 for (
const auto& reference_token : reference_tokens)
8934 switch (ptr->m_type)
8936 case detail::value_t::object:
8939 ptr = &ptr->at(reference_token);
8943 case detail::value_t::array:
8949 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
8950 ") is out of range"));
8954 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
8956 JSON_THROW(detail::parse_error::create(106, 0,
8957 "array index '" + reference_token +
8958 "' must not begin with '0'"));
8964 ptr = &ptr->at(
static_cast<size_type>(array_index(reference_token)));
8968 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
8974 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
8994 const BasicJsonType& get_unchecked(
const BasicJsonType* ptr)
const 8996 using size_type =
typename BasicJsonType::size_type;
8997 for (
const auto& reference_token : reference_tokens)
8999 switch (ptr->m_type)
9001 case detail::value_t::object:
9004 ptr = &ptr->operator[](reference_token);
9008 case detail::value_t::array:
9014 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
9015 ") is out of range"));
9019 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
9021 JSON_THROW(detail::parse_error::create(106, 0,
9022 "array index '" + reference_token +
9023 "' must not begin with '0'"));
9029 ptr = &ptr->operator[](
9030 static_cast<size_type>(array_index(reference_token)));
9034 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
9040 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
9053 const BasicJsonType& get_checked(
const BasicJsonType* ptr)
const 9055 using size_type =
typename BasicJsonType::size_type;
9056 for (
const auto& reference_token : reference_tokens)
9058 switch (ptr->m_type)
9060 case detail::value_t::object:
9063 ptr = &ptr->at(reference_token);
9067 case detail::value_t::array:
9073 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
9074 ") is out of range"));
9078 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
9080 JSON_THROW(detail::parse_error::create(106, 0,
9081 "array index '" + reference_token +
9082 "' must not begin with '0'"));
9088 ptr = &ptr->at(
static_cast<size_type>(array_index(reference_token)));
9092 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
9098 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
9114 static std::vector<std::string> split(
const std::string& reference_string)
9116 std::vector<std::string> result;
9119 if (reference_string.empty())
9127 JSON_THROW(detail::parse_error::create(107, 1,
9128 "JSON pointer must be empty or begin with '/' - was: '" +
9129 reference_string +
"'"));
9137 std::size_t slash = reference_string.find_first_of(
'/', 1),
9144 start = (slash == std::string::npos) ? 0 : slash + 1,
9146 slash = reference_string.find_first_of(
'/', start))
9150 auto reference_token = reference_string.substr(start, slash - start);
9153 for (std::size_t pos = reference_token.find_first_of(
'~');
9154 pos != std::string::npos;
9155 pos = reference_token.find_first_of(
'~', pos + 1))
9157 assert(reference_token[pos] ==
'~');
9161 (reference_token[pos + 1] !=
'0' and 9162 reference_token[pos + 1] !=
'1')))
9164 JSON_THROW(detail::parse_error::create(108, 0,
"escape character '~' must be followed with '0' or '1'"));
9169 unescape(reference_token);
9170 result.push_back(reference_token);
9189 static void replace_substring(std::string& s,
const std::string& f,
9190 const std::string& t)
9192 assert(
not f.empty());
9193 for (
auto pos = s.find(f);
9194 pos != std::string::npos;
9195 s.replace(pos, f.size(), t),
9196 pos = s.find(f, pos + t.size()))
9201 static std::string escape(std::string s)
9203 replace_substring(s,
"~",
"~0");
9204 replace_substring(s,
"/",
"~1");
9209 static void unescape(std::string& s)
9211 replace_substring(s,
"~1",
"/");
9212 replace_substring(s,
"~0",
"~");
9222 static void flatten(
const std::string& reference_string,
9223 const BasicJsonType& value,
9224 BasicJsonType& result)
9226 switch (value.m_type)
9228 case detail::value_t::array:
9230 if (value.m_value.array->empty())
9233 result[reference_string] =
nullptr;
9238 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
9240 flatten(reference_string +
"/" + std::to_string(i),
9241 value.m_value.array->operator[](i), result);
9247 case detail::value_t::object:
9249 if (value.m_value.object->empty())
9252 result[reference_string] =
nullptr;
9257 for (
const auto& element : *value.m_value.object)
9259 flatten(reference_string +
"/" + escape(element.first), element.second, result);
9268 result[reference_string] = value;
9284 static BasicJsonType
9285 unflatten(
const BasicJsonType& value)
9289 JSON_THROW(detail::type_error::create(314,
"only objects can be unflattened"));
9292 BasicJsonType result;
9295 for (
const auto& element : *value.m_value.object)
9299 JSON_THROW(detail::type_error::create(315,
"values in object must be primitive"));
9306 json_pointer(element.first).get_and_create(result) = element.second;
9323 friend bool operator==(json_pointer
const& lhs,
9324 json_pointer
const& rhs)
noexcept 9326 return lhs.reference_tokens == rhs.reference_tokens;
9340 friend bool operator!=(json_pointer
const& lhs,
9341 json_pointer
const& rhs)
noexcept 9343 return not (lhs == rhs);
9347 std::vector<std::string> reference_tokens;
9354 #include <initializer_list> 9364 template<
typename BasicJsonType>
9368 using value_type = BasicJsonType;
9370 json_ref(value_type&& value)
9371 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(
true)
9374 json_ref(
const value_type& value)
9375 : value_ref(
const_cast<value_type*>(&value)), is_rvalue(
false)
9378 json_ref(std::initializer_list<json_ref> init)
9379 : owned_value(init), value_ref(&owned_value), is_rvalue(
true)
9384 enable_if_t<std::is_constructible<value_type, Args...>::value,
int> = 0 >
9385 json_ref(Args && ... args)
9386 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
9390 json_ref(json_ref&&) =
default;
9391 json_ref(
const json_ref&) =
delete;
9392 json_ref& operator=(
const json_ref&) =
delete;
9393 json_ref& operator=(json_ref&&) =
delete;
9394 ~json_ref() =
default;
9396 value_type moved_or_copied()
const 9400 return std::move(*value_ref);
9405 value_type
const& operator*()
const 9407 return *
static_cast<value_type
const*>(value_ref);
9410 value_type
const* operator->()
const 9412 return static_cast<value_type
const*>(value_ref);
9416 mutable value_type owned_value =
nullptr;
9417 value_type* value_ref =
nullptr;
9418 const bool is_rvalue;
9432 #include <algorithm> 9444 #include <algorithm> 9458 template<
typename CharType>
struct output_adapter_protocol
9460 virtual void write_character(CharType c) = 0;
9461 virtual void write_characters(
const CharType* s, std::size_t length) = 0;
9462 virtual ~output_adapter_protocol() =
default;
9466 template<
typename CharType>
9467 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
9470 template<
typename CharType>
9471 class output_vector_adapter :
public output_adapter_protocol<CharType>
9474 explicit output_vector_adapter(std::vector<CharType>& vec)
noexcept 9478 void write_character(CharType c) override
9483 void write_characters(
const CharType* s, std::size_t length) override
9485 std::copy(s, s + length, std::back_inserter(v));
9489 std::vector<CharType>& v;
9493 template<
typename CharType>
9494 class output_stream_adapter :
public output_adapter_protocol<CharType>
9497 explicit output_stream_adapter(std::basic_ostream<CharType>& s)
noexcept 9501 void write_character(CharType c) override
9506 void write_characters(
const CharType* s, std::size_t length) override
9508 stream.write(s,
static_cast<std::streamsize>(length));
9512 std::basic_ostream<CharType>& stream;
9516 template<
typename CharType,
typename StringType = std::basic_string<CharType>>
9517 class output_string_adapter :
public output_adapter_protocol<CharType>
9520 explicit output_string_adapter(StringType& s)
noexcept 9524 void write_character(CharType c) override
9529 void write_characters(
const CharType* s, std::size_t length) override
9531 str.append(s, length);
9538 template<
typename CharType,
typename StringType = std::basic_string<CharType>>
9539 class output_adapter
9542 output_adapter(std::vector<CharType>& vec)
9543 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
9545 output_adapter(std::basic_ostream<CharType>& s)
9546 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
9548 output_adapter(StringType& s)
9549 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
9551 operator output_adapter_t<CharType>()
9557 output_adapter_t<CharType> oa =
nullptr;
9574 template<
typename BasicJsonType,
typename CharType>
9577 using string_t =
typename BasicJsonType::string_t;
9585 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
9594 void write_bson(
const BasicJsonType& j)
9598 case value_t::object:
9600 write_bson_object(*j.m_value.object);
9606 JSON_THROW(type_error::create(317,
"to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
9614 void write_cbor(
const BasicJsonType& j)
9620 oa->write_character(to_char_type(0xF6));
9624 case value_t::boolean:
9626 oa->write_character(j.m_value.boolean
9627 ? to_char_type(0xF5)
9628 : to_char_type(0xF4));
9632 case value_t::number_integer:
9634 if (j.m_value.number_integer >= 0)
9639 if (j.m_value.number_integer <= 0x17)
9641 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
9643 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
9645 oa->write_character(to_char_type(0x18));
9646 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
9648 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
9650 oa->write_character(to_char_type(0x19));
9651 write_number(
static_cast<std::uint16_t>(j.m_value.number_integer));
9653 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
9655 oa->write_character(to_char_type(0x1A));
9656 write_number(
static_cast<std::uint32_t>(j.m_value.number_integer));
9660 oa->write_character(to_char_type(0x1B));
9661 write_number(
static_cast<std::uint64_t>(j.m_value.number_integer));
9668 const auto positive_number = -1 - j.m_value.number_integer;
9669 if (j.m_value.number_integer >= -24)
9671 write_number(
static_cast<std::uint8_t>(0x20 + positive_number));
9673 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
9675 oa->write_character(to_char_type(0x38));
9676 write_number(
static_cast<std::uint8_t>(positive_number));
9678 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
9680 oa->write_character(to_char_type(0x39));
9681 write_number(
static_cast<std::uint16_t>(positive_number));
9683 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
9685 oa->write_character(to_char_type(0x3A));
9686 write_number(
static_cast<std::uint32_t>(positive_number));
9690 oa->write_character(to_char_type(0x3B));
9691 write_number(
static_cast<std::uint64_t>(positive_number));
9697 case value_t::number_unsigned:
9699 if (j.m_value.number_unsigned <= 0x17)
9701 write_number(
static_cast<std::uint8_t>(j.m_value.number_unsigned));
9703 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
9705 oa->write_character(to_char_type(0x18));
9706 write_number(
static_cast<std::uint8_t>(j.m_value.number_unsigned));
9708 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
9710 oa->write_character(to_char_type(0x19));
9711 write_number(
static_cast<std::uint16_t>(j.m_value.number_unsigned));
9713 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
9715 oa->write_character(to_char_type(0x1A));
9716 write_number(
static_cast<std::uint32_t>(j.m_value.number_unsigned));
9720 oa->write_character(to_char_type(0x1B));
9721 write_number(
static_cast<std::uint64_t>(j.m_value.number_unsigned));
9726 case value_t::number_float:
9728 oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
9729 write_number(j.m_value.number_float);
9733 case value_t::string:
9736 const auto N = j.m_value.string->size();
9739 write_number(
static_cast<std::uint8_t>(0x60 + N));
9741 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
9743 oa->write_character(to_char_type(0x78));
9744 write_number(
static_cast<std::uint8_t>(N));
9746 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
9748 oa->write_character(to_char_type(0x79));
9749 write_number(
static_cast<std::uint16_t>(N));
9751 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
9753 oa->write_character(to_char_type(0x7A));
9754 write_number(
static_cast<std::uint32_t>(N));
9757 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
9759 oa->write_character(to_char_type(0x7B));
9760 write_number(
static_cast<std::uint64_t>(N));
9765 oa->write_characters(
9766 reinterpret_cast<
const CharType*>(j.m_value.string->c_str()),
9767 j.m_value.string->size());
9771 case value_t::array:
9774 const auto N = j.m_value.array->size();
9777 write_number(
static_cast<std::uint8_t>(0x80 + N));
9779 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
9781 oa->write_character(to_char_type(0x98));
9782 write_number(
static_cast<std::uint8_t>(N));
9784 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
9786 oa->write_character(to_char_type(0x99));
9787 write_number(
static_cast<std::uint16_t>(N));
9789 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
9791 oa->write_character(to_char_type(0x9A));
9792 write_number(
static_cast<std::uint32_t>(N));
9795 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
9797 oa->write_character(to_char_type(0x9B));
9798 write_number(
static_cast<std::uint64_t>(N));
9803 for (
const auto& el : *j.m_value.array)
9810 case value_t::object:
9813 const auto N = j.m_value.object->size();
9816 write_number(
static_cast<std::uint8_t>(0xA0 + N));
9818 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
9820 oa->write_character(to_char_type(0xB8));
9821 write_number(
static_cast<std::uint8_t>(N));
9823 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
9825 oa->write_character(to_char_type(0xB9));
9826 write_number(
static_cast<std::uint16_t>(N));
9828 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
9830 oa->write_character(to_char_type(0xBA));
9831 write_number(
static_cast<std::uint32_t>(N));
9834 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
9836 oa->write_character(to_char_type(0xBB));
9837 write_number(
static_cast<std::uint64_t>(N));
9842 for (
const auto& el : *j.m_value.object)
9844 write_cbor(el.first);
9845 write_cbor(el.second);
9858 void write_msgpack(
const BasicJsonType& j)
9864 oa->write_character(to_char_type(0xC0));
9868 case value_t::boolean:
9870 oa->write_character(j.m_value.boolean
9871 ? to_char_type(0xC3)
9872 : to_char_type(0xC2));
9876 case value_t::number_integer:
9878 if (j.m_value.number_integer >= 0)
9883 if (j.m_value.number_unsigned < 128)
9886 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
9888 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
9891 oa->write_character(to_char_type(0xCC));
9892 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
9894 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
9897 oa->write_character(to_char_type(0xCD));
9898 write_number(
static_cast<std::uint16_t>(j.m_value.number_integer));
9900 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
9903 oa->write_character(to_char_type(0xCE));
9904 write_number(
static_cast<std::uint32_t>(j.m_value.number_integer));
9906 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
9909 oa->write_character(to_char_type(0xCF));
9910 write_number(
static_cast<std::uint64_t>(j.m_value.number_integer));
9915 if (j.m_value.number_integer >= -32)
9918 write_number(
static_cast<std::int8_t>(j.m_value.number_integer));
9920 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)()
and 9921 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
9924 oa->write_character(to_char_type(0xD0));
9925 write_number(
static_cast<std::int8_t>(j.m_value.number_integer));
9927 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)()
and 9928 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
9931 oa->write_character(to_char_type(0xD1));
9932 write_number(
static_cast<std::int16_t>(j.m_value.number_integer));
9934 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)()
and 9935 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
9938 oa->write_character(to_char_type(0xD2));
9939 write_number(
static_cast<std::int32_t>(j.m_value.number_integer));
9941 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)()
and 9942 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
9945 oa->write_character(to_char_type(0xD3));
9946 write_number(
static_cast<std::int64_t>(j.m_value.number_integer));
9952 case value_t::number_unsigned:
9954 if (j.m_value.number_unsigned < 128)
9957 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
9959 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
9962 oa->write_character(to_char_type(0xCC));
9963 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
9965 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
9968 oa->write_character(to_char_type(0xCD));
9969 write_number(
static_cast<std::uint16_t>(j.m_value.number_integer));
9971 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
9974 oa->write_character(to_char_type(0xCE));
9975 write_number(
static_cast<std::uint32_t>(j.m_value.number_integer));
9977 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
9980 oa->write_character(to_char_type(0xCF));
9981 write_number(
static_cast<std::uint64_t>(j.m_value.number_integer));
9986 case value_t::number_float:
9988 oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
9989 write_number(j.m_value.number_float);
9993 case value_t::string:
9996 const auto N = j.m_value.string->size();
10000 write_number(
static_cast<std::uint8_t>(0xA0 | N));
10002 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
10005 oa->write_character(to_char_type(0xD9));
10006 write_number(
static_cast<std::uint8_t>(N));
10008 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
10011 oa->write_character(to_char_type(0xDA));
10012 write_number(
static_cast<std::uint16_t>(N));
10014 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
10017 oa->write_character(to_char_type(0xDB));
10018 write_number(
static_cast<std::uint32_t>(N));
10022 oa->write_characters(
10023 reinterpret_cast<
const CharType*>(j.m_value.string->c_str()),
10024 j.m_value.string->size());
10028 case value_t::array:
10031 const auto N = j.m_value.array->size();
10035 write_number(
static_cast<std::uint8_t>(0x90 | N));
10037 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
10040 oa->write_character(to_char_type(0xDC));
10041 write_number(
static_cast<std::uint16_t>(N));
10043 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
10046 oa->write_character(to_char_type(0xDD));
10047 write_number(
static_cast<std::uint32_t>(N));
10051 for (
const auto& el : *j.m_value.array)
10058 case value_t::object:
10061 const auto N = j.m_value.object->size();
10065 write_number(
static_cast<std::uint8_t>(0x80 | (N & 0xF)));
10067 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
10070 oa->write_character(to_char_type(0xDE));
10071 write_number(
static_cast<std::uint16_t>(N));
10073 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
10076 oa->write_character(to_char_type(0xDF));
10077 write_number(
static_cast<std::uint32_t>(N));
10081 for (
const auto& el : *j.m_value.object)
10083 write_msgpack(el.first);
10084 write_msgpack(el.second);
10100 void write_ubjson(
const BasicJsonType& j,
const bool use_count,
10101 const bool use_type,
const bool add_prefix =
true)
10105 case value_t::null:
10109 oa->write_character(to_char_type(
'Z'));
10114 case value_t::boolean:
10118 oa->write_character(j.m_value.boolean
10119 ? to_char_type(
'T')
10120 : to_char_type(
'F'));
10125 case value_t::number_integer:
10127 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
10131 case value_t::number_unsigned:
10133 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
10137 case value_t::number_float:
10139 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
10143 case value_t::string:
10147 oa->write_character(to_char_type(
'S'));
10149 write_number_with_ubjson_prefix(j.m_value.string->size(),
true);
10150 oa->write_characters(
10151 reinterpret_cast<
const CharType*>(j.m_value.string->c_str()),
10152 j.m_value.string->size());
10156 case value_t::array:
10160 oa->write_character(to_char_type(
'['));
10163 bool prefix_required =
true;
10164 if (use_type
and not j.m_value.array->empty())
10167 const CharType first_prefix = ubjson_prefix(j.front());
10168 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
10169 [
this, first_prefix](
const BasicJsonType & v)
10171 return ubjson_prefix(v) == first_prefix;
10176 prefix_required =
false;
10177 oa->write_character(to_char_type(
'$'));
10178 oa->write_character(first_prefix);
10184 oa->write_character(to_char_type(
'#'));
10185 write_number_with_ubjson_prefix(j.m_value.array->size(),
true);
10188 for (
const auto& el : *j.m_value.array)
10190 write_ubjson(el, use_count, use_type, prefix_required);
10195 oa->write_character(to_char_type(
']'));
10201 case value_t::object:
10205 oa->write_character(to_char_type(
'{'));
10208 bool prefix_required =
true;
10209 if (use_type
and not j.m_value.object->empty())
10212 const CharType first_prefix = ubjson_prefix(j.front());
10213 const bool same_prefix = std::all_of(j.begin(), j.end(),
10214 [
this, first_prefix](
const BasicJsonType & v)
10216 return ubjson_prefix(v) == first_prefix;
10221 prefix_required =
false;
10222 oa->write_character(to_char_type(
'$'));
10223 oa->write_character(first_prefix);
10229 oa->write_character(to_char_type(
'#'));
10230 write_number_with_ubjson_prefix(j.m_value.object->size(),
true);
10233 for (
const auto& el : *j.m_value.object)
10235 write_number_with_ubjson_prefix(el.first.size(),
true);
10236 oa->write_characters(
10237 reinterpret_cast<
const CharType*>(el.first.c_str()),
10239 write_ubjson(el.second, use_count, use_type, prefix_required);
10244 oa->write_character(to_char_type(
'}'));
10264 static std::size_t calc_bson_entry_header_size(
const string_t& name)
10266 const auto it = name.find(
static_cast<
typename string_t::value_type>(0));
10270 "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) +
")"));
10273 return 1ul + name.size() + 1u;
10279 void write_bson_entry_header(
const string_t& name,
10280 const std::uint8_t element_type)
10282 oa->write_character(to_char_type(element_type));
10283 oa->write_characters(
10284 reinterpret_cast<
const CharType*>(name.c_str()),
10291 void write_bson_boolean(
const string_t& name,
10294 write_bson_entry_header(name, 0x08);
10295 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
10301 void write_bson_double(
const string_t& name,
10302 const double value)
10304 write_bson_entry_header(name, 0x01);
10305 write_number<
double,
true>(value);
10311 static std::size_t calc_bson_string_size(
const string_t& value)
10313 return sizeof(std::int32_t) + value.size() + 1ul;
10319 void write_bson_string(
const string_t& name,
10320 const string_t& value)
10322 write_bson_entry_header(name, 0x02);
10324 write_number<std::int32_t,
true>(
static_cast<std::int32_t>(value.size() + 1ul));
10325 oa->write_characters(
10326 reinterpret_cast<
const CharType*>(value.c_str()),
10333 void write_bson_null(
const string_t& name)
10335 write_bson_entry_header(name, 0x0A);
10341 static std::size_t calc_bson_integer_size(
const std::int64_t value)
10343 return (std::numeric_limits<std::int32_t>::min)() <= value
and value <= (std::numeric_limits<std::int32_t>::max)()
10344 ?
sizeof(std::int32_t)
10345 :
sizeof(std::int64_t);
10351 void write_bson_integer(
const string_t& name,
10352 const std::int64_t value)
10354 if ((std::numeric_limits<std::int32_t>::min)() <= value
and value <= (std::numeric_limits<std::int32_t>::max)())
10356 write_bson_entry_header(name, 0x10);
10357 write_number<std::int32_t,
true>(
static_cast<std::int32_t>(value));
10361 write_bson_entry_header(name, 0x12);
10362 write_number<std::int64_t,
true>(
static_cast<std::int64_t>(value));
10369 static constexpr std::size_t calc_bson_unsigned_size(
const std::uint64_t value)
noexcept 10371 return (value <=
static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
10372 ?
sizeof(std::int32_t)
10373 :
sizeof(std::int64_t);
10379 void write_bson_unsigned(
const string_t& name,
10380 const std::uint64_t value)
10382 if (value <=
static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
10384 write_bson_entry_header(name, 0x10 );
10385 write_number<std::int32_t,
true>(
static_cast<std::int32_t>(value));
10387 else if (value <=
static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
10389 write_bson_entry_header(name, 0x12 );
10390 write_number<std::int64_t,
true>(
static_cast<std::int64_t>(value));
10394 JSON_THROW(out_of_range::create(407,
"integer number " + std::to_string(value) +
" cannot be represented by BSON as it does not fit int64"));
10401 void write_bson_object_entry(
const string_t& name,
10402 const typename BasicJsonType::object_t& value)
10404 write_bson_entry_header(name, 0x03);
10405 write_bson_object(value);
10411 static std::size_t calc_bson_array_size(
const typename BasicJsonType::array_t& value)
10413 std::size_t embedded_document_size = 0ul;
10414 std::size_t array_index = 0ul;
10416 for (
const auto& el : value)
10418 embedded_document_size += calc_bson_element_size(std::to_string(array_index++), el);
10421 return sizeof(std::int32_t) + embedded_document_size + 1ul;
10427 void write_bson_array(
const string_t& name,
10428 const typename BasicJsonType::array_t& value)
10430 write_bson_entry_header(name, 0x04);
10431 write_number<std::int32_t,
true>(
static_cast<std::int32_t>(calc_bson_array_size(value)));
10433 std::size_t array_index = 0ul;
10435 for (
const auto& el : value)
10437 write_bson_element(std::to_string(array_index++), el);
10440 oa->write_character(to_char_type(0x00));
10447 static std::size_t calc_bson_element_size(
const string_t& name,
10448 const BasicJsonType& j)
10450 const auto header_size = calc_bson_entry_header_size(name);
10453 case value_t::object:
10454 return header_size + calc_bson_object_size(*j.m_value.object);
10456 case value_t::array:
10457 return header_size + calc_bson_array_size(*j.m_value.array);
10459 case value_t::boolean:
10460 return header_size + 1ul;
10462 case value_t::number_float:
10463 return header_size + 8ul;
10465 case value_t::number_integer:
10466 return header_size + calc_bson_integer_size(j.m_value.number_integer);
10468 case value_t::number_unsigned:
10469 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
10471 case value_t::string:
10472 return header_size + calc_bson_string_size(*j.m_value.string);
10474 case value_t::null:
10475 return header_size + 0ul;
10492 void write_bson_element(
const string_t& name,
10493 const BasicJsonType& j)
10497 case value_t::object:
10498 return write_bson_object_entry(name, *j.m_value.object);
10500 case value_t::array:
10501 return write_bson_array(name, *j.m_value.array);
10503 case value_t::boolean:
10504 return write_bson_boolean(name, j.m_value.boolean);
10506 case value_t::number_float:
10507 return write_bson_double(name, j.m_value.number_float);
10509 case value_t::number_integer:
10510 return write_bson_integer(name, j.m_value.number_integer);
10512 case value_t::number_unsigned:
10513 return write_bson_unsigned(name, j.m_value.number_unsigned);
10515 case value_t::string:
10516 return write_bson_string(name, *j.m_value.string);
10518 case value_t::null:
10519 return write_bson_null(name);
10535 static std::size_t calc_bson_object_size(
const typename BasicJsonType::object_t& value)
10537 std::size_t document_size = std::accumulate(value.begin(), value.end(), 0ul,
10538 [](size_t result,
const typename BasicJsonType::object_t::value_type & el)
10540 return result += calc_bson_element_size(el.first, el.second);
10543 return sizeof(std::int32_t) + document_size + 1ul;
10550 void write_bson_object(
const typename BasicJsonType::object_t& value)
10552 write_number<std::int32_t,
true>(
static_cast<std::int32_t>(calc_bson_object_size(value)));
10554 for (
const auto& el : value)
10556 write_bson_element(el.first, el.second);
10559 oa->write_character(to_char_type(0x00));
10566 static constexpr CharType get_cbor_float_prefix(
float )
10568 return to_char_type(0xFA);
10571 static constexpr CharType get_cbor_float_prefix(
double )
10573 return to_char_type(0xFB);
10580 static constexpr CharType get_msgpack_float_prefix(
float )
10582 return to_char_type(0xCA);
10585 static constexpr CharType get_msgpack_float_prefix(
double )
10587 return to_char_type(0xCB);
10595 template<
typename NumberType,
typename std::enable_if<
10596 std::is_floating_point<NumberType>::value,
int>::type = 0>
10597 void write_number_with_ubjson_prefix(
const NumberType n,
10598 const bool add_prefix)
10602 oa->write_character(get_ubjson_float_prefix(n));
10608 template<
typename NumberType,
typename std::enable_if<
10609 std::is_unsigned<NumberType>::value,
int>::type = 0>
10610 void write_number_with_ubjson_prefix(
const NumberType n,
10611 const bool add_prefix)
10613 if (n <=
static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
10617 oa->write_character(to_char_type(
'i'));
10619 write_number(
static_cast<std::uint8_t>(n));
10621 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
10625 oa->write_character(to_char_type(
'U'));
10627 write_number(
static_cast<std::uint8_t>(n));
10629 else if (n <=
static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
10633 oa->write_character(to_char_type(
'I'));
10635 write_number(
static_cast<std::int16_t>(n));
10637 else if (n <=
static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
10641 oa->write_character(to_char_type(
'l'));
10643 write_number(
static_cast<std::int32_t>(n));
10645 else if (n <=
static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
10649 oa->write_character(to_char_type(
'L'));
10651 write_number(
static_cast<std::int64_t>(n));
10655 JSON_THROW(out_of_range::create(407,
"integer number " + std::to_string(n) +
" cannot be represented by UBJSON as it does not fit int64"));
10660 template<
typename NumberType,
typename std::enable_if<
10661 std::is_signed<NumberType>::value
and 10662 not std::is_floating_point<NumberType>::value,
int>::type = 0>
10663 void write_number_with_ubjson_prefix(
const NumberType n,
10664 const bool add_prefix)
10666 if ((std::numeric_limits<std::int8_t>::min)() <= n
and n <= (std::numeric_limits<std::int8_t>::max)())
10670 oa->write_character(to_char_type(
'i'));
10672 write_number(
static_cast<std::int8_t>(n));
10674 else if (
static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n
and n <=
static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
10678 oa->write_character(to_char_type(
'U'));
10680 write_number(
static_cast<std::uint8_t>(n));
10682 else if ((std::numeric_limits<std::int16_t>::min)() <= n
and n <= (std::numeric_limits<std::int16_t>::max)())
10686 oa->write_character(to_char_type(
'I'));
10688 write_number(
static_cast<std::int16_t>(n));
10690 else if ((std::numeric_limits<std::int32_t>::min)() <= n
and n <= (std::numeric_limits<std::int32_t>::max)())
10694 oa->write_character(to_char_type(
'l'));
10696 write_number(
static_cast<std::int32_t>(n));
10698 else if ((std::numeric_limits<std::int64_t>::min)() <= n
and n <= (std::numeric_limits<std::int64_t>::max)())
10702 oa->write_character(to_char_type(
'L'));
10704 write_number(
static_cast<std::int64_t>(n));
10709 JSON_THROW(out_of_range::create(407,
"integer number " + std::to_string(n) +
" cannot be represented by UBJSON as it does not fit int64"));
10723 CharType ubjson_prefix(
const BasicJsonType& j)
const noexcept 10727 case value_t::null:
10730 case value_t::boolean:
10731 return j.m_value.boolean ?
'T' :
'F';
10733 case value_t::number_integer:
10735 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer
and j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
10739 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer
and j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
10743 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer
and j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
10747 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer
and j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
10755 case value_t::number_unsigned:
10757 if (j.m_value.number_unsigned <= (std::numeric_limits<std::int8_t>::max)())
10761 if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
10765 if (j.m_value.number_unsigned <= (std::numeric_limits<std::int16_t>::max)())
10769 if (j.m_value.number_unsigned <= (std::numeric_limits<std::int32_t>::max)())
10777 case value_t::number_float:
10778 return get_ubjson_float_prefix(j.m_value.number_float);
10780 case value_t::string:
10783 case value_t::array:
10786 case value_t::object:
10794 static constexpr CharType get_ubjson_float_prefix(
float )
10799 static constexpr CharType get_ubjson_float_prefix(
double )
10819 template<
typename NumberType,
bool OutputIsLittleEndian =
false>
10820 void write_number(
const NumberType n)
10823 std::array<CharType,
sizeof(NumberType)> vec;
10824 std::memcpy(vec.data(), &n,
sizeof(NumberType));
10827 if (is_little_endian != OutputIsLittleEndian)
10830 std::reverse(vec.begin(), vec.end());
10833 oa->write_characters(vec.data(),
sizeof(NumberType));
10841 template <
typename C = CharType,
10842 enable_if_t < std::is_signed<C>::value
and std::is_signed<
char>::value > * =
nullptr >
10843 static constexpr CharType to_char_type(std::uint8_t x)
noexcept 10845 return *
reinterpret_cast<
char*>(&x);
10848 template <
typename C = CharType,
10849 enable_if_t < std::is_signed<C>::value
and std::is_unsigned<
char>::value > * =
nullptr >
10850 static CharType to_char_type(std::uint8_t x)
noexcept 10852 static_assert(
sizeof(std::uint8_t) ==
sizeof(CharType),
"size of CharType must be equal to std::uint8_t");
10853 static_assert(std::is_pod<CharType>::value,
"CharType must be POD");
10855 std::memcpy(&result, &x,
sizeof(x));
10859 template<
typename C = CharType,
10860 enable_if_t<std::is_unsigned<C>::value>* =
nullptr>
10861 static constexpr CharType to_char_type(std::uint8_t x)
noexcept 10866 template <
typename InputCharType,
typename C = CharType,
10868 std::is_signed<C>::value
and 10869 std::is_signed<
char>::value
and 10870 std::is_same<
char,
typename std::remove_cv<InputCharType>::type>::value
10872 static constexpr CharType to_char_type(InputCharType x)
noexcept 10879 const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
10882 output_adapter_t<CharType> oa =
nullptr;
10892 #include <algorithm> 10903 #include <type_traits> 10916 #include <type_traits> 10942 namespace dtoa_impl
10945 template <
typename Target,
typename Source>
10946 Target reinterpret_bits(
const Source source)
10948 static_assert(
sizeof(Target) ==
sizeof(Source),
"size mismatch");
10951 std::memcpy(&target, &source,
sizeof(Source));
10957 static constexpr int kPrecision = 64;
10959 std::uint64_t f = 0;
10962 constexpr diyfp(std::uint64_t f_,
int e_)
noexcept : f(f_), e(e_) {}
10968 static diyfp sub(
const diyfp& x,
const diyfp& y)
noexcept 10970 assert(x.e == y.e);
10971 assert(x.f >= y.f);
10973 return {x.f - y.f, x.e};
10980 static diyfp mul(
const diyfp& x,
const diyfp& y)
noexcept 10982 static_assert(kPrecision == 64,
"internal error");
11007 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
11008 const std::uint64_t u_hi = x.f >> 32u;
11009 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
11010 const std::uint64_t v_hi = y.f >> 32u;
11012 const std::uint64_t p0 = u_lo * v_lo;
11013 const std::uint64_t p1 = u_lo * v_hi;
11014 const std::uint64_t p2 = u_hi * v_lo;
11015 const std::uint64_t p3 = u_hi * v_hi;
11017 const std::uint64_t p0_hi = p0 >> 32u;
11018 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
11019 const std::uint64_t p1_hi = p1 >> 32u;
11020 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
11021 const std::uint64_t p2_hi = p2 >> 32u;
11023 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
11034 Q += std::uint64_t{1} << (64u - 32u - 1u);
11036 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
11038 return {h, x.e + y.e + 64};
11045 static diyfp normalize(diyfp x)
noexcept 11049 while ((x.f >> 63u) == 0)
11062 static diyfp normalize_to(
const diyfp& x,
const int target_exponent)
noexcept 11064 const int delta = x.e - target_exponent;
11066 assert(delta >= 0);
11067 assert(((x.f << delta) >> delta) == x.f);
11069 return {x.f << delta, target_exponent};
11086 template <
typename FloatType>
11087 boundaries compute_boundaries(FloatType value)
11089 assert(std::isfinite(value));
11099 static_assert(std::numeric_limits<FloatType>::is_iec559,
11100 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
11102 constexpr int kPrecision = std::numeric_limits<FloatType>::digits;
11103 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
11104 constexpr int kMinExp = 1 - kBias;
11105 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1);
11107 using bits_type =
typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
11109 const std::uint64_t bits = reinterpret_bits<bits_type>(value);
11110 const std::uint64_t E = bits >> (kPrecision - 1);
11111 const std::uint64_t F = bits & (kHiddenBit - 1);
11113 const bool is_denormal = E == 0;
11114 const diyfp v = is_denormal
11115 ? diyfp(F, kMinExp)
11116 : diyfp(F + kHiddenBit,
static_cast<
int>(E) - kBias);
11139 const bool lower_boundary_is_closer = F == 0
and E > 1;
11140 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
11141 const diyfp m_minus = lower_boundary_is_closer
11142 ? diyfp(4 * v.f - 1, v.e - 2)
11143 : diyfp(2 * v.f - 1, v.e - 1);
11146 const diyfp w_plus = diyfp::normalize(m_plus);
11149 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
11151 return {diyfp::normalize(v), w_minus, w_plus};
11209 constexpr int kAlpha = -60;
11210 constexpr int kGamma = -32;
11212 struct cached_power
11226 inline cached_power get_cached_power_for_binary_exponent(
int e)
11278 constexpr int kCachedPowersMinDecExp = -300;
11279 constexpr int kCachedPowersDecStep = 8;
11281 static constexpr std::array<cached_power, 79> kCachedPowers =
11284 { 0xAB70FE17C79AC6CA, -1060, -300 },
11285 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
11286 { 0xBE5691EF416BD60C, -1007, -284 },
11287 { 0x8DD01FAD907FFC3C, -980, -276 },
11288 { 0xD3515C2831559A83, -954, -268 },
11289 { 0x9D71AC8FADA6C9B5, -927, -260 },
11290 { 0xEA9C227723EE8BCB, -901, -252 },
11291 { 0xAECC49914078536D, -874, -244 },
11292 { 0x823C12795DB6CE57, -847, -236 },
11293 { 0xC21094364DFB5637, -821, -228 },
11294 { 0x9096EA6F3848984F, -794, -220 },
11295 { 0xD77485CB25823AC7, -768, -212 },
11296 { 0xA086CFCD97BF97F4, -741, -204 },
11297 { 0xEF340A98172AACE5, -715, -196 },
11298 { 0xB23867FB2A35B28E, -688, -188 },
11299 { 0x84C8D4DFD2C63F3B, -661, -180 },
11300 { 0xC5DD44271AD3CDBA, -635, -172 },
11301 { 0x936B9FCEBB25C996, -608, -164 },
11302 { 0xDBAC6C247D62A584, -582, -156 },
11303 { 0xA3AB66580D5FDAF6, -555, -148 },
11304 { 0xF3E2F893DEC3F126, -529, -140 },
11305 { 0xB5B5ADA8AAFF80B8, -502, -132 },
11306 { 0x87625F056C7C4A8B, -475, -124 },
11307 { 0xC9BCFF6034C13053, -449, -116 },
11308 { 0x964E858C91BA2655, -422, -108 },
11309 { 0xDFF9772470297EBD, -396, -100 },
11310 { 0xA6DFBD9FB8E5B88F, -369, -92 },
11311 { 0xF8A95FCF88747D94, -343, -84 },
11312 { 0xB94470938FA89BCF, -316, -76 },
11313 { 0x8A08F0F8BF0F156B, -289, -68 },
11314 { 0xCDB02555653131B6, -263, -60 },
11315 { 0x993FE2C6D07B7FAC, -236, -52 },
11316 { 0xE45C10C42A2B3B06, -210, -44 },
11317 { 0xAA242499697392D3, -183, -36 },
11318 { 0xFD87B5F28300CA0E, -157, -28 },
11319 { 0xBCE5086492111AEB, -130, -20 },
11320 { 0x8CBCCC096F5088CC, -103, -12 },
11321 { 0xD1B71758E219652C, -77, -4 },
11322 { 0x9C40000000000000, -50, 4 },
11323 { 0xE8D4A51000000000, -24, 12 },
11324 { 0xAD78EBC5AC620000, 3, 20 },
11325 { 0x813F3978F8940984, 30, 28 },
11326 { 0xC097CE7BC90715B3, 56, 36 },
11327 { 0x8F7E32CE7BEA5C70, 83, 44 },
11328 { 0xD5D238A4ABE98068, 109, 52 },
11329 { 0x9F4F2726179A2245, 136, 60 },
11330 { 0xED63A231D4C4FB27, 162, 68 },
11331 { 0xB0DE65388CC8ADA8, 189, 76 },
11332 { 0x83C7088E1AAB65DB, 216, 84 },
11333 { 0xC45D1DF942711D9A, 242, 92 },
11334 { 0x924D692CA61BE758, 269, 100 },
11335 { 0xDA01EE641A708DEA, 295, 108 },
11336 { 0xA26DA3999AEF774A, 322, 116 },
11337 { 0xF209787BB47D6B85, 348, 124 },
11338 { 0xB454E4A179DD1877, 375, 132 },
11339 { 0x865B86925B9BC5C2, 402, 140 },
11340 { 0xC83553C5C8965D3D, 428, 148 },
11341 { 0x952AB45CFA97A0B3, 455, 156 },
11342 { 0xDE469FBD99A05FE3, 481, 164 },
11343 { 0xA59BC234DB398C25, 508, 172 },
11344 { 0xF6C69A72A3989F5C, 534, 180 },
11345 { 0xB7DCBF5354E9BECE, 561, 188 },
11346 { 0x88FCF317F22241E2, 588, 196 },
11347 { 0xCC20CE9BD35C78A5, 614, 204 },
11348 { 0x98165AF37B2153DF, 641, 212 },
11349 { 0xE2A0B5DC971F303A, 667, 220 },
11350 { 0xA8D9D1535CE3B396, 694, 228 },
11351 { 0xFB9B7CD9A4A7443C, 720, 236 },
11352 { 0xBB764C4CA7A44410, 747, 244 },
11353 { 0x8BAB8EEFB6409C1A, 774, 252 },
11354 { 0xD01FEF10A657842C, 800, 260 },
11355 { 0x9B10A4E5E9913129, 827, 268 },
11356 { 0xE7109BFBA19C0C9D, 853, 276 },
11357 { 0xAC2820D9623BF429, 880, 284 },
11358 { 0x80444B5E7AA7CF85, 907, 292 },
11359 { 0xBF21E44003ACDD2D, 933, 300 },
11360 { 0x8E679C2F5E44FF8F, 960, 308 },
11361 { 0xD433179D9C8CB841, 986, 316 },
11362 { 0x9E19DB92B4E31BA9, 1013, 324 },
11370 assert(e >= -1500);
11372 const int f = kAlpha - e - 1;
11373 const int k = (f * 78913) / (1 << 18) +
static_cast<
int>(f > 0);
11375 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
11376 assert(index >= 0);
11377 assert(
static_cast<std::size_t>(index) < kCachedPowers.size());
11379 const cached_power cached = kCachedPowers[
static_cast<std::size_t>(index)];
11380 assert(kAlpha <= cached.e + e + 64);
11381 assert(kGamma >= cached.e + e + 64);
11390 inline int find_largest_pow10(
const std::uint32_t n, std::uint32_t& pow10)
11393 if (n >= 1000000000)
11395 pow10 = 1000000000;
11399 else if (n >= 100000000)
11404 else if (n >= 10000000)
11409 else if (n >= 1000000)
11414 else if (n >= 100000)
11419 else if (n >= 10000)
11424 else if (n >= 1000)
11446 inline void grisu2_round(
char* buf,
int len, std::uint64_t dist, std::uint64_t delta,
11447 std::uint64_t rest, std::uint64_t ten_k)
11450 assert(dist <= delta);
11451 assert(rest <= delta);
11474 and delta - rest >= ten_k
11475 and (rest + ten_k < dist
or dist - rest > rest + ten_k - dist))
11477 assert(buf[len - 1] !=
'0');
11487 inline void grisu2_digit_gen(
char* buffer,
int& length,
int& decimal_exponent,
11488 diyfp M_minus, diyfp w, diyfp M_plus)
11490 static_assert(kAlpha >= -60,
"internal error");
11491 static_assert(kGamma <= -32,
"internal error");
11505 assert(M_plus.e >= kAlpha);
11506 assert(M_plus.e <= kGamma);
11508 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f;
11509 std::uint64_t dist = diyfp::sub(M_plus, w ).f;
11518 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
11520 auto p1 =
static_cast<std::uint32_t>(M_plus.f >> -one.e);
11521 std::uint64_t p2 = M_plus.f & (one.f - 1);
11529 std::uint32_t pow10;
11530 const int k = find_largest_pow10(p1, pow10);
11557 const std::uint32_t d = p1 / pow10;
11558 const std::uint32_t r = p1 % pow10;
11564 buffer[length++] =
static_cast<
char>(
'0' + d);
11583 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
11588 decimal_exponent += n;
11599 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
11600 grisu2_round(buffer, length, dist, delta, rest, ten_n);
11650 assert(p2 > delta);
11661 assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
11663 const std::uint64_t d = p2 >> -one.e;
11664 const std::uint64_t r = p2 & (one.f - 1);
11671 buffer[length++] =
static_cast<
char>(
'0' + d);
11696 decimal_exponent -= m;
11704 const std::uint64_t ten_m = one.f;
11705 grisu2_round(buffer, length, dist, delta, p2, ten_m);
11727 inline void grisu2(
char* buf,
int& len,
int& decimal_exponent,
11728 diyfp m_minus, diyfp v, diyfp m_plus)
11730 assert(m_plus.e == m_minus.e);
11731 assert(m_plus.e == v.e);
11742 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
11744 const diyfp c_minus_k(cached.f, cached.e);
11747 const diyfp w = diyfp::mul(v, c_minus_k);
11748 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
11749 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
11772 const diyfp M_minus(w_minus.f + 1, w_minus.e);
11773 const diyfp M_plus (w_plus.f - 1, w_plus.e );
11775 decimal_exponent = -cached.k;
11777 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
11785 template <
typename FloatType>
11786 void grisu2(
char* buf,
int& len,
int& decimal_exponent, FloatType value)
11788 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
11789 "internal error: not enough precision");
11791 assert(std::isfinite(value));
11811 const boundaries w = compute_boundaries(
static_cast<
double>(value));
11813 const boundaries w = compute_boundaries(value);
11816 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
11824 inline char* append_exponent(
char* buf,
int e)
11839 auto k =
static_cast<std::uint32_t>(e);
11845 *buf++ =
static_cast<
char>(
'0' + k);
11849 *buf++ =
static_cast<
char>(
'0' + k / 10);
11851 *buf++ =
static_cast<
char>(
'0' + k);
11855 *buf++ =
static_cast<
char>(
'0' + k / 100);
11857 *buf++ =
static_cast<
char>(
'0' + k / 10);
11859 *buf++ =
static_cast<
char>(
'0' + k);
11874 inline char* format_buffer(
char* buf,
int len,
int decimal_exponent,
11875 int min_exp,
int max_exp)
11877 assert(min_exp < 0);
11878 assert(max_exp > 0);
11881 const int n = len + decimal_exponent;
11887 if (k <= n
and n <= max_exp)
11892 std::memset(buf + k,
'0',
static_cast<size_t>(n - k));
11896 return buf + (n + 2);
11899 if (0 < n
and n <= max_exp)
11906 std::memmove(buf + (n + 1), buf + n,
static_cast<size_t>(k - n));
11908 return buf + (k + 1);
11911 if (min_exp < n
and n <= 0)
11916 std::memmove(buf + (2 + -n), buf,
static_cast<size_t>(k));
11919 std::memset(buf + 2,
'0',
static_cast<size_t>(-n));
11920 return buf + (2 + (-n) + k);
11935 std::memmove(buf + 2, buf + 1,
static_cast<size_t>(k - 1));
11941 return append_exponent(buf, n - 1);
11956 template <
typename FloatType>
11957 char* to_chars(
char* first,
const char* last, FloatType value)
11959 static_cast<
void>(last);
11960 assert(std::isfinite(value));
11963 if (std::signbit(value))
11978 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
11985 int decimal_exponent = 0;
11986 dtoa_impl::grisu2(first, len, decimal_exponent, value);
11988 assert(len <= std::numeric_limits<FloatType>::max_digits10);
11991 constexpr int kMinExp = -4;
11993 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
11995 assert(last - first >= kMaxExp + 2);
11996 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
11997 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
11999 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
12027 enum class error_handler_t
12034 template<
typename BasicJsonType>
12037 using string_t =
typename BasicJsonType::string_t;
12038 using number_float_t =
typename BasicJsonType::number_float_t;
12039 using number_integer_t =
typename BasicJsonType::number_integer_t;
12040 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
12041 static constexpr std::uint8_t UTF8_ACCEPT = 0;
12042 static constexpr std::uint8_t UTF8_REJECT = 1;
12050 serializer(output_adapter_t<
char> s,
const char ichar,
12051 error_handler_t error_handler_ = error_handler_t::strict)
12053 , loc(std::localeconv())
12054 , thousands_sep(loc->thousands_sep ==
nullptr ?
'\0' : * (loc->thousands_sep))
12055 , decimal_point(loc->decimal_point ==
nullptr ?
'\0' : * (loc->decimal_point))
12056 , indent_char(ichar)
12057 , indent_string(512, indent_char)
12058 , error_handler(error_handler_)
12062 serializer(
const serializer&) =
delete;
12063 serializer& operator=(
const serializer&) =
delete;
12064 serializer(serializer&&) =
delete;
12065 serializer& operator=(serializer&&) =
delete;
12066 ~serializer() =
default;
12085 void dump(
const BasicJsonType& val,
const bool pretty_print,
12086 const bool ensure_ascii,
12087 const unsigned int indent_step,
12088 const unsigned int current_indent = 0)
12090 switch (val.m_type)
12092 case value_t::object:
12094 if (val.m_value.object->empty())
12096 o->write_characters(
"{}", 2);
12102 o->write_characters(
"{\n", 2);
12105 const auto new_indent = current_indent + indent_step;
12108 indent_string.resize(indent_string.size() * 2,
' ');
12112 auto i = val.m_value.object->cbegin();
12113 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
12115 o->write_characters(indent_string.c_str(), new_indent);
12116 o->write_character(
'\"');
12117 dump_escaped(i->first, ensure_ascii);
12118 o->write_characters(
"\": ", 3);
12119 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
12120 o->write_characters(
",\n", 2);
12124 assert(i != val.m_value.object->cend());
12125 assert(std::next(i) == val.m_value.object->cend());
12126 o->write_characters(indent_string.c_str(), new_indent);
12127 o->write_character(
'\"');
12128 dump_escaped(i->first, ensure_ascii);
12129 o->write_characters(
"\": ", 3);
12130 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
12132 o->write_character(
'\n');
12133 o->write_characters(indent_string.c_str(), current_indent);
12134 o->write_character(
'}');
12138 o->write_character(
'{');
12141 auto i = val.m_value.object->cbegin();
12142 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
12144 o->write_character(
'\"');
12145 dump_escaped(i->first, ensure_ascii);
12146 o->write_characters(
"\":", 2);
12147 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
12148 o->write_character(
',');
12152 assert(i != val.m_value.object->cend());
12153 assert(std::next(i) == val.m_value.object->cend());
12154 o->write_character(
'\"');
12155 dump_escaped(i->first, ensure_ascii);
12156 o->write_characters(
"\":", 2);
12157 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
12159 o->write_character(
'}');
12165 case value_t::array:
12167 if (val.m_value.array->empty())
12169 o->write_characters(
"[]", 2);
12175 o->write_characters(
"[\n", 2);
12178 const auto new_indent = current_indent + indent_step;
12181 indent_string.resize(indent_string.size() * 2,
' ');
12185 for (
auto i = val.m_value.array->cbegin();
12186 i != val.m_value.array->cend() - 1; ++i)
12188 o->write_characters(indent_string.c_str(), new_indent);
12189 dump(*i,
true, ensure_ascii, indent_step, new_indent);
12190 o->write_characters(
",\n", 2);
12194 assert(
not val.m_value.array->empty());
12195 o->write_characters(indent_string.c_str(), new_indent);
12196 dump(val.m_value.array->back(),
true, ensure_ascii, indent_step, new_indent);
12198 o->write_character(
'\n');
12199 o->write_characters(indent_string.c_str(), current_indent);
12200 o->write_character(
']');
12204 o->write_character(
'[');
12207 for (
auto i = val.m_value.array->cbegin();
12208 i != val.m_value.array->cend() - 1; ++i)
12210 dump(*i,
false, ensure_ascii, indent_step, current_indent);
12211 o->write_character(
',');
12215 assert(
not val.m_value.array->empty());
12216 dump(val.m_value.array->back(),
false, ensure_ascii, indent_step, current_indent);
12218 o->write_character(
']');
12224 case value_t::string:
12226 o->write_character(
'\"');
12227 dump_escaped(*val.m_value.string, ensure_ascii);
12228 o->write_character(
'\"');
12232 case value_t::boolean:
12234 if (val.m_value.boolean)
12236 o->write_characters(
"true", 4);
12240 o->write_characters(
"false", 5);
12245 case value_t::number_integer:
12247 dump_integer(val.m_value.number_integer);
12251 case value_t::number_unsigned:
12253 dump_integer(val.m_value.number_unsigned);
12257 case value_t::number_float:
12259 dump_float(val.m_value.number_float);
12263 case value_t::discarded:
12265 o->write_characters(
"<discarded>", 11);
12269 case value_t::null:
12271 o->write_characters(
"null", 4);
12295 void dump_escaped(
const string_t& s,
const bool ensure_ascii)
12297 std::uint32_t codepoint;
12298 std::uint8_t state = UTF8_ACCEPT;
12299 std::size_t bytes = 0;
12302 std::size_t bytes_after_last_accept = 0;
12303 std::size_t undumped_chars = 0;
12305 for (std::size_t i = 0; i < s.size(); ++i)
12307 const auto byte =
static_cast<uint8_t>(s[i]);
12309 switch (decode(state, codepoint, byte))
12317 string_buffer[bytes++] =
'\\';
12318 string_buffer[bytes++] =
'b';
12324 string_buffer[bytes++] =
'\\';
12325 string_buffer[bytes++] =
't';
12331 string_buffer[bytes++] =
'\\';
12332 string_buffer[bytes++] =
'n';
12338 string_buffer[bytes++] =
'\\';
12339 string_buffer[bytes++] =
'f';
12345 string_buffer[bytes++] =
'\\';
12346 string_buffer[bytes++] =
'r';
12352 string_buffer[bytes++] =
'\\';
12353 string_buffer[bytes++] =
'\"';
12359 string_buffer[bytes++] =
'\\';
12360 string_buffer[bytes++] =
'\\';
12368 if ((codepoint <= 0x1F)
or (ensure_ascii
and (codepoint >= 0x7F)))
12370 if (codepoint <= 0xFFFF)
12372 (std::snprintf)(string_buffer.data() + bytes, 7,
"\\u%04x",
12373 static_cast<std::uint16_t>(codepoint));
12378 (std::snprintf)(string_buffer.data() + bytes, 13,
"\\u%04x\\u%04x",
12379 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
12380 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
12388 string_buffer[bytes++] = s[i];
12397 if (string_buffer.size() - bytes < 13)
12399 o->write_characters(string_buffer.data(), bytes);
12404 bytes_after_last_accept = bytes;
12405 undumped_chars = 0;
12411 switch (error_handler)
12413 case error_handler_t::strict:
12415 std::string sn(3,
'\0');
12416 (std::snprintf)(&sn[0], sn.size(),
"%.2X", byte);
12417 JSON_THROW(type_error::create(316,
"invalid UTF-8 byte at index " + std::to_string(i) +
": 0x" + sn));
12420 case error_handler_t::ignore:
12421 case error_handler_t::replace:
12427 if (undumped_chars > 0)
12434 bytes = bytes_after_last_accept;
12436 if (error_handler == error_handler_t::replace)
12441 string_buffer[bytes++] =
'\\';
12442 string_buffer[bytes++] =
'u';
12443 string_buffer[bytes++] =
'f';
12444 string_buffer[bytes++] =
'f';
12445 string_buffer[bytes++] =
'f';
12446 string_buffer[bytes++] =
'd';
12450 string_buffer[bytes++] = detail::binary_writer<BasicJsonType,
char>::to_char_type(
'\xEF');
12451 string_buffer[bytes++] = detail::binary_writer<BasicJsonType,
char>::to_char_type(
'\xBF');
12452 string_buffer[bytes++] = detail::binary_writer<BasicJsonType,
char>::to_char_type(
'\xBD');
12458 if (string_buffer.size() - bytes < 13)
12460 o->write_characters(string_buffer.data(), bytes);
12464 bytes_after_last_accept = bytes;
12467 undumped_chars = 0;
12470 state = UTF8_ACCEPT;
12482 if (
not ensure_ascii)
12485 string_buffer[bytes++] = s[i];
12499 o->write_characters(string_buffer.data(), bytes);
12505 switch (error_handler)
12507 case error_handler_t::strict:
12509 std::string sn(3,
'\0');
12510 (std::snprintf)(&sn[0], sn.size(),
"%.2X",
static_cast<std::uint8_t>(s.back()));
12511 JSON_THROW(type_error::create(316,
"incomplete UTF-8 string; last byte: 0x" + sn));
12514 case error_handler_t::ignore:
12517 o->write_characters(string_buffer.data(), bytes_after_last_accept);
12521 case error_handler_t::replace:
12524 o->write_characters(string_buffer.data(), bytes_after_last_accept);
12528 o->write_characters(
"\\ufffd", 6);
12532 o->write_characters(
"\xEF\xBF\xBD", 3);
12551 inline unsigned int count_digits(number_unsigned_t x)
noexcept 12553 unsigned int n_digits = 1;
12562 return n_digits + 1;
12566 return n_digits + 2;
12570 return n_digits + 3;
12586 template<
typename NumberType, detail::enable_if_t<
12587 std::is_same<NumberType, number_unsigned_t>::value
or 12588 std::is_same<NumberType, number_integer_t>::value,
12590 void dump_integer(NumberType x)
12592 static constexpr std::array<std::array<
char, 2>, 100> digits_to_99
12595 {{
'0',
'0'}}, {{
'0',
'1'}}, {{
'0',
'2'}}, {{
'0',
'3'}}, {{
'0',
'4'}}, {{
'0',
'5'}}, {{
'0',
'6'}}, {{
'0',
'7'}}, {{
'0',
'8'}}, {{
'0',
'9'}},
12596 {{
'1',
'0'}}, {{
'1',
'1'}}, {{
'1',
'2'}}, {{
'1',
'3'}}, {{
'1',
'4'}}, {{
'1',
'5'}}, {{
'1',
'6'}}, {{
'1',
'7'}}, {{
'1',
'8'}}, {{
'1',
'9'}},
12597 {{
'2',
'0'}}, {{
'2',
'1'}}, {{
'2',
'2'}}, {{
'2',
'3'}}, {{
'2',
'4'}}, {{
'2',
'5'}}, {{
'2',
'6'}}, {{
'2',
'7'}}, {{
'2',
'8'}}, {{
'2',
'9'}},
12598 {{
'3',
'0'}}, {{
'3',
'1'}}, {{
'3',
'2'}}, {{
'3',
'3'}}, {{
'3',
'4'}}, {{
'3',
'5'}}, {{
'3',
'6'}}, {{
'3',
'7'}}, {{
'3',
'8'}}, {{
'3',
'9'}},
12599 {{
'4',
'0'}}, {{
'4',
'1'}}, {{
'4',
'2'}}, {{
'4',
'3'}}, {{
'4',
'4'}}, {{
'4',
'5'}}, {{
'4',
'6'}}, {{
'4',
'7'}}, {{
'4',
'8'}}, {{
'4',
'9'}},
12600 {{
'5',
'0'}}, {{
'5',
'1'}}, {{
'5',
'2'}}, {{
'5',
'3'}}, {{
'5',
'4'}}, {{
'5',
'5'}}, {{
'5',
'6'}}, {{
'5',
'7'}}, {{
'5',
'8'}}, {{
'5',
'9'}},
12601 {{
'6',
'0'}}, {{
'6',
'1'}}, {{
'6',
'2'}}, {{
'6',
'3'}}, {{
'6',
'4'}}, {{
'6',
'5'}}, {{
'6',
'6'}}, {{
'6',
'7'}}, {{
'6',
'8'}}, {{
'6',
'9'}},
12602 {{
'7',
'0'}}, {{
'7',
'1'}}, {{
'7',
'2'}}, {{
'7',
'3'}}, {{
'7',
'4'}}, {{
'7',
'5'}}, {{
'7',
'6'}}, {{
'7',
'7'}}, {{
'7',
'8'}}, {{
'7',
'9'}},
12603 {{
'8',
'0'}}, {{
'8',
'1'}}, {{
'8',
'2'}}, {{
'8',
'3'}}, {{
'8',
'4'}}, {{
'8',
'5'}}, {{
'8',
'6'}}, {{
'8',
'7'}}, {{
'8',
'8'}}, {{
'8',
'9'}},
12604 {{
'9',
'0'}}, {{
'9',
'1'}}, {{
'9',
'2'}}, {{
'9',
'3'}}, {{
'9',
'4'}}, {{
'9',
'5'}}, {{
'9',
'6'}}, {{
'9',
'7'}}, {{
'9',
'8'}}, {{
'9',
'9'}},
12611 o->write_character(
'0');
12616 auto buffer_ptr = number_buffer.begin();
12618 const bool is_negative = std::is_same<NumberType, number_integer_t>::value
and not(x >= 0);
12619 number_unsigned_t abs_value;
12621 unsigned int n_chars;
12626 abs_value =
static_cast<number_unsigned_t>(std::abs(
static_cast<std::intmax_t>(x)));
12629 n_chars = 1 + count_digits(abs_value);
12633 abs_value =
static_cast<number_unsigned_t>(x);
12634 n_chars = count_digits(abs_value);
12638 assert(n_chars < number_buffer.size() - 1);
12642 buffer_ptr += n_chars;
12646 while (abs_value >= 100)
12648 const auto digits_index =
static_cast<
unsigned>((abs_value % 100));
12650 *(--buffer_ptr) = digits_to_99[digits_index][1];
12651 *(--buffer_ptr) = digits_to_99[digits_index][0];
12654 if (abs_value >= 10)
12656 const auto digits_index =
static_cast<
unsigned>(abs_value);
12657 *(--buffer_ptr) = digits_to_99[digits_index][1];
12658 *(--buffer_ptr) = digits_to_99[digits_index][0];
12662 *(--buffer_ptr) =
static_cast<
char>(
'0' + abs_value);
12665 o->write_characters(number_buffer.data(), n_chars);
12676 void dump_float(number_float_t x)
12679 if (
not std::isfinite(x))
12681 o->write_characters(
"null", 4);
12690 static constexpr bool is_ieee_single_or_double
12691 = (std::numeric_limits<number_float_t>::is_iec559
and std::numeric_limits<number_float_t>::digits == 24
and std::numeric_limits<number_float_t>::max_exponent == 128)
or 12692 (std::numeric_limits<number_float_t>::is_iec559
and std::numeric_limits<number_float_t>::digits == 53
and std::numeric_limits<number_float_t>::max_exponent == 1024);
12694 dump_float(x, std::integral_constant<
bool, is_ieee_single_or_double>());
12697 void dump_float(number_float_t x, std::true_type )
12699 char* begin = number_buffer.data();
12700 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
12702 o->write_characters(begin,
static_cast<size_t>(end - begin));
12705 void dump_float(number_float_t x, std::false_type )
12708 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
12711 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(),
"%.*g", d, x);
12716 assert(
static_cast<std::size_t>(len) < number_buffer.size());
12719 if (thousands_sep !=
'\0')
12721 const auto end = std::remove(number_buffer.begin(),
12722 number_buffer.begin() + len, thousands_sep);
12723 std::fill(end, number_buffer.end(),
'\0');
12724 assert((end - number_buffer.begin()) <= len);
12725 len = (end - number_buffer.begin());
12729 if (decimal_point !=
'\0' and decimal_point !=
'.')
12731 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
12732 if (dec_pos != number_buffer.end())
12738 o->write_characters(number_buffer.data(),
static_cast<std::size_t>(len));
12741 const bool value_is_int_like =
12742 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
12745 return c ==
'.' or c ==
'e';
12748 if (value_is_int_like)
12750 o->write_characters(
".0", 2);
12775 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep,
const std::uint8_t byte)
noexcept 12777 static const std::array<std::uint8_t, 400> utf8d =
12780 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12781 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12782 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12783 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12784 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
12785 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
12786 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
12787 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
12788 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
12789 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
12790 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1,
12791 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
12792 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1,
12793 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
12797 const std::uint8_t type = utf8d[byte];
12799 codep = (state != UTF8_ACCEPT)
12800 ? (byte & 0x3fu) | (codep << 6u)
12801 : (0xFFu >> type) & (byte);
12803 state = utf8d[256u + state * 16u + type];
12809 output_adapter_t<
char> o =
nullptr;
12812 std::array<
char, 64> number_buffer{{}};
12815 const std::lconv* loc =
nullptr;
12817 const char thousands_sep =
'\0';
12819 const char decimal_point =
'\0';
12822 std::array<
char, 512> string_buffer{{}};
12825 const char indent_char;
12827 string_t indent_string;
12830 const error_handler_t error_handler;
12933 template<detail::value_t>
friend struct detail::external_constructor;
12934 friend ::nlohmann::json_pointer<basic_json>;
12935 friend ::nlohmann::detail::parser<basic_json>;
12936 friend ::nlohmann::detail::serializer<basic_json>;
12937 template<
typename BasicJsonType>
12938 friend class ::nlohmann::detail::iter_impl;
12939 template<
typename BasicJsonType,
typename CharType>
12940 friend class ::nlohmann::detail::binary_writer;
12941 template<
typename BasicJsonType,
typename SAX>
12942 friend class ::nlohmann::detail::binary_reader;
12943 template<
typename BasicJsonType>
12944 friend class ::nlohmann::detail::json_sax_dom_parser;
12945 template<
typename BasicJsonType>
12946 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
12952 using lexer = ::nlohmann::detail::lexer<basic_json>;
12953 using parser = ::nlohmann::detail::parser<basic_json>;
12955 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
12956 template<
typename BasicJsonType>
12957 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
12958 template<
typename BasicJsonType>
12959 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
12960 template<
typename Iterator>
12961 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
12962 template<
typename Base>
using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
12964 template<
typename CharType>
12965 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
12967 using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
12968 template<
typename CharType>
using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
12970 using serializer = ::nlohmann::detail::serializer<basic_json>;
12973 using value_t = detail::value_t;
12975 using json_pointer = ::nlohmann::json_pointer<basic_json>;
12976 template<
typename T,
typename SFINAE>
12977 using json_serializer = JSONSerializer<T, SFINAE>;
12979 using error_handler_t = detail::error_handler_t;
12981 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
12983 using input_format_t = detail::input_format_t;
12985 using json_sax_t = json_sax<basic_json>;
12996 using exception = detail::exception;
12998 using parse_error = detail::parse_error;
13000 using invalid_iterator = detail::invalid_iterator;
13002 using type_error = detail::type_error;
13004 using out_of_range = detail::out_of_range;
13006 using other_error = detail::other_error;
13021 using value_type = basic_json;
13024 using reference = value_type&;
13026 using const_reference =
const value_type&;
13029 using difference_type = std::ptrdiff_t;
13031 using size_type = std::size_t;
13034 using allocator_type = AllocatorType<basic_json>;
13037 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
13039 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
13042 using iterator = iter_impl<basic_json>;
13044 using const_iterator = iter_impl<
const basic_json>;
13046 using reverse_iterator = json_reverse_iterator<
typename basic_json::iterator>;
13048 using const_reverse_iterator = json_reverse_iterator<
typename basic_json::const_iterator>;
13056 static allocator_type get_allocator()
13058 return allocator_type();
13088 static basic_json meta()
13092 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
13093 result[
"name"] =
"JSON for Modern C++";
13094 result[
"url"] =
"https://github.com/nlohmann/json";
13095 result[
"version"][
"string"] =
13104 result[
"platform"] =
"win32";
13105 #elif defined __linux__
13106 result[
"platform"] =
"linux";
13107 #elif defined __APPLE__ 13108 result[
"platform"] =
"apple";
13109 #elif defined __unix__ 13110 result[
"platform"] =
"unix";
13112 result[
"platform"] =
"unknown";
13115 #if defined(__ICC) || defined(__INTEL_COMPILER) 13116 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
13117 #elif defined(__clang__
) 13118 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
13119 #elif defined(__GNUC__) || defined(__GNUG__) 13120 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(__GNUC_PATCHLEVEL__)}};
13121 #elif defined(__HP_cc) || defined(__HP_aCC) 13122 result[
"compiler"] =
"hp" 13123 #elif defined(__IBMCPP__) 13124 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
13125 #elif defined(_MSC_VER) 13126 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
13127 #elif defined(__PGI) 13128 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
13129 #elif defined(__SUNPRO_CC) 13130 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
13132 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
13136 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
13138 result[
"compiler"][
"c++"] =
"unknown";
13153 #if defined(JSON_HAS_CPP_14) 13156 using object_comparator_t = std::less<>;
13158 using object_comparator_t = std::less<StringType>;
13244 using object_t = ObjectType<StringType,
13246 object_comparator_t,
13247 AllocatorType<std::pair<
const StringType,
13294 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
13347 using string_t = StringType;
13373 using boolean_t = BooleanType;
13445 using number_integer_t = NumberIntegerType;
13516 using number_unsigned_t = NumberUnsignedType;
13584 using number_float_t = NumberFloatType;
13591 template<
typename T,
typename... Args>
13592 static T* create(Args&& ... args)
13594 AllocatorType<T> alloc;
13595 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
13597 auto deleter = [&](T * object)
13599 AllocatorTraits::deallocate(alloc, object, 1);
13601 std::unique_ptr<T,
decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
13602 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
13603 assert(object !=
nullptr);
13604 return object.release();
13646 number_integer_t number_integer;
13648 number_unsigned_t number_unsigned;
13650 number_float_t number_float;
13653 json_value() =
default;
13655 json_value(boolean_t v)
noexcept : boolean(v) {}
13657 json_value(number_integer_t v)
noexcept : number_integer(v) {}
13659 json_value(number_unsigned_t v)
noexcept : number_unsigned(v) {}
13661 json_value(number_float_t v)
noexcept : number_float(v) {}
13663 json_value(value_t t)
13667 case value_t::object:
13669 object = create<object_t>();
13673 case value_t::array:
13675 array = create<array_t>();
13679 case value_t::string:
13681 string = create<string_t>(
"");
13685 case value_t::boolean:
13687 boolean = boolean_t(
false);
13691 case value_t::number_integer:
13693 number_integer = number_integer_t(0);
13697 case value_t::number_unsigned:
13699 number_unsigned = number_unsigned_t(0);
13703 case value_t::number_float:
13705 number_float = number_float_t(0.0);
13709 case value_t::null:
13720 JSON_THROW(other_error::create(500,
"961c151d2e87f2686a955a9be24d316f1362bf21 3.6.1"));
13728 json_value(
const string_t& value)
13730 string = create<string_t>(value);
13734 json_value(string_t&& value)
13736 string = create<string_t>(std::move(value));
13740 json_value(
const object_t& value)
13742 object = create<object_t>(value);
13746 json_value(object_t&& value)
13748 object = create<object_t>(std::move(value));
13752 json_value(
const array_t& value)
13754 array = create<array_t>(value);
13758 json_value(array_t&& value)
13760 array = create<array_t>(std::move(value));
13763 void destroy(value_t t)
noexcept 13767 case value_t::object:
13769 AllocatorType<object_t> alloc;
13770 std::allocator_traits<
decltype(alloc)>::destroy(alloc, object);
13771 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, object, 1);
13775 case value_t::array:
13777 AllocatorType<array_t> alloc;
13778 std::allocator_traits<
decltype(alloc)>::destroy(alloc, array);
13779 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, array, 1);
13783 case value_t::string:
13785 AllocatorType<string_t> alloc;
13786 std::allocator_traits<
decltype(alloc)>::destroy(alloc, string);
13787 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, string, 1);
13808 void assert_invariant()
const noexcept 13810 assert(m_type != value_t::object
or m_value.object !=
nullptr);
13811 assert(m_type != value_t::array
or m_value.array !=
nullptr);
13812 assert(m_type != value_t::string
or m_value.string !=
nullptr);
13835 using parse_event_t =
typename parser::parse_event_t;
13886 using parser_callback_t =
typename parser::parser_callback_t;
13926 basic_json(
const value_t v)
13927 : m_type(v), m_value(v)
13929 assert_invariant();
13950 basic_json(std::nullptr_t =
nullptr)
noexcept 13951 : basic_json(value_t::null)
13953 assert_invariant();
14013 template <
typename CompatibleType,
14014 typename U = detail::uncvref_t<CompatibleType>,
14015 detail::enable_if_t<
14016 not detail::is_basic_json<U>::value
and detail::is_compatible_type<basic_json_t, U>::value,
int> = 0>
14017 basic_json(CompatibleType && val)
noexcept(
noexcept(
14018 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
14019 std::forward<CompatibleType>(val))))
14021 JSONSerializer<U>::to_json(*
this, std::forward<CompatibleType>(val));
14022 assert_invariant();
14051 template <
typename BasicJsonType,
14052 detail::enable_if_t<
14053 detail::is_basic_json<BasicJsonType>::value
and not std::is_same<basic_json, BasicJsonType>::value,
int> = 0>
14054 basic_json(
const BasicJsonType& val)
14056 using other_boolean_t =
typename BasicJsonType::boolean_t;
14057 using other_number_float_t =
typename BasicJsonType::number_float_t;
14058 using other_number_integer_t =
typename BasicJsonType::number_integer_t;
14059 using other_number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
14060 using other_string_t =
typename BasicJsonType::string_t;
14061 using other_object_t =
typename BasicJsonType::object_t;
14062 using other_array_t =
typename BasicJsonType::array_t;
14064 switch (val.type())
14066 case value_t::boolean:
14067 JSONSerializer<other_boolean_t>::to_json(*
this, val.
template get<other_boolean_t>());
14069 case value_t::number_float:
14070 JSONSerializer<other_number_float_t>::to_json(*
this, val.
template get<other_number_float_t>());
14072 case value_t::number_integer:
14073 JSONSerializer<other_number_integer_t>::to_json(*
this, val.
template get<other_number_integer_t>());
14075 case value_t::number_unsigned:
14076 JSONSerializer<other_number_unsigned_t>::to_json(*
this, val.
template get<other_number_unsigned_t>());
14078 case value_t::string:
14079 JSONSerializer<other_string_t>::to_json(*
this, val.
template get_ref<
const other_string_t&>());
14081 case value_t::object:
14082 JSONSerializer<other_object_t>::to_json(*
this, val.
template get_ref<
const other_object_t&>());
14084 case value_t::array:
14085 JSONSerializer<other_array_t>::to_json(*
this, val.
template get_ref<
const other_array_t&>());
14087 case value_t::null:
14090 case value_t::discarded:
14091 m_type = value_t::discarded;
14096 assert_invariant();
14173 basic_json(initializer_list_t init,
14174 bool type_deduction =
true,
14175 value_t manual_type = value_t::array)
14179 bool is_an_object = std::all_of(init.begin(), init.end(),
14180 [](
const detail::json_ref<basic_json>& element_ref)
14182 return element_ref->is_array()
and element_ref->size() == 2
and (*element_ref)[0].is_string();
14186 if (
not type_deduction)
14189 if (manual_type == value_t::array)
14191 is_an_object =
false;
14195 if (
JSON_UNLIKELY(manual_type == value_t::object
and not is_an_object))
14197 JSON_THROW(type_error::create(301,
"cannot create object from initializer list"));
14204 m_type = value_t::object;
14205 m_value = value_t::object;
14207 std::for_each(init.begin(), init.end(), [
this](
const detail::json_ref<basic_json>& element_ref)
14209 auto element = element_ref.moved_or_copied();
14210 m_value.object->emplace(
14211 std::move(*((*element.m_value.array)[0].m_value.string)),
14212 std::move((*element.m_value.array)[1]));
14218 m_type = value_t::array;
14219 m_value.array = create<array_t>(init.begin(), init.end());
14222 assert_invariant();
14263 static basic_json array(initializer_list_t init = {})
14265 return basic_json(init,
false, value_t::array);
14307 static basic_json object(initializer_list_t init = {})
14309 return basic_json(init,
false, value_t::object);
14334 basic_json(size_type cnt,
const basic_json& val)
14335 : m_type(value_t::array)
14337 m_value.array = create<array_t>(cnt, val);
14338 assert_invariant();
14396 template<
class InputIT,
typename std::enable_if<
14397 std::is_same<InputIT,
typename basic_json_t::iterator>::value
or 14398 std::is_same<InputIT,
typename basic_json_t::const_iterator>::value,
int>::type = 0>
14399 basic_json(InputIT first, InputIT last)
14401 assert(first.m_object !=
nullptr);
14402 assert(last.m_object !=
nullptr);
14407 JSON_THROW(invalid_iterator::create(201,
"iterators are not compatible"));
14411 m_type = first.m_object->m_type;
14416 case value_t::boolean:
14417 case value_t::number_float:
14418 case value_t::number_integer:
14419 case value_t::number_unsigned:
14420 case value_t::string:
14422 if (
JSON_UNLIKELY(
not first.m_it.primitive_iterator.is_begin()
14423 or not last.m_it.primitive_iterator.is_end()))
14425 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
14436 case value_t::number_integer:
14438 m_value.number_integer = first.m_object->m_value.number_integer;
14442 case value_t::number_unsigned:
14444 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
14448 case value_t::number_float:
14450 m_value.number_float = first.m_object->m_value.number_float;
14454 case value_t::boolean:
14456 m_value.boolean = first.m_object->m_value.boolean;
14460 case value_t::string:
14462 m_value = *first.m_object->m_value.string;
14466 case value_t::object:
14468 m_value.object = create<object_t>(first.m_it.object_iterator,
14469 last.m_it.object_iterator);
14473 case value_t::array:
14475 m_value.array = create<array_t>(first.m_it.array_iterator,
14476 last.m_it.array_iterator);
14481 JSON_THROW(invalid_iterator::create(206,
"cannot construct with iterators from " +
14482 std::string(first.m_object->type_name())));
14485 assert_invariant();
14494 basic_json(
const detail::json_ref<basic_json>& ref)
14495 : basic_json(ref.moved_or_copied())
14523 basic_json(
const basic_json& other)
14524 : m_type(other.m_type)
14527 other.assert_invariant();
14531 case value_t::object:
14533 m_value = *other.m_value.object;
14537 case value_t::array:
14539 m_value = *other.m_value.array;
14543 case value_t::string:
14545 m_value = *other.m_value.string;
14549 case value_t::boolean:
14551 m_value = other.m_value.boolean;
14555 case value_t::number_integer:
14557 m_value = other.m_value.number_integer;
14561 case value_t::number_unsigned:
14563 m_value = other.m_value.number_unsigned;
14567 case value_t::number_float:
14569 m_value = other.m_value.number_float;
14577 assert_invariant();
14606 basic_json(basic_json&& other)
noexcept 14607 : m_type(std::move(other.m_type)),
14608 m_value(std::move(other.m_value))
14611 other.assert_invariant();
14614 other.m_type = value_t::null;
14615 other.m_value = {};
14617 assert_invariant();
14643 basic_json& operator=(basic_json other)
noexcept (
14644 std::is_nothrow_move_constructible<value_t>::value
and 14645 std::is_nothrow_move_assignable<value_t>::value
and 14646 std::is_nothrow_move_constructible<json_value>::value
and 14647 std::is_nothrow_move_assignable<json_value>::value
14651 other.assert_invariant();
14654 swap(m_type, other.m_type);
14655 swap(m_value, other.m_value);
14657 assert_invariant();
14676 ~basic_json()
noexcept 14678 assert_invariant();
14679 m_value.destroy(m_type);
14734 string_t dump(
const int indent = -1,
14735 const char indent_char =
' ',
14736 const bool ensure_ascii =
false,
14737 const error_handler_t error_handler = error_handler_t::strict)
const 14740 serializer s(detail::output_adapter<
char, string_t>(result), indent_char, error_handler);
14744 s.dump(*
this,
true, ensure_ascii,
static_cast<
unsigned int>(indent));
14748 s.dump(*
this,
false, ensure_ascii, 0);
14786 constexpr value_t type()
const noexcept 14816 constexpr bool is_primitive()
const noexcept 14818 return is_null()
or is_string()
or is_boolean()
or is_number();
14843 constexpr bool is_structured()
const noexcept 14845 return is_array()
or is_object();
14865 constexpr bool is_null()
const noexcept 14867 return m_type == value_t::null;
14887 constexpr bool is_boolean()
const noexcept 14889 return m_type == value_t::boolean;
14917 constexpr bool is_number()
const noexcept 14919 return is_number_integer()
or is_number_float();
14946 constexpr bool is_number_integer()
const noexcept 14948 return m_type == value_t::number_integer
or m_type == value_t::number_unsigned;
14974 constexpr bool is_number_unsigned()
const noexcept 14976 return m_type == value_t::number_unsigned;
15002 constexpr bool is_number_float()
const noexcept 15004 return m_type == value_t::number_float;
15024 constexpr bool is_object()
const noexcept 15026 return m_type == value_t::object;
15046 constexpr bool is_array()
const noexcept 15048 return m_type == value_t::array;
15068 constexpr bool is_string()
const noexcept 15070 return m_type == value_t::string;
15095 constexpr bool is_discarded()
const noexcept 15097 return m_type == value_t::discarded;
15121 constexpr operator value_t()
const noexcept 15134 boolean_t get_impl(boolean_t* )
const 15138 return m_value.boolean;
15141 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(type_name())));
15145 object_t* get_impl_ptr(object_t* )
noexcept 15147 return is_object() ? m_value.object :
nullptr;
15151 constexpr const object_t* get_impl_ptr(
const object_t* )
const noexcept 15153 return is_object() ? m_value.object :
nullptr;
15157 array_t* get_impl_ptr(array_t* )
noexcept 15159 return is_array() ? m_value.array :
nullptr;
15163 constexpr const array_t* get_impl_ptr(
const array_t* )
const noexcept 15165 return is_array() ? m_value.array :
nullptr;
15169 string_t* get_impl_ptr(string_t* )
noexcept 15171 return is_string() ? m_value.string :
nullptr;
15175 constexpr const string_t* get_impl_ptr(
const string_t* )
const noexcept 15177 return is_string() ? m_value.string :
nullptr;
15181 boolean_t* get_impl_ptr(boolean_t* )
noexcept 15183 return is_boolean() ? &m_value.boolean :
nullptr;
15187 constexpr const boolean_t* get_impl_ptr(
const boolean_t* )
const noexcept 15189 return is_boolean() ? &m_value.boolean :
nullptr;
15193 number_integer_t* get_impl_ptr(number_integer_t* )
noexcept 15195 return is_number_integer() ? &m_value.number_integer :
nullptr;
15199 constexpr const number_integer_t* get_impl_ptr(
const number_integer_t* )
const noexcept 15201 return is_number_integer() ? &m_value.number_integer :
nullptr;
15205 number_unsigned_t* get_impl_ptr(number_unsigned_t* )
noexcept 15207 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
15211 constexpr const number_unsigned_t* get_impl_ptr(
const number_unsigned_t* )
const noexcept 15213 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
15217 number_float_t* get_impl_ptr(number_float_t* )
noexcept 15219 return is_number_float() ? &m_value.number_float :
nullptr;
15223 constexpr const number_float_t* get_impl_ptr(
const number_float_t* )
const noexcept 15225 return is_number_float() ? &m_value.number_float :
nullptr;
15239 template<
typename ReferenceType,
typename ThisType>
15240 static ReferenceType get_ref_impl(ThisType& obj)
15243 auto ptr = obj.
template get_ptr<
typename std::add_pointer<ReferenceType>::type>();
15250 JSON_THROW(type_error::create(303,
"incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
15272 template<
typename BasicJsonType, detail::enable_if_t<
15273 std::is_same<
typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
15275 basic_json get()
const 15295 template<
typename BasicJsonType, detail::enable_if_t<
15296 not std::is_same<BasicJsonType, basic_json>::value
and 15297 detail::is_basic_json<BasicJsonType>::value,
int> = 0>
15298 BasicJsonType get()
const 15342 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
15343 detail::enable_if_t <
15344 not detail::is_basic_json<ValueType>::value
and 15345 detail::has_from_json<basic_json_t, ValueType>::value
and 15346 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
15348 ValueType get()
const noexcept(
noexcept(
15349 JSONSerializer<ValueType>::from_json(std::declval<
const basic_json_t&>(), std::declval<ValueType&>())))
15354 static_assert(
not std::is_reference<ValueTypeCV>::value,
15355 "get() cannot be used with reference types, you might want to use get_ref()");
15356 static_assert(std::is_default_constructible<ValueType>::value,
15357 "types must be DefaultConstructible when used with get()");
15360 JSONSerializer<ValueType>::from_json(*
this, ret);
15395 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
15396 detail::enable_if_t<
not std::is_same<basic_json_t, ValueType>::value
and 15397 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
15399 ValueType get()
const noexcept(
noexcept(
15400 JSONSerializer<ValueTypeCV>::from_json(std::declval<
const basic_json_t&>())))
15402 static_assert(
not std::is_reference<ValueTypeCV>::value,
15403 "get() cannot be used with reference types, you might want to use get_ref()");
15404 return JSONSerializer<ValueTypeCV>::from_json(*
this);
15440 template<
typename ValueType,
15441 detail::enable_if_t <
15442 not detail::is_basic_json<ValueType>::value
and 15443 detail::has_from_json<basic_json_t, ValueType>::value,
15445 ValueType & get_to(ValueType& v)
const noexcept(
noexcept(
15446 JSONSerializer<ValueType>::from_json(std::declval<
const basic_json_t&>(), v)))
15448 JSONSerializer<ValueType>::from_json(*
this, v);
15479 template<
typename PointerType,
typename std::enable_if<
15480 std::is_pointer<PointerType>::value,
int>::type = 0>
15481 auto get_ptr()
noexcept ->
decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
15484 return get_impl_ptr(
static_cast<PointerType>(
nullptr));
15491 template<
typename PointerType,
typename std::enable_if<
15492 std::is_pointer<PointerType>::value
and 15493 std::is_const<
typename std::remove_pointer<PointerType>::type>::value,
int>::type = 0>
15494 constexpr auto get_ptr()
const noexcept ->
decltype(std::declval<
const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
15497 return get_impl_ptr(
static_cast<PointerType>(
nullptr));
15527 template<
typename PointerType,
typename std::enable_if<
15528 std::is_pointer<PointerType>::value,
int>::type = 0>
15529 auto get()
noexcept ->
decltype(std::declval<basic_json_t&>().
template get_ptr<PointerType>())
15532 return get_ptr<PointerType>();
15539 template<
typename PointerType,
typename std::enable_if<
15540 std::is_pointer<PointerType>::value,
int>::type = 0>
15541 constexpr auto get()
const noexcept ->
decltype(std::declval<
const basic_json_t&>().
template get_ptr<PointerType>())
15544 return get_ptr<PointerType>();
15573 template<
typename ReferenceType,
typename std::enable_if<
15574 std::is_reference<ReferenceType>::value,
int>::type = 0>
15575 ReferenceType get_ref()
15578 return get_ref_impl<ReferenceType>(*
this);
15585 template<
typename ReferenceType,
typename std::enable_if<
15586 std::is_reference<ReferenceType>::value
and 15587 std::is_const<
typename std::remove_reference<ReferenceType>::type>::value,
int>::type = 0>
15588 ReferenceType get_ref()
const 15591 return get_ref_impl<ReferenceType>(*
this);
15623 template <
typename ValueType,
typename std::enable_if <
15624 not std::is_pointer<ValueType>::value
and 15625 not std::is_same<ValueType, detail::json_ref<basic_json>>::value
and 15626 not std::is_same<ValueType,
typename string_t::value_type>::value
and 15627 not detail::is_basic_json<ValueType>::value
15630 and not std::is_same<ValueType, std::initializer_list<
typename string_t::value_type>>::value
15631 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__
) || (defined(_MSC_VER) and _MSC_VER <= 1914
)) 15632 and not std::is_same<ValueType,
typename std::string_view>::value
15635 and detail::is_detected<detail::get_template_function,
const basic_json_t&, ValueType>::value
15636 ,
int >::type = 0 >
15637 operator ValueType()
const 15640 return get<ValueType>();
15680 reference at(size_type idx)
15687 return m_value.array->at(idx);
15692 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
15697 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
15727 const_reference at(size_type idx)
const 15734 return m_value.array->at(idx);
15739 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
15744 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
15778 reference at(
const typename object_t::key_type& key)
15785 return m_value.object->at(key);
15790 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
15795 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
15829 const_reference at(
const typename object_t::key_type& key)
const 15836 return m_value.object->at(key);
15841 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
15846 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
15875 reference operator[](size_type idx)
15880 m_type = value_t::array;
15881 m_value.array = create<array_t>();
15882 assert_invariant();
15889 if (idx >= m_value.array->size())
15891 m_value.array->insert(m_value.array->end(),
15892 idx - m_value.array->size() + 1,
15896 return m_value.array->operator[](idx);
15899 JSON_THROW(type_error::create(305,
"cannot use operator[] with a numeric argument with " + std::string(type_name())));
15921 const_reference operator[](size_type idx)
const 15926 return m_value.array->operator[](idx);
15929 JSON_THROW(type_error::create(305,
"cannot use operator[] with a numeric argument with " + std::string(type_name())));
15959 reference operator[](
const typename object_t::key_type& key)
15964 m_type = value_t::object;
15965 m_value.object = create<object_t>();
15966 assert_invariant();
15972 return m_value.object->operator[](key);
15975 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
16008 const_reference operator[](
const typename object_t::key_type& key)
const 16013 assert(m_value.object->find(key) != m_value.object->end());
16014 return m_value.object->find(key)->second;
16017 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
16047 template<
typename T>
16048 reference operator[](T* key)
16053 m_type = value_t::object;
16054 m_value = value_t::object;
16055 assert_invariant();
16061 return m_value.object->operator[](key);
16064 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
16097 template<
typename T>
16098 const_reference operator[](T* key)
const 16103 assert(m_value.object->find(key) != m_value.object->end());
16104 return m_value.object->find(key)->second;
16107 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
16158 template<
class ValueType,
typename std::enable_if<
16159 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
16160 ValueType value(
const typename object_t::key_type& key,
const ValueType& default_value)
const 16166 const auto it = find(key);
16172 return default_value;
16175 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
16182 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 16184 return value(key, string_t(default_value));
16228 template<
class ValueType,
typename std::enable_if<
16229 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
16230 ValueType value(
const json_pointer& ptr,
const ValueType& default_value)
const 16238 return ptr.get_checked(
this);
16242 return default_value;
16246 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
16253 string_t value(
const json_pointer& ptr,
const char* default_value)
const 16255 return value(ptr, string_t(default_value));
16291 const_reference front()
const 16337 const_reference back()
const 16390 template<
class IteratorType,
typename std::enable_if<
16391 std::is_same<IteratorType,
typename basic_json_t::iterator>::value
or 16392 std::is_same<IteratorType,
typename basic_json_t::const_iterator>::value,
int>::type
16394 IteratorType erase(IteratorType pos)
16399 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
16402 IteratorType result = end();
16406 case value_t::boolean:
16407 case value_t::number_float:
16408 case value_t::number_integer:
16409 case value_t::number_unsigned:
16410 case value_t::string:
16412 if (
JSON_UNLIKELY(
not pos.m_it.primitive_iterator.is_begin()))
16414 JSON_THROW(invalid_iterator::create(205,
"iterator out of range"));
16419 AllocatorType<string_t> alloc;
16420 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_value.string);
16421 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_value.string, 1);
16422 m_value.string =
nullptr;
16425 m_type = value_t::null;
16426 assert_invariant();
16430 case value_t::object:
16432 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
16436 case value_t::array:
16438 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
16443 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
16495 template<
class IteratorType,
typename std::enable_if<
16496 std::is_same<IteratorType,
typename basic_json_t::iterator>::value
or 16497 std::is_same<IteratorType,
typename basic_json_t::const_iterator>::value,
int>::type
16499 IteratorType erase(IteratorType first, IteratorType last)
16502 if (
JSON_UNLIKELY(
this != first.m_object
or this != last.m_object))
16504 JSON_THROW(invalid_iterator::create(203,
"iterators do not fit current value"));
16507 IteratorType result = end();
16511 case value_t::boolean:
16512 case value_t::number_float:
16513 case value_t::number_integer:
16514 case value_t::number_unsigned:
16515 case value_t::string:
16517 if (
JSON_LIKELY(
not first.m_it.primitive_iterator.is_begin()
16518 or not last.m_it.primitive_iterator.is_end()))
16520 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
16525 AllocatorType<string_t> alloc;
16526 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_value.string);
16527 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_value.string, 1);
16528 m_value.string =
nullptr;
16531 m_type = value_t::null;
16532 assert_invariant();
16536 case value_t::object:
16538 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
16539 last.m_it.object_iterator);
16543 case value_t::array:
16545 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
16546 last.m_it.array_iterator);
16551 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
16586 size_type erase(
const typename object_t::key_type& key)
16591 return m_value.object->erase(key);
16594 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
16621 void erase(
const size_type idx)
16628 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
16631 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
16635 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
16673 template<
typename KeyT>
16674 iterator find(KeyT&& key)
16676 auto result = end();
16680 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
16690 template<
typename KeyT>
16691 const_iterator find(KeyT&& key)
const 16693 auto result = cend();
16697 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
16724 template<
typename KeyT>
16725 size_type count(KeyT&& key)
const 16728 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
16755 template<
typename KeyT>
16756 bool contains(KeyT&& key)
const 16758 return is_object()
and m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
16795 iterator begin()
noexcept 16797 iterator result(
this);
16798 result.set_begin();
16805 const_iterator begin()
const noexcept 16835 const_iterator cbegin()
const noexcept 16837 const_iterator result(
this);
16838 result.set_begin();
16866 iterator end()
noexcept 16868 iterator result(
this);
16876 const_iterator end()
const noexcept 16906 const_iterator cend()
const noexcept 16908 const_iterator result(
this);
16936 reverse_iterator rbegin()
noexcept 16938 return reverse_iterator(end());
16944 const_reverse_iterator rbegin()
const noexcept 16973 reverse_iterator rend()
noexcept 16975 return reverse_iterator(begin());
16981 const_reverse_iterator rend()
const noexcept 17010 const_reverse_iterator crbegin()
const noexcept 17012 return const_reverse_iterator(cend());
17039 const_reverse_iterator crend()
const noexcept 17041 return const_reverse_iterator(cbegin());
17103 static iteration_proxy<iterator> iterator_wrapper(reference ref)
noexcept 17105 return ref.items();
17112 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref)
noexcept 17114 return ref.items();
17180 iteration_proxy<iterator> items()
noexcept 17182 return iteration_proxy<iterator>(*
this);
17188 iteration_proxy<const_iterator> items()
const noexcept 17190 return iteration_proxy<const_iterator>(*
this);
17244 bool empty()
const noexcept 17248 case value_t::null:
17254 case value_t::array:
17257 return m_value.array->empty();
17260 case value_t::object:
17263 return m_value.object->empty();
17316 size_type size()
const noexcept 17320 case value_t::null:
17326 case value_t::array:
17329 return m_value.array->size();
17332 case value_t::object:
17335 return m_value.object->size();
17386 size_type max_size()
const noexcept 17390 case value_t::array:
17393 return m_value.array->max_size();
17396 case value_t::object:
17399 return m_value.object->max_size();
17456 void clear()
noexcept 17460 case value_t::number_integer:
17462 m_value.number_integer = 0;
17466 case value_t::number_unsigned:
17468 m_value.number_unsigned = 0;
17472 case value_t::number_float:
17474 m_value.number_float = 0.0;
17478 case value_t::boolean:
17480 m_value.boolean =
false;
17484 case value_t::string:
17486 m_value.string->clear();
17490 case value_t::array:
17492 m_value.array->clear();
17496 case value_t::object:
17498 m_value.object->clear();
17527 void push_back(basic_json&& val)
17532 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
17538 m_type = value_t::array;
17539 m_value = value_t::array;
17540 assert_invariant();
17544 m_value.array->push_back(std::move(val));
17547 val.m_type = value_t::null;
17554 reference operator+=(basic_json&& val)
17556 push_back(std::move(val));
17564 void push_back(
const basic_json& val)
17569 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
17575 m_type = value_t::array;
17576 m_value = value_t::array;
17577 assert_invariant();
17581 m_value.array->push_back(val);
17588 reference operator+=(
const basic_json& val)
17614 void push_back(
const typename object_t::value_type& val)
17619 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
17625 m_type = value_t::object;
17626 m_value = value_t::object;
17627 assert_invariant();
17631 m_value.object->insert(val);
17638 reference operator+=(
const typename object_t::value_type& val)
17669 void push_back(initializer_list_t init)
17671 if (is_object()
and init.size() == 2
and (*init.begin())->is_string())
17673 basic_json&& key = init.begin()->moved_or_copied();
17674 push_back(
typename object_t::value_type(
17675 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
17679 push_back(basic_json(init));
17687 reference operator+=(initializer_list_t init)
17714 template<
class... Args>
17715 void emplace_back(Args&& ... args)
17720 JSON_THROW(type_error::create(311,
"cannot use emplace_back() with " + std::string(type_name())));
17726 m_type = value_t::array;
17727 m_value = value_t::array;
17728 assert_invariant();
17732 m_value.array->emplace_back(std::forward<Args>(args)...);
17762 template<
class... Args>
17763 std::pair<iterator,
bool> emplace(Args&& ... args)
17768 JSON_THROW(type_error::create(311,
"cannot use emplace() with " + std::string(type_name())));
17774 m_type = value_t::object;
17775 m_value = value_t::object;
17776 assert_invariant();
17780 auto res = m_value.object->emplace(std::forward<Args>(args)...);
17783 it.m_it.object_iterator = res.first;
17786 return {it, res.second};
17792 template<
typename... Args>
17793 iterator insert_iterator(const_iterator pos, Args&& ... args)
17795 iterator result(
this);
17796 assert(m_value.array !=
nullptr);
17798 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
17799 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
17800 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
17831 iterator insert(const_iterator pos,
const basic_json& val)
17839 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
17843 return insert_iterator(pos, val);
17846 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
17853 iterator insert(const_iterator pos, basic_json&& val)
17855 return insert(pos, val);
17882 iterator insert(const_iterator pos, size_type cnt,
const basic_json& val)
17890 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
17894 return insert_iterator(pos, cnt, val);
17897 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
17930 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
17935 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
17941 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
17947 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
17952 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container"));
17956 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
17983 iterator insert(const_iterator pos, initializer_list_t ilist)
17988 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
17994 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
17998 return insert_iterator(pos, ilist.begin(), ilist.end());
18024 void insert(const_iterator first, const_iterator last)
18029 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
18035 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
18041 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
18044 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
18066 void update(const_reference j)
18071 m_type = value_t::object;
18072 m_value.object = create<object_t>();
18073 assert_invariant();
18078 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
18082 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(j.type_name())));
18085 for (
auto it = j.cbegin(); it != j.cend(); ++it)
18087 m_value.object->operator[](it.key()) = it.value();
18117 void update(const_iterator first, const_iterator last)
18122 m_type = value_t::object;
18123 m_value.object = create<object_t>();
18124 assert_invariant();
18129 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
18135 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
18140 or not last.m_object->is_object()))
18142 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
18145 for (
auto it = first; it != last; ++it)
18147 m_value.object->operator[](it.key()) = it.value();
18168 void swap(reference other)
noexcept (
18169 std::is_nothrow_move_constructible<value_t>::value
and 18170 std::is_nothrow_move_assignable<value_t>::value
and 18171 std::is_nothrow_move_constructible<json_value>::value
and 18172 std::is_nothrow_move_assignable<json_value>::value
18175 std::swap(m_type, other.m_type);
18176 std::swap(m_value, other.m_value);
18177 assert_invariant();
18200 void swap(array_t& other)
18205 std::swap(*(m_value.array), other);
18209 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
18233 void swap(object_t& other)
18238 std::swap(*(m_value.object), other);
18242 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
18266 void swap(string_t& other)
18271 std::swap(*(m_value.string), other);
18275 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
18328 friend bool operator==(const_reference lhs, const_reference rhs)
noexcept 18330 const auto lhs_type = lhs.type();
18331 const auto rhs_type = rhs.type();
18333 if (lhs_type == rhs_type)
18337 case value_t::array:
18338 return *lhs.m_value.array == *rhs.m_value.array;
18340 case value_t::object:
18341 return *lhs.m_value.object == *rhs.m_value.object;
18343 case value_t::null:
18346 case value_t::string:
18347 return *lhs.m_value.string == *rhs.m_value.string;
18349 case value_t::boolean:
18350 return lhs.m_value.boolean == rhs.m_value.boolean;
18352 case value_t::number_integer:
18353 return lhs.m_value.number_integer == rhs.m_value.number_integer;
18355 case value_t::number_unsigned:
18356 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
18358 case value_t::number_float:
18359 return lhs.m_value.number_float == rhs.m_value.number_float;
18365 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_float)
18367 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
18369 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_integer)
18371 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
18373 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_float)
18375 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
18377 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_unsigned)
18379 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
18381 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_integer)
18383 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
18385 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_unsigned)
18387 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
18397 template<
typename ScalarType,
typename std::enable_if<
18398 std::is_scalar<ScalarType>::value,
int>::type = 0>
18399 friend bool operator==(const_reference lhs,
const ScalarType rhs)
noexcept 18401 return lhs == basic_json(rhs);
18408 template<
typename ScalarType,
typename std::enable_if<
18409 std::is_scalar<ScalarType>::value,
int>::type = 0>
18410 friend bool operator==(
const ScalarType lhs, const_reference rhs)
noexcept 18412 return basic_json(lhs) == rhs;
18433 friend bool operator!=(const_reference lhs, const_reference rhs)
noexcept 18435 return not (lhs == rhs);
18442 template<
typename ScalarType,
typename std::enable_if<
18443 std::is_scalar<ScalarType>::value,
int>::type = 0>
18444 friend bool operator!=(const_reference lhs,
const ScalarType rhs)
noexcept 18446 return lhs != basic_json(rhs);
18453 template<
typename ScalarType,
typename std::enable_if<
18454 std::is_scalar<ScalarType>::value,
int>::type = 0>
18455 friend bool operator!=(
const ScalarType lhs, const_reference rhs)
noexcept 18457 return basic_json(lhs) != rhs;
18486 friend bool operator<(const_reference lhs, const_reference rhs)
noexcept 18488 const auto lhs_type = lhs.type();
18489 const auto rhs_type = rhs.type();
18491 if (lhs_type == rhs_type)
18495 case value_t::array:
18498 return (*lhs.m_value.array) < (*rhs.m_value.array);
18500 case value_t::object:
18501 return *lhs.m_value.object < *rhs.m_value.object;
18503 case value_t::null:
18506 case value_t::string:
18507 return *lhs.m_value.string < *rhs.m_value.string;
18509 case value_t::boolean:
18510 return lhs.m_value.boolean < rhs.m_value.boolean;
18512 case value_t::number_integer:
18513 return lhs.m_value.number_integer < rhs.m_value.number_integer;
18515 case value_t::number_unsigned:
18516 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
18518 case value_t::number_float:
18519 return lhs.m_value.number_float < rhs.m_value.number_float;
18525 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_float)
18527 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
18529 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_integer)
18531 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
18533 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_float)
18535 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
18537 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_unsigned)
18539 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
18541 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_unsigned)
18543 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
18545 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_integer)
18547 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
18553 return operator<(lhs_type, rhs_type);
18560 template<
typename ScalarType,
typename std::enable_if<
18561 std::is_scalar<ScalarType>::value,
int>::type = 0>
18562 friend bool operator<(const_reference lhs,
const ScalarType rhs)
noexcept 18564 return lhs < basic_json(rhs);
18571 template<
typename ScalarType,
typename std::enable_if<
18572 std::is_scalar<ScalarType>::value,
int>::type = 0>
18573 friend bool operator<(
const ScalarType lhs, const_reference rhs)
noexcept 18575 return basic_json(lhs) < rhs;
18597 friend bool operator<=(const_reference lhs, const_reference rhs)
noexcept 18599 return not (rhs < lhs);
18606 template<
typename ScalarType,
typename std::enable_if<
18607 std::is_scalar<ScalarType>::value,
int>::type = 0>
18608 friend bool operator<=(const_reference lhs,
const ScalarType rhs)
noexcept 18610 return lhs <= basic_json(rhs);
18617 template<
typename ScalarType,
typename std::enable_if<
18618 std::is_scalar<ScalarType>::value,
int>::type = 0>
18619 friend bool operator<=(
const ScalarType lhs, const_reference rhs)
noexcept 18621 return basic_json(lhs) <= rhs;
18643 friend bool operator>(const_reference lhs, const_reference rhs)
noexcept 18645 return not (lhs <= rhs);
18652 template<
typename ScalarType,
typename std::enable_if<
18653 std::is_scalar<ScalarType>::value,
int>::type = 0>
18654 friend bool operator>(const_reference lhs,
const ScalarType rhs)
noexcept 18656 return lhs > basic_json(rhs);
18663 template<
typename ScalarType,
typename std::enable_if<
18664 std::is_scalar<ScalarType>::value,
int>::type = 0>
18665 friend bool operator>(
const ScalarType lhs, const_reference rhs)
noexcept 18667 return basic_json(lhs) > rhs;
18689 friend bool operator>=(const_reference lhs, const_reference rhs)
noexcept 18691 return not (lhs < rhs);
18698 template<
typename ScalarType,
typename std::enable_if<
18699 std::is_scalar<ScalarType>::value,
int>::type = 0>
18700 friend bool operator>=(const_reference lhs,
const ScalarType rhs)
noexcept 18702 return lhs >= basic_json(rhs);
18709 template<
typename ScalarType,
typename std::enable_if<
18710 std::is_scalar<ScalarType>::value,
int>::type = 0>
18711 friend bool operator>=(
const ScalarType lhs, const_reference rhs)
noexcept 18713 return basic_json(lhs) >= rhs;
18756 friend std::ostream& operator<<(std::ostream& o,
const basic_json& j)
18759 const bool pretty_print = o.width() > 0;
18760 const auto indentation = pretty_print ? o.width() : 0;
18766 serializer s(detail::output_adapter<
char>(o), o.fill());
18767 s.dump(j, pretty_print,
false,
static_cast<
unsigned int>(indentation));
18780 friend std::ostream& operator>>(
const basic_json& j, std::ostream& o)
18859 static basic_json parse(detail::input_adapter&& i,
18860 const parser_callback_t cb =
nullptr,
18861 const bool allow_exceptions =
true)
18864 parser(i, cb, allow_exceptions).parse(
true, result);
18868 static bool accept(detail::input_adapter&& i)
18870 return parser(i).accept(
true);
18926 template <
typename SAX>
18927 static bool sax_parse(detail::input_adapter&& i, SAX* sax,
18928 input_format_t format = input_format_t::json,
18929 const bool strict =
true)
18932 return format == input_format_t::json
18933 ? parser(std::move(i)).sax_parse(sax, strict)
18934 : detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
18986 template<
class IteratorType,
typename std::enable_if<
18988 std::random_access_iterator_tag,
18989 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
18990 static basic_json parse(IteratorType first, IteratorType last,
18991 const parser_callback_t cb =
nullptr,
18992 const bool allow_exceptions =
true)
18995 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(
true, result);
18999 template<
class IteratorType,
typename std::enable_if<
19001 std::random_access_iterator_tag,
19002 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
19003 static bool accept(IteratorType first, IteratorType last)
19005 return parser(detail::input_adapter(first, last)).accept(
true);
19008 template<
class IteratorType,
class SAX,
typename std::enable_if<
19010 std::random_access_iterator_tag,
19011 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
19012 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
19014 return parser(detail::input_adapter(first, last)).sax_parse(sax);
19026 friend std::istream& operator<<(basic_json& j, std::istream& i)
19028 return operator>>(i, j);
19056 friend std::istream& operator>>(std::istream& i, basic_json& j)
19058 parser(detail::input_adapter(i)).parse(
false, j);
19098 const char* type_name()
const noexcept 19103 case value_t::null:
19105 case value_t::object:
19107 case value_t::array:
19109 case value_t::string:
19111 case value_t::boolean:
19113 case value_t::discarded:
19114 return "discarded";
19128 value_t m_type = value_t::null;
19131 json_value m_value = {};
19229 static std::vector<uint8_t> to_cbor(
const basic_json& j)
19231 std::vector<uint8_t> result;
19232 to_cbor(j, result);
19236 static void to_cbor(
const basic_json& j, detail::output_adapter<uint8_t> o)
19238 binary_writer<uint8_t>(o).write_cbor(j);
19241 static void to_cbor(
const basic_json& j, detail::output_adapter<
char> o)
19243 binary_writer<
char>(o).write_cbor(j);
19325 static std::vector<uint8_t> to_msgpack(
const basic_json& j)
19327 std::vector<uint8_t> result;
19328 to_msgpack(j, result);
19332 static void to_msgpack(
const basic_json& j, detail::output_adapter<uint8_t> o)
19334 binary_writer<uint8_t>(o).write_msgpack(j);
19337 static void to_msgpack(
const basic_json& j, detail::output_adapter<
char> o)
19339 binary_writer<
char>(o).write_msgpack(j);
19422 static std::vector<uint8_t> to_ubjson(
const basic_json& j,
19423 const bool use_size =
false,
19424 const bool use_type =
false)
19426 std::vector<uint8_t> result;
19427 to_ubjson(j, result, use_size, use_type);
19431 static void to_ubjson(
const basic_json& j, detail::output_adapter<uint8_t> o,
19432 const bool use_size =
false,
const bool use_type =
false)
19434 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
19437 static void to_ubjson(
const basic_json& j, detail::output_adapter<
char> o,
19438 const bool use_size =
false,
const bool use_type =
false)
19440 binary_writer<
char>(o).write_ubjson(j, use_size, use_type);
19499 static std::vector<uint8_t> to_bson(
const basic_json& j)
19501 std::vector<uint8_t> result;
19502 to_bson(j, result);
19514 static void to_bson(
const basic_json& j, detail::output_adapter<uint8_t> o)
19516 binary_writer<uint8_t>(o).write_bson(j);
19522 static void to_bson(
const basic_json& j, detail::output_adapter<
char> o)
19524 binary_writer<
char>(o).write_bson(j);
19628 static basic_json from_cbor(detail::input_adapter&& i,
19629 const bool strict =
true,
19630 const bool allow_exceptions =
true)
19633 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19634 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::cbor, &sdp, strict);
19635 return res ? result : basic_json(value_t::discarded);
19641 template<
typename A1,
typename A2,
19642 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
19644 static basic_json from_cbor(A1 && a1, A2 && a2,
19645 const bool strict =
true,
19646 const bool allow_exceptions =
true)
19649 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19650 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict);
19651 return res ? result : basic_json(value_t::discarded);
19737 static basic_json from_msgpack(detail::input_adapter&& i,
19738 const bool strict =
true,
19739 const bool allow_exceptions =
true)
19742 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19743 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::msgpack, &sdp, strict);
19744 return res ? result : basic_json(value_t::discarded);
19750 template<
typename A1,
typename A2,
19751 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
19753 static basic_json from_msgpack(A1 && a1, A2 && a2,
19754 const bool strict =
true,
19755 const bool allow_exceptions =
true)
19758 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19759 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict);
19760 return res ? result : basic_json(value_t::discarded);
19825 static basic_json from_ubjson(detail::input_adapter&& i,
19826 const bool strict =
true,
19827 const bool allow_exceptions =
true)
19830 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19831 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::ubjson, &sdp, strict);
19832 return res ? result : basic_json(value_t::discarded);
19838 template<
typename A1,
typename A2,
19839 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
19841 static basic_json from_ubjson(A1 && a1, A2 && a2,
19842 const bool strict =
true,
19843 const bool allow_exceptions =
true)
19846 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19847 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict);
19848 return res ? result : basic_json(value_t::discarded);
19912 static basic_json from_bson(detail::input_adapter&& i,
19913 const bool strict =
true,
19914 const bool allow_exceptions =
true)
19917 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19918 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::bson, &sdp, strict);
19919 return res ? result : basic_json(value_t::discarded);
19925 template<
typename A1,
typename A2,
19926 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
19928 static basic_json from_bson(A1 && a1, A2 && a2,
19929 const bool strict =
true,
19930 const bool allow_exceptions =
true)
19933 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19934 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::bson, &sdp, strict);
19935 return res ? result : basic_json(value_t::discarded);
19982 reference operator[](
const json_pointer& ptr)
19984 return ptr.get_unchecked(
this);
20010 const_reference operator[](
const json_pointer& ptr)
const 20012 return ptr.get_unchecked(
this);
20053 reference at(
const json_pointer& ptr)
20055 return ptr.get_checked(
this);
20096 const_reference at(
const json_pointer& ptr)
const 20098 return ptr.get_checked(
this);
20123 basic_json flatten()
const 20125 basic_json result(value_t::object);
20126 json_pointer::flatten(
"", *
this, result);
20160 basic_json unflatten()
const 20162 return json_pointer::unflatten(*
this);
20221 basic_json patch(
const basic_json& json_patch)
const 20224 basic_json result = *
this;
20227 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
20229 const auto get_op = [](
const std::string & op)
20233 return patch_operations::add;
20235 if (op ==
"remove")
20237 return patch_operations::remove;
20239 if (op ==
"replace")
20241 return patch_operations::replace;
20245 return patch_operations::move;
20249 return patch_operations::copy;
20253 return patch_operations::test;
20256 return patch_operations::invalid;
20260 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
20270 json_pointer top_pointer = ptr.top();
20271 if (top_pointer != ptr)
20273 result.at(top_pointer);
20277 const auto last_path = ptr.back();
20279 basic_json& parent = result[ptr];
20281 switch (parent.m_type)
20283 case value_t::null:
20284 case value_t::object:
20287 parent[last_path] = val;
20291 case value_t::array:
20293 if (last_path ==
"-")
20296 parent.push_back(val);
20300 const auto idx = json_pointer::array_index(last_path);
20301 if (
JSON_UNLIKELY(
static_cast<size_type>(idx) > parent.size()))
20304 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
20308 parent.insert(parent.begin() +
static_cast<difference_type>(idx), val);
20320 const auto operation_remove = [&result](json_pointer & ptr)
20323 const auto last_path = ptr.back();
20325 basic_json& parent = result.at(ptr);
20328 if (parent.is_object())
20331 auto it = parent.find(last_path);
20338 JSON_THROW(out_of_range::create(403,
"key '" + last_path +
"' not found"));
20341 else if (parent.is_array())
20344 parent.erase(
static_cast<size_type>(json_pointer::array_index(last_path)));
20351 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
20355 for (
const auto& val : json_patch)
20358 const auto get_value = [&val](
const std::string & op,
20359 const std::string & member,
20360 bool string_type) -> basic_json &
20363 auto it = val.m_value.object->find(member);
20366 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
20371 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have member '" + member +
"'"));
20375 if (
JSON_UNLIKELY(string_type
and not it->second.is_string()))
20377 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have string member '" + member +
"'"));
20387 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
20391 const std::string op = get_value(
"op",
"op",
true);
20392 const std::string path = get_value(op,
"path",
true);
20393 json_pointer ptr(path);
20395 switch (get_op(op))
20397 case patch_operations::add:
20399 operation_add(ptr, get_value(
"add",
"value",
false));
20403 case patch_operations::remove:
20405 operation_remove(ptr);
20409 case patch_operations::replace:
20412 result.at(ptr) = get_value(
"replace",
"value",
false);
20416 case patch_operations::move:
20418 const std::string from_path = get_value(
"move",
"from",
true);
20419 json_pointer from_ptr(from_path);
20422 basic_json v = result.at(from_ptr);
20428 operation_remove(from_ptr);
20429 operation_add(ptr, v);
20433 case patch_operations::copy:
20435 const std::string from_path = get_value(
"copy",
"from",
true);
20436 const json_pointer from_ptr(from_path);
20439 basic_json v = result.at(from_ptr);
20444 operation_add(ptr, v);
20448 case patch_operations::test:
20450 bool success =
false;
20455 success = (result.at(ptr) == get_value(
"test",
"value",
false));
20465 JSON_THROW(other_error::create(501,
"unsuccessful: " + val.dump()));
20475 JSON_THROW(parse_error::create(105, 0,
"operation value '" + op +
"' is invalid"));
20517 static basic_json diff(
const basic_json& source,
const basic_json& target,
20518 const std::string& path =
"")
20521 basic_json result(value_t::array);
20524 if (source == target)
20529 if (source.type() != target.type())
20534 {
"op",
"replace"}, {
"path", path}, {
"value", target}
20539 switch (source.type())
20541 case value_t::array:
20545 while (i < source.size()
and i < target.size())
20548 auto temp_diff = diff(source[i], target[i], path +
"/" + std::to_string(i));
20549 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
20557 const auto end_index =
static_cast<difference_type>(result.size());
20558 while (i < source.size())
20562 result.insert(result.begin() + end_index, object(
20565 {
"path", path +
"/" + std::to_string(i)}
20571 while (i < target.size())
20576 {
"path", path +
"/" + std::to_string(i)},
20577 {
"value", target[i]}
20585 case value_t::object:
20588 for (
auto it = source.cbegin(); it != source.cend(); ++it)
20591 const auto key = json_pointer::escape(it.key());
20593 if (target.find(it.key()) != target.end())
20596 auto temp_diff = diff(it.value(), target[it.key()], path +
"/" + key);
20597 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
20602 result.push_back(object(
20604 {
"op",
"remove"}, {
"path", path +
"/" + key}
20610 for (
auto it = target.cbegin(); it != target.cend(); ++it)
20612 if (source.find(it.key()) == source.end())
20615 const auto key = json_pointer::escape(it.key());
20618 {
"op",
"add"}, {
"path", path +
"/" + key},
20619 {
"value", it.value()}
20632 {
"op",
"replace"}, {
"path", path}, {
"value", target}
20692 void merge_patch(
const basic_json& apply_patch)
20694 if (apply_patch.is_object())
20696 if (
not is_object())
20700 for (
auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
20702 if (it.value().is_null())
20708 operator[](it.key()).merge_patch(it.value());
20714 *
this = apply_patch;
20732 struct hash<nlohmann::json>
20739 std::size_t operator()(
const nlohmann::json& j)
const 20742 const auto& h = hash<nlohmann::json::string_t>();
20743 return h(j.dump());
20751 struct less< ::nlohmann::detail::value_t>
20757 bool operator()(nlohmann::detail::value_t lhs,
20758 nlohmann::detail::value_t rhs)
const noexcept 20760 return nlohmann::detail::operator<(lhs, rhs);
20770 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2)
noexcept(
20771 is_nothrow_move_constructible<nlohmann::json>::value
and 20772 is_nothrow_move_assignable<nlohmann::json>::value
20793 inline nlohmann::json operator
"" _json(
const char* s, std::size_t n)
20795 return nlohmann::json::parse(s, s + n);
20811 inline nlohmann::json::json_pointer operator
"" _json_pointer(
const char* s, std::size_t n)
20813 return nlohmann::json::json_pointer(std::string(s, n));
20820 #if defined(__clang__
) || defined(__GNUC__
) || defined(__GNUG__
) 20821 #pragma GCC diagnostic pop 20823 #if defined(__clang__
) 20824 #pragma GCC diagnostic pop 20828 #undef JSON_INTERNAL_CATCH 20833 #undef JSON_UNLIKELY 20834 #undef JSON_DEPRECATED 20835 #undef JSON_NODISCARD 20836 #undef JSON_HAS_CPP_14 20837 #undef JSON_HAS_CPP_17 20838 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION 20839 #undef NLOHMANN_BASIC_JSON_TPL #define NLOHMANN_BASIC_JSON_TPL_DECLARATION
#define NLOHMANN_JSON_VERSION_MAJOR
#define JSON_INTERNAL_CATCH(exception)
#define JSON_CATCH(exception)
#define NLOHMANN_BASIC_JSON_TPL
#define NLOHMANN_JSON_VERSION_PATCH
#define NLOHMANN_JSON_VERSION_MINOR
#define JSON_THROW(exception)