29 #ifndef NLOHMANN_JSON_HPP 30 #define NLOHMANN_JSON_HPP 42 #include <forward_list> 44 #include <initializer_list> 55 #include <type_traits> 61 #if defined(__clang__
) 62 #if (__clang_major__
* 10000
+ __clang_minor__
* 100
+ __clang_patchlevel__
) < 30400
63 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" 65 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) 66 #if (__GNUC__ * 10000
+ __GNUC_MINOR__ * 100
+ __GNUC_PATCHLEVEL__) < 40900
67 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" 72 #if defined(__clang__
) || defined(__GNUC__
) || defined(__GNUG__
) 73 #pragma GCC diagnostic push 74 #pragma GCC diagnostic ignored "-Wfloat-equal" 78 #if defined(__clang__
) 79 #pragma GCC diagnostic push 80 #pragma GCC diagnostic ignored "-Wdocumentation" 84 #if defined(__clang__
) || defined(__GNUC__
) || defined(__GNUG__
) 85 #define JSON_DEPRECATED __attribute__((deprecated)) 86 #elif defined(_MSC_VER) 87 #define JSON_DEPRECATED __declspec(deprecated) 89 #define JSON_DEPRECATED 93 #if (defined(__cpp_exceptions
) || defined(__EXCEPTIONS
) || defined(_CPPUNWIND)) && not defined(JSON_NOEXCEPTION) 94 #define JSON_THROW(exception) throw exception 96 #define JSON_CATCH(exception) catch(exception) 98 #define JSON_THROW(exception) std::abort() 99 #define JSON_TRY if(true) 100 #define JSON_CATCH(exception) if(false) 104 #if defined(__clang__
) || defined(__GNUC__
) || defined(__GNUG__
) 105 #define JSON_LIKELY(x) __builtin_expect(!!(x), 1
) 106 #define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0
) 108 #define JSON_LIKELY(x) x 109 #define JSON_UNLIKELY(x) x 113 #if (defined(__cplusplus
) && __cplusplus
>= 201703L
) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1
) 114 #define JSON_HAS_CPP_17 115 #define JSON_HAS_CPP_14 116 #elif (defined(__cplusplus
) && __cplusplus
>= 201402L
) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1
) 117 #define JSON_HAS_CPP_14 127 template<
typename =
void,
typename =
void>
128 struct adl_serializer;
131 template<
template<
typename,
typename,
typename...>
class ObjectType = std::map,
132 template<
typename,
typename...>
class ArrayType = std::vector,
133 class StringType = std::string,
class BooleanType =
bool,
134 class NumberIntegerType = std::int64_t,
135 class NumberUnsignedType = std::uint64_t,
136 class NumberFloatType =
double,
137 template<
typename>
class AllocatorType = std::allocator,
138 template<
typename,
typename =
void>
class JSONSerializer = adl_serializer>
144 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION 145 template<template<typename, typename, typename...> class ObjectType, 146 template<typename, typename...> class ArrayType, 147 class StringType, class BooleanType, class NumberIntegerType, 148 class NumberUnsignedType, class NumberFloatType, 149 template<typename> class AllocatorType, 150 template<typename, typename = void> class JSONSerializer> 152 #define NLOHMANN_BASIC_JSON_TPL 153 basic_json<ObjectType, ArrayType, StringType, BooleanType, 154 NumberIntegerType, NumberUnsignedType, NumberFloatType, 155 AllocatorType, JSONSerializer> 200 class exception :
public std::exception
204 const char* what()
const noexcept override 213 exception(
int id_,
const char* what_arg) : id(id_), m(what_arg) {}
215 static std::string name(
const std::string& ename,
int id_)
217 return "[json.exception." + ename +
"." + std::to_string(id_) +
"] ";
222 std::runtime_error m;
268 class parse_error :
public exception
279 static parse_error create(
int id_, std::size_t byte_,
const std::string& what_arg)
281 std::string w = exception::name(
"parse_error", id_) +
"parse error" +
282 (byte_ != 0 ? (
" at " + std::to_string(byte_)) :
"") +
284 return parse_error(id_, byte_, w.c_str());
296 const std::size_t byte;
299 parse_error(
int id_, std::size_t byte_,
const char* what_arg)
300 : exception(id_, what_arg), byte(byte_) {}
340 class invalid_iterator :
public exception
343 static invalid_iterator create(
int id_,
const std::string& what_arg)
345 std::string w = exception::name(
"invalid_iterator", id_) + what_arg;
346 return invalid_iterator(id_, w.c_str());
350 invalid_iterator(
int id_,
const char* what_arg)
351 : exception(id_, what_arg) {}
392 class type_error :
public exception
395 static type_error create(
int id_,
const std::string& what_arg)
397 std::string w = exception::name(
"type_error", id_) + what_arg;
398 return type_error(id_, w.c_str());
402 type_error(
int id_,
const char* what_arg) : exception(id_, what_arg) {}
435 class out_of_range :
public exception
438 static out_of_range create(
int id_,
const std::string& what_arg)
440 std::string w = exception::name(
"out_of_range", id_) + what_arg;
441 return out_of_range(id_, w.c_str());
445 out_of_range(
int id_,
const char* what_arg) : exception(id_, what_arg) {}
473 class other_error :
public exception
476 static other_error create(
int id_,
const std::string& what_arg)
478 std::string w = exception::name(
"other_error", id_) + what_arg;
479 return other_error(id_, w.c_str());
483 other_error(
int id_,
const char* what_arg) : exception(id_, what_arg) {}
516 enum class value_t : uint8_t
539 inline bool operator<(
const value_t lhs,
const value_t rhs)
noexcept 541 static constexpr std::array<uint8_t, 8> order = {{
547 const auto l_index =
static_cast<std::size_t>(lhs);
548 const auto r_index =
static_cast<std::size_t>(rhs);
549 return l_index < order.size()
and r_index < order.size()
and order[l_index] < order[r_index];
557 template<
typename>
struct is_basic_json : std::false_type {};
563 template<
bool B,
typename T =
void>
564 using enable_if_t =
typename std::enable_if<B, T>::type;
567 using uncvref_t =
typename std::remove_cv<
typename std::remove_reference<T>::type>::type;
571 template<std::size_t... Ints>
572 struct index_sequence
574 using type = index_sequence;
575 using value_type = std::size_t;
576 static constexpr std::size_t size()
noexcept 578 return sizeof...(Ints);
582 template<
class Sequence1,
class Sequence2>
583 struct merge_and_renumber;
585 template<std::size_t... I1, std::size_t... I2>
586 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
587 : index_sequence < I1..., (
sizeof...(I1) + I2)... > {};
589 template<std::size_t N>
590 struct make_index_sequence
591 : merge_and_renumber <
typename make_index_sequence < N / 2 >::type,
592 typename make_index_sequence < N - N / 2 >::type > {};
594 template<>
struct make_index_sequence<0> : index_sequence<> {};
595 template<>
struct make_index_sequence<1> : index_sequence<0> {};
597 template<
typename... Ts>
598 using index_sequence_for = make_index_sequence<
sizeof...(Ts)>;
613 template<
class...>
struct conjunction : std::true_type {};
614 template<
class B1>
struct conjunction<B1> : B1 {};
615 template<
class B1,
class... Bn>
616 struct conjunction<B1, Bn...> : std::conditional<
bool(B1::value), conjunction<Bn...>, B1>::type {};
618 template<
class B>
struct negation : std::integral_constant<
bool,
not B::value> {};
621 template<
unsigned N>
struct priority_tag : priority_tag < N - 1 > {};
622 template<>
struct priority_tag<0> {};
629 template<value_t>
struct external_constructor;
632 struct external_constructor<value_t::boolean>
634 template<
typename BasicJsonType>
635 static void construct(BasicJsonType& j,
typename BasicJsonType::boolean_t b)
noexcept 637 j.m_type = value_t::boolean;
639 j.assert_invariant();
644 struct external_constructor<value_t::string>
646 template<
typename BasicJsonType>
647 static void construct(BasicJsonType& j,
const typename BasicJsonType::string_t& s)
649 j.m_type = value_t::string;
651 j.assert_invariant();
654 template<
typename BasicJsonType>
655 static void construct(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
657 j.m_type = value_t::string;
658 j.m_value = std::move(s);
659 j.assert_invariant();
664 struct external_constructor<value_t::number_float>
666 template<
typename BasicJsonType>
667 static void construct(BasicJsonType& j,
typename BasicJsonType::number_float_t val)
noexcept 669 j.m_type = value_t::number_float;
671 j.assert_invariant();
676 struct external_constructor<value_t::number_unsigned>
678 template<
typename BasicJsonType>
679 static void construct(BasicJsonType& j,
typename BasicJsonType::number_unsigned_t val)
noexcept 681 j.m_type = value_t::number_unsigned;
683 j.assert_invariant();
688 struct external_constructor<value_t::number_integer>
690 template<
typename BasicJsonType>
691 static void construct(BasicJsonType& j,
typename BasicJsonType::number_integer_t val)
noexcept 693 j.m_type = value_t::number_integer;
695 j.assert_invariant();
700 struct external_constructor<value_t::array>
702 template<
typename BasicJsonType>
703 static void construct(BasicJsonType& j,
const typename BasicJsonType::array_t& arr)
705 j.m_type = value_t::array;
707 j.assert_invariant();
710 template<
typename BasicJsonType>
711 static void construct(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
713 j.m_type = value_t::array;
714 j.m_value = std::move(arr);
715 j.assert_invariant();
718 template<
typename BasicJsonType,
typename CompatibleArrayType,
719 enable_if_t<
not std::is_same<CompatibleArrayType,
typename BasicJsonType::array_t>::value,
721 static void construct(BasicJsonType& j,
const CompatibleArrayType& arr)
725 j.m_type = value_t::array;
726 j.m_value.array = j.
template create<
typename BasicJsonType::array_t>(begin(arr), end(arr));
727 j.assert_invariant();
730 template<
typename BasicJsonType>
731 static void construct(BasicJsonType& j,
const std::vector<
bool>& arr)
733 j.m_type = value_t::array;
734 j.m_value = value_t::array;
735 j.m_value.array->reserve(arr.size());
738 j.m_value.array->push_back(x);
740 j.assert_invariant();
743 template<
typename BasicJsonType,
typename T,
744 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
745 static void construct(BasicJsonType& j,
const std::valarray<T>& arr)
747 j.m_type = value_t::array;
748 j.m_value = value_t::array;
749 j.m_value.array->resize(arr.size());
750 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
751 j.assert_invariant();
756 struct external_constructor<value_t::object>
758 template<
typename BasicJsonType>
759 static void construct(BasicJsonType& j,
const typename BasicJsonType::object_t& obj)
761 j.m_type = value_t::object;
763 j.assert_invariant();
766 template<
typename BasicJsonType>
767 static void construct(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
769 j.m_type = value_t::object;
770 j.m_value = std::move(obj);
771 j.assert_invariant();
774 template<
typename BasicJsonType,
typename CompatibleObjectType,
775 enable_if_t<
not std::is_same<CompatibleObjectType,
typename BasicJsonType::object_t>::value,
int> = 0>
776 static void construct(BasicJsonType& j,
const CompatibleObjectType& obj)
781 j.m_type = value_t::object;
782 j.m_value.object = j.
template create<
typename BasicJsonType::object_t>(begin(obj), end(obj));
783 j.assert_invariant();
802 #define NLOHMANN_JSON_HAS_HELPER(type) 803 template<typename T> struct has_##type { 805 template<typename U, typename = typename U::type> 806 static int detect(U &&); 807 static void detect(...); 809 static constexpr bool value = 810 std::is_integral<decltype(detect(std::declval<T>()))>::value; 818 #undef NLOHMANN_JSON_HAS_HELPER 821 template<
bool B,
class RealType,
class CompatibleObjectType>
822 struct is_compatible_object_type_impl : std::false_type {};
824 template<
class RealType,
class CompatibleObjectType>
825 struct is_compatible_object_type_impl<
true, RealType, CompatibleObjectType>
827 static constexpr auto value =
828 std::is_constructible<
typename RealType::key_type,
typename CompatibleObjectType::key_type>::value
and 829 std::is_constructible<
typename RealType::mapped_type,
typename CompatibleObjectType::mapped_type>::value;
832 template<
class BasicJsonType,
class CompatibleObjectType>
833 struct is_compatible_object_type
835 static auto constexpr value = is_compatible_object_type_impl <
836 conjunction<negation<std::is_same<
void, CompatibleObjectType>>,
837 has_mapped_type<CompatibleObjectType>,
838 has_key_type<CompatibleObjectType>>::value,
839 typename BasicJsonType::object_t, CompatibleObjectType >::value;
842 template<
typename BasicJsonType,
typename T>
843 struct is_basic_json_nested_type
845 static auto constexpr value = std::is_same<T,
typename BasicJsonType::iterator>::value
or 846 std::is_same<T,
typename BasicJsonType::const_iterator>::value
or 847 std::is_same<T,
typename BasicJsonType::reverse_iterator>::value
or 848 std::is_same<T,
typename BasicJsonType::const_reverse_iterator>::value;
851 template<
class BasicJsonType,
class CompatibleArrayType>
852 struct is_compatible_array_type
854 static auto constexpr value =
855 conjunction<negation<std::is_same<
void, CompatibleArrayType>>,
856 negation<is_compatible_object_type<
857 BasicJsonType, CompatibleArrayType>>,
858 negation<std::is_constructible<
typename BasicJsonType::string_t,
859 CompatibleArrayType>>,
860 negation<is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>>,
861 has_value_type<CompatibleArrayType>,
862 has_iterator<CompatibleArrayType>>::value;
865 template<
bool,
typename,
typename>
866 struct is_compatible_integer_type_impl : std::false_type {};
868 template<
typename RealIntegerType,
typename CompatibleNumberIntegerType>
869 struct is_compatible_integer_type_impl<
true, RealIntegerType, CompatibleNumberIntegerType>
872 using RealLimits = std::numeric_limits<RealIntegerType>;
873 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
875 static constexpr auto value =
876 std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value
and 877 CompatibleLimits::is_integer
and 878 RealLimits::is_signed == CompatibleLimits::is_signed;
881 template<
typename RealIntegerType,
typename CompatibleNumberIntegerType>
882 struct is_compatible_integer_type
884 static constexpr auto value =
885 is_compatible_integer_type_impl <
886 std::is_integral<CompatibleNumberIntegerType>::value
and 887 not std::is_same<
bool, CompatibleNumberIntegerType>::value,
888 RealIntegerType, CompatibleNumberIntegerType >::value;
893 template<
typename BasicJsonType,
typename T>
898 template<
typename U,
typename = enable_if_t<std::is_same<
void,
decltype(uncvref_t<U>::from_json(
899 std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
900 static int detect(U&&);
901 static void detect(...);
904 static constexpr bool value = std::is_integral<
decltype(
905 detect(std::declval<
typename BasicJsonType::
template json_serializer<T,
void>>()))>::value;
910 template<
typename BasicJsonType,
typename T>
911 struct has_non_default_from_json
914 template<
typename U,
typename =
915 enable_if_t<std::is_same<T,
decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value>>
916 static int detect(U&&);
917 static void detect(...);
920 static constexpr bool value = std::is_integral<
decltype(detect(
921 std::declval<
typename BasicJsonType::
template json_serializer<T,
void>>()))>::value;
925 template<
typename BasicJsonType,
typename T>
929 template<
typename U,
typename =
decltype(uncvref_t<U>::to_json(
930 std::declval<BasicJsonType&>(), std::declval<T>()))>
931 static int detect(U&&);
932 static void detect(...);
935 static constexpr bool value = std::is_integral<
decltype(detect(
936 std::declval<
typename BasicJsonType::
template json_serializer<T,
void>>()))>::value;
944 template<
typename BasicJsonType,
typename T,
945 enable_if_t<std::is_same<T,
typename BasicJsonType::boolean_t>::value,
int> = 0>
946 void to_json(BasicJsonType& j, T b)
noexcept 948 external_constructor<value_t::boolean>::construct(j, b);
951 template<
typename BasicJsonType,
typename CompatibleString,
952 enable_if_t<std::is_constructible<
typename BasicJsonType::string_t, CompatibleString>::value,
int> = 0>
953 void to_json(BasicJsonType& j,
const CompatibleString& s)
955 external_constructor<value_t::string>::construct(j, s);
958 template<
typename BasicJsonType>
959 void to_json(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
961 external_constructor<value_t::string>::construct(j, std::move(s));
964 template<
typename BasicJsonType,
typename FloatType,
965 enable_if_t<std::is_floating_point<FloatType>::value,
int> = 0>
966 void to_json(BasicJsonType& j, FloatType val)
noexcept 968 external_constructor<value_t::number_float>::construct(j,
static_cast<
typename BasicJsonType::number_float_t>(val));
971 template<
typename BasicJsonType,
typename CompatibleNumberUnsignedType,
972 enable_if_t<is_compatible_integer_type<
typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value,
int> = 0>
973 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val)
noexcept 975 external_constructor<value_t::number_unsigned>::construct(j,
static_cast<
typename BasicJsonType::number_unsigned_t>(val));
978 template<
typename BasicJsonType,
typename CompatibleNumberIntegerType,
979 enable_if_t<is_compatible_integer_type<
typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value,
int> = 0>
980 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val)
noexcept 982 external_constructor<value_t::number_integer>::construct(j,
static_cast<
typename BasicJsonType::number_integer_t>(val));
985 template<
typename BasicJsonType,
typename EnumType,
986 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
987 void to_json(BasicJsonType& j, EnumType e)
noexcept 989 using underlying_type =
typename std::underlying_type<EnumType>::type;
990 external_constructor<value_t::number_integer>::construct(j,
static_cast<underlying_type>(e));
993 template<
typename BasicJsonType>
994 void to_json(BasicJsonType& j,
const std::vector<
bool>& e)
996 external_constructor<value_t::array>::construct(j, e);
999 template<
typename BasicJsonType,
typename CompatibleArrayType,
1000 enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value
or 1001 std::is_same<
typename BasicJsonType::array_t, CompatibleArrayType>::value,
1003 void to_json(BasicJsonType& j,
const CompatibleArrayType& arr)
1005 external_constructor<value_t::array>::construct(j, arr);
1008 template<
typename BasicJsonType,
typename T,
1009 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
1010 void to_json(BasicJsonType& j, std::valarray<T> arr)
1012 external_constructor<value_t::array>::construct(j, std::move(arr));
1015 template<
typename BasicJsonType>
1016 void to_json(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
1018 external_constructor<value_t::array>::construct(j, std::move(arr));
1021 template<
typename BasicJsonType,
typename CompatibleObjectType,
1022 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
int> = 0>
1023 void to_json(BasicJsonType& j,
const CompatibleObjectType& obj)
1025 external_constructor<value_t::object>::construct(j, obj);
1028 template<
typename BasicJsonType>
1029 void to_json(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
1031 external_constructor<value_t::object>::construct(j, std::move(obj));
1034 template<
typename BasicJsonType,
typename T, std::size_t N,
1035 enable_if_t<
not std::is_constructible<
typename BasicJsonType::string_t, T (&)[N]>::value,
int> = 0>
1036 void to_json(BasicJsonType& j, T (&arr)[N])
1038 external_constructor<value_t::array>::construct(j, arr);
1041 template<
typename BasicJsonType,
typename... Args>
1042 void to_json(BasicJsonType& j,
const std::pair<Args...>& p)
1044 j = {p.first, p.second};
1047 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1048 void to_json_tuple_impl(BasicJsonType& j,
const Tuple& t, index_sequence<Idx...>)
1050 j = {std::get<Idx>(t)...};
1053 template<
typename BasicJsonType,
typename... Args>
1054 void to_json(BasicJsonType& j,
const std::tuple<Args...>& t)
1056 to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1064 template<
typename BasicJsonType,
typename ArithmeticType,
1065 enable_if_t<std::is_arithmetic<ArithmeticType>::value
and 1066 not std::is_same<ArithmeticType,
typename BasicJsonType::boolean_t>::value,
1068 void get_arithmetic_value(
const BasicJsonType& j, ArithmeticType& val)
1070 switch (
static_cast<value_t>(j))
1072 case value_t::number_unsigned:
1074 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_unsigned_t*>());
1077 case value_t::number_integer:
1079 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_integer_t*>());
1082 case value_t::number_float:
1084 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_float_t*>());
1089 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
1093 template<
typename BasicJsonType>
1094 void from_json(
const BasicJsonType& j,
typename BasicJsonType::boolean_t& b)
1098 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(j.type_name())));
1100 b = *j.
template get_ptr<
const typename BasicJsonType::boolean_t*>();
1103 template<
typename BasicJsonType>
1104 void from_json(
const BasicJsonType& j,
typename BasicJsonType::string_t& s)
1108 JSON_THROW(type_error::create(302,
"type must be string, but is " + std::string(j.type_name())));
1110 s = *j.
template get_ptr<
const typename BasicJsonType::string_t*>();
1113 template<
typename BasicJsonType>
1114 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_float_t& val)
1116 get_arithmetic_value(j, val);
1119 template<
typename BasicJsonType>
1120 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_unsigned_t& val)
1122 get_arithmetic_value(j, val);
1125 template<
typename BasicJsonType>
1126 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_integer_t& val)
1128 get_arithmetic_value(j, val);
1131 template<
typename BasicJsonType,
typename EnumType,
1132 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
1133 void from_json(
const BasicJsonType& j, EnumType& e)
1135 typename std::underlying_type<EnumType>::type val;
1136 get_arithmetic_value(j, val);
1137 e =
static_cast<EnumType>(val);
1140 template<
typename BasicJsonType>
1141 void from_json(
const BasicJsonType& j,
typename BasicJsonType::array_t& arr)
1145 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1147 arr = *j.
template get_ptr<
const typename BasicJsonType::array_t*>();
1151 template<
typename BasicJsonType,
typename T,
typename Allocator,
1152 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1153 void from_json(
const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1157 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1159 std::transform(j.rbegin(), j.rend(),
1160 std::front_inserter(l), [](
const BasicJsonType & i)
1162 return i.
template get<T>();
1167 template<
typename BasicJsonType,
typename T,
1168 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1169 void from_json(
const BasicJsonType& j, std::valarray<T>& l)
1173 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1176 std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1179 template<
typename BasicJsonType,
typename CompatibleArrayType>
1180 void from_json_array_impl(
const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0> )
1184 std::transform(j.begin(), j.end(),
1185 std::inserter(arr, end(arr)), [](
const BasicJsonType & i)
1189 return i.
template get<
typename CompatibleArrayType::value_type>();
1193 template<
typename BasicJsonType,
typename CompatibleArrayType>
1194 auto from_json_array_impl(
const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1> )
1196 arr.reserve(std::declval<
typename CompatibleArrayType::size_type>()),
1201 arr.reserve(j.size());
1202 std::transform(j.begin(), j.end(),
1203 std::inserter(arr, end(arr)), [](
const BasicJsonType & i)
1207 return i.
template get<
typename CompatibleArrayType::value_type>();
1211 template<
typename BasicJsonType,
typename T, std::size_t N>
1212 void from_json_array_impl(
const BasicJsonType& j, std::array<T, N>& arr, priority_tag<2> )
1214 for (std::size_t i = 0; i < N; ++i)
1216 arr[i] = j.at(i).
template get<T>();
1220 template<
typename BasicJsonType,
typename CompatibleArrayType,
1221 enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value
and 1222 std::is_convertible<BasicJsonType,
typename CompatibleArrayType::value_type>::value
and 1223 not std::is_same<
typename BasicJsonType::array_t, CompatibleArrayType>::value,
int> = 0>
1224 void from_json(
const BasicJsonType& j, CompatibleArrayType& arr)
1228 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1231 from_json_array_impl(j, arr, priority_tag<2> {});
1234 template<
typename BasicJsonType,
typename CompatibleObjectType,
1235 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
int> = 0>
1236 void from_json(
const BasicJsonType& j, CompatibleObjectType& obj)
1240 JSON_THROW(type_error::create(302,
"type must be object, but is " + std::string(j.type_name())));
1243 auto inner_object = j.
template get_ptr<
const typename BasicJsonType::object_t*>();
1244 using value_type =
typename CompatibleObjectType::value_type;
1246 inner_object->begin(), inner_object->end(),
1247 std::inserter(obj, obj.begin()),
1248 [](
typename BasicJsonType::object_t::value_type
const & p)
1250 return value_type(p.first, p.second.
template get<
typename CompatibleObjectType::mapped_type>());
1258 template<
typename BasicJsonType,
typename ArithmeticType,
1260 std::is_arithmetic<ArithmeticType>::value
and 1261 not std::is_same<ArithmeticType,
typename BasicJsonType::number_unsigned_t>::value
and 1262 not std::is_same<ArithmeticType,
typename BasicJsonType::number_integer_t>::value
and 1263 not std::is_same<ArithmeticType,
typename BasicJsonType::number_float_t>::value
and 1264 not std::is_same<ArithmeticType,
typename BasicJsonType::boolean_t>::value,
1266 void from_json(
const BasicJsonType& j, ArithmeticType& val)
1268 switch (
static_cast<value_t>(j))
1270 case value_t::number_unsigned:
1272 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_unsigned_t*>());
1275 case value_t::number_integer:
1277 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_integer_t*>());
1280 case value_t::number_float:
1282 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_float_t*>());
1285 case value_t::boolean:
1287 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::boolean_t*>());
1292 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
1296 template<
typename BasicJsonType,
typename A1,
typename A2>
1297 void from_json(
const BasicJsonType& j, std::pair<A1, A2>& p)
1299 p = {j.at(0).
template get<A1>(), j.at(1).
template get<A2>()};
1302 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1303 void from_json_tuple_impl(
const BasicJsonType& j, Tuple& t, index_sequence<Idx...>)
1305 t = std::make_tuple(j.at(Idx).
template get<
typename std::tuple_element<Idx, Tuple>::type>()...);
1308 template<
typename BasicJsonType,
typename... Args>
1309 void from_json(
const BasicJsonType& j, std::tuple<Args...>& t)
1311 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1317 template<
typename BasicJsonType,
typename T>
1318 auto call(BasicJsonType& j, T&& val, priority_tag<1> )
const noexcept(
noexcept(to_json(j, std::forward<T>(val))))
1319 ->
decltype(to_json(j, std::forward<T>(val)),
void())
1321 return to_json(j, std::forward<T>(val));
1324 template<
typename BasicJsonType,
typename T>
1325 void call(BasicJsonType& , T&& , priority_tag<0> )
const noexcept 1327 static_assert(
sizeof(BasicJsonType) == 0,
1328 "could not find to_json() method in T's namespace");
1332 using decayed = uncvref_t<T>;
1333 static_assert(
sizeof(
typename decayed::force_msvc_stacktrace) == 0,
1334 "forcing MSVC stacktrace to show which T we're talking about.");
1339 template<
typename BasicJsonType,
typename T>
1340 void operator()(BasicJsonType& j, T&& val)
const 1341 noexcept(
noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1> {})))
1343 return call(j, std::forward<T>(val), priority_tag<1> {});
1350 template<
typename BasicJsonType,
typename T>
1351 auto call(
const BasicJsonType& j, T& val, priority_tag<1> )
const 1352 noexcept(
noexcept(from_json(j, val)))
1353 ->
decltype(from_json(j, val),
void())
1355 return from_json(j, val);
1358 template<
typename BasicJsonType,
typename T>
1359 void call(
const BasicJsonType& , T& , priority_tag<0> )
const noexcept 1361 static_assert(
sizeof(BasicJsonType) == 0,
1362 "could not find from_json() method in T's namespace");
1365 using decayed = uncvref_t<T>;
1366 static_assert(
sizeof(
typename decayed::force_msvc_stacktrace) == 0,
1367 "forcing MSVC stacktrace to show which T we're talking about.");
1372 template<
typename BasicJsonType,
typename T>
1373 void operator()(
const BasicJsonType& j, T& val)
const 1374 noexcept(
noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
1376 return call(j, val, priority_tag<1> {});
1381 template<
typename T>
1384 static constexpr T value{};
1387 template<
typename T>
1388 constexpr T static_const<T>::value;
1405 struct input_adapter_protocol
1408 virtual std::char_traits<
char>::int_type get_character() = 0;
1410 virtual void unget_character() = 0;
1411 virtual ~input_adapter_protocol() =
default;
1415 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
1426 class input_stream_adapter :
public input_adapter_protocol
1429 ~input_stream_adapter()
override 1436 explicit input_stream_adapter(std::istream& i)
1437 : is(i), sb(*i.rdbuf())
1440 std::char_traits<
char>::int_type c;
1441 if ((c = get_character()) == 0xEF)
1443 if ((c = get_character()) == 0xBB)
1445 if ((c = get_character()) == 0xBF)
1449 else if (c != std::char_traits<
char>::eof())
1455 else if (c != std::char_traits<
char>::eof())
1461 else if (c != std::char_traits<
char>::eof())
1468 input_stream_adapter(
const input_stream_adapter&) =
delete;
1469 input_stream_adapter& operator=(input_stream_adapter&) =
delete;
1474 std::char_traits<
char>::int_type get_character()
override 1479 void unget_character()
override 1491 class input_buffer_adapter :
public input_adapter_protocol
1494 input_buffer_adapter(
const char* b,
const std::size_t l)
1495 : cursor(b), limit(b + l), start(b)
1498 if (l >= 3
and b[0] ==
'\xEF' and b[1] ==
'\xBB' and b[2] ==
'\xBF')
1505 input_buffer_adapter(
const input_buffer_adapter&) =
delete;
1506 input_buffer_adapter& operator=(input_buffer_adapter&) =
delete;
1508 std::char_traits<
char>::int_type get_character()
noexcept override 1512 return std::char_traits<
char>::to_int_type(*(cursor++));
1515 return std::char_traits<
char>::eof();
1518 void unget_character()
noexcept override 1541 input_adapter(std::istream& i)
1542 : ia(std::make_shared<input_stream_adapter>(i)) {}
1545 input_adapter(std::istream&& i)
1546 : ia(std::make_shared<input_stream_adapter>(i)) {}
1549 template<
typename CharT,
1550 typename std::enable_if<
1551 std::is_pointer<CharT>::value
and 1552 std::is_integral<
typename std::remove_pointer<CharT>::type>::value
and 1553 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
1555 input_adapter(CharT b, std::size_t l)
1556 : ia(std::make_shared<input_buffer_adapter>(
reinterpret_cast<
const char*>(b), l)) {}
1561 template<
typename CharT,
1562 typename std::enable_if<
1563 std::is_pointer<CharT>::value
and 1564 std::is_integral<
typename std::remove_pointer<CharT>::type>::value
and 1565 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
1567 input_adapter(CharT b)
1568 : input_adapter(
reinterpret_cast<
const char*>(b),
1569 std::strlen(
reinterpret_cast<
const char*>(b))) {}
1572 template<
class IteratorType,
1573 typename std::enable_if<
1574 std::is_same<
typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
1576 input_adapter(IteratorType first, IteratorType last)
1580 assert(std::accumulate(
1581 first, last, std::pair<
bool,
int>(
true, 0),
1582 [&first](std::pair<
bool,
int> res,
decltype(*first) val)
1584 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
1590 sizeof(
typename std::iterator_traits<IteratorType>::value_type) == 1,
1591 "each element in the iterator range must have the size of 1 byte");
1593 const auto len =
static_cast<size_t>(std::distance(first, last));
1597 ia = std::make_shared<input_buffer_adapter>(
reinterpret_cast<
const char*>(&(*first)), len);
1602 ia = std::make_shared<input_buffer_adapter>(
nullptr, len);
1607 template<
class T, std::size_t N>
1608 input_adapter(T (&array)[N])
1609 : input_adapter(std::begin(array), std::end(array)) {}
1612 template<
class ContiguousContainer,
typename 1613 std::enable_if<
not std::is_pointer<ContiguousContainer>::value
and 1614 std::is_base_of<std::random_access_iterator_tag,
typename std::iterator_traits<
decltype(std::begin(std::declval<ContiguousContainer
const>()))>::iterator_category>::value,
1616 input_adapter(
const ContiguousContainer& c)
1617 : input_adapter(std::begin(c), std::end(c)) {}
1619 operator input_adapter_t()
1626 input_adapter_t ia =
nullptr;
1638 template<
typename BasicJsonType>
1641 using number_integer_t =
typename BasicJsonType::number_integer_t;
1642 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
1643 using number_float_t =
typename BasicJsonType::number_float_t;
1647 enum class token_type
1669 static const char* token_type_name(
const token_type t)
noexcept 1673 case token_type::uninitialized:
1674 return "<uninitialized>";
1675 case token_type::literal_true:
1676 return "true literal";
1677 case token_type::literal_false:
1678 return "false literal";
1679 case token_type::literal_null:
1680 return "null literal";
1681 case token_type::value_string:
1682 return "string literal";
1683 case lexer::token_type::value_unsigned:
1684 case lexer::token_type::value_integer:
1685 case lexer::token_type::value_float:
1686 return "number literal";
1687 case token_type::begin_array:
1689 case token_type::begin_object:
1691 case token_type::end_array:
1693 case token_type::end_object:
1695 case token_type::name_separator:
1697 case token_type::value_separator:
1699 case token_type::parse_error:
1700 return "<parse error>";
1701 case token_type::end_of_input:
1702 return "end of input";
1703 case token_type::literal_or_value:
1704 return "'[', '{', or a literal";
1706 return "unknown token";
1710 explicit lexer(detail::input_adapter_t adapter)
1711 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
1714 lexer(
const lexer&) =
delete;
1715 lexer& operator=(lexer&) =
delete;
1723 static char get_decimal_point()
noexcept 1725 const auto loc = localeconv();
1726 assert(loc !=
nullptr);
1727 return (loc->decimal_point ==
nullptr) ?
'.' : *(loc->decimal_point);
1752 assert(current ==
'u');
1755 const auto factors = { 12, 8, 4, 0 };
1756 for (
const auto factor : factors)
1760 if (current >=
'0' and current <=
'9')
1762 codepoint += ((current - 0x30) << factor);
1764 else if (current >=
'A' and current <=
'F')
1766 codepoint += ((current - 0x37) << factor);
1768 else if (current >=
'a' and current <=
'f')
1770 codepoint += ((current - 0x57) << factor);
1778 assert(0x0000 <= codepoint
and codepoint <= 0xFFFF);
1797 bool next_byte_in_range(std::initializer_list<
int> ranges)
1799 assert(ranges.size() == 2
or ranges.size() == 4
or ranges.size() == 6);
1802 for (
auto range = ranges.begin(); range != ranges.end(); ++range)
1805 if (
JSON_LIKELY(*range <= current
and current <= *(++range)))
1811 error_message =
"invalid string: ill-formed UTF-8 byte";
1833 token_type scan_string()
1839 assert(current ==
'\"');
1847 case std::char_traits<
char>::eof():
1849 error_message =
"invalid string: missing closing quote";
1850 return token_type::parse_error;
1856 return token_type::value_string;
1900 const int codepoint1 = get_codepoint();
1901 int codepoint = codepoint1;
1905 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
1906 return token_type::parse_error;
1910 if (0xD800 <= codepoint1
and codepoint1 <= 0xDBFF)
1915 const int codepoint2 = get_codepoint();
1919 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
1920 return token_type::parse_error;
1924 if (
JSON_LIKELY(0xDC00 <= codepoint2
and codepoint2 <= 0xDFFF))
1939 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
1940 return token_type::parse_error;
1945 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
1946 return token_type::parse_error;
1951 if (
JSON_UNLIKELY(0xDC00 <= codepoint1
and codepoint1 <= 0xDFFF))
1953 error_message =
"invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
1954 return token_type::parse_error;
1959 assert(0x00 <= codepoint
and codepoint <= 0x10FFFF);
1962 if (codepoint < 0x80)
1967 else if (codepoint <= 0x7FF)
1970 add(0xC0 | (codepoint >> 6));
1971 add(0x80 | (codepoint & 0x3F));
1973 else if (codepoint <= 0xFFFF)
1976 add(0xE0 | (codepoint >> 12));
1977 add(0x80 | ((codepoint >> 6) & 0x3F));
1978 add(0x80 | (codepoint & 0x3F));
1983 add(0xF0 | (codepoint >> 18));
1984 add(0x80 | ((codepoint >> 12) & 0x3F));
1985 add(0x80 | ((codepoint >> 6) & 0x3F));
1986 add(0x80 | (codepoint & 0x3F));
1994 error_message =
"invalid string: forbidden character after backslash";
1995 return token_type::parse_error;
2035 error_message =
"invalid string: control character must be escaped";
2036 return token_type::parse_error;
2173 return token_type::parse_error;
2181 if (
JSON_UNLIKELY(
not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
2183 return token_type::parse_error;
2205 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
2207 return token_type::parse_error;
2215 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
2217 return token_type::parse_error;
2225 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2227 return token_type::parse_error;
2237 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2239 return token_type::parse_error;
2247 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
2249 return token_type::parse_error;
2257 error_message =
"invalid string: ill-formed UTF-8 byte";
2258 return token_type::parse_error;
2264 static void strtof(
float& f,
const char* str,
char** endptr)
noexcept 2266 f = std::strtof(str, endptr);
2269 static void strtof(
double& f,
const char* str,
char** endptr)
noexcept 2271 f = std::strtod(str, endptr);
2274 static void strtof(
long double& f,
const char* str,
char** endptr)
noexcept 2276 f = std::strtold(str, endptr);
2319 token_type scan_number()
2326 token_type number_type = token_type::value_unsigned;
2334 goto scan_number_minus;
2340 goto scan_number_zero;
2354 goto scan_number_any1;
2366 number_type = token_type::value_integer;
2372 goto scan_number_zero;
2386 goto scan_number_any1;
2391 error_message =
"invalid number; expected digit after '-'";
2392 return token_type::parse_error;
2402 add(decimal_point_char);
2403 goto scan_number_decimal1;
2410 goto scan_number_exponent;
2414 goto scan_number_done;
2433 goto scan_number_any1;
2438 add(decimal_point_char);
2439 goto scan_number_decimal1;
2446 goto scan_number_exponent;
2450 goto scan_number_done;
2453 scan_number_decimal1:
2455 number_type = token_type::value_float;
2470 goto scan_number_decimal2;
2475 error_message =
"invalid number; expected digit after '.'";
2476 return token_type::parse_error;
2480 scan_number_decimal2:
2496 goto scan_number_decimal2;
2503 goto scan_number_exponent;
2507 goto scan_number_done;
2510 scan_number_exponent:
2512 number_type = token_type::value_float;
2519 goto scan_number_sign;
2534 goto scan_number_any2;
2540 "invalid number; expected '+', '-', or digit after exponent";
2541 return token_type::parse_error;
2561 goto scan_number_any2;
2566 error_message =
"invalid number; expected digit after exponent sign";
2567 return token_type::parse_error;
2587 goto scan_number_any2;
2591 goto scan_number_done;
2599 char* endptr =
nullptr;
2603 if (number_type == token_type::value_unsigned)
2605 const auto x = std::strtoull(yytext.data(), &endptr, 10);
2608 assert(endptr == yytext.data() + yytext.size());
2612 value_unsigned =
static_cast<number_unsigned_t>(x);
2613 if (value_unsigned == x)
2615 return token_type::value_unsigned;
2619 else if (number_type == token_type::value_integer)
2621 const auto x = std::strtoll(yytext.data(), &endptr, 10);
2624 assert(endptr == yytext.data() + yytext.size());
2628 value_integer =
static_cast<number_integer_t>(x);
2629 if (value_integer == x)
2631 return token_type::value_integer;
2638 strtof(value_float, yytext.data(), &endptr);
2641 assert(endptr == yytext.data() + yytext.size());
2643 return token_type::value_float;
2651 token_type scan_literal(
const char* literal_text,
const std::size_t length,
2652 token_type return_type)
2654 assert(current == literal_text[0]);
2655 for (std::size_t i = 1; i < length; ++i)
2659 error_message =
"invalid literal";
2660 return token_type::parse_error;
2671 void reset()
noexcept 2674 token_string.clear();
2675 token_string.push_back(std::char_traits<
char>::to_char_type(current));
2688 std::char_traits<
char>::int_type get()
2691 current = ia->get_character();
2692 if (
JSON_LIKELY(current != std::char_traits<
char>::eof()))
2694 token_string.push_back(std::char_traits<
char>::to_char_type(current));
2703 if (
JSON_LIKELY(current != std::char_traits<
char>::eof()))
2705 ia->unget_character();
2706 assert(token_string.size() != 0);
2707 token_string.pop_back();
2714 yytext.push_back(std::char_traits<
char>::to_char_type(c));
2723 constexpr number_integer_t get_number_integer()
const noexcept 2725 return value_integer;
2729 constexpr number_unsigned_t get_number_unsigned()
const noexcept 2731 return value_unsigned;
2735 constexpr number_float_t get_number_float()
const noexcept 2741 std::string move_string()
2743 return std::move(yytext);
2751 constexpr std::size_t get_position()
const noexcept 2759 std::string get_token_string()
const 2763 for (
auto c : token_string)
2765 if (
'\x00' <= c
and c <=
'\x1F')
2768 std::stringstream ss;
2769 ss <<
"<U+" << std::setw(4) << std::uppercase << std::setfill(
'0')
2770 << std::hex <<
static_cast<
int>(c) <<
">";
2776 result.push_back(c);
2784 constexpr const char* get_error_message()
const noexcept 2786 return error_message;
2800 while (current ==
' ' or current ==
'\t' or current ==
'\n' or current ==
'\r');
2806 return token_type::begin_array;
2808 return token_type::end_array;
2810 return token_type::begin_object;
2812 return token_type::end_object;
2814 return token_type::name_separator;
2816 return token_type::value_separator;
2820 return scan_literal(
"true", 4, token_type::literal_true);
2822 return scan_literal(
"false", 5, token_type::literal_false);
2824 return scan_literal(
"null", 4, token_type::literal_null);
2828 return scan_string();
2842 return scan_number();
2847 case std::char_traits<
char>::eof():
2848 return token_type::end_of_input;
2852 error_message =
"invalid literal";
2853 return token_type::parse_error;
2859 detail::input_adapter_t ia =
nullptr;
2862 std::char_traits<
char>::int_type current = std::char_traits<
char>::eof();
2865 std::size_t chars_read = 0;
2868 std::vector<
char> token_string {};
2871 std::string yytext {};
2874 const char* error_message =
"";
2877 number_integer_t value_integer = 0;
2878 number_unsigned_t value_unsigned = 0;
2879 number_float_t value_float = 0;
2882 const char decimal_point_char =
'.';
2890 template<
typename BasicJsonType>
2893 using number_integer_t =
typename BasicJsonType::number_integer_t;
2894 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
2895 using number_float_t =
typename BasicJsonType::number_float_t;
2896 using lexer_t = lexer<BasicJsonType>;
2897 using token_type =
typename lexer_t::token_type;
2900 enum class parse_event_t : uint8_t
2916 using parser_callback_t =
2917 std::function<
bool(
int depth, parse_event_t event, BasicJsonType& parsed)>;
2920 explicit parser(detail::input_adapter_t adapter,
2921 const parser_callback_t cb =
nullptr,
2922 const bool allow_exceptions_ =
true)
2923 : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_)
2936 void parse(
const bool strict, BasicJsonType& result)
2941 parse_internal(
true, result);
2942 result.assert_invariant();
2948 expect(token_type::end_of_input);
2954 result = value_t::discarded;
2960 if (result.is_discarded())
2972 bool accept(
const bool strict =
true)
2977 if (
not accept_internal())
2983 return not strict
or (get_token() == token_type::end_of_input);
2993 void parse_internal(
bool keep, BasicJsonType& result)
2996 assert(
not errored);
2999 if (
not result.is_discarded())
3001 result.m_value.destroy(result.m_type);
3002 result.m_type = value_t::discarded;
3007 case token_type::begin_object:
3013 keep = callback(depth++, parse_event_t::object_start, result);
3016 if (
not callback
or keep)
3019 result.m_type = value_t::object;
3020 result.m_value = value_t::object;
3028 if (last_token == token_type::end_object)
3030 if (keep
and callback
and not callback(--depth, parse_event_t::object_end, result))
3032 result.m_value.destroy(result.m_type);
3033 result.m_type = value_t::discarded;
3040 BasicJsonType value;
3044 if (
not expect(token_type::value_string))
3048 key = m_lexer.move_string();
3050 bool keep_tag =
false;
3055 BasicJsonType k(key);
3056 keep_tag = callback(depth, parse_event_t::key, k);
3066 if (
not expect(token_type::name_separator))
3073 value.m_value.destroy(value.m_type);
3074 value.m_type = value_t::discarded;
3075 parse_internal(keep, value);
3082 if (keep
and keep_tag
and not value.is_discarded())
3084 result.m_value.object->emplace(std::move(key), std::move(value));
3089 if (last_token == token_type::value_separator)
3096 if (
not expect(token_type::end_object))
3103 if (keep
and callback
and not callback(--depth, parse_event_t::object_end, result))
3105 result.m_value.destroy(result.m_type);
3106 result.m_type = value_t::discarded;
3111 case token_type::begin_array:
3117 keep = callback(depth++, parse_event_t::array_start, result);
3120 if (
not callback
or keep)
3123 result.m_type = value_t::array;
3124 result.m_value = value_t::array;
3132 if (last_token == token_type::end_array)
3134 if (callback
and not callback(--depth, parse_event_t::array_end, result))
3136 result.m_value.destroy(result.m_type);
3137 result.m_type = value_t::discarded;
3143 BasicJsonType value;
3147 value.m_value.destroy(value.m_type);
3148 value.m_type = value_t::discarded;
3149 parse_internal(keep, value);
3156 if (keep
and not value.is_discarded())
3158 result.m_value.array->push_back(std::move(value));
3163 if (last_token == token_type::value_separator)
3170 if (
not expect(token_type::end_array))
3177 if (keep
and callback
and not callback(--depth, parse_event_t::array_end, result))
3179 result.m_value.destroy(result.m_type);
3180 result.m_type = value_t::discarded;
3185 case token_type::literal_null:
3187 result.m_type = value_t::null;
3191 case token_type::value_string:
3193 result.m_type = value_t::string;
3194 result.m_value = m_lexer.move_string();
3198 case token_type::literal_true:
3200 result.m_type = value_t::boolean;
3201 result.m_value =
true;
3205 case token_type::literal_false:
3207 result.m_type = value_t::boolean;
3208 result.m_value =
false;
3212 case token_type::value_unsigned:
3214 result.m_type = value_t::number_unsigned;
3215 result.m_value = m_lexer.get_number_unsigned();
3219 case token_type::value_integer:
3221 result.m_type = value_t::number_integer;
3222 result.m_value = m_lexer.get_number_integer();
3226 case token_type::value_float:
3228 result.m_type = value_t::number_float;
3229 result.m_value = m_lexer.get_number_float();
3232 if (
JSON_UNLIKELY(
not std::isfinite(result.m_value.number_float)))
3234 if (allow_exceptions)
3236 JSON_THROW(out_of_range::create(406,
"number overflow parsing '" +
3237 m_lexer.get_token_string() +
"'"));
3239 expect(token_type::uninitialized);
3244 case token_type::parse_error:
3247 if (
not expect(token_type::uninitialized))
3257 if (
not expect(token_type::literal_or_value))
3265 if (keep
and callback
and not callback(depth, parse_event_t::value, result))
3267 result.m_type = value_t::discarded;
3281 bool accept_internal()
3285 case token_type::begin_object:
3291 if (last_token == token_type::end_object)
3300 if (last_token != token_type::value_string)
3307 if (last_token != token_type::name_separator)
3314 if (
not accept_internal())
3321 if (last_token == token_type::value_separator)
3328 return (last_token == token_type::end_object);
3332 case token_type::begin_array:
3338 if (last_token == token_type::end_array)
3347 if (
not accept_internal())
3354 if (last_token == token_type::value_separator)
3361 return (last_token == token_type::end_array);
3365 case token_type::value_float:
3368 return std::isfinite(m_lexer.get_number_float());
3371 case token_type::literal_false:
3372 case token_type::literal_null:
3373 case token_type::literal_true:
3374 case token_type::value_integer:
3375 case token_type::value_string:
3376 case token_type::value_unsigned:
3385 token_type get_token()
3387 return (last_token = m_lexer.scan());
3393 bool expect(token_type t)
3399 if (allow_exceptions)
3412 [[noreturn]]
void throw_exception()
const 3414 std::string error_msg =
"syntax error - ";
3415 if (last_token == token_type::parse_error)
3417 error_msg += std::string(m_lexer.get_error_message()) +
"; last read: '" +
3418 m_lexer.get_token_string() +
"'";
3422 error_msg +=
"unexpected " + std::string(lexer_t::token_type_name(last_token));
3425 if (expected != token_type::uninitialized)
3427 error_msg +=
"; expected " + std::string(lexer_t::token_type_name(expected));
3430 JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
3437 const parser_callback_t callback =
nullptr;
3439 token_type last_token = token_type::uninitialized;
3443 bool errored =
false;
3445 token_type expected = token_type::uninitialized;
3447 const bool allow_exceptions =
true;
3463 class primitive_iterator_t
3466 using difference_type = std::ptrdiff_t;
3468 constexpr difference_type get_value()
const noexcept 3474 void set_begin()
noexcept 3480 void set_end()
noexcept 3486 constexpr bool is_begin()
const noexcept 3488 return m_it == begin_value;
3492 constexpr bool is_end()
const noexcept 3494 return m_it == end_value;
3497 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs)
noexcept 3499 return lhs.m_it == rhs.m_it;
3502 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs)
noexcept 3504 return lhs.m_it < rhs.m_it;
3507 primitive_iterator_t operator+(difference_type i)
3509 auto result = *
this;
3514 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs)
noexcept 3516 return lhs.m_it - rhs.m_it;
3519 friend std::ostream& operator<<(std::ostream& os, primitive_iterator_t it)
3521 return os << it.m_it;
3524 primitive_iterator_t& operator++()
3530 primitive_iterator_t operator++(
int)
3532 auto result = *
this;
3537 primitive_iterator_t& operator--()
3543 primitive_iterator_t operator--(
int)
3545 auto result = *
this;
3550 primitive_iterator_t& operator+=(difference_type n)
3556 primitive_iterator_t& operator-=(difference_type n)
3563 static constexpr difference_type begin_value = 0;
3564 static constexpr difference_type end_value = begin_value + 1;
3567 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
3576 template<
typename BasicJsonType>
struct internal_iterator
3579 typename BasicJsonType::object_t::iterator object_iterator {};
3581 typename BasicJsonType::array_t::iterator array_iterator {};
3583 primitive_iterator_t primitive_iterator {};
3586 template<
typename IteratorType>
class iteration_proxy;
3608 template<
typename BasicJsonType>
3612 friend iter_impl<
typename std::conditional<std::is_const<BasicJsonType>::value,
typename std::remove_const<BasicJsonType>::type,
const BasicJsonType>::type>;
3613 friend BasicJsonType;
3614 friend iteration_proxy<iter_impl>;
3616 using object_t =
typename BasicJsonType::object_t;
3617 using array_t =
typename BasicJsonType::array_t;
3619 static_assert(is_basic_json<
typename std::remove_const<BasicJsonType>::type>::value,
3620 "iter_impl only accepts (const) basic_json");
3629 using iterator_category = std::bidirectional_iterator_tag;
3632 using value_type =
typename BasicJsonType::value_type;
3634 using difference_type =
typename BasicJsonType::difference_type;
3636 using pointer =
typename std::conditional<std::is_const<BasicJsonType>::value,
3637 typename BasicJsonType::const_pointer,
3638 typename BasicJsonType::pointer>::type;
3641 typename std::conditional<std::is_const<BasicJsonType>::value,
3642 typename BasicJsonType::const_reference,
3643 typename BasicJsonType::reference>::type;
3646 iter_impl() =
default;
3654 explicit iter_impl(pointer object)
noexcept : m_object(object)
3656 assert(m_object !=
nullptr);
3658 switch (m_object->m_type)
3660 case value_t::object:
3662 m_it.object_iterator =
typename object_t::iterator();
3666 case value_t::array:
3668 m_it.array_iterator =
typename array_t::iterator();
3674 m_it.primitive_iterator = primitive_iterator_t();
3694 iter_impl(
const iter_impl<
typename std::remove_const<BasicJsonType>::type>& other)
noexcept 3695 : m_object(other.m_object), m_it(other.m_it) {}
3703 iter_impl& operator=(
const iter_impl<
typename std::remove_const<BasicJsonType>::type>& other)
noexcept 3705 m_object = other.m_object;
3715 void set_begin()
noexcept 3717 assert(m_object !=
nullptr);
3719 switch (m_object->m_type)
3721 case value_t::object:
3723 m_it.object_iterator = m_object->m_value.object->begin();
3727 case value_t::array:
3729 m_it.array_iterator = m_object->m_value.array->begin();
3736 m_it.primitive_iterator.set_end();
3742 m_it.primitive_iterator.set_begin();
3752 void set_end()
noexcept 3754 assert(m_object !=
nullptr);
3756 switch (m_object->m_type)
3758 case value_t::object:
3760 m_it.object_iterator = m_object->m_value.object->end();
3764 case value_t::array:
3766 m_it.array_iterator = m_object->m_value.array->end();
3772 m_it.primitive_iterator.set_end();
3783 reference operator*()
const 3785 assert(m_object !=
nullptr);
3787 switch (m_object->m_type)
3789 case value_t::object:
3791 assert(m_it.object_iterator != m_object->m_value.object->end());
3792 return m_it.object_iterator->second;
3795 case value_t::array:
3797 assert(m_it.array_iterator != m_object->m_value.array->end());
3798 return *m_it.array_iterator;
3802 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
3806 if (
JSON_LIKELY(m_it.primitive_iterator.is_begin()))
3811 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
3820 pointer operator->()
const 3822 assert(m_object !=
nullptr);
3824 switch (m_object->m_type)
3826 case value_t::object:
3828 assert(m_it.object_iterator != m_object->m_value.object->end());
3829 return &(m_it.object_iterator->second);
3832 case value_t::array:
3834 assert(m_it.array_iterator != m_object->m_value.array->end());
3835 return &*m_it.array_iterator;
3840 if (
JSON_LIKELY(m_it.primitive_iterator.is_begin()))
3845 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
3854 iter_impl operator++(
int)
3856 auto result = *
this;
3865 iter_impl& operator++()
3867 assert(m_object !=
nullptr);
3869 switch (m_object->m_type)
3871 case value_t::object:
3873 std::advance(m_it.object_iterator, 1);
3877 case value_t::array:
3879 std::advance(m_it.array_iterator, 1);
3885 ++m_it.primitive_iterator;
3897 iter_impl operator--(
int)
3899 auto result = *
this;
3908 iter_impl& operator--()
3910 assert(m_object !=
nullptr);
3912 switch (m_object->m_type)
3914 case value_t::object:
3916 std::advance(m_it.object_iterator, -1);
3920 case value_t::array:
3922 std::advance(m_it.array_iterator, -1);
3928 --m_it.primitive_iterator;
3940 bool operator==(
const iter_impl& other)
const 3945 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
3948 assert(m_object !=
nullptr);
3950 switch (m_object->m_type)
3952 case value_t::object:
3953 return (m_it.object_iterator == other.m_it.object_iterator);
3955 case value_t::array:
3956 return (m_it.array_iterator == other.m_it.array_iterator);
3959 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
3967 bool operator!=(
const iter_impl& other)
const 3969 return not operator==(other);
3976 bool operator<(
const iter_impl& other)
const 3981 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
3984 assert(m_object !=
nullptr);
3986 switch (m_object->m_type)
3988 case value_t::object:
3989 JSON_THROW(invalid_iterator::create(213,
"cannot compare order of object iterators"));
3991 case value_t::array:
3992 return (m_it.array_iterator < other.m_it.array_iterator);
3995 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
4003 bool operator<=(
const iter_impl& other)
const 4005 return not other.operator < (*
this);
4012 bool operator>(
const iter_impl& other)
const 4014 return not operator<=(other);
4021 bool operator>=(
const iter_impl& other)
const 4023 return not operator<(other);
4030 iter_impl& operator+=(difference_type i)
4032 assert(m_object !=
nullptr);
4034 switch (m_object->m_type)
4036 case value_t::object:
4037 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
4039 case value_t::array:
4041 std::advance(m_it.array_iterator, i);
4047 m_it.primitive_iterator += i;
4059 iter_impl& operator-=(difference_type i)
4061 return operator+=(-i);
4068 iter_impl operator+(difference_type i)
const 4070 auto result = *
this;
4079 friend iter_impl operator+(difference_type i,
const iter_impl& it)
4090 iter_impl operator-(difference_type i)
const 4092 auto result = *
this;
4101 difference_type operator-(
const iter_impl& other)
const 4103 assert(m_object !=
nullptr);
4105 switch (m_object->m_type)
4107 case value_t::object:
4108 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
4110 case value_t::array:
4111 return m_it.array_iterator - other.m_it.array_iterator;
4114 return m_it.primitive_iterator - other.m_it.primitive_iterator;
4122 reference operator[](difference_type n)
const 4124 assert(m_object !=
nullptr);
4126 switch (m_object->m_type)
4128 case value_t::object:
4129 JSON_THROW(invalid_iterator::create(208,
"cannot use operator[] for object iterators"));
4131 case value_t::array:
4132 return *std::next(m_it.array_iterator, n);
4135 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4139 if (
JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
4144 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4153 typename object_t::key_type key()
const 4155 assert(m_object !=
nullptr);
4159 return m_it.object_iterator->first;
4162 JSON_THROW(invalid_iterator::create(207,
"cannot use key() for non-object iterators"));
4169 reference value()
const 4176 pointer m_object =
nullptr;
4178 internal_iterator<
typename std::remove_const<BasicJsonType>::type> m_it = {};
4182 template<
typename IteratorType>
class iteration_proxy
4186 class iteration_proxy_internal
4190 IteratorType anchor;
4192 std::size_t array_index = 0;
4195 explicit iteration_proxy_internal(IteratorType it)
noexcept : anchor(it) {}
4198 iteration_proxy_internal& operator*()
4204 iteration_proxy_internal& operator++()
4213 bool operator!=(
const iteration_proxy_internal& o)
const noexcept 4215 return anchor != o.anchor;
4219 std::string key()
const 4221 assert(anchor.m_object !=
nullptr);
4223 switch (anchor.m_object->type())
4226 case value_t::array:
4227 return std::to_string(array_index);
4230 case value_t::object:
4231 return anchor.key();
4240 typename IteratorType::reference value()
const 4242 return anchor.value();
4247 typename IteratorType::reference container;
4251 explicit iteration_proxy(
typename IteratorType::reference cont)
4252 : container(cont) {}
4255 iteration_proxy_internal begin()
noexcept 4257 return iteration_proxy_internal(container.begin());
4261 iteration_proxy_internal end()
noexcept 4263 return iteration_proxy_internal(container.end());
4285 template<
typename Base>
4286 class json_reverse_iterator :
public std::reverse_iterator<Base>
4289 using difference_type = std::ptrdiff_t;
4291 using base_iterator = std::reverse_iterator<Base>;
4293 using reference =
typename Base::reference;
4296 json_reverse_iterator(
const typename base_iterator::iterator_type& it)
noexcept 4297 : base_iterator(it) {}
4300 json_reverse_iterator(
const base_iterator& it)
noexcept : base_iterator(it) {}
4303 json_reverse_iterator operator++(
int)
4305 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
4309 json_reverse_iterator& operator++()
4311 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
4315 json_reverse_iterator operator--(
int)
4317 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
4321 json_reverse_iterator& operator--()
4323 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
4327 json_reverse_iterator& operator+=(difference_type i)
4329 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
4333 json_reverse_iterator operator+(difference_type i)
const 4335 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
4339 json_reverse_iterator operator-(difference_type i)
const 4341 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
4345 difference_type operator-(
const json_reverse_iterator& other)
const 4347 return base_iterator(*
this) - base_iterator(other);
4351 reference operator[](difference_type n)
const 4353 return *(
this->operator+(n));
4357 auto key()
const ->
decltype(std::declval<Base>().key())
4359 auto it = --
this->base();
4364 reference value()
const 4366 auto it = --
this->base();
4367 return it.operator * ();
4376 template<
typename CharType>
struct output_adapter_protocol
4378 virtual void write_character(CharType c) = 0;
4379 virtual void write_characters(
const CharType* s, std::size_t length) = 0;
4380 virtual ~output_adapter_protocol() =
default;
4384 template<
typename CharType>
4385 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
4388 template<
typename CharType>
4389 class output_vector_adapter :
public output_adapter_protocol<CharType>
4392 explicit output_vector_adapter(std::vector<CharType>& vec) : v(vec) {}
4394 void write_character(CharType c)
override 4399 void write_characters(
const CharType* s, std::size_t length)
override 4401 std::copy(s, s + length, std::back_inserter(v));
4405 std::vector<CharType>& v;
4409 template<
typename CharType>
4410 class output_stream_adapter :
public output_adapter_protocol<CharType>
4413 explicit output_stream_adapter(std::basic_ostream<CharType>& s) : stream(s) {}
4415 void write_character(CharType c)
override 4420 void write_characters(
const CharType* s, std::size_t length)
override 4422 stream.write(s,
static_cast<std::streamsize>(length));
4426 std::basic_ostream<CharType>& stream;
4430 template<
typename CharType>
4431 class output_string_adapter :
public output_adapter_protocol<CharType>
4434 explicit output_string_adapter(std::basic_string<CharType>& s) : str(s) {}
4436 void write_character(CharType c)
override 4441 void write_characters(
const CharType* s, std::size_t length)
override 4443 str.append(s, length);
4447 std::basic_string<CharType>& str;
4450 template<
typename CharType>
4451 class output_adapter
4454 output_adapter(std::vector<CharType>& vec)
4455 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
4457 output_adapter(std::basic_ostream<CharType>& s)
4458 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
4460 output_adapter(std::basic_string<CharType>& s)
4461 : oa(std::make_shared<output_string_adapter<CharType>>(s)) {}
4463 operator output_adapter_t<CharType>()
4469 output_adapter_t<CharType> oa =
nullptr;
4479 template<
typename BasicJsonType>
4482 using number_integer_t =
typename BasicJsonType::number_integer_t;
4483 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
4491 explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
4506 BasicJsonType parse_cbor(
const bool strict)
4508 const auto res = parse_cbor_internal();
4527 BasicJsonType parse_msgpack(
const bool strict)
4529 const auto res = parse_msgpack_internal();
4545 static constexpr bool little_endianess(
int num = 1)
noexcept 4547 return (*
reinterpret_cast<
char*>(&num) == 1);
4556 BasicJsonType parse_cbor_internal(
const bool get_char =
true)
4558 switch (get_char ? get() : current)
4561 case std::char_traits<
char>::eof():
4562 JSON_THROW(parse_error::create(110, chars_read,
"unexpected end of input"));
4589 return static_cast<number_unsigned_t>(current);
4592 return get_number<uint8_t>();
4595 return get_number<uint16_t>();
4598 return get_number<uint32_t>();
4601 return get_number<uint64_t>();
4628 return static_cast<int8_t>(0x20 - 1 - current);
4633 return static_cast<number_integer_t>(-1) - get_number<uint8_t>();
4638 return static_cast<number_integer_t>(-1) - get_number<uint16_t>();
4643 return static_cast<number_integer_t>(-1) - get_number<uint32_t>();
4648 return static_cast<number_integer_t>(-1) -
4649 static_cast<number_integer_t>(get_number<uint64_t>());
4683 return get_cbor_string();
4712 return get_cbor_array(current & 0x1F);
4717 return get_cbor_array(get_number<uint8_t>());
4722 return get_cbor_array(get_number<uint16_t>());
4727 return get_cbor_array(get_number<uint32_t>());
4732 return get_cbor_array(get_number<uint64_t>());
4737 BasicJsonType result = value_t::array;
4738 while (get() != 0xFF)
4740 result.push_back(parse_cbor_internal(
false));
4771 return get_cbor_object(current & 0x1F);
4776 return get_cbor_object(get_number<uint8_t>());
4781 return get_cbor_object(get_number<uint16_t>());
4786 return get_cbor_object(get_number<uint32_t>());
4791 return get_cbor_object(get_number<uint64_t>());
4796 BasicJsonType result = value_t::object;
4797 while (get() != 0xFF)
4799 auto key = get_cbor_string();
4800 result[key] = parse_cbor_internal();
4817 return value_t::null;
4822 const int byte1 = get();
4824 const int byte2 = get();
4835 const int half = (byte1 << 8) + byte2;
4836 const int exp = (half >> 10) & 0x1F;
4837 const int mant = half & 0x3FF;
4841 val = std::ldexp(mant, -24);
4845 val = std::ldexp(mant + 1024, exp - 25);
4849 val = (mant == 0) ? std::numeric_limits<
double>::infinity()
4850 : std::numeric_limits<
double>::quiet_NaN();
4852 return (half & 0x8000) != 0 ? -val : val;
4857 return get_number<
float>();
4862 return get_number<
double>();
4867 std::stringstream ss;
4868 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
4869 JSON_THROW(parse_error::create(112, chars_read,
"error reading CBOR; last byte: 0x" + ss.str()));
4874 BasicJsonType parse_msgpack_internal()
4879 case std::char_traits<
char>::eof():
4880 JSON_THROW(parse_error::create(110, chars_read,
"unexpected end of input"));
5011 return static_cast<number_unsigned_t>(current);
5031 return get_msgpack_object(current & 0x0F);
5052 return get_msgpack_array(current & 0x0F);
5088 return get_msgpack_string();
5091 return value_t::null;
5100 return get_number<
float>();
5103 return get_number<
double>();
5106 return get_number<uint8_t>();
5109 return get_number<uint16_t>();
5112 return get_number<uint32_t>();
5115 return get_number<uint64_t>();
5118 return get_number<int8_t>();
5121 return get_number<int16_t>();
5124 return get_number<int32_t>();
5127 return get_number<int64_t>();
5132 return get_msgpack_string();
5136 return get_msgpack_array(get_number<uint16_t>());
5141 return get_msgpack_array(get_number<uint32_t>());
5146 return get_msgpack_object(get_number<uint16_t>());
5151 return get_msgpack_object(get_number<uint32_t>());
5187 return static_cast<int8_t>(current);
5191 std::stringstream ss;
5192 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5193 JSON_THROW(parse_error::create(112, chars_read,
5194 "error reading MessagePack; last byte: 0x" + ss.str()));
5211 return (current = ia->get_character());
5227 template<
typename NumberType> NumberType get_number()
5230 std::array<uint8_t,
sizeof(NumberType)> vec;
5231 for (std::size_t i = 0; i <
sizeof(NumberType); ++i)
5237 if (is_little_endian)
5239 vec[
sizeof(NumberType) - i - 1] =
static_cast<uint8_t>(current);
5243 vec[i] =
static_cast<uint8_t>(current);
5249 std::memcpy(&result, vec.data(),
sizeof(NumberType));
5266 template<
typename NumberType>
5267 std::string get_string(
const NumberType len)
5270 std::generate_n(std::back_inserter(result), len, [
this]()
5274 return static_cast<
char>(current);
5291 std::string get_cbor_string()
5323 return get_string(current & 0x1F);
5328 return get_string(get_number<uint8_t>());
5333 return get_string(get_number<uint16_t>());
5338 return get_string(get_number<uint32_t>());
5343 return get_string(get_number<uint64_t>());
5349 while (get() != 0xFF)
5352 result.push_back(
static_cast<
char>(current));
5359 std::stringstream ss;
5360 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5361 JSON_THROW(parse_error::create(113, chars_read,
"expected a CBOR string; last byte: 0x" + ss.str()));
5366 template<
typename NumberType>
5367 BasicJsonType get_cbor_array(
const NumberType len)
5369 BasicJsonType result = value_t::array;
5370 std::generate_n(std::back_inserter(*result.m_value.array), len, [
this]()
5372 return parse_cbor_internal();
5377 template<
typename NumberType>
5378 BasicJsonType get_cbor_object(
const NumberType len)
5380 BasicJsonType result = value_t::object;
5381 std::generate_n(std::inserter(*result.m_value.object,
5382 result.m_value.object->end()),
5386 auto key = get_cbor_string();
5387 auto val = parse_cbor_internal();
5388 return std::make_pair(std::move(key), std::move(val));
5404 std::string get_msgpack_string()
5444 return get_string(current & 0x1F);
5449 return get_string(get_number<uint8_t>());
5454 return get_string(get_number<uint16_t>());
5459 return get_string(get_number<uint32_t>());
5464 std::stringstream ss;
5465 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5466 JSON_THROW(parse_error::create(113, chars_read,
5467 "expected a MessagePack string; last byte: 0x" + ss.str()));
5472 template<
typename NumberType>
5473 BasicJsonType get_msgpack_array(
const NumberType len)
5475 BasicJsonType result = value_t::array;
5476 std::generate_n(std::back_inserter(*result.m_value.array), len, [
this]()
5478 return parse_msgpack_internal();
5483 template<
typename NumberType>
5484 BasicJsonType get_msgpack_object(
const NumberType len)
5486 BasicJsonType result = value_t::object;
5487 std::generate_n(std::inserter(*result.m_value.object,
5488 result.m_value.object->end()),
5492 auto key = get_msgpack_string();
5493 auto val = parse_msgpack_internal();
5494 return std::make_pair(std::move(key), std::move(val));
5503 void check_eof(
const bool expect_eof =
false)
const 5507 if (
JSON_UNLIKELY(current != std::char_traits<
char>::eof()))
5509 JSON_THROW(parse_error::create(110, chars_read,
"expected end of input"));
5514 if (
JSON_UNLIKELY(current == std::char_traits<
char>::eof()))
5516 JSON_THROW(parse_error::create(110, chars_read,
"unexpected end of input"));
5523 input_adapter_t ia =
nullptr;
5526 int current = std::char_traits<
char>::eof();
5529 std::size_t chars_read = 0;
5532 const bool is_little_endian = little_endianess();
5538 template<
typename BasicJsonType,
typename CharType>
5547 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
5555 void write_cbor(
const BasicJsonType& j)
5561 oa->write_character(
static_cast<CharType>(0xF6));
5565 case value_t::boolean:
5567 oa->write_character(j.m_value.boolean
5568 ?
static_cast<CharType>(0xF5)
5569 :
static_cast<CharType>(0xF4));
5573 case value_t::number_integer:
5575 if (j.m_value.number_integer >= 0)
5580 if (j.m_value.number_integer <= 0x17)
5582 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
5584 else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
5586 oa->write_character(
static_cast<CharType>(0x18));
5587 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
5589 else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
5591 oa->write_character(
static_cast<CharType>(0x19));
5592 write_number(
static_cast<uint16_t>(j.m_value.number_integer));
5594 else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
5596 oa->write_character(
static_cast<CharType>(0x1A));
5597 write_number(
static_cast<uint32_t>(j.m_value.number_integer));
5601 oa->write_character(
static_cast<CharType>(0x1B));
5602 write_number(
static_cast<uint64_t>(j.m_value.number_integer));
5609 const auto positive_number = -1 - j.m_value.number_integer;
5610 if (j.m_value.number_integer >= -24)
5612 write_number(
static_cast<uint8_t>(0x20 + positive_number));
5614 else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
5616 oa->write_character(
static_cast<CharType>(0x38));
5617 write_number(
static_cast<uint8_t>(positive_number));
5619 else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
5621 oa->write_character(
static_cast<CharType>(0x39));
5622 write_number(
static_cast<uint16_t>(positive_number));
5624 else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
5626 oa->write_character(
static_cast<CharType>(0x3A));
5627 write_number(
static_cast<uint32_t>(positive_number));
5631 oa->write_character(
static_cast<CharType>(0x3B));
5632 write_number(
static_cast<uint64_t>(positive_number));
5638 case value_t::number_unsigned:
5640 if (j.m_value.number_unsigned <= 0x17)
5642 write_number(
static_cast<uint8_t>(j.m_value.number_unsigned));
5644 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
5646 oa->write_character(
static_cast<CharType>(0x18));
5647 write_number(
static_cast<uint8_t>(j.m_value.number_unsigned));
5649 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
5651 oa->write_character(
static_cast<CharType>(0x19));
5652 write_number(
static_cast<uint16_t>(j.m_value.number_unsigned));
5654 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
5656 oa->write_character(
static_cast<CharType>(0x1A));
5657 write_number(
static_cast<uint32_t>(j.m_value.number_unsigned));
5661 oa->write_character(
static_cast<CharType>(0x1B));
5662 write_number(
static_cast<uint64_t>(j.m_value.number_unsigned));
5667 case value_t::number_float:
5669 oa->write_character(
static_cast<CharType>(0xFB));
5670 write_number(j.m_value.number_float);
5674 case value_t::string:
5677 const auto N = j.m_value.string->size();
5680 write_number(
static_cast<uint8_t>(0x60 + N));
5684 oa->write_character(
static_cast<CharType>(0x78));
5685 write_number(
static_cast<uint8_t>(N));
5687 else if (N <= 0xFFFF)
5689 oa->write_character(
static_cast<CharType>(0x79));
5690 write_number(
static_cast<uint16_t>(N));
5692 else if (N <= 0xFFFFFFFF)
5694 oa->write_character(
static_cast<CharType>(0x7A));
5695 write_number(
static_cast<uint32_t>(N));
5698 else if (N <= 0xFFFFFFFFFFFFFFFF)
5700 oa->write_character(
static_cast<CharType>(0x7B));
5701 write_number(
static_cast<uint64_t>(N));
5706 oa->write_characters(
5707 reinterpret_cast<
const CharType*>(j.m_value.string->c_str()),
5708 j.m_value.string->size());
5712 case value_t::array:
5715 const auto N = j.m_value.array->size();
5718 write_number(
static_cast<uint8_t>(0x80 + N));
5722 oa->write_character(
static_cast<CharType>(0x98));
5723 write_number(
static_cast<uint8_t>(N));
5725 else if (N <= 0xFFFF)
5727 oa->write_character(
static_cast<CharType>(0x99));
5728 write_number(
static_cast<uint16_t>(N));
5730 else if (N <= 0xFFFFFFFF)
5732 oa->write_character(
static_cast<CharType>(0x9A));
5733 write_number(
static_cast<uint32_t>(N));
5736 else if (N <= 0xFFFFFFFFFFFFFFFF)
5738 oa->write_character(
static_cast<CharType>(0x9B));
5739 write_number(
static_cast<uint64_t>(N));
5744 for (
const auto& el : *j.m_value.array)
5751 case value_t::object:
5754 const auto N = j.m_value.object->size();
5757 write_number(
static_cast<uint8_t>(0xA0 + N));
5761 oa->write_character(
static_cast<CharType>(0xB8));
5762 write_number(
static_cast<uint8_t>(N));
5764 else if (N <= 0xFFFF)
5766 oa->write_character(
static_cast<CharType>(0xB9));
5767 write_number(
static_cast<uint16_t>(N));
5769 else if (N <= 0xFFFFFFFF)
5771 oa->write_character(
static_cast<CharType>(0xBA));
5772 write_number(
static_cast<uint32_t>(N));
5775 else if (N <= 0xFFFFFFFFFFFFFFFF)
5777 oa->write_character(
static_cast<CharType>(0xBB));
5778 write_number(
static_cast<uint64_t>(N));
5783 for (
const auto& el : *j.m_value.object)
5785 write_cbor(el.first);
5786 write_cbor(el.second);
5799 void write_msgpack(
const BasicJsonType& j)
5805 oa->write_character(
static_cast<CharType>(0xC0));
5809 case value_t::boolean:
5811 oa->write_character(j.m_value.boolean
5812 ?
static_cast<CharType>(0xC3)
5813 :
static_cast<CharType>(0xC2));
5817 case value_t::number_integer:
5819 if (j.m_value.number_integer >= 0)
5824 if (j.m_value.number_unsigned < 128)
5827 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
5829 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
5832 oa->write_character(
static_cast<CharType>(0xCC));
5833 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
5835 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
5838 oa->write_character(
static_cast<CharType>(0xCD));
5839 write_number(
static_cast<uint16_t>(j.m_value.number_integer));
5841 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
5844 oa->write_character(
static_cast<CharType>(0xCE));
5845 write_number(
static_cast<uint32_t>(j.m_value.number_integer));
5847 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
5850 oa->write_character(
static_cast<CharType>(0xCF));
5851 write_number(
static_cast<uint64_t>(j.m_value.number_integer));
5856 if (j.m_value.number_integer >= -32)
5859 write_number(
static_cast<int8_t>(j.m_value.number_integer));
5861 else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)()
and 5862 j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
5865 oa->write_character(
static_cast<CharType>(0xD0));
5866 write_number(
static_cast<int8_t>(j.m_value.number_integer));
5868 else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)()
and 5869 j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
5872 oa->write_character(
static_cast<CharType>(0xD1));
5873 write_number(
static_cast<int16_t>(j.m_value.number_integer));
5875 else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)()
and 5876 j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
5879 oa->write_character(
static_cast<CharType>(0xD2));
5880 write_number(
static_cast<int32_t>(j.m_value.number_integer));
5882 else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)()
and 5883 j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
5886 oa->write_character(
static_cast<CharType>(0xD3));
5887 write_number(
static_cast<int64_t>(j.m_value.number_integer));
5893 case value_t::number_unsigned:
5895 if (j.m_value.number_unsigned < 128)
5898 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
5900 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
5903 oa->write_character(
static_cast<CharType>(0xCC));
5904 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
5906 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
5909 oa->write_character(
static_cast<CharType>(0xCD));
5910 write_number(
static_cast<uint16_t>(j.m_value.number_integer));
5912 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
5915 oa->write_character(
static_cast<CharType>(0xCE));
5916 write_number(
static_cast<uint32_t>(j.m_value.number_integer));
5918 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
5921 oa->write_character(
static_cast<CharType>(0xCF));
5922 write_number(
static_cast<uint64_t>(j.m_value.number_integer));
5927 case value_t::number_float:
5929 oa->write_character(
static_cast<CharType>(0xCB));
5930 write_number(j.m_value.number_float);
5934 case value_t::string:
5937 const auto N = j.m_value.string->size();
5941 write_number(
static_cast<uint8_t>(0xA0 | N));
5946 oa->write_character(
static_cast<CharType>(0xD9));
5947 write_number(
static_cast<uint8_t>(N));
5949 else if (N <= 65535)
5952 oa->write_character(
static_cast<CharType>(0xDA));
5953 write_number(
static_cast<uint16_t>(N));
5955 else if (N <= 4294967295)
5958 oa->write_character(
static_cast<CharType>(0xDB));
5959 write_number(
static_cast<uint32_t>(N));
5963 oa->write_characters(
5964 reinterpret_cast<
const CharType*>(j.m_value.string->c_str()),
5965 j.m_value.string->size());
5969 case value_t::array:
5972 const auto N = j.m_value.array->size();
5976 write_number(
static_cast<uint8_t>(0x90 | N));
5978 else if (N <= 0xFFFF)
5981 oa->write_character(
static_cast<CharType>(0xDC));
5982 write_number(
static_cast<uint16_t>(N));
5984 else if (N <= 0xFFFFFFFF)
5987 oa->write_character(
static_cast<CharType>(0xDD));
5988 write_number(
static_cast<uint32_t>(N));
5992 for (
const auto& el : *j.m_value.array)
5999 case value_t::object:
6002 const auto N = j.m_value.object->size();
6006 write_number(
static_cast<uint8_t>(0x80 | (N & 0xF)));
6008 else if (N <= 65535)
6011 oa->write_character(
static_cast<CharType>(0xDE));
6012 write_number(
static_cast<uint16_t>(N));
6014 else if (N <= 4294967295)
6017 oa->write_character(
static_cast<CharType>(0xDF));
6018 write_number(
static_cast<uint32_t>(N));
6022 for (
const auto& el : *j.m_value.object)
6024 write_msgpack(el.first);
6025 write_msgpack(el.second);
6046 template<
typename NumberType>
void write_number(NumberType n)
6049 std::array<CharType,
sizeof(NumberType)> vec;
6050 std::memcpy(vec.data(), &n,
sizeof(NumberType));
6053 if (is_little_endian)
6056 std::reverse(vec.begin(), vec.end());
6059 oa->write_characters(vec.data(),
sizeof(NumberType));
6064 const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
6067 output_adapter_t<CharType> oa =
nullptr;
6074 template<
typename BasicJsonType>
6077 using string_t =
typename BasicJsonType::string_t;
6078 using number_float_t =
typename BasicJsonType::number_float_t;
6079 using number_integer_t =
typename BasicJsonType::number_integer_t;
6080 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
6086 serializer(output_adapter_t<
char> s,
const char ichar)
6087 : o(std::move(s)), loc(std::localeconv()),
6088 thousands_sep(loc->thousands_sep ==
nullptr ?
'\0' : * (loc->thousands_sep)),
6089 decimal_point(loc->decimal_point ==
nullptr ?
'\0' : * (loc->decimal_point)),
6090 indent_char(ichar), indent_string(512, indent_char) {}
6093 serializer(
const serializer&) =
delete;
6094 serializer& operator=(
const serializer&) =
delete;
6113 void dump(
const BasicJsonType& val,
const bool pretty_print,
6114 const bool ensure_ascii,
6115 const unsigned int indent_step,
6116 const unsigned int current_indent = 0)
6120 case value_t::object:
6122 if (val.m_value.object->empty())
6124 o->write_characters(
"{}", 2);
6130 o->write_characters(
"{\n", 2);
6133 const auto new_indent = current_indent + indent_step;
6136 indent_string.resize(indent_string.size() * 2,
' ');
6140 auto i = val.m_value.object->cbegin();
6141 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
6143 o->write_characters(indent_string.c_str(), new_indent);
6144 o->write_character(
'\"');
6145 dump_escaped(i->first, ensure_ascii);
6146 o->write_characters(
"\": ", 3);
6147 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
6148 o->write_characters(
",\n", 2);
6152 assert(i != val.m_value.object->cend());
6153 assert(std::next(i) == val.m_value.object->cend());
6154 o->write_characters(indent_string.c_str(), new_indent);
6155 o->write_character(
'\"');
6156 dump_escaped(i->first, ensure_ascii);
6157 o->write_characters(
"\": ", 3);
6158 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
6160 o->write_character(
'\n');
6161 o->write_characters(indent_string.c_str(), current_indent);
6162 o->write_character(
'}');
6166 o->write_character(
'{');
6169 auto i = val.m_value.object->cbegin();
6170 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
6172 o->write_character(
'\"');
6173 dump_escaped(i->first, ensure_ascii);
6174 o->write_characters(
"\":", 2);
6175 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
6176 o->write_character(
',');
6180 assert(i != val.m_value.object->cend());
6181 assert(std::next(i) == val.m_value.object->cend());
6182 o->write_character(
'\"');
6183 dump_escaped(i->first, ensure_ascii);
6184 o->write_characters(
"\":", 2);
6185 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
6187 o->write_character(
'}');
6193 case value_t::array:
6195 if (val.m_value.array->empty())
6197 o->write_characters(
"[]", 2);
6203 o->write_characters(
"[\n", 2);
6206 const auto new_indent = current_indent + indent_step;
6209 indent_string.resize(indent_string.size() * 2,
' ');
6213 for (
auto i = val.m_value.array->cbegin();
6214 i != val.m_value.array->cend() - 1; ++i)
6216 o->write_characters(indent_string.c_str(), new_indent);
6217 dump(*i,
true, ensure_ascii, indent_step, new_indent);
6218 o->write_characters(
",\n", 2);
6222 assert(
not val.m_value.array->empty());
6223 o->write_characters(indent_string.c_str(), new_indent);
6224 dump(val.m_value.array->back(),
true, ensure_ascii, indent_step, new_indent);
6226 o->write_character(
'\n');
6227 o->write_characters(indent_string.c_str(), current_indent);
6228 o->write_character(
']');
6232 o->write_character(
'[');
6235 for (
auto i = val.m_value.array->cbegin();
6236 i != val.m_value.array->cend() - 1; ++i)
6238 dump(*i,
false, ensure_ascii, indent_step, current_indent);
6239 o->write_character(
',');
6243 assert(
not val.m_value.array->empty());
6244 dump(val.m_value.array->back(),
false, ensure_ascii, indent_step, current_indent);
6246 o->write_character(
']');
6252 case value_t::string:
6254 o->write_character(
'\"');
6255 dump_escaped(*val.m_value.string, ensure_ascii);
6256 o->write_character(
'\"');
6260 case value_t::boolean:
6262 if (val.m_value.boolean)
6264 o->write_characters(
"true", 4);
6268 o->write_characters(
"false", 5);
6273 case value_t::number_integer:
6275 dump_integer(val.m_value.number_integer);
6279 case value_t::number_unsigned:
6281 dump_integer(val.m_value.number_unsigned);
6285 case value_t::number_float:
6287 dump_float(val.m_value.number_float);
6291 case value_t::discarded:
6293 o->write_characters(
"<discarded>", 11);
6299 o->write_characters(
"null", 4);
6312 static constexpr std::size_t bytes_following(
const uint8_t u)
6314 return ((u <= 127) ? 0
6315 : ((192 <= u
and u <= 223) ? 1
6316 : ((224 <= u
and u <= 239) ? 2
6317 : ((240 <= u
and u <= 247) ? 3 : std::string::npos))));
6330 static std::size_t extra_space(
const string_t& s,
6331 const bool ensure_ascii)
noexcept 6333 std::size_t res = 0;
6335 for (std::size_t i = 0; i < s.size(); ++i)
6389 if (ensure_ascii
and (s[i] & 0x80
or s[i] == 0x7F))
6391 const auto bytes = bytes_following(
static_cast<uint8_t>(s[i]));
6393 assert (bytes != std::string::npos);
6401 res += (12 - bytes - 1);
6406 res += (6 - bytes - 1);
6420 static void escape_codepoint(
int codepoint, string_t& result, std::size_t& pos)
6423 assert(0x00 <= codepoint
and codepoint <= 0x10FFFF);
6426 assert(result[pos] ==
'\\');
6429 result[++pos] =
'u';
6432 static const std::array<
char, 16> hexify =
6435 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
6436 '8',
'9',
'a',
'b',
'c',
'd',
'e',
'f' 6440 if (codepoint < 0x10000)
6443 result[++pos] = hexify[(codepoint >> 12) & 0x0F];
6444 result[++pos] = hexify[(codepoint >> 8) & 0x0F];
6445 result[++pos] = hexify[(codepoint >> 4) & 0x0F];
6446 result[++pos] = hexify[codepoint & 0x0F];
6453 codepoint -= 0x10000;
6454 const int high_surrogate = 0xD800 | ((codepoint >> 10) & 0x3FF);
6455 const int low_surrogate = 0xDC00 | (codepoint & 0x3FF);
6456 result[++pos] = hexify[(high_surrogate >> 12) & 0x0F];
6457 result[++pos] = hexify[(high_surrogate >> 8) & 0x0F];
6458 result[++pos] = hexify[(high_surrogate >> 4) & 0x0F];
6459 result[++pos] = hexify[high_surrogate & 0x0F];
6461 result[++pos] =
'u';
6462 result[++pos] = hexify[(low_surrogate >> 12) & 0x0F];
6463 result[++pos] = hexify[(low_surrogate >> 8) & 0x0F];
6464 result[++pos] = hexify[(low_surrogate >> 4) & 0x0F];
6465 result[++pos] = hexify[low_surrogate & 0x0F];
6485 void dump_escaped(
const string_t& s,
const bool ensure_ascii)
const 6487 throw_if_invalid_utf8(s);
6489 const auto space = extra_space(s, ensure_ascii);
6492 o->write_characters(s.c_str(), s.size());
6497 string_t result(s.size() + space,
'\\');
6498 std::size_t pos = 0;
6500 for (std::size_t i = 0; i < s.size(); ++i)
6506 result[pos + 1] =
'"';
6520 result[pos + 1] =
'b';
6527 result[pos + 1] =
'f';
6534 result[pos + 1] =
'n';
6541 result[pos + 1] =
'r';
6548 result[pos + 1] =
't';
6557 if ((0x00 <= s[i]
and s[i] <= 0x1F)
or 6558 (ensure_ascii
and (s[i] & 0x80
or s[i] == 0x7F)))
6560 const auto bytes = bytes_following(
static_cast<uint8_t>(s[i]));
6562 assert (bytes != std::string::npos);
6565 assert(i + bytes < s.size());
6571 assert(0 <= bytes
and bytes <= 3);
6576 codepoint = s[i] & 0xFF;
6582 codepoint = ((s[i] & 0x3F) << 6)
6583 + (s[i + 1] & 0x7F);
6589 codepoint = ((s[i] & 0x1F) << 12)
6590 + ((s[i + 1] & 0x7F) << 6)
6591 + (s[i + 2] & 0x7F);
6597 codepoint = ((s[i] & 0xF) << 18)
6598 + ((s[i + 1] & 0x7F) << 12)
6599 + ((s[i + 2] & 0x7F) << 6)
6600 + (s[i + 3] & 0x7F);
6608 escape_codepoint(codepoint, result, pos);
6614 result[pos++] = s[i];
6621 assert(pos == result.size());
6622 o->write_characters(result.c_str(), result.size());
6634 template<
typename NumberType, detail::enable_if_t<
6635 std::is_same<NumberType, number_unsigned_t>::value
or 6636 std::is_same<NumberType, number_integer_t>::value,
6638 void dump_integer(NumberType x)
6643 o->write_character(
'0');
6647 const bool is_negative = (x <= 0)
and (x != 0);
6653 assert(i < number_buffer.size() - 1);
6655 const auto digit = std::labs(
static_cast<
long>(x % 10));
6656 number_buffer[i++] =
static_cast<
char>(
'0' + digit);
6663 assert(i < number_buffer.size() - 2);
6664 number_buffer[i++] =
'-';
6667 std::reverse(number_buffer.begin(), number_buffer.begin() + i);
6668 o->write_characters(number_buffer.data(), i);
6679 void dump_float(number_float_t x)
6682 if (
not std::isfinite(x)
or std::isnan(x))
6684 o->write_characters(
"null", 4);
6689 static constexpr auto d = std::numeric_limits<number_float_t>::digits10;
6692 std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(),
"%.*g", d, x);
6697 assert(
static_cast<std::size_t>(len) < number_buffer.size());
6700 if (thousands_sep !=
'\0')
6702 const auto end = std::remove(number_buffer.begin(),
6703 number_buffer.begin() + len, thousands_sep);
6704 std::fill(end, number_buffer.end(),
'\0');
6705 assert((end - number_buffer.begin()) <= len);
6706 len = (end - number_buffer.begin());
6710 if (decimal_point !=
'\0' and decimal_point !=
'.')
6712 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
6713 if (dec_pos != number_buffer.end())
6719 o->write_characters(number_buffer.data(),
static_cast<std::size_t>(len));
6722 const bool value_is_int_like =
6723 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
6726 return (c ==
'.' or c ==
'e');
6729 if (value_is_int_like)
6731 o->write_characters(
".0", 2);
6755 static void decode(uint8_t& state,
const uint8_t byte)
6757 static const std::array<uint8_t, 400> utf8d =
6760 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,
6761 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,
6762 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,
6763 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,
6764 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,
6765 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,
6766 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,
6767 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
6768 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
6769 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
6770 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,
6771 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,
6772 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,
6773 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
6777 const uint8_t type = utf8d[byte];
6778 state = utf8d[256u + state * 16u + type];
6789 static void throw_if_invalid_utf8(
const std::string& str)
6794 for (size_t i = 0; i < str.size(); ++i)
6796 const auto byte =
static_cast<uint8_t>(str[i]);
6797 decode(state, byte);
6801 std::stringstream ss;
6802 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex <<
static_cast<
int>(byte);
6803 JSON_THROW(type_error::create(316,
"invalid UTF-8 byte at index " + std::to_string(i) +
": 0x" + ss.str()));
6810 std::stringstream ss;
6811 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex <<
static_cast<
int>(
static_cast<uint8_t>(str.back()));
6812 JSON_THROW(type_error::create(316,
"incomplete UTF-8 string; last byte: 0x" + ss.str()));
6818 output_adapter_t<
char> o =
nullptr;
6821 std::array<
char, 64> number_buffer{{}};
6824 const std::lconv* loc =
nullptr;
6826 const char thousands_sep =
'\0';
6828 const char decimal_point =
'\0';
6831 const char indent_char;
6834 string_t indent_string;
6837 template<
typename BasicJsonType>
6841 using value_type = BasicJsonType;
6843 json_ref(value_type&& value)
6844 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(
true)
6847 json_ref(
const value_type& value)
6848 : value_ref(
const_cast<value_type*>(&value)), is_rvalue(
false)
6851 json_ref(std::initializer_list<json_ref> init)
6852 : owned_value(init), value_ref(&owned_value), is_rvalue(
true)
6855 template<
class... Args>
6856 json_ref(Args&& ... args)
6857 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value), is_rvalue(
true)
6861 json_ref(json_ref&&) =
default;
6862 json_ref(
const json_ref&) =
delete;
6863 json_ref& operator=(
const json_ref&) =
delete;
6865 value_type moved_or_copied()
const 6869 return std::move(*value_ref);
6874 value_type
const& operator*()
const 6876 return *
static_cast<value_type
const*>(value_ref);
6879 value_type
const* operator->()
const 6881 return static_cast<value_type
const*>(value_ref);
6885 mutable value_type owned_value =
nullptr;
6886 value_type* value_ref =
nullptr;
6887 const bool is_rvalue;
6895 constexpr const auto&
to_json = detail::static_const<detail::to_json_fn>::value;
6896 constexpr const auto&
from_json = detail::static_const<detail::from_json_fn>::value;
6907 template<
typename,
typename>
6908 struct adl_serializer
6919 template<
typename BasicJsonType,
typename ValueType>
6920 static void from_json(BasicJsonType&& j, ValueType& val)
noexcept(
6935 template<
typename BasicJsonType,
typename ValueType>
6936 static void to_json(BasicJsonType& j, ValueType&& val)
noexcept(
6982 explicit json_pointer(
const std::string& s =
"") : reference_tokens(split(s)) {}
6999 std::string to_string()
const noexcept 7001 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
7003 [](
const std::string & a,
const std::string & b)
7005 return a +
"/" + escape(b);
7010 operator std::string()
const 7020 std::string pop_back()
7024 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
7027 auto last = reference_tokens.back();
7028 reference_tokens.pop_back();
7033 bool is_root()
const 7035 return reference_tokens.empty();
7042 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
7046 result.reference_tokens = {reference_tokens[0]};
7127 static std::vector<std::string> split(
const std::string& reference_string)
7129 std::vector<std::string> result;
7132 if (reference_string.empty())
7140 JSON_THROW(detail::parse_error::create(107, 1,
7141 "JSON pointer must be empty or begin with '/' - was: '" +
7142 reference_string +
"'"));
7150 std::size_t slash = reference_string.find_first_of(
'/', 1),
7159 slash = reference_string.find_first_of(
'/', start))
7163 auto reference_token = reference_string.substr(start, slash - start);
7166 for (std::size_t pos = reference_token.find_first_of(
'~');
7167 pos != std::string::npos;
7168 pos = reference_token.find_first_of(
'~', pos + 1))
7170 assert(reference_token[pos] ==
'~');
7174 (reference_token[pos + 1] !=
'0' and 7175 reference_token[pos + 1] !=
'1')))
7177 JSON_THROW(detail::parse_error::create(108, 0,
"escape character '~' must be followed with '0' or '1'"));
7182 unescape(reference_token);
7183 result.push_back(reference_token);
7202 static void replace_substring(std::string& s,
const std::string& f,
7203 const std::string& t)
7205 assert(
not f.empty());
7206 for (
auto pos = s.find(f);
7207 pos != std::string::npos;
7208 s.replace(pos, f.size(), t),
7209 pos = s.find(f, pos + t.size()))
7214 static std::string escape(std::string s)
7216 replace_substring(s,
"~",
"~0");
7217 replace_substring(s,
"/",
"~1");
7222 static void unescape(std::string& s)
7224 replace_substring(s,
"~1",
"/");
7225 replace_substring(s,
"~0",
"~");
7236 static void flatten(
const std::string& reference_string,
7261 std::vector<std::string> reference_tokens;
7349 template<detail::value_t>
friend struct detail::external_constructor;
7353 template<
typename BasicJsonType>
7355 template<
typename BasicJsonType,
typename CharType>
7356 friend class ::
nlohmann::detail::binary_writer;
7357 template<
typename BasicJsonType>
7358 friend class ::
nlohmann::detail::binary_reader;
7367 using primitive_iterator_t = ::
nlohmann::detail::primitive_iterator_t;
7368 template<
typename BasicJsonType>
7369 using internal_iterator = ::
nlohmann::detail::internal_iterator<BasicJsonType>;
7370 template<
typename BasicJsonType>
7371 using iter_impl = ::
nlohmann::detail::iter_impl<BasicJsonType>;
7372 template<
typename Iterator>
7373 using iteration_proxy = ::
nlohmann::detail::iteration_proxy<Iterator>;
7374 template<
typename Base>
using json_reverse_iterator = ::
nlohmann::detail::json_reverse_iterator<Base>;
7376 template<
typename CharType>
7377 using output_adapter_t = ::
nlohmann::detail::output_adapter_t<CharType>;
7380 template<
typename CharType>
using binary_writer = ::
nlohmann::detail::binary_writer<
basic_json, CharType>;
7385 using value_t = detail::value_t;
7388 template<
typename T,
typename SFINAE>
7389 using json_serializer = JSONSerializer<T, SFINAE>;
7391 using initializer_list_t = std::initializer_list<detail::json_ref<
basic_json>>;
7402 using exception = detail::exception;
7404 using parse_error = detail::parse_error;
7406 using invalid_iterator = detail::invalid_iterator;
7408 using type_error = detail::type_error;
7410 using out_of_range = detail::out_of_range;
7412 using other_error = detail::other_error;
7430 using reference = value_type&;
7432 using const_reference =
const value_type&;
7435 using difference_type = std::ptrdiff_t;
7437 using size_type = std::size_t;
7443 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
7445 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
7452 using reverse_iterator = json_reverse_iterator<
typename basic_json::iterator>;
7454 using const_reverse_iterator = json_reverse_iterator<
typename basic_json::const_iterator>;
7462 static allocator_type get_allocator()
7464 return allocator_type();
7497 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
7498 result[
"name"] =
"JSON for Modern C++";
7499 result[
"url"] =
"https://github.com/nlohmann/json";
7502 {
"string",
"3.0.0"}, {
"major", 3}, {
"minor", 0}, {
"patch", 0}
7506 result[
"platform"] =
"win32";
7507 #elif defined __linux__ 7508 result[
"platform"] =
"linux";
7509 #elif defined __APPLE__
7510 result[
"platform"] =
"apple";
7511 #elif defined __unix__ 7512 result[
"platform"] =
"unix";
7514 result[
"platform"] =
"unknown";
7517 #if defined(__ICC) || defined(__INTEL_COMPILER) 7518 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
7519 #elif defined(__clang__
) 7520 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
7521 #elif defined(__GNUC__) || defined(__GNUG__) 7522 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(__GNUC_PATCHLEVEL__)}};
7523 #elif defined(__HP_cc) || defined(__HP_aCC) 7524 result[
"compiler"] =
"hp" 7525 #elif defined(__IBMCPP__) 7526 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
7527 #elif defined(_MSC_VER) 7528 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
7529 #elif defined(__PGI) 7530 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
7531 #elif defined(__SUNPRO_CC) 7532 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
7534 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
7538 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
7540 result[
"compiler"][
"c++"] =
"unknown";
7555 #if defined(JSON_HAS_CPP_14) 7560 using object_comparator_t = std::less<StringType>;
7646 using object_t = ObjectType<StringType,
7648 object_comparator_t,
7649 AllocatorType<std::pair<
const StringType,
7749 using string_t = StringType;
7775 using boolean_t = BooleanType;
7847 using number_integer_t = NumberIntegerType;
7918 using number_unsigned_t = NumberUnsignedType;
7986 using number_float_t = NumberFloatType;
7993 template<
typename T,
typename... Args>
7994 static T* create(Args&& ... args)
7996 AllocatorType<T> alloc;
7997 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
7999 auto deleter = [&](T * object)
8001 AllocatorTraits::deallocate(alloc, object, 1);
8003 std::unique_ptr<T,
decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
8004 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
8005 assert(object !=
nullptr);
8006 return object.release();
8048 number_integer_t number_integer;
8050 number_unsigned_t number_unsigned;
8052 number_float_t number_float;
8055 json_value() =
default;
8057 json_value(boolean_t v)
noexcept : boolean(v) {}
8059 json_value(number_integer_t v)
noexcept : number_integer(v) {}
8061 json_value(number_unsigned_t v)
noexcept : number_unsigned(v) {}
8063 json_value(number_float_t v)
noexcept : number_float(v) {}
8065 json_value(value_t t)
8069 case value_t::object:
8071 object = create<object_t>();
8075 case value_t::array:
8077 array = create<array_t>();
8081 case value_t::string:
8083 string = create<string_t>(
"");
8087 case value_t::boolean:
8089 boolean = boolean_t(
false);
8093 case value_t::number_integer:
8095 number_integer = number_integer_t(0);
8099 case value_t::number_unsigned:
8101 number_unsigned = number_unsigned_t(0);
8105 case value_t::number_float:
8107 number_float = number_float_t(0.0);
8122 JSON_THROW(other_error::create(500,
"961c151d2e87f2686a955a9be24d316f1362bf21 3.0.0"));
8130 json_value(
const string_t& value)
8132 string = create<string_t>(value);
8136 json_value(string_t&& value)
8138 string = create<string_t>(std::move(value));
8142 json_value(
const object_t& value)
8144 object = create<object_t>(value);
8148 json_value(object_t&& value)
8150 object = create<object_t>(std::move(value));
8154 json_value(
const array_t& value)
8156 array = create<array_t>(value);
8160 json_value(array_t&& value)
8162 array = create<array_t>(std::move(value));
8165 void destroy(value_t t)
8169 case value_t::object:
8171 AllocatorType<object_t> alloc;
8172 std::allocator_traits<
decltype(alloc)>::destroy(alloc, object);
8173 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, object, 1);
8177 case value_t::array:
8179 AllocatorType<array_t> alloc;
8180 std::allocator_traits<
decltype(alloc)>::destroy(alloc, array);
8181 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, array, 1);
8185 case value_t::string:
8187 AllocatorType<string_t> alloc;
8188 std::allocator_traits<
decltype(alloc)>::destroy(alloc, string);
8189 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, string, 1);
8210 void assert_invariant()
const 8212 assert(m_type != value_t::object
or m_value.object !=
nullptr);
8213 assert(m_type != value_t::array
or m_value.array !=
nullptr);
8214 assert(m_type != value_t::string
or m_value.string !=
nullptr);
8237 using parse_event_t =
typename parser::parse_event_t;
8288 using parser_callback_t =
typename parser::parser_callback_t;
8329 basic_json(
const value_t v)
8330 : m_type(v), m_value(v)
8353 basic_json(std::nullptr_t =
nullptr)
noexcept 8415 template<
typename CompatibleType,
typename U = detail::uncvref_t<CompatibleType>,
8416 detail::enable_if_t<
not std::is_base_of<std::istream, U>::value
and 8417 not std::is_same<U, basic_json_t>::value
and 8418 not detail::is_basic_json_nested_type<
8419 basic_json_t, U>::value
and 8422 basic_json(CompatibleType && val)
noexcept(
noexcept(JSONSerializer<U>::to_json(
8423 std::declval<basic_json_t&>(), std::forward<CompatibleType>(val))))
8425 JSONSerializer<U>::to_json(*
this, std::forward<CompatibleType>(val));
8503 basic_json(initializer_list_t init,
8504 bool type_deduction =
true,
8505 value_t manual_type = value_t::array)
8509 bool is_an_object = std::all_of(init.begin(), init.end(),
8510 [](
const detail::json_ref<
basic_json>& element_ref)
8512 return (element_ref->is_array()
and element_ref->size() == 2
and (*element_ref)[0].is_string());
8516 if (
not type_deduction)
8519 if (manual_type == value_t::array)
8521 is_an_object =
false;
8525 if (
JSON_UNLIKELY(manual_type == value_t::object
and not is_an_object))
8527 JSON_THROW(type_error::create(301,
"cannot create object from initializer list"));
8534 m_type = value_t::object;
8535 m_value = value_t::object;
8537 std::for_each(init.begin(), init.end(), [
this](
const detail::json_ref<
basic_json>& element_ref)
8539 auto element = element_ref.moved_or_copied();
8540 m_value.object->emplace(
8541 std::move(*((*element.m_value.array)[0].m_value.string)),
8542 std::move((*element.m_value.array)[1]));
8548 m_type = value_t::array;
8549 m_value.array = create<array_t>(init.begin(), init.end());
8592 static basic_json array(initializer_list_t init = {})
8594 return basic_json(init,
false, value_t::array);
8635 static basic_json object(initializer_list_t init = {})
8637 return basic_json(init,
false, value_t::object);
8662 basic_json(size_type cnt,
const basic_json& val)
8663 : m_type(value_t::array)
8665 m_value.array = create<array_t>(cnt, val);
8724 template<
class InputIT,
typename std::enable_if<
8725 std::is_same<InputIT,
typename basic_json_t::iterator>::value
or 8726 std::is_same<InputIT,
typename basic_json_t::const_iterator>::value,
int>::type = 0>
8727 basic_json(InputIT first, InputIT last)
8729 assert(first.m_object !=
nullptr);
8730 assert(last.m_object !=
nullptr);
8735 JSON_THROW(invalid_iterator::create(201,
"iterators are not compatible"));
8739 m_type = first.m_object->m_type;
8744 case value_t::boolean:
8745 case value_t::number_float:
8746 case value_t::number_integer:
8747 case value_t::number_unsigned:
8748 case value_t::string:
8750 if (
JSON_UNLIKELY(
not first.m_it.primitive_iterator.is_begin()
8751 or not last.m_it.primitive_iterator.is_end()))
8753 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
8764 case value_t::number_integer:
8766 m_value.number_integer = first.m_object->m_value.number_integer;
8770 case value_t::number_unsigned:
8772 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
8776 case value_t::number_float:
8778 m_value.number_float = first.m_object->m_value.number_float;
8782 case value_t::boolean:
8784 m_value.boolean = first.m_object->m_value.boolean;
8788 case value_t::string:
8790 m_value = *first.m_object->m_value.string;
8794 case value_t::object:
8796 m_value.object = create<object_t>(first.m_it.object_iterator,
8797 last.m_it.object_iterator);
8801 case value_t::array:
8803 m_value.array = create<array_t>(first.m_it.array_iterator,
8804 last.m_it.array_iterator);
8809 JSON_THROW(invalid_iterator::create(206,
"cannot construct with iterators from " +
8810 std::string(first.m_object->type_name())));
8822 basic_json(
const detail::json_ref<
basic_json>& ref)
8852 : m_type(other.m_type)
8855 other.assert_invariant();
8859 case value_t::object:
8861 m_value = *other.m_value.object;
8865 case value_t::array:
8867 m_value = *other.m_value.array;
8871 case value_t::string:
8873 m_value = *other.m_value.string;
8877 case value_t::boolean:
8879 m_value = other.m_value.boolean;
8883 case value_t::number_integer:
8885 m_value = other.m_value.number_integer;
8889 case value_t::number_unsigned:
8891 m_value = other.m_value.number_unsigned;
8895 case value_t::number_float:
8897 m_value = other.m_value.number_float;
8935 : m_type(std::move(other.m_type)),
8936 m_value(std::move(other.m_value))
8939 other.assert_invariant();
8942 other.m_type = value_t::null;
8971 reference& operator=(
basic_json other)
noexcept (
8972 std::is_nothrow_move_constructible<value_t>::value
and 8973 std::is_nothrow_move_assignable<value_t>::value
and 8974 std::is_nothrow_move_constructible<json_value>::value
and 8975 std::is_nothrow_move_assignable<json_value>::value
8979 other.assert_invariant();
8982 swap(m_type, other.m_type);
8983 swap(m_value, other.m_value);
9007 m_value.destroy(m_type);
9057 string_t dump(
const int indent = -1,
const char indent_char =
' ',
9058 const bool ensure_ascii =
false)
const 9061 serializer s(detail::output_adapter<
char>(result), indent_char);
9065 s.dump(*
this,
true, ensure_ascii,
static_cast<
unsigned int>(indent));
9069 s.dump(*
this,
false, ensure_ascii, 0);
9107 constexpr value_t type()
const noexcept 9137 constexpr bool is_primitive()
const noexcept 9139 return is_null()
or is_string()
or is_boolean()
or is_number();
9164 constexpr bool is_structured()
const noexcept 9166 return is_array()
or is_object();
9186 constexpr bool is_null()
const noexcept 9188 return (m_type == value_t::null);
9208 constexpr bool is_boolean()
const noexcept 9210 return (m_type == value_t::boolean);
9238 constexpr bool is_number()
const noexcept 9240 return is_number_integer()
or is_number_float();
9267 constexpr bool is_number_integer()
const noexcept 9269 return (m_type == value_t::number_integer
or m_type == value_t::number_unsigned);
9295 constexpr bool is_number_unsigned()
const noexcept 9297 return (m_type == value_t::number_unsigned);
9323 constexpr bool is_number_float()
const noexcept 9325 return (m_type == value_t::number_float);
9345 constexpr bool is_object()
const noexcept 9347 return (m_type == value_t::object);
9367 constexpr bool is_array()
const noexcept 9369 return (m_type == value_t::array);
9389 constexpr bool is_string()
const noexcept 9391 return (m_type == value_t::string);
9416 constexpr bool is_discarded()
const noexcept 9418 return (m_type == value_t::discarded);
9442 constexpr operator value_t()
const noexcept 9455 boolean_t get_impl(boolean_t* )
const 9459 return m_value.boolean;
9462 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(type_name())));
9466 object_t* get_impl_ptr(object_t* )
noexcept 9468 return is_object() ? m_value.object :
nullptr;
9472 constexpr const object_t* get_impl_ptr(
const object_t* )
const noexcept 9474 return is_object() ? m_value.object :
nullptr;
9478 array_t* get_impl_ptr(array_t* )
noexcept 9480 return is_array() ? m_value.array :
nullptr;
9484 constexpr const array_t* get_impl_ptr(
const array_t* )
const noexcept 9486 return is_array() ? m_value.array :
nullptr;
9490 string_t* get_impl_ptr(string_t* )
noexcept 9492 return is_string() ? m_value.string :
nullptr;
9496 constexpr const string_t* get_impl_ptr(
const string_t* )
const noexcept 9498 return is_string() ? m_value.string :
nullptr;
9502 boolean_t* get_impl_ptr(boolean_t* )
noexcept 9504 return is_boolean() ? &m_value.boolean :
nullptr;
9508 constexpr const boolean_t* get_impl_ptr(
const boolean_t* )
const noexcept 9510 return is_boolean() ? &m_value.boolean :
nullptr;
9514 number_integer_t* get_impl_ptr(number_integer_t* )
noexcept 9516 return is_number_integer() ? &m_value.number_integer :
nullptr;
9520 constexpr const number_integer_t* get_impl_ptr(
const number_integer_t* )
const noexcept 9522 return is_number_integer() ? &m_value.number_integer :
nullptr;
9526 number_unsigned_t* get_impl_ptr(number_unsigned_t* )
noexcept 9528 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
9532 constexpr const number_unsigned_t* get_impl_ptr(
const number_unsigned_t* )
const noexcept 9534 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
9538 number_float_t* get_impl_ptr(number_float_t* )
noexcept 9540 return is_number_float() ? &m_value.number_float :
nullptr;
9544 constexpr const number_float_t* get_impl_ptr(
const number_float_t* )
const noexcept 9546 return is_number_float() ? &m_value.number_float :
nullptr;
9560 template<
typename ReferenceType,
typename ThisType>
9561 static ReferenceType get_ref_impl(ThisType& obj)
9564 auto ptr = obj.
template get_ptr<
typename std::add_pointer<ReferenceType>::type>();
9571 JSON_THROW(type_error::create(303,
"incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
9593 template<
typename BasicJsonType, detail::enable_if_t<
9594 std::is_same<
typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
9640 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
9641 detail::enable_if_t <
9642 not std::is_same<basic_json_t, ValueType>::value
and 9643 detail::has_from_json<basic_json_t, ValueType>::value
and 9644 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
9646 ValueType get()
const noexcept(
noexcept(
9647 JSONSerializer<ValueType>::from_json(std::declval<
const basic_json_t&>(), std::declval<ValueType&>())))
9652 static_assert(
not std::is_reference<ValueTypeCV>::value,
9653 "get() cannot be used with reference types, you might want to use get_ref()");
9654 static_assert(std::is_default_constructible<ValueType>::value,
9655 "types must be DefaultConstructible when used with get()");
9658 JSONSerializer<ValueType>::from_json(*
this, ret);
9693 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
9694 detail::enable_if_t<
not std::is_same<basic_json_t, ValueType>::value
and 9695 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
9697 ValueType get()
const noexcept(
noexcept(
9698 JSONSerializer<ValueTypeCV>::from_json(std::declval<
const basic_json_t&>())))
9700 static_assert(
not std::is_reference<ValueTypeCV>::value,
9701 "get() cannot be used with reference types, you might want to use get_ref()");
9702 return JSONSerializer<ValueTypeCV>::from_json(*
this);
9732 template<
typename PointerType,
typename std::enable_if<
9733 std::is_pointer<PointerType>::value,
int>::type = 0>
9734 PointerType get()
noexcept 9737 return get_ptr<PointerType>();
9744 template<
typename PointerType,
typename std::enable_if<
9745 std::is_pointer<PointerType>::value,
int>::type = 0>
9746 constexpr const PointerType get()
const noexcept 9749 return get_ptr<PointerType>();
9778 template<
typename PointerType,
typename std::enable_if<
9779 std::is_pointer<PointerType>::value,
int>::type = 0>
9780 PointerType get_ptr()
noexcept 9783 using pointee_t =
typename std::remove_const<
typename 9784 std::remove_pointer<
typename 9785 std::remove_const<PointerType>::type>::type>::type;
9788 std::is_same<object_t, pointee_t>::value
9789 or std::is_same<array_t, pointee_t>::value
9790 or std::is_same<string_t, pointee_t>::value
9791 or std::is_same<boolean_t, pointee_t>::value
9792 or std::is_same<number_integer_t, pointee_t>::value
9793 or std::is_same<number_unsigned_t, pointee_t>::value
9794 or std::is_same<number_float_t, pointee_t>::value
9795 ,
"incompatible pointer type");
9798 return get_impl_ptr(
static_cast<PointerType>(
nullptr));
9805 template<
typename PointerType,
typename std::enable_if<
9806 std::is_pointer<PointerType>::value
and 9807 std::is_const<
typename std::remove_pointer<PointerType>::type>::value,
int>::type = 0>
9808 constexpr const PointerType get_ptr()
const noexcept 9811 using pointee_t =
typename std::remove_const<
typename 9812 std::remove_pointer<
typename 9813 std::remove_const<PointerType>::type>::type>::type;
9816 std::is_same<object_t, pointee_t>::value
9817 or std::is_same<array_t, pointee_t>::value
9818 or std::is_same<string_t, pointee_t>::value
9819 or std::is_same<boolean_t, pointee_t>::value
9820 or std::is_same<number_integer_t, pointee_t>::value
9821 or std::is_same<number_unsigned_t, pointee_t>::value
9822 or std::is_same<number_float_t, pointee_t>::value
9823 ,
"incompatible pointer type");
9826 return get_impl_ptr(
static_cast<PointerType>(
nullptr));
9855 template<
typename ReferenceType,
typename std::enable_if<
9856 std::is_reference<ReferenceType>::value,
int>::type = 0>
9857 ReferenceType get_ref()
9860 return get_ref_impl<ReferenceType>(*
this);
9867 template<
typename ReferenceType,
typename std::enable_if<
9868 std::is_reference<ReferenceType>::value
and 9869 std::is_const<
typename std::remove_reference<ReferenceType>::type>::value,
int>::type = 0>
9870 ReferenceType get_ref()
const 9873 return get_ref_impl<ReferenceType>(*
this);
9905 template <
typename ValueType,
typename std::enable_if <
9906 not std::is_pointer<ValueType>::value
and 9907 not std::is_same<ValueType, detail::json_ref<
basic_json>>::value
and 9908 not std::is_same<ValueType,
typename string_t::value_type>::value
9910 and not std::is_same<ValueType, std::initializer_list<
typename string_t::value_type>>::value
9912 #if defined(JSON_HAS_CPP_17) 9913 and not std::is_same<ValueType,
typename std::string_view>::value
9916 operator ValueType()
const 9919 return get<ValueType>();
9959 reference at(size_type idx)
9966 return m_value.array->at(idx);
9971 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
9976 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
10006 const_reference at(size_type idx)
const 10013 return m_value.array->at(idx);
10018 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
10023 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
10057 reference at(
const typename object_t::key_type& key)
10064 return m_value.object->at(key);
10069 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
10074 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
10108 const_reference at(
const typename object_t::key_type& key)
const 10115 return m_value.object->at(key);
10120 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
10125 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
10154 reference operator[](size_type idx)
10159 m_type = value_t::array;
10160 m_value.array = create<array_t>();
10161 assert_invariant();
10168 if (idx >= m_value.array->size())
10170 m_value.array->insert(m_value.array->end(),
10171 idx - m_value.array->size() + 1,
10175 return m_value.array->operator[](idx);
10178 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10200 const_reference operator[](size_type idx)
const 10205 return m_value.array->operator[](idx);
10208 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10238 reference operator[](
const typename object_t::key_type& key)
10243 m_type = value_t::object;
10244 m_value.object = create<object_t>();
10245 assert_invariant();
10251 return m_value.object->operator[](key);
10254 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10287 const_reference operator[](
const typename object_t::key_type& key)
const 10292 assert(m_value.object->find(key) != m_value.object->end());
10293 return m_value.object->find(key)->second;
10296 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10326 template<
typename T>
10327 reference operator[](T* key)
10332 m_type = value_t::object;
10333 m_value = value_t::object;
10334 assert_invariant();
10340 return m_value.object->operator[](key);
10343 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10376 template<
typename T>
10377 const_reference operator[](T* key)
const 10382 assert(m_value.object->find(key) != m_value.object->end());
10383 return m_value.object->find(key)->second;
10386 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10437 template<
class ValueType,
typename std::enable_if<
10438 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
10439 ValueType value(
const typename object_t::key_type& key,
const ValueType& default_value)
const 10445 const auto it = find(key);
10451 return default_value;
10454 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
10461 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 10463 return value(key, string_t(default_value));
10507 template<
class ValueType,
typename std::enable_if<
10508 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
10509 ValueType value(
const json_pointer& ptr,
const ValueType& default_value)
const 10517 return ptr.get_checked(
this);
10521 return default_value;
10525 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
10532 string_t value(
const json_pointer& ptr,
const char* default_value)
const 10534 return value(ptr, string_t(default_value));
10570 const_reference front()
const 10616 const_reference back()
const 10669 template<
class IteratorType,
typename std::enable_if<
10670 std::is_same<IteratorType,
typename basic_json_t::iterator>::value
or 10671 std::is_same<IteratorType,
typename basic_json_t::const_iterator>::value,
int>::type
10673 IteratorType erase(IteratorType pos)
10678 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
10681 IteratorType result = end();
10685 case value_t::boolean:
10686 case value_t::number_float:
10687 case value_t::number_integer:
10688 case value_t::number_unsigned:
10689 case value_t::string:
10691 if (
JSON_UNLIKELY(
not pos.m_it.primitive_iterator.is_begin()))
10693 JSON_THROW(invalid_iterator::create(205,
"iterator out of range"));
10698 AllocatorType<string_t> alloc;
10699 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_value.string);
10700 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_value.string, 1);
10701 m_value.string =
nullptr;
10704 m_type = value_t::null;
10705 assert_invariant();
10709 case value_t::object:
10711 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
10715 case value_t::array:
10717 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
10722 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
10774 template<
class IteratorType,
typename std::enable_if<
10775 std::is_same<IteratorType,
typename basic_json_t::iterator>::value
or 10776 std::is_same<IteratorType,
typename basic_json_t::const_iterator>::value,
int>::type
10778 IteratorType erase(IteratorType first, IteratorType last)
10781 if (
JSON_UNLIKELY(
this != first.m_object
or this != last.m_object))
10783 JSON_THROW(invalid_iterator::create(203,
"iterators do not fit current value"));
10786 IteratorType result = end();
10790 case value_t::boolean:
10791 case value_t::number_float:
10792 case value_t::number_integer:
10793 case value_t::number_unsigned:
10794 case value_t::string:
10796 if (
JSON_LIKELY(
not first.m_it.primitive_iterator.is_begin()
10797 or not last.m_it.primitive_iterator.is_end()))
10799 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
10804 AllocatorType<string_t> alloc;
10805 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_value.string);
10806 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_value.string, 1);
10807 m_value.string =
nullptr;
10810 m_type = value_t::null;
10811 assert_invariant();
10815 case value_t::object:
10817 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
10818 last.m_it.object_iterator);
10822 case value_t::array:
10824 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
10825 last.m_it.array_iterator);
10830 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
10865 size_type erase(
const typename object_t::key_type& key)
10870 return m_value.object->erase(key);
10873 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
10900 void erase(
const size_type idx)
10907 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
10910 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
10914 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
10950 template<
typename KeyT>
10951 iterator find(KeyT&& key)
10953 auto result = end();
10957 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
10967 template<
typename KeyT>
10968 const_iterator find(KeyT&& key)
const 10970 auto result = cend();
10974 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
11001 template<
typename KeyT>
11002 size_type count(KeyT&& key)
const 11005 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
11042 iterator begin()
noexcept 11044 iterator result(
this);
11045 result.set_begin();
11052 const_iterator begin()
const noexcept 11082 const_iterator cbegin()
const noexcept 11084 const_iterator result(
this);
11085 result.set_begin();
11113 iterator end()
noexcept 11115 iterator result(
this);
11123 const_iterator end()
const noexcept 11153 const_iterator cend()
const noexcept 11155 const_iterator result(
this);
11183 reverse_iterator rbegin()
noexcept 11185 return reverse_iterator(end());
11191 const_reverse_iterator rbegin()
const noexcept 11220 reverse_iterator rend()
noexcept 11222 return reverse_iterator(begin());
11228 const_reverse_iterator rend()
const noexcept 11257 const_reverse_iterator crbegin()
const noexcept 11259 return const_reverse_iterator(cend());
11286 const_reverse_iterator crend()
const noexcept 11288 return const_reverse_iterator(cbegin());
11345 static iteration_proxy<iterator> iterator_wrapper(reference ref)
11347 return iteration_proxy<iterator>(ref);
11353 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref)
11355 return iteration_proxy<const_iterator>(ref);
11409 bool empty()
const noexcept 11413 case value_t::null:
11419 case value_t::array:
11422 return m_value.array->empty();
11425 case value_t::object:
11428 return m_value.object->empty();
11481 size_type size()
const noexcept 11485 case value_t::null:
11491 case value_t::array:
11494 return m_value.array->size();
11497 case value_t::object:
11500 return m_value.object->size();
11551 size_type max_size()
const noexcept 11555 case value_t::array:
11558 return m_value.array->max_size();
11561 case value_t::object:
11564 return m_value.object->max_size();
11621 void clear()
noexcept 11625 case value_t::number_integer:
11627 m_value.number_integer = 0;
11631 case value_t::number_unsigned:
11633 m_value.number_unsigned = 0;
11637 case value_t::number_float:
11639 m_value.number_float = 0.0;
11643 case value_t::boolean:
11645 m_value.boolean =
false;
11649 case value_t::string:
11651 m_value.string->clear();
11655 case value_t::array:
11657 m_value.array->clear();
11661 case value_t::object:
11663 m_value.object->clear();
11697 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
11703 m_type = value_t::array;
11704 m_value = value_t::array;
11705 assert_invariant();
11709 m_value.array->push_back(std::move(val));
11711 val.m_type = value_t::null;
11720 push_back(std::move(val));
11733 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
11739 m_type = value_t::array;
11740 m_value = value_t::array;
11741 assert_invariant();
11745 m_value.array->push_back(val);
11778 void push_back(
const typename object_t::value_type& val)
11783 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
11789 m_type = value_t::object;
11790 m_value = value_t::object;
11791 assert_invariant();
11795 m_value.object->insert(val);
11802 reference operator+=(
const typename object_t::value_type& val)
11833 void push_back(initializer_list_t init)
11835 if (is_object()
and init.size() == 2
and (*init.begin())->is_string())
11837 basic_json&& key = init.begin()->moved_or_copied();
11838 push_back(
typename object_t::value_type(
11839 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
11851 reference operator+=(initializer_list_t init)
11878 template<
class... Args>
11879 void emplace_back(Args&& ... args)
11884 JSON_THROW(type_error::create(311,
"cannot use emplace_back() with " + std::string(type_name())));
11890 m_type = value_t::array;
11891 m_value = value_t::array;
11892 assert_invariant();
11896 m_value.array->emplace_back(std::forward<Args>(args)...);
11926 template<
class... Args>
11927 std::pair<iterator,
bool> emplace(Args&& ... args)
11932 JSON_THROW(type_error::create(311,
"cannot use emplace() with " + std::string(type_name())));
11938 m_type = value_t::object;
11939 m_value = value_t::object;
11940 assert_invariant();
11944 auto res = m_value.object->emplace(std::forward<Args>(args)...);
11947 it.m_it.object_iterator = res.first;
11950 return {it, res.second};
11975 iterator insert(const_iterator pos,
const basic_json& val)
11983 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
11987 iterator result(
this);
11988 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
11992 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
11999 iterator insert(const_iterator pos,
basic_json&& val)
12001 return insert(pos, val);
12028 iterator insert(const_iterator pos, size_type cnt,
const basic_json& val)
12036 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
12040 iterator result(
this);
12041 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
12045 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12078 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
12083 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12089 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
12095 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
12100 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container"));
12104 iterator result(
this);
12105 result.m_it.array_iterator = m_value.array->insert(
12106 pos.m_it.array_iterator,
12107 first.m_it.array_iterator,
12108 last.m_it.array_iterator);
12136 iterator insert(const_iterator pos, initializer_list_t ilist)
12141 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12147 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
12151 iterator result(
this);
12152 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
12179 void insert(const_iterator first, const_iterator last)
12184 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12190 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
12196 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
12199 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
12221 void update(const_reference j)
12226 m_type = value_t::object;
12227 m_value.object = create<object_t>();
12228 assert_invariant();
12233 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
12237 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(j.type_name())));
12240 for (
auto it = j.begin(); it != j.end(); ++it)
12242 m_value.object->operator[](it.key()) = it.value();
12272 void update(const_iterator first, const_iterator last)
12277 m_type = value_t::object;
12278 m_value.object = create<object_t>();
12279 assert_invariant();
12284 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
12290 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
12295 or not first.m_object->is_object()))
12297 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
12300 for (
auto it = first; it != last; ++it)
12302 m_value.object->operator[](it.key()) = it.value();
12323 void swap(reference other)
noexcept (
12324 std::is_nothrow_move_constructible<value_t>::value
and 12325 std::is_nothrow_move_assignable<value_t>::value
and 12326 std::is_nothrow_move_constructible<json_value>::value
and 12327 std::is_nothrow_move_assignable<json_value>::value
12330 std::swap(m_type, other.m_type);
12331 std::swap(m_value, other.m_value);
12332 assert_invariant();
12355 void swap(array_t& other)
12360 std::swap(*(m_value.array), other);
12364 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
12388 void swap(object_t& other)
12393 std::swap(*(m_value.object), other);
12397 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
12421 void swap(string_t& other)
12426 std::swap(*(m_value.string), other);
12430 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
12483 friend bool operator==(const_reference lhs, const_reference rhs)
noexcept 12485 const auto lhs_type = lhs.type();
12486 const auto rhs_type = rhs.type();
12488 if (lhs_type == rhs_type)
12492 case value_t::array:
12493 return (*lhs.m_value.array == *rhs.m_value.array);
12495 case value_t::object:
12496 return (*lhs.m_value.object == *rhs.m_value.object);
12498 case value_t::null:
12501 case value_t::string:
12502 return (*lhs.m_value.string == *rhs.m_value.string);
12504 case value_t::boolean:
12505 return (lhs.m_value.boolean == rhs.m_value.boolean);
12507 case value_t::number_integer:
12508 return (lhs.m_value.number_integer == rhs.m_value.number_integer);
12510 case value_t::number_unsigned:
12511 return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
12513 case value_t::number_float:
12514 return (lhs.m_value.number_float == rhs.m_value.number_float);
12520 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_float)
12522 return (
static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
12524 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_integer)
12526 return (lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer));
12528 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_float)
12530 return (
static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
12532 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_unsigned)
12534 return (lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned));
12536 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_integer)
12538 return (
static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
12540 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_unsigned)
12542 return (lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned));
12552 template<
typename ScalarType,
typename std::enable_if<
12553 std::is_scalar<ScalarType>::value,
int>::type = 0>
12554 friend bool operator==(const_reference lhs,
const ScalarType rhs)
noexcept 12563 template<
typename ScalarType,
typename std::enable_if<
12564 std::is_scalar<ScalarType>::value,
int>::type = 0>
12565 friend bool operator==(
const ScalarType lhs, const_reference rhs)
noexcept 12588 friend bool operator!=(const_reference lhs, const_reference rhs)
noexcept 12590 return not (lhs == rhs);
12597 template<
typename ScalarType,
typename std::enable_if<
12598 std::is_scalar<ScalarType>::value,
int>::type = 0>
12599 friend bool operator!=(const_reference lhs,
const ScalarType rhs)
noexcept 12608 template<
typename ScalarType,
typename std::enable_if<
12609 std::is_scalar<ScalarType>::value,
int>::type = 0>
12610 friend bool operator!=(
const ScalarType lhs, const_reference rhs)
noexcept 12641 friend bool operator<(const_reference lhs, const_reference rhs)
noexcept 12643 const auto lhs_type = lhs.type();
12644 const auto rhs_type = rhs.type();
12646 if (lhs_type == rhs_type)
12650 case value_t::array:
12651 return (*lhs.m_value.array) < (*rhs.m_value.array);
12653 case value_t::object:
12654 return *lhs.m_value.object < *rhs.m_value.object;
12656 case value_t::null:
12659 case value_t::string:
12660 return *lhs.m_value.string < *rhs.m_value.string;
12662 case value_t::boolean:
12663 return lhs.m_value.boolean < rhs.m_value.boolean;
12665 case value_t::number_integer:
12666 return lhs.m_value.number_integer < rhs.m_value.number_integer;
12668 case value_t::number_unsigned:
12669 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
12671 case value_t::number_float:
12672 return lhs.m_value.number_float < rhs.m_value.number_float;
12678 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_float)
12680 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
12682 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_integer)
12684 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
12686 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_float)
12688 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
12690 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_unsigned)
12692 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
12694 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_unsigned)
12696 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
12698 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_integer)
12700 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
12706 return operator<(lhs_type, rhs_type);
12713 template<
typename ScalarType,
typename std::enable_if<
12714 std::is_scalar<ScalarType>::value,
int>::type = 0>
12715 friend bool operator<(const_reference lhs,
const ScalarType rhs)
noexcept 12724 template<
typename ScalarType,
typename std::enable_if<
12725 std::is_scalar<ScalarType>::value,
int>::type = 0>
12726 friend bool operator<(
const ScalarType lhs, const_reference rhs)
noexcept 12750 friend bool operator<=(const_reference lhs, const_reference rhs)
noexcept 12752 return not (rhs < lhs);
12759 template<
typename ScalarType,
typename std::enable_if<
12760 std::is_scalar<ScalarType>::value,
int>::type = 0>
12761 friend bool operator<=(const_reference lhs,
const ScalarType rhs)
noexcept 12770 template<
typename ScalarType,
typename std::enable_if<
12771 std::is_scalar<ScalarType>::value,
int>::type = 0>
12772 friend bool operator<=(
const ScalarType lhs, const_reference rhs)
noexcept 12796 friend bool operator>(const_reference lhs, const_reference rhs)
noexcept 12798 return not (lhs <= rhs);
12805 template<
typename ScalarType,
typename std::enable_if<
12806 std::is_scalar<ScalarType>::value,
int>::type = 0>
12807 friend bool operator>(const_reference lhs,
const ScalarType rhs)
noexcept 12816 template<
typename ScalarType,
typename std::enable_if<
12817 std::is_scalar<ScalarType>::value,
int>::type = 0>
12818 friend bool operator>(
const ScalarType lhs, const_reference rhs)
noexcept 12842 friend bool operator>=(const_reference lhs, const_reference rhs)
noexcept 12844 return not (lhs < rhs);
12851 template<
typename ScalarType,
typename std::enable_if<
12852 std::is_scalar<ScalarType>::value,
int>::type = 0>
12853 friend bool operator>=(const_reference lhs,
const ScalarType rhs)
noexcept 12862 template<
typename ScalarType,
typename std::enable_if<
12863 std::is_scalar<ScalarType>::value,
int>::type = 0>
12864 friend bool operator>=(
const ScalarType lhs, const_reference rhs)
noexcept 12909 friend std::ostream& operator<<(std::ostream& o,
const basic_json& j)
12912 const bool pretty_print = (o.width() > 0);
12913 const auto indentation = (pretty_print ? o.width() : 0);
12919 serializer s(detail::output_adapter<
char>(o), o.fill());
12920 s.dump(j, pretty_print,
false,
static_cast<
unsigned int>(indentation));
12933 friend std::ostream& operator>>(
const basic_json& j, std::ostream& o)
13010 static basic_json parse(detail::input_adapter i,
13011 const parser_callback_t cb =
nullptr,
13012 const bool allow_exceptions =
true)
13015 parser(i, cb, allow_exceptions).parse(
true, result);
13022 static basic_json parse(detail::input_adapter& i,
13023 const parser_callback_t cb =
nullptr,
13024 const bool allow_exceptions =
true)
13027 parser(i, cb, allow_exceptions).parse(
true, result);
13031 static bool accept(detail::input_adapter i)
13033 return parser(i).accept(
true);
13036 static bool accept(detail::input_adapter& i)
13038 return parser(i).accept(
true);
13088 template<
class IteratorType,
typename std::enable_if<
13090 std::random_access_iterator_tag,
13091 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
13092 static basic_json parse(IteratorType first, IteratorType last,
13093 const parser_callback_t cb =
nullptr,
13094 const bool allow_exceptions =
true)
13097 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(
true, result);
13101 template<
class IteratorType,
typename std::enable_if<
13103 std::random_access_iterator_tag,
13104 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
13105 static bool accept(IteratorType first, IteratorType last)
13107 return parser(detail::input_adapter(first, last)).accept(
true);
13119 friend std::istream& operator<<(
basic_json& j, std::istream& i)
13121 return operator>>(i, j);
13149 friend std::istream& operator>>(std::istream& i,
basic_json& j)
13151 parser(detail::input_adapter(i)).parse(
false, j);
13191 const char* type_name()
const noexcept 13196 case value_t::null:
13198 case value_t::object:
13200 case value_t::array:
13202 case value_t::string:
13204 case value_t::boolean:
13206 case value_t::discarded:
13207 return "discarded";
13221 value_t m_type = value_t::null;
13224 json_value m_value = {};
13320 static std::vector<uint8_t> to_cbor(
const basic_json& j)
13322 std::vector<uint8_t> result;
13323 to_cbor(j, result);
13327 static void to_cbor(
const basic_json& j, detail::output_adapter<uint8_t> o)
13329 binary_writer<uint8_t>(o).write_cbor(j);
13332 static void to_cbor(
const basic_json& j, detail::output_adapter<
char> o)
13334 binary_writer<
char>(o).write_cbor(j);
13415 static std::vector<uint8_t> to_msgpack(
const basic_json& j)
13417 std::vector<uint8_t> result;
13418 to_msgpack(j, result);
13422 static void to_msgpack(
const basic_json& j, detail::output_adapter<uint8_t> o)
13424 binary_writer<uint8_t>(o).write_msgpack(j);
13427 static void to_msgpack(
const basic_json& j, detail::output_adapter<
char> o)
13429 binary_writer<
char>(o).write_msgpack(j);
13523 static basic_json from_cbor(detail::input_adapter i,
13524 const bool strict =
true)
13526 return binary_reader(i).parse_cbor(strict);
13532 template<
typename A1,
typename A2,
13533 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
13534 static basic_json from_cbor(A1 && a1, A2 && a2,
const bool strict =
true)
13536 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_cbor(strict);
13610 static basic_json from_msgpack(detail::input_adapter i,
13611 const bool strict =
true)
13613 return binary_reader(i).parse_msgpack(strict);
13619 template<
typename A1,
typename A2,
13620 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
13621 static basic_json from_msgpack(A1 && a1, A2 && a2,
const bool strict =
true)
13623 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_msgpack(strict);
13668 reference operator[](
const json_pointer& ptr)
13670 return ptr.get_unchecked(
this);
13696 const_reference operator[](
const json_pointer& ptr)
const 13698 return ptr.get_unchecked(
this);
13736 reference at(
const json_pointer& ptr)
13738 return ptr.get_checked(
this);
13776 const_reference at(
const json_pointer& ptr)
const 13778 return ptr.get_checked(
this);
13806 json_pointer::flatten(
"", *
this, result);
13842 return json_pointer::unflatten(*
this);
13907 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
13909 const auto get_op = [](
const std::string & op)
13913 return patch_operations::add;
13915 if (op ==
"remove")
13917 return patch_operations::remove;
13919 if (op ==
"replace")
13921 return patch_operations::replace;
13925 return patch_operations::move;
13929 return patch_operations::copy;
13933 return patch_operations::test;
13936 return patch_operations::invalid;
13940 const auto operation_add = [&result](json_pointer & ptr,
basic_json val)
13950 json_pointer top_pointer = ptr.top();
13951 if (top_pointer != ptr)
13953 result.at(top_pointer);
13957 const auto last_path = ptr.pop_back();
13960 switch (parent.m_type)
13962 case value_t::null:
13963 case value_t::object:
13966 parent[last_path] = val;
13970 case value_t::array:
13972 if (last_path ==
"-")
13975 parent.push_back(val);
13979 const auto idx = std::stoi(last_path);
13980 if (
JSON_UNLIKELY(
static_cast<size_type>(idx) > parent.size()))
13983 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
13988 parent.insert(parent.begin() +
static_cast<difference_type>(idx), val);
14004 const auto operation_remove = [&result](json_pointer & ptr)
14007 const auto last_path = ptr.pop_back();
14011 if (parent.is_object())
14014 auto it = parent.find(last_path);
14021 JSON_THROW(out_of_range::create(403,
"key '" + last_path +
"' not found"));
14024 else if (parent.is_array())
14027 parent.erase(
static_cast<size_type>(std::stoi(last_path)));
14034 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
14038 for (
const auto& val : json_patch)
14041 const auto get_value = [&val](
const std::string & op,
14042 const std::string & member,
14046 auto it = val.m_value.object->find(member);
14049 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
14054 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have member '" + member +
"'"));
14058 if (
JSON_UNLIKELY(string_type
and not it->second.is_string()))
14060 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have string member '" + member +
"'"));
14070 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
14074 const std::string op = get_value(
"op",
"op",
true);
14075 const std::string path = get_value(op,
"path",
true);
14076 json_pointer ptr
(path
);
14078 switch (get_op(op))
14080 case patch_operations::add:
14082 operation_add(ptr, get_value(
"add",
"value",
false));
14086 case patch_operations::remove:
14088 operation_remove(ptr);
14092 case patch_operations::replace:
14095 result.at(ptr) = get_value(
"replace",
"value",
false);
14099 case patch_operations::move:
14101 const std::string from_path = get_value(
"move",
"from",
true);
14102 json_pointer from_ptr
(from_path
);
14111 operation_remove(from_ptr);
14112 operation_add(ptr, v);
14116 case patch_operations::copy:
14118 const std::string from_path = get_value(
"copy",
"from",
true);
14119 const json_pointer from_ptr
(from_path
);
14122 result[ptr] = result.at(from_ptr);
14126 case patch_operations::test:
14128 bool success =
false;
14133 success = (result.at(ptr) == get_value(
"test",
"value",
false));
14143 JSON_THROW(other_error::create(501,
"unsuccessful: " + val.dump()));
14149 case patch_operations::invalid:
14153 JSON_THROW(parse_error::create(105, 0,
"operation value '" + op +
"' is invalid"));
14194 const std::string& path =
"")
14200 if (source == target)
14205 if (source.type() != target.type())
14210 {
"op",
"replace"}, {
"path", path}, {
"value", target}
14215 switch (source.type())
14217 case value_t::array:
14221 while (i < source.size()
and i < target.size())
14224 auto temp_diff = diff(source[i], target[i], path +
"/" + std::to_string(i));
14225 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
14233 const auto end_index =
static_cast<difference_type>(result.size());
14234 while (i < source.size())
14238 result.insert(result.begin() + end_index, object(
14241 {
"path", path +
"/" + std::to_string(i)}
14247 while (i < target.size())
14252 {
"path", path +
"/" + std::to_string(i)},
14253 {
"value", target[i]}
14261 case value_t::object:
14264 for (
auto it = source.begin(); it != source.end(); ++it)
14267 const auto key = json_pointer::escape(it.key());
14269 if (target.find(it.key()) != target.end())
14272 auto temp_diff = diff(it.value(), target[it.key()], path +
"/" + key);
14273 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
14278 result.push_back(object(
14280 {
"op",
"remove"}, {
"path", path +
"/" + key}
14286 for (
auto it = target.begin(); it != target.end(); ++it)
14288 if (source.find(it.key()) == source.end())
14291 const auto key = json_pointer::escape(it.key());
14294 {
"op",
"add"}, {
"path", path +
"/" + key},
14295 {
"value", it.value()}
14308 {
"op",
"replace"}, {
"path", path}, {
"value", target}
14348 for (
const auto& reference_token : reference_tokens)
14350 switch (result->m_type)
14352 case detail::value_t::null:
14354 if (reference_token ==
"0")
14357 result = &result->operator[](0);
14362 result = &result->operator[](reference_token);
14367 case detail::value_t::object:
14370 result = &result->operator[](reference_token);
14374 case detail::value_t::array:
14379 result = &result->operator[](
static_cast<size_type>(std::stoi(reference_token)));
14383 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14395 JSON_THROW(detail::type_error::create(313,
"invalid value to unflatten"));
14407 for (
const auto& reference_token : reference_tokens)
14410 if (ptr->m_type == detail::value_t::null)
14414 std::all_of(reference_token.begin(), reference_token.end(),
14417 return (x >=
'0' and x <=
'9');
14421 *ptr = (nums
or reference_token ==
"-")
14422 ? detail::value_t::array
14423 : detail::value_t::object;
14426 switch (ptr->m_type)
14428 case detail::value_t::object:
14431 ptr = &ptr->operator[](reference_token);
14435 case detail::value_t::array:
14438 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
14440 JSON_THROW(detail::parse_error::create(106, 0,
14441 "array index '" + reference_token +
14442 "' must not begin with '0'"));
14445 if (reference_token ==
"-")
14448 ptr = &ptr->operator[](ptr->m_value.array->size());
14455 ptr = &ptr->operator[](
14456 static_cast<size_type>(std::stoi(reference_token)));
14460 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14467 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
14479 for (
const auto& reference_token : reference_tokens)
14481 switch (ptr->m_type)
14483 case detail::value_t::object:
14486 ptr = &ptr->at(reference_token);
14490 case detail::value_t::array:
14495 JSON_THROW(detail::out_of_range::create(402,
14496 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
14497 ") is out of range"));
14501 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
14503 JSON_THROW(detail::parse_error::create(106, 0,
14504 "array index '" + reference_token +
14505 "' must not begin with '0'"));
14511 ptr = &ptr->at(
static_cast<size_type>(std::stoi(reference_token)));
14515 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14521 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
14533 for (
const auto& reference_token : reference_tokens)
14535 switch (ptr->m_type)
14537 case detail::value_t::object:
14540 ptr = &ptr->operator[](reference_token);
14544 case detail::value_t::array:
14549 JSON_THROW(detail::out_of_range::create(402,
14550 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
14551 ") is out of range"));
14555 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
14557 JSON_THROW(detail::parse_error::create(106, 0,
14558 "array index '" + reference_token +
14559 "' must not begin with '0'"));
14565 ptr = &ptr->operator[](
14566 static_cast<size_type>(std::stoi(reference_token)));
14570 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14576 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
14588 for (
const auto& reference_token : reference_tokens)
14590 switch (ptr->m_type)
14592 case detail::value_t::object:
14595 ptr = &ptr->at(reference_token);
14599 case detail::value_t::array:
14604 JSON_THROW(detail::out_of_range::create(402,
14605 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
14606 ") is out of range"));
14610 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
14612 JSON_THROW(detail::parse_error::create(106, 0,
14613 "array index '" + reference_token +
14614 "' must not begin with '0'"));
14620 ptr = &ptr->at(
static_cast<size_type>(std::stoi(reference_token)));
14624 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14630 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
14638 void json_pointer::flatten(
const std::string& reference_string,
14642 switch (value.m_type)
14644 case detail::value_t::array:
14646 if (value.m_value.array->empty())
14649 result[reference_string] =
nullptr;
14654 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
14656 flatten(reference_string +
"/" + std::to_string(i),
14657 value.m_value.array->operator[](i), result);
14663 case detail::value_t::object:
14665 if (value.m_value.object->empty())
14668 result[reference_string] =
nullptr;
14673 for (
const auto& element : *value.m_value.object)
14675 flatten(reference_string +
"/" + escape(element.first), element.second, result);
14684 result[reference_string] = value;
14696 JSON_THROW(detail::type_error::create(314,
"only objects can be unflattened"));
14702 for (
const auto& element : *value.m_value.object)
14706 JSON_THROW(detail::type_error::create(315,
"values in object must be primitive"));
14713 json_pointer(element.first).get_and_create(result) = element.second;
14721 return (lhs.reference_tokens == rhs.reference_tokens);
14726 return not (lhs == rhs);
14744 inline void swap(
nlohmann::json& j1,
14746 is_nothrow_move_constructible<nlohmann::json>::value
and 14747 is_nothrow_move_assignable<nlohmann::json>::value
14762 std::size_t operator()(
const nlohmann::json& j)
const 14765 const auto& h = hash<
nlohmann::json::string_t>();
14766 return h(j.dump());
14774 struct less< ::
nlohmann::detail::value_t>
14780 bool operator()(
nlohmann::detail::value_t lhs,
14781 nlohmann::detail::value_t rhs)
const noexcept 14783 return nlohmann::detail::operator<(lhs, rhs);
14802 inline nlohmann::json operator
"" _json(
const char* s, std::size_t n)
14804 return nlohmann::json::parse(s, s + n);
14820 inline nlohmann::json::json_pointer operator
"" _json_pointer(
const char* s, std::size_t n)
14822 return nlohmann::json::json_pointer
(std::string(s, n)
);
14826 #if defined(__clang__
) || defined(__GNUC__
) || defined(__GNUG__
) 14827 #pragma GCC diagnostic pop 14829 #if defined(__clang__
) 14830 #pragma GCC diagnostic pop 14838 #undef JSON_UNLIKELY 14839 #undef JSON_DEPRECATED 14840 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION 14841 #undef NLOHMANN_BASIC_JSON_TPL #define NLOHMANN_BASIC_JSON_TPL_DECLARATION
#define NLOHMANN_JSON_HAS_HELPER(type)
Helper to determine whether there's a key_type for T.
friend class basic_json
allow basic_json to access private members
static void from_json(BasicJsonType &&j, ValueType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val)))
convert a JSON value to any value type
constexpr const auto & from_json
#define JSON_CATCH(exception)
namespace for Niels Lohmann
#define NLOHMANN_BASIC_JSON_TPL
static void to_json(BasicJsonType &j, ValueType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< ValueType >(val))))
convert any value type to a JSON value
#define JSON_THROW(exception)
constexpr const auto & to_json
json_pointer(const std::string &s="")
create JSON pointer