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) {}
472 class other_error :
public exception
475 static other_error create(
int id_,
const std::string& what_arg)
477 std::string w = exception::name(
"other_error", id_) + what_arg;
478 return other_error(id_, w.c_str());
482 other_error(
int id_,
const char* what_arg) : exception(id_, what_arg) {}
515 enum class value_t : uint8_t
538 inline bool operator<(
const value_t lhs,
const value_t rhs)
noexcept 540 static constexpr std::array<uint8_t, 8> order = {{
546 const auto l_index =
static_cast<std::size_t>(lhs);
547 const auto r_index =
static_cast<std::size_t>(rhs);
548 return l_index < order.size()
and r_index < order.size()
and order[l_index] < order[r_index];
556 template<
typename>
struct is_basic_json : std::false_type {};
562 template<
bool B,
typename T =
void>
563 using enable_if_t =
typename std::enable_if<B, T>::type;
566 using uncvref_t =
typename std::remove_cv<
typename std::remove_reference<T>::type>::type;
570 template<std::size_t... Ints>
571 struct index_sequence
573 using type = index_sequence;
574 using value_type = std::size_t;
575 static constexpr std::size_t size()
noexcept 577 return sizeof...(Ints);
581 template<
class Sequence1,
class Sequence2>
582 struct merge_and_renumber;
584 template<std::size_t... I1, std::size_t... I2>
585 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
586 : index_sequence < I1..., (
sizeof...(I1) + I2)... > {};
588 template<std::size_t N>
589 struct make_index_sequence
590 : merge_and_renumber <
typename make_index_sequence < N / 2 >::type,
591 typename make_index_sequence < N - N / 2 >::type > {};
593 template<>
struct make_index_sequence<0> : index_sequence<> {};
594 template<>
struct make_index_sequence<1> : index_sequence<0> {};
596 template<
typename... Ts>
597 using index_sequence_for = make_index_sequence<
sizeof...(Ts)>;
612 template<
class...>
struct conjunction : std::true_type {};
613 template<
class B1>
struct conjunction<B1> : B1 {};
614 template<
class B1,
class... Bn>
615 struct conjunction<B1, Bn...> : std::conditional<
bool(B1::value), conjunction<Bn...>, B1>::type {};
617 template<
class B>
struct negation : std::integral_constant<
bool,
not B::value> {};
620 template<
unsigned N>
struct priority_tag : priority_tag < N - 1 > {};
621 template<>
struct priority_tag<0> {};
628 template<value_t>
struct external_constructor;
631 struct external_constructor<value_t::boolean>
633 template<
typename BasicJsonType>
634 static void construct(BasicJsonType& j,
typename BasicJsonType::boolean_t b)
noexcept 636 j.m_type = value_t::boolean;
638 j.assert_invariant();
643 struct external_constructor<value_t::string>
645 template<
typename BasicJsonType>
646 static void construct(BasicJsonType& j,
const typename BasicJsonType::string_t& s)
648 j.m_type = value_t::string;
650 j.assert_invariant();
653 template<
typename BasicJsonType>
654 static void construct(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
656 j.m_type = value_t::string;
657 j.m_value = std::move(s);
658 j.assert_invariant();
663 struct external_constructor<value_t::number_float>
665 template<
typename BasicJsonType>
666 static void construct(BasicJsonType& j,
typename BasicJsonType::number_float_t val)
noexcept 668 j.m_type = value_t::number_float;
670 j.assert_invariant();
675 struct external_constructor<value_t::number_unsigned>
677 template<
typename BasicJsonType>
678 static void construct(BasicJsonType& j,
typename BasicJsonType::number_unsigned_t val)
noexcept 680 j.m_type = value_t::number_unsigned;
682 j.assert_invariant();
687 struct external_constructor<value_t::number_integer>
689 template<
typename BasicJsonType>
690 static void construct(BasicJsonType& j,
typename BasicJsonType::number_integer_t val)
noexcept 692 j.m_type = value_t::number_integer;
694 j.assert_invariant();
699 struct external_constructor<value_t::array>
701 template<
typename BasicJsonType>
702 static void construct(BasicJsonType& j,
const typename BasicJsonType::array_t& arr)
704 j.m_type = value_t::array;
706 j.assert_invariant();
709 template<
typename BasicJsonType>
710 static void construct(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
712 j.m_type = value_t::array;
713 j.m_value = std::move(arr);
714 j.assert_invariant();
717 template<
typename BasicJsonType,
typename CompatibleArrayType,
718 enable_if_t<
not std::is_same<CompatibleArrayType,
typename BasicJsonType::array_t>::value,
720 static void construct(BasicJsonType& j,
const CompatibleArrayType& arr)
724 j.m_type = value_t::array;
725 j.m_value.array = j.
template create<
typename BasicJsonType::array_t>(begin(arr), end(arr));
726 j.assert_invariant();
729 template<
typename BasicJsonType>
730 static void construct(BasicJsonType& j,
const std::vector<
bool>& arr)
732 j.m_type = value_t::array;
733 j.m_value = value_t::array;
734 j.m_value.array->reserve(arr.size());
737 j.m_value.array->push_back(x);
739 j.assert_invariant();
742 template<
typename BasicJsonType,
typename T,
743 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
744 static void construct(BasicJsonType& j,
const std::valarray<T>& arr)
746 j.m_type = value_t::array;
747 j.m_value = value_t::array;
748 j.m_value.array->resize(arr.size());
749 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
750 j.assert_invariant();
755 struct external_constructor<value_t::object>
757 template<
typename BasicJsonType>
758 static void construct(BasicJsonType& j,
const typename BasicJsonType::object_t& obj)
760 j.m_type = value_t::object;
762 j.assert_invariant();
765 template<
typename BasicJsonType>
766 static void construct(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
768 j.m_type = value_t::object;
769 j.m_value = std::move(obj);
770 j.assert_invariant();
773 template<
typename BasicJsonType,
typename CompatibleObjectType,
774 enable_if_t<
not std::is_same<CompatibleObjectType,
typename BasicJsonType::object_t>::value,
int> = 0>
775 static void construct(BasicJsonType& j,
const CompatibleObjectType& obj)
780 j.m_type = value_t::object;
781 j.m_value.object = j.
template create<
typename BasicJsonType::object_t>(begin(obj), end(obj));
782 j.assert_invariant();
801 #define NLOHMANN_JSON_HAS_HELPER(type) 802 template<typename T> struct has_##type { 804 template<typename U, typename = typename U::type> 805 static int detect(U &&); 806 static void detect(...); 808 static constexpr bool value = 809 std::is_integral<decltype(detect(std::declval<T>()))>::value; 817 #undef NLOHMANN_JSON_HAS_HELPER 820 template<
bool B,
class RealType,
class CompatibleObjectType>
821 struct is_compatible_object_type_impl : std::false_type {};
823 template<
class RealType,
class CompatibleObjectType>
824 struct is_compatible_object_type_impl<
true, RealType, CompatibleObjectType>
826 static constexpr auto value =
827 std::is_constructible<
typename RealType::key_type,
typename CompatibleObjectType::key_type>::value
and 828 std::is_constructible<
typename RealType::mapped_type,
typename CompatibleObjectType::mapped_type>::value;
831 template<
class BasicJsonType,
class CompatibleObjectType>
832 struct is_compatible_object_type
834 static auto constexpr value = is_compatible_object_type_impl <
835 conjunction<negation<std::is_same<
void, CompatibleObjectType>>,
836 has_mapped_type<CompatibleObjectType>,
837 has_key_type<CompatibleObjectType>>::value,
838 typename BasicJsonType::object_t, CompatibleObjectType >::value;
841 template<
typename BasicJsonType,
typename T>
842 struct is_basic_json_nested_type
844 static auto constexpr value = std::is_same<T,
typename BasicJsonType::iterator>::value
or 845 std::is_same<T,
typename BasicJsonType::const_iterator>::value
or 846 std::is_same<T,
typename BasicJsonType::reverse_iterator>::value
or 847 std::is_same<T,
typename BasicJsonType::const_reverse_iterator>::value;
850 template<
class BasicJsonType,
class CompatibleArrayType>
851 struct is_compatible_array_type
853 static auto constexpr value =
854 conjunction<negation<std::is_same<
void, CompatibleArrayType>>,
855 negation<is_compatible_object_type<
856 BasicJsonType, CompatibleArrayType>>,
857 negation<std::is_constructible<
typename BasicJsonType::string_t,
858 CompatibleArrayType>>,
859 negation<is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>>,
860 has_value_type<CompatibleArrayType>,
861 has_iterator<CompatibleArrayType>>::value;
864 template<
bool,
typename,
typename>
865 struct is_compatible_integer_type_impl : std::false_type {};
867 template<
typename RealIntegerType,
typename CompatibleNumberIntegerType>
868 struct is_compatible_integer_type_impl<
true, RealIntegerType, CompatibleNumberIntegerType>
871 using RealLimits = std::numeric_limits<RealIntegerType>;
872 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
874 static constexpr auto value =
875 std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value
and 876 CompatibleLimits::is_integer
and 877 RealLimits::is_signed == CompatibleLimits::is_signed;
880 template<
typename RealIntegerType,
typename CompatibleNumberIntegerType>
881 struct is_compatible_integer_type
883 static constexpr auto value =
884 is_compatible_integer_type_impl <
885 std::is_integral<CompatibleNumberIntegerType>::value
and 886 not std::is_same<
bool, CompatibleNumberIntegerType>::value,
887 RealIntegerType, CompatibleNumberIntegerType >::value;
892 template<
typename BasicJsonType,
typename T>
897 template<
typename U,
typename = enable_if_t<std::is_same<
void,
decltype(uncvref_t<U>::from_json(
898 std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
899 static int detect(U&&);
900 static void detect(...);
903 static constexpr bool value = std::is_integral<
decltype(
904 detect(std::declval<
typename BasicJsonType::
template json_serializer<T,
void>>()))>::value;
909 template<
typename BasicJsonType,
typename T>
910 struct has_non_default_from_json
913 template<
typename U,
typename =
914 enable_if_t<std::is_same<T,
decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value>>
915 static int detect(U&&);
916 static void detect(...);
919 static constexpr bool value = std::is_integral<
decltype(detect(
920 std::declval<
typename BasicJsonType::
template json_serializer<T,
void>>()))>::value;
924 template<
typename BasicJsonType,
typename T>
928 template<
typename U,
typename =
decltype(uncvref_t<U>::to_json(
929 std::declval<BasicJsonType&>(), std::declval<T>()))>
930 static int detect(U&&);
931 static void detect(...);
934 static constexpr bool value = std::is_integral<
decltype(detect(
935 std::declval<
typename BasicJsonType::
template json_serializer<T,
void>>()))>::value;
943 template<
typename BasicJsonType,
typename T,
944 enable_if_t<std::is_same<T,
typename BasicJsonType::boolean_t>::value,
int> = 0>
945 void to_json(BasicJsonType& j, T b)
noexcept 947 external_constructor<value_t::boolean>::construct(j, b);
950 template<
typename BasicJsonType,
typename CompatibleString,
951 enable_if_t<std::is_constructible<
typename BasicJsonType::string_t, CompatibleString>::value,
int> = 0>
952 void to_json(BasicJsonType& j,
const CompatibleString& s)
954 external_constructor<value_t::string>::construct(j, s);
957 template<
typename BasicJsonType>
958 void to_json(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
960 external_constructor<value_t::string>::construct(j, std::move(s));
963 template<
typename BasicJsonType,
typename FloatType,
964 enable_if_t<std::is_floating_point<FloatType>::value,
int> = 0>
965 void to_json(BasicJsonType& j, FloatType val)
noexcept 967 external_constructor<value_t::number_float>::construct(j,
static_cast<
typename BasicJsonType::number_float_t>(val));
970 template<
typename BasicJsonType,
typename CompatibleNumberUnsignedType,
971 enable_if_t<is_compatible_integer_type<
typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value,
int> = 0>
972 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val)
noexcept 974 external_constructor<value_t::number_unsigned>::construct(j,
static_cast<
typename BasicJsonType::number_unsigned_t>(val));
977 template<
typename BasicJsonType,
typename CompatibleNumberIntegerType,
978 enable_if_t<is_compatible_integer_type<
typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value,
int> = 0>
979 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val)
noexcept 981 external_constructor<value_t::number_integer>::construct(j,
static_cast<
typename BasicJsonType::number_integer_t>(val));
984 template<
typename BasicJsonType,
typename EnumType,
985 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
986 void to_json(BasicJsonType& j, EnumType e)
noexcept 988 using underlying_type =
typename std::underlying_type<EnumType>::type;
989 external_constructor<value_t::number_integer>::construct(j,
static_cast<underlying_type>(e));
992 template<
typename BasicJsonType>
993 void to_json(BasicJsonType& j,
const std::vector<
bool>& e)
995 external_constructor<value_t::array>::construct(j, e);
998 template<
typename BasicJsonType,
typename CompatibleArrayType,
999 enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value
or 1000 std::is_same<
typename BasicJsonType::array_t, CompatibleArrayType>::value,
1002 void to_json(BasicJsonType& j,
const CompatibleArrayType& arr)
1004 external_constructor<value_t::array>::construct(j, arr);
1007 template<
typename BasicJsonType,
typename T,
1008 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
1009 void to_json(BasicJsonType& j, std::valarray<T> arr)
1011 external_constructor<value_t::array>::construct(j, std::move(arr));
1014 template<
typename BasicJsonType>
1015 void to_json(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
1017 external_constructor<value_t::array>::construct(j, std::move(arr));
1020 template<
typename BasicJsonType,
typename CompatibleObjectType,
1021 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
int> = 0>
1022 void to_json(BasicJsonType& j,
const CompatibleObjectType& obj)
1024 external_constructor<value_t::object>::construct(j, obj);
1027 template<
typename BasicJsonType>
1028 void to_json(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
1030 external_constructor<value_t::object>::construct(j, std::move(obj));
1033 template<
typename BasicJsonType,
typename T, std::size_t N,
1034 enable_if_t<
not std::is_constructible<
typename BasicJsonType::string_t, T (&)[N]>::value,
int> = 0>
1035 void to_json(BasicJsonType& j, T (&arr)[N])
1037 external_constructor<value_t::array>::construct(j, arr);
1040 template<
typename BasicJsonType,
typename... Args>
1041 void to_json(BasicJsonType& j,
const std::pair<Args...>& p)
1043 j = {p.first, p.second};
1046 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1047 void to_json_tuple_impl(BasicJsonType& j,
const Tuple& t, index_sequence<Idx...>)
1049 j = {std::get<Idx>(t)...};
1052 template<
typename BasicJsonType,
typename... Args>
1053 void to_json(BasicJsonType& j,
const std::tuple<Args...>& t)
1055 to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1063 template<
typename BasicJsonType,
typename ArithmeticType,
1064 enable_if_t<std::is_arithmetic<ArithmeticType>::value
and 1065 not std::is_same<ArithmeticType,
typename BasicJsonType::boolean_t>::value,
1067 void get_arithmetic_value(
const BasicJsonType& j, ArithmeticType& val)
1069 switch (
static_cast<value_t>(j))
1071 case value_t::number_unsigned:
1073 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_unsigned_t*>());
1076 case value_t::number_integer:
1078 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_integer_t*>());
1081 case value_t::number_float:
1083 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_float_t*>());
1088 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
1092 template<
typename BasicJsonType>
1093 void from_json(
const BasicJsonType& j,
typename BasicJsonType::boolean_t& b)
1097 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(j.type_name())));
1099 b = *j.
template get_ptr<
const typename BasicJsonType::boolean_t*>();
1102 template<
typename BasicJsonType>
1103 void from_json(
const BasicJsonType& j,
typename BasicJsonType::string_t& s)
1107 JSON_THROW(type_error::create(302,
"type must be string, but is " + std::string(j.type_name())));
1109 s = *j.
template get_ptr<
const typename BasicJsonType::string_t*>();
1112 template<
typename BasicJsonType>
1113 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_float_t& val)
1115 get_arithmetic_value(j, val);
1118 template<
typename BasicJsonType>
1119 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_unsigned_t& val)
1121 get_arithmetic_value(j, val);
1124 template<
typename BasicJsonType>
1125 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_integer_t& val)
1127 get_arithmetic_value(j, val);
1130 template<
typename BasicJsonType,
typename EnumType,
1131 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
1132 void from_json(
const BasicJsonType& j, EnumType& e)
1134 typename std::underlying_type<EnumType>::type val;
1135 get_arithmetic_value(j, val);
1136 e =
static_cast<EnumType>(val);
1139 template<
typename BasicJsonType>
1140 void from_json(
const BasicJsonType& j,
typename BasicJsonType::array_t& arr)
1144 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1146 arr = *j.
template get_ptr<
const typename BasicJsonType::array_t*>();
1150 template<
typename BasicJsonType,
typename T,
typename Allocator,
1151 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1152 void from_json(
const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1156 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1158 std::transform(j.rbegin(), j.rend(),
1159 std::front_inserter(l), [](
const BasicJsonType & i)
1161 return i.
template get<T>();
1166 template<
typename BasicJsonType,
typename T,
1167 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1168 void from_json(
const BasicJsonType& j, std::valarray<T>& l)
1172 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1175 std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1178 template<
typename BasicJsonType,
typename CompatibleArrayType>
1179 void from_json_array_impl(
const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0> )
1183 std::transform(j.begin(), j.end(),
1184 std::inserter(arr, end(arr)), [](
const BasicJsonType & i)
1188 return i.
template get<
typename CompatibleArrayType::value_type>();
1192 template<
typename BasicJsonType,
typename CompatibleArrayType>
1193 auto from_json_array_impl(
const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1> )
1195 arr.reserve(std::declval<
typename CompatibleArrayType::size_type>()),
1200 arr.reserve(j.size());
1201 std::transform(j.begin(), j.end(),
1202 std::inserter(arr, end(arr)), [](
const BasicJsonType & i)
1206 return i.
template get<
typename CompatibleArrayType::value_type>();
1210 template<
typename BasicJsonType,
typename T, std::size_t N>
1211 void from_json_array_impl(
const BasicJsonType& j, std::array<T, N>& arr, priority_tag<2> )
1213 for (std::size_t i = 0; i < N; ++i)
1215 arr[i] = j.at(i).
template get<T>();
1219 template<
typename BasicJsonType,
typename CompatibleArrayType,
1220 enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value
and 1221 std::is_convertible<BasicJsonType,
typename CompatibleArrayType::value_type>::value
and 1222 not std::is_same<
typename BasicJsonType::array_t, CompatibleArrayType>::value,
int> = 0>
1223 void from_json(
const BasicJsonType& j, CompatibleArrayType& arr)
1227 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1230 from_json_array_impl(j, arr, priority_tag<2> {});
1233 template<
typename BasicJsonType,
typename CompatibleObjectType,
1234 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
int> = 0>
1235 void from_json(
const BasicJsonType& j, CompatibleObjectType& obj)
1239 JSON_THROW(type_error::create(302,
"type must be object, but is " + std::string(j.type_name())));
1242 auto inner_object = j.
template get_ptr<
const typename BasicJsonType::object_t*>();
1243 using value_type =
typename CompatibleObjectType::value_type;
1245 inner_object->begin(), inner_object->end(),
1246 std::inserter(obj, obj.begin()),
1247 [](
typename BasicJsonType::object_t::value_type
const & p)
1249 return value_type(p.first, p.second.
template get<
typename CompatibleObjectType::mapped_type>());
1257 template<
typename BasicJsonType,
typename ArithmeticType,
1259 std::is_arithmetic<ArithmeticType>::value
and 1260 not std::is_same<ArithmeticType,
typename BasicJsonType::number_unsigned_t>::value
and 1261 not std::is_same<ArithmeticType,
typename BasicJsonType::number_integer_t>::value
and 1262 not std::is_same<ArithmeticType,
typename BasicJsonType::number_float_t>::value
and 1263 not std::is_same<ArithmeticType,
typename BasicJsonType::boolean_t>::value,
1265 void from_json(
const BasicJsonType& j, ArithmeticType& val)
1267 switch (
static_cast<value_t>(j))
1269 case value_t::number_unsigned:
1271 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_unsigned_t*>());
1274 case value_t::number_integer:
1276 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_integer_t*>());
1279 case value_t::number_float:
1281 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_float_t*>());
1284 case value_t::boolean:
1286 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::boolean_t*>());
1291 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
1295 template<
typename BasicJsonType,
typename A1,
typename A2>
1296 void from_json(
const BasicJsonType& j, std::pair<A1, A2>& p)
1298 p = {j.at(0).
template get<A1>(), j.at(1).
template get<A2>()};
1301 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1302 void from_json_tuple_impl(
const BasicJsonType& j, Tuple& t, index_sequence<Idx...>)
1304 t = std::make_tuple(j.at(Idx).
template get<
typename std::tuple_element<Idx, Tuple>::type>()...);
1307 template<
typename BasicJsonType,
typename... Args>
1308 void from_json(
const BasicJsonType& j, std::tuple<Args...>& t)
1310 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1316 template<
typename BasicJsonType,
typename T>
1317 auto call(BasicJsonType& j, T&& val, priority_tag<1> )
const noexcept(
noexcept(to_json(j, std::forward<T>(val))))
1318 ->
decltype(to_json(j, std::forward<T>(val)),
void())
1320 return to_json(j, std::forward<T>(val));
1323 template<
typename BasicJsonType,
typename T>
1324 void call(BasicJsonType& , T&& , priority_tag<0> )
const noexcept 1326 static_assert(
sizeof(BasicJsonType) == 0,
1327 "could not find to_json() method in T's namespace");
1331 using decayed = uncvref_t<T>;
1332 static_assert(
sizeof(
typename decayed::force_msvc_stacktrace) == 0,
1333 "forcing MSVC stacktrace to show which T we're talking about.");
1338 template<
typename BasicJsonType,
typename T>
1339 void operator()(BasicJsonType& j, T&& val)
const 1340 noexcept(
noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1> {})))
1342 return call(j, std::forward<T>(val), priority_tag<1> {});
1349 template<
typename BasicJsonType,
typename T>
1350 auto call(
const BasicJsonType& j, T& val, priority_tag<1> )
const 1351 noexcept(
noexcept(from_json(j, val)))
1352 ->
decltype(from_json(j, val),
void())
1354 return from_json(j, val);
1357 template<
typename BasicJsonType,
typename T>
1358 void call(
const BasicJsonType& , T& , priority_tag<0> )
const noexcept 1360 static_assert(
sizeof(BasicJsonType) == 0,
1361 "could not find from_json() method in T's namespace");
1364 using decayed = uncvref_t<T>;
1365 static_assert(
sizeof(
typename decayed::force_msvc_stacktrace) == 0,
1366 "forcing MSVC stacktrace to show which T we're talking about.");
1371 template<
typename BasicJsonType,
typename T>
1372 void operator()(
const BasicJsonType& j, T& val)
const 1373 noexcept(
noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
1375 return call(j, val, priority_tag<1> {});
1380 template<
typename T>
1383 static constexpr T value{};
1386 template<
typename T>
1387 constexpr T static_const<T>::value;
1404 struct input_adapter_protocol
1407 virtual std::char_traits<
char>::int_type get_character() = 0;
1409 virtual void unget_character() = 0;
1410 virtual ~input_adapter_protocol() =
default;
1414 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
1425 class input_stream_adapter :
public input_adapter_protocol
1428 ~input_stream_adapter()
override 1435 explicit input_stream_adapter(std::istream& i)
1436 : is(i), sb(*i.rdbuf())
1439 std::char_traits<
char>::int_type c;
1440 if ((c = get_character()) == 0xEF)
1442 if ((c = get_character()) == 0xBB)
1444 if ((c = get_character()) == 0xBF)
1448 else if (c != std::char_traits<
char>::eof())
1454 else if (c != std::char_traits<
char>::eof())
1460 else if (c != std::char_traits<
char>::eof())
1467 input_stream_adapter(
const input_stream_adapter&) =
delete;
1468 input_stream_adapter& operator=(input_stream_adapter&) =
delete;
1473 std::char_traits<
char>::int_type get_character()
override 1478 void unget_character()
override 1490 class input_buffer_adapter :
public input_adapter_protocol
1493 input_buffer_adapter(
const char* b,
const std::size_t l)
1494 : cursor(b), limit(b + l), start(b)
1497 if (l >= 3
and b[0] ==
'\xEF' and b[1] ==
'\xBB' and b[2] ==
'\xBF')
1504 input_buffer_adapter(
const input_buffer_adapter&) =
delete;
1505 input_buffer_adapter& operator=(input_buffer_adapter&) =
delete;
1507 std::char_traits<
char>::int_type get_character()
noexcept override 1511 return std::char_traits<
char>::to_int_type(*(cursor++));
1514 return std::char_traits<
char>::eof();
1517 void unget_character()
noexcept override 1540 input_adapter(std::istream& i)
1541 : ia(std::make_shared<input_stream_adapter>(i)) {}
1544 input_adapter(std::istream&& i)
1545 : ia(std::make_shared<input_stream_adapter>(i)) {}
1548 template<
typename CharT,
1549 typename std::enable_if<
1550 std::is_pointer<CharT>::value
and 1551 std::is_integral<
typename std::remove_pointer<CharT>::type>::value
and 1552 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
1554 input_adapter(CharT b, std::size_t l)
1555 : ia(std::make_shared<input_buffer_adapter>(
reinterpret_cast<
const char*>(b), l)) {}
1560 template<
typename CharT,
1561 typename std::enable_if<
1562 std::is_pointer<CharT>::value
and 1563 std::is_integral<
typename std::remove_pointer<CharT>::type>::value
and 1564 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
1566 input_adapter(CharT b)
1567 : input_adapter(
reinterpret_cast<
const char*>(b),
1568 std::strlen(
reinterpret_cast<
const char*>(b))) {}
1571 template<
class IteratorType,
1572 typename std::enable_if<
1573 std::is_same<
typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
1575 input_adapter(IteratorType first, IteratorType last)
1579 assert(std::accumulate(
1580 first, last, std::pair<
bool,
int>(
true, 0),
1581 [&first](std::pair<
bool,
int> res,
decltype(*first) val)
1583 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
1589 sizeof(
typename std::iterator_traits<IteratorType>::value_type) == 1,
1590 "each element in the iterator range must have the size of 1 byte");
1592 const auto len =
static_cast<size_t>(std::distance(first, last));
1596 ia = std::make_shared<input_buffer_adapter>(
reinterpret_cast<
const char*>(&(*first)), len);
1601 ia = std::make_shared<input_buffer_adapter>(
nullptr, len);
1606 template<
class T, std::size_t N>
1607 input_adapter(T (&array)[N])
1608 : input_adapter(std::begin(array), std::end(array)) {}
1611 template<
class ContiguousContainer,
typename 1612 std::enable_if<
not std::is_pointer<ContiguousContainer>::value
and 1613 std::is_base_of<std::random_access_iterator_tag,
typename std::iterator_traits<
decltype(std::begin(std::declval<ContiguousContainer
const>()))>::iterator_category>::value,
1615 input_adapter(
const ContiguousContainer& c)
1616 : input_adapter(std::begin(c), std::end(c)) {}
1618 operator input_adapter_t()
1625 input_adapter_t ia =
nullptr;
1637 template<
typename BasicJsonType>
1640 using number_integer_t =
typename BasicJsonType::number_integer_t;
1641 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
1642 using number_float_t =
typename BasicJsonType::number_float_t;
1646 enum class token_type
1668 static const char* token_type_name(
const token_type t)
noexcept 1672 case token_type::uninitialized:
1673 return "<uninitialized>";
1674 case token_type::literal_true:
1675 return "true literal";
1676 case token_type::literal_false:
1677 return "false literal";
1678 case token_type::literal_null:
1679 return "null literal";
1680 case token_type::value_string:
1681 return "string literal";
1682 case lexer::token_type::value_unsigned:
1683 case lexer::token_type::value_integer:
1684 case lexer::token_type::value_float:
1685 return "number literal";
1686 case token_type::begin_array:
1688 case token_type::begin_object:
1690 case token_type::end_array:
1692 case token_type::end_object:
1694 case token_type::name_separator:
1696 case token_type::value_separator:
1698 case token_type::parse_error:
1699 return "<parse error>";
1700 case token_type::end_of_input:
1701 return "end of input";
1702 case token_type::literal_or_value:
1703 return "'[', '{', or a literal";
1705 return "unknown token";
1709 explicit lexer(detail::input_adapter_t adapter)
1710 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
1713 lexer(
const lexer&) =
delete;
1714 lexer& operator=(lexer&) =
delete;
1722 static char get_decimal_point()
noexcept 1724 const auto loc = localeconv();
1725 assert(loc !=
nullptr);
1726 return (loc->decimal_point ==
nullptr) ?
'.' : *(loc->decimal_point);
1751 assert(current ==
'u');
1754 const auto factors = { 12, 8, 4, 0 };
1755 for (
const auto factor : factors)
1759 if (current >=
'0' and current <=
'9')
1761 codepoint += ((current - 0x30) << factor);
1763 else if (current >=
'A' and current <=
'F')
1765 codepoint += ((current - 0x37) << factor);
1767 else if (current >=
'a' and current <=
'f')
1769 codepoint += ((current - 0x57) << factor);
1777 assert(0x0000 <= codepoint
and codepoint <= 0xFFFF);
1796 bool next_byte_in_range(std::initializer_list<
int> ranges)
1798 assert(ranges.size() == 2
or ranges.size() == 4
or ranges.size() == 6);
1801 for (
auto range = ranges.begin(); range != ranges.end(); ++range)
1804 if (
JSON_LIKELY(*range <= current
and current <= *(++range)))
1810 error_message =
"invalid string: ill-formed UTF-8 byte";
1832 token_type scan_string()
1838 assert(current ==
'\"');
1846 case std::char_traits<
char>::eof():
1848 error_message =
"invalid string: missing closing quote";
1849 return token_type::parse_error;
1855 return token_type::value_string;
1899 const int codepoint1 = get_codepoint();
1900 int codepoint = codepoint1;
1904 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
1905 return token_type::parse_error;
1909 if (0xD800 <= codepoint1
and codepoint1 <= 0xDBFF)
1914 const int codepoint2 = get_codepoint();
1918 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
1919 return token_type::parse_error;
1923 if (
JSON_LIKELY(0xDC00 <= codepoint2
and codepoint2 <= 0xDFFF))
1938 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
1939 return token_type::parse_error;
1944 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
1945 return token_type::parse_error;
1950 if (
JSON_UNLIKELY(0xDC00 <= codepoint1
and codepoint1 <= 0xDFFF))
1952 error_message =
"invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
1953 return token_type::parse_error;
1958 assert(0x00 <= codepoint
and codepoint <= 0x10FFFF);
1961 if (codepoint < 0x80)
1966 else if (codepoint <= 0x7FF)
1969 add(0xC0 | (codepoint >> 6));
1970 add(0x80 | (codepoint & 0x3F));
1972 else if (codepoint <= 0xFFFF)
1975 add(0xE0 | (codepoint >> 12));
1976 add(0x80 | ((codepoint >> 6) & 0x3F));
1977 add(0x80 | (codepoint & 0x3F));
1982 add(0xF0 | (codepoint >> 18));
1983 add(0x80 | ((codepoint >> 12) & 0x3F));
1984 add(0x80 | ((codepoint >> 6) & 0x3F));
1985 add(0x80 | (codepoint & 0x3F));
1993 error_message =
"invalid string: forbidden character after backslash";
1994 return token_type::parse_error;
2034 error_message =
"invalid string: control character must be escaped";
2035 return token_type::parse_error;
2172 return token_type::parse_error;
2180 if (
JSON_UNLIKELY(
not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
2182 return token_type::parse_error;
2204 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
2206 return token_type::parse_error;
2214 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
2216 return token_type::parse_error;
2224 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2226 return token_type::parse_error;
2236 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2238 return token_type::parse_error;
2246 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
2248 return token_type::parse_error;
2256 error_message =
"invalid string: ill-formed UTF-8 byte";
2257 return token_type::parse_error;
2263 static void strtof(
float& f,
const char* str,
char** endptr)
noexcept 2265 f = std::strtof(str, endptr);
2268 static void strtof(
double& f,
const char* str,
char** endptr)
noexcept 2270 f = std::strtod(str, endptr);
2273 static void strtof(
long double& f,
const char* str,
char** endptr)
noexcept 2275 f = std::strtold(str, endptr);
2318 token_type scan_number()
2325 token_type number_type = token_type::value_unsigned;
2333 goto scan_number_minus;
2339 goto scan_number_zero;
2353 goto scan_number_any1;
2365 number_type = token_type::value_integer;
2371 goto scan_number_zero;
2385 goto scan_number_any1;
2390 error_message =
"invalid number; expected digit after '-'";
2391 return token_type::parse_error;
2401 add(decimal_point_char);
2402 goto scan_number_decimal1;
2409 goto scan_number_exponent;
2413 goto scan_number_done;
2432 goto scan_number_any1;
2437 add(decimal_point_char);
2438 goto scan_number_decimal1;
2445 goto scan_number_exponent;
2449 goto scan_number_done;
2452 scan_number_decimal1:
2454 number_type = token_type::value_float;
2469 goto scan_number_decimal2;
2474 error_message =
"invalid number; expected digit after '.'";
2475 return token_type::parse_error;
2479 scan_number_decimal2:
2495 goto scan_number_decimal2;
2502 goto scan_number_exponent;
2506 goto scan_number_done;
2509 scan_number_exponent:
2511 number_type = token_type::value_float;
2518 goto scan_number_sign;
2533 goto scan_number_any2;
2539 "invalid number; expected '+', '-', or digit after exponent";
2540 return token_type::parse_error;
2560 goto scan_number_any2;
2565 error_message =
"invalid number; expected digit after exponent sign";
2566 return token_type::parse_error;
2586 goto scan_number_any2;
2590 goto scan_number_done;
2598 char* endptr =
nullptr;
2602 if (number_type == token_type::value_unsigned)
2604 const auto x = std::strtoull(yytext.data(), &endptr, 10);
2607 assert(endptr == yytext.data() + yytext.size());
2611 value_unsigned =
static_cast<number_unsigned_t>(x);
2612 if (value_unsigned == x)
2614 return token_type::value_unsigned;
2618 else if (number_type == token_type::value_integer)
2620 const auto x = std::strtoll(yytext.data(), &endptr, 10);
2623 assert(endptr == yytext.data() + yytext.size());
2627 value_integer =
static_cast<number_integer_t>(x);
2628 if (value_integer == x)
2630 return token_type::value_integer;
2637 strtof(value_float, yytext.data(), &endptr);
2640 assert(endptr == yytext.data() + yytext.size());
2642 return token_type::value_float;
2650 token_type scan_literal(
const char* literal_text,
const std::size_t length,
2651 token_type return_type)
2653 assert(current == literal_text[0]);
2654 for (std::size_t i = 1; i < length; ++i)
2658 error_message =
"invalid literal";
2659 return token_type::parse_error;
2670 void reset()
noexcept 2673 token_string.clear();
2674 token_string.push_back(std::char_traits<
char>::to_char_type(current));
2687 std::char_traits<
char>::int_type get()
2690 current = ia->get_character();
2691 if (
JSON_LIKELY(current != std::char_traits<
char>::eof()))
2693 token_string.push_back(std::char_traits<
char>::to_char_type(current));
2702 if (
JSON_LIKELY(current != std::char_traits<
char>::eof()))
2704 ia->unget_character();
2705 assert(token_string.size() != 0);
2706 token_string.pop_back();
2713 yytext.push_back(std::char_traits<
char>::to_char_type(c));
2722 constexpr number_integer_t get_number_integer()
const noexcept 2724 return value_integer;
2728 constexpr number_unsigned_t get_number_unsigned()
const noexcept 2730 return value_unsigned;
2734 constexpr number_float_t get_number_float()
const noexcept 2740 std::string move_string()
2742 return std::move(yytext);
2750 constexpr std::size_t get_position()
const noexcept 2758 std::string get_token_string()
const 2762 for (
auto c : token_string)
2764 if (
'\x00' <= c
and c <=
'\x1F')
2767 std::stringstream ss;
2768 ss <<
"<U+" << std::setw(4) << std::uppercase << std::setfill(
'0')
2769 << std::hex <<
static_cast<
int>(c) <<
">";
2775 result.push_back(c);
2783 constexpr const char* get_error_message()
const noexcept 2785 return error_message;
2799 while (current ==
' ' or current ==
'\t' or current ==
'\n' or current ==
'\r');
2805 return token_type::begin_array;
2807 return token_type::end_array;
2809 return token_type::begin_object;
2811 return token_type::end_object;
2813 return token_type::name_separator;
2815 return token_type::value_separator;
2819 return scan_literal(
"true", 4, token_type::literal_true);
2821 return scan_literal(
"false", 5, token_type::literal_false);
2823 return scan_literal(
"null", 4, token_type::literal_null);
2827 return scan_string();
2841 return scan_number();
2846 case std::char_traits<
char>::eof():
2847 return token_type::end_of_input;
2851 error_message =
"invalid literal";
2852 return token_type::parse_error;
2858 detail::input_adapter_t ia =
nullptr;
2861 std::char_traits<
char>::int_type current = std::char_traits<
char>::eof();
2864 std::size_t chars_read = 0;
2867 std::vector<
char> token_string {};
2870 std::string yytext {};
2873 const char* error_message =
"";
2876 number_integer_t value_integer = 0;
2877 number_unsigned_t value_unsigned = 0;
2878 number_float_t value_float = 0;
2881 const char decimal_point_char =
'.';
2889 template<
typename BasicJsonType>
2892 using number_integer_t =
typename BasicJsonType::number_integer_t;
2893 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
2894 using number_float_t =
typename BasicJsonType::number_float_t;
2895 using lexer_t = lexer<BasicJsonType>;
2896 using token_type =
typename lexer_t::token_type;
2899 enum class parse_event_t : uint8_t
2915 using parser_callback_t =
2916 std::function<
bool(
int depth, parse_event_t event, BasicJsonType& parsed)>;
2919 explicit parser(detail::input_adapter_t adapter,
2920 const parser_callback_t cb =
nullptr,
2921 const bool allow_exceptions_ =
true)
2922 : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_)
2935 void parse(
const bool strict, BasicJsonType& result)
2940 parse_internal(
true, result);
2941 result.assert_invariant();
2947 expect(token_type::end_of_input);
2953 result = value_t::discarded;
2959 if (result.is_discarded())
2971 bool accept(
const bool strict =
true)
2976 if (
not accept_internal())
2982 return not strict
or (get_token() == token_type::end_of_input);
2992 void parse_internal(
bool keep, BasicJsonType& result)
2995 assert(
not errored);
2998 if (
not result.is_discarded())
3000 result.m_value.destroy(result.m_type);
3001 result.m_type = value_t::discarded;
3006 case token_type::begin_object:
3012 keep = callback(depth++, parse_event_t::object_start, result);
3015 if (
not callback
or keep)
3018 result.m_type = value_t::object;
3019 result.m_value = value_t::object;
3027 if (last_token == token_type::end_object)
3029 if (keep
and callback
and not callback(--depth, parse_event_t::object_end, result))
3031 result.m_value.destroy(result.m_type);
3032 result.m_type = value_t::discarded;
3039 BasicJsonType value;
3043 if (
not expect(token_type::value_string))
3047 key = m_lexer.move_string();
3049 bool keep_tag =
false;
3054 BasicJsonType k(key);
3055 keep_tag = callback(depth, parse_event_t::key, k);
3065 if (
not expect(token_type::name_separator))
3072 value.m_value.destroy(value.m_type);
3073 value.m_type = value_t::discarded;
3074 parse_internal(keep, value);
3081 if (keep
and keep_tag
and not value.is_discarded())
3083 result.m_value.object->emplace(std::move(key), std::move(value));
3088 if (last_token == token_type::value_separator)
3095 if (
not expect(token_type::end_object))
3102 if (keep
and callback
and not callback(--depth, parse_event_t::object_end, result))
3104 result.m_value.destroy(result.m_type);
3105 result.m_type = value_t::discarded;
3110 case token_type::begin_array:
3116 keep = callback(depth++, parse_event_t::array_start, result);
3119 if (
not callback
or keep)
3122 result.m_type = value_t::array;
3123 result.m_value = value_t::array;
3131 if (last_token == token_type::end_array)
3133 if (callback
and not callback(--depth, parse_event_t::array_end, result))
3135 result.m_value.destroy(result.m_type);
3136 result.m_type = value_t::discarded;
3142 BasicJsonType value;
3146 value.m_value.destroy(value.m_type);
3147 value.m_type = value_t::discarded;
3148 parse_internal(keep, value);
3155 if (keep
and not value.is_discarded())
3157 result.m_value.array->push_back(std::move(value));
3162 if (last_token == token_type::value_separator)
3169 if (
not expect(token_type::end_array))
3176 if (keep
and callback
and not callback(--depth, parse_event_t::array_end, result))
3178 result.m_value.destroy(result.m_type);
3179 result.m_type = value_t::discarded;
3184 case token_type::literal_null:
3186 result.m_type = value_t::null;
3190 case token_type::value_string:
3192 result.m_type = value_t::string;
3193 result.m_value = m_lexer.move_string();
3197 case token_type::literal_true:
3199 result.m_type = value_t::boolean;
3200 result.m_value =
true;
3204 case token_type::literal_false:
3206 result.m_type = value_t::boolean;
3207 result.m_value =
false;
3211 case token_type::value_unsigned:
3213 result.m_type = value_t::number_unsigned;
3214 result.m_value = m_lexer.get_number_unsigned();
3218 case token_type::value_integer:
3220 result.m_type = value_t::number_integer;
3221 result.m_value = m_lexer.get_number_integer();
3225 case token_type::value_float:
3227 result.m_type = value_t::number_float;
3228 result.m_value = m_lexer.get_number_float();
3231 if (
JSON_UNLIKELY(
not std::isfinite(result.m_value.number_float)))
3233 if (allow_exceptions)
3235 JSON_THROW(out_of_range::create(406,
"number overflow parsing '" +
3236 m_lexer.get_token_string() +
"'"));
3238 expect(token_type::uninitialized);
3243 case token_type::parse_error:
3246 if (
not expect(token_type::uninitialized))
3256 if (
not expect(token_type::literal_or_value))
3264 if (keep
and callback
and not callback(depth, parse_event_t::value, result))
3266 result.m_type = value_t::discarded;
3280 bool accept_internal()
3284 case token_type::begin_object:
3290 if (last_token == token_type::end_object)
3299 if (last_token != token_type::value_string)
3306 if (last_token != token_type::name_separator)
3313 if (
not accept_internal())
3320 if (last_token == token_type::value_separator)
3327 return (last_token == token_type::end_object);
3331 case token_type::begin_array:
3337 if (last_token == token_type::end_array)
3346 if (
not accept_internal())
3353 if (last_token == token_type::value_separator)
3360 return (last_token == token_type::end_array);
3364 case token_type::value_float:
3367 return std::isfinite(m_lexer.get_number_float());
3370 case token_type::literal_false:
3371 case token_type::literal_null:
3372 case token_type::literal_true:
3373 case token_type::value_integer:
3374 case token_type::value_string:
3375 case token_type::value_unsigned:
3384 token_type get_token()
3386 return (last_token = m_lexer.scan());
3392 bool expect(token_type t)
3398 if (allow_exceptions)
3411 [[noreturn]]
void throw_exception()
const 3413 std::string error_msg =
"syntax error - ";
3414 if (last_token == token_type::parse_error)
3416 error_msg += std::string(m_lexer.get_error_message()) +
"; last read: '" +
3417 m_lexer.get_token_string() +
"'";
3421 error_msg +=
"unexpected " + std::string(lexer_t::token_type_name(last_token));
3424 if (expected != token_type::uninitialized)
3426 error_msg +=
"; expected " + std::string(lexer_t::token_type_name(expected));
3429 JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
3436 const parser_callback_t callback =
nullptr;
3438 token_type last_token = token_type::uninitialized;
3442 bool errored =
false;
3444 token_type expected = token_type::uninitialized;
3446 const bool allow_exceptions =
true;
3462 class primitive_iterator_t
3465 using difference_type = std::ptrdiff_t;
3467 constexpr difference_type get_value()
const noexcept 3473 void set_begin()
noexcept 3479 void set_end()
noexcept 3485 constexpr bool is_begin()
const noexcept 3487 return m_it == begin_value;
3491 constexpr bool is_end()
const noexcept 3493 return m_it == end_value;
3496 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs)
noexcept 3498 return lhs.m_it == rhs.m_it;
3501 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs)
noexcept 3503 return lhs.m_it < rhs.m_it;
3506 primitive_iterator_t operator+(difference_type i)
3508 auto result = *
this;
3513 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs)
noexcept 3515 return lhs.m_it - rhs.m_it;
3518 friend std::ostream& operator<<(std::ostream& os, primitive_iterator_t it)
3520 return os << it.m_it;
3523 primitive_iterator_t& operator++()
3529 primitive_iterator_t operator++(
int)
3531 auto result = *
this;
3536 primitive_iterator_t& operator--()
3542 primitive_iterator_t operator--(
int)
3544 auto result = *
this;
3549 primitive_iterator_t& operator+=(difference_type n)
3555 primitive_iterator_t& operator-=(difference_type n)
3562 static constexpr difference_type begin_value = 0;
3563 static constexpr difference_type end_value = begin_value + 1;
3566 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
3575 template<
typename BasicJsonType>
struct internal_iterator
3578 typename BasicJsonType::object_t::iterator object_iterator {};
3580 typename BasicJsonType::array_t::iterator array_iterator {};
3582 primitive_iterator_t primitive_iterator {};
3585 template<
typename IteratorType>
class iteration_proxy;
3607 template<
typename BasicJsonType>
3611 friend iter_impl<
typename std::conditional<std::is_const<BasicJsonType>::value,
typename std::remove_const<BasicJsonType>::type,
const BasicJsonType>::type>;
3612 friend BasicJsonType;
3613 friend iteration_proxy<iter_impl>;
3615 using object_t =
typename BasicJsonType::object_t;
3616 using array_t =
typename BasicJsonType::array_t;
3618 static_assert(is_basic_json<
typename std::remove_const<BasicJsonType>::type>::value,
3619 "iter_impl only accepts (const) basic_json");
3628 using iterator_category = std::bidirectional_iterator_tag;
3631 using value_type =
typename BasicJsonType::value_type;
3633 using difference_type =
typename BasicJsonType::difference_type;
3635 using pointer =
typename std::conditional<std::is_const<BasicJsonType>::value,
3636 typename BasicJsonType::const_pointer,
3637 typename BasicJsonType::pointer>::type;
3640 typename std::conditional<std::is_const<BasicJsonType>::value,
3641 typename BasicJsonType::const_reference,
3642 typename BasicJsonType::reference>::type;
3645 iter_impl() =
default;
3653 explicit iter_impl(pointer object)
noexcept : m_object(object)
3655 assert(m_object !=
nullptr);
3657 switch (m_object->m_type)
3659 case value_t::object:
3661 m_it.object_iterator =
typename object_t::iterator();
3665 case value_t::array:
3667 m_it.array_iterator =
typename array_t::iterator();
3673 m_it.primitive_iterator = primitive_iterator_t();
3693 iter_impl(
const iter_impl<
typename std::remove_const<BasicJsonType>::type>& other)
noexcept 3694 : m_object(other.m_object), m_it(other.m_it) {}
3702 iter_impl& operator=(
const iter_impl<
typename std::remove_const<BasicJsonType>::type>& other)
noexcept 3704 m_object = other.m_object;
3714 void set_begin()
noexcept 3716 assert(m_object !=
nullptr);
3718 switch (m_object->m_type)
3720 case value_t::object:
3722 m_it.object_iterator = m_object->m_value.object->begin();
3726 case value_t::array:
3728 m_it.array_iterator = m_object->m_value.array->begin();
3735 m_it.primitive_iterator.set_end();
3741 m_it.primitive_iterator.set_begin();
3751 void set_end()
noexcept 3753 assert(m_object !=
nullptr);
3755 switch (m_object->m_type)
3757 case value_t::object:
3759 m_it.object_iterator = m_object->m_value.object->end();
3763 case value_t::array:
3765 m_it.array_iterator = m_object->m_value.array->end();
3771 m_it.primitive_iterator.set_end();
3782 reference operator*()
const 3784 assert(m_object !=
nullptr);
3786 switch (m_object->m_type)
3788 case value_t::object:
3790 assert(m_it.object_iterator != m_object->m_value.object->end());
3791 return m_it.object_iterator->second;
3794 case value_t::array:
3796 assert(m_it.array_iterator != m_object->m_value.array->end());
3797 return *m_it.array_iterator;
3801 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
3805 if (
JSON_LIKELY(m_it.primitive_iterator.is_begin()))
3810 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
3819 pointer operator->()
const 3821 assert(m_object !=
nullptr);
3823 switch (m_object->m_type)
3825 case value_t::object:
3827 assert(m_it.object_iterator != m_object->m_value.object->end());
3828 return &(m_it.object_iterator->second);
3831 case value_t::array:
3833 assert(m_it.array_iterator != m_object->m_value.array->end());
3834 return &*m_it.array_iterator;
3839 if (
JSON_LIKELY(m_it.primitive_iterator.is_begin()))
3844 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
3853 iter_impl operator++(
int)
3855 auto result = *
this;
3864 iter_impl& operator++()
3866 assert(m_object !=
nullptr);
3868 switch (m_object->m_type)
3870 case value_t::object:
3872 std::advance(m_it.object_iterator, 1);
3876 case value_t::array:
3878 std::advance(m_it.array_iterator, 1);
3884 ++m_it.primitive_iterator;
3896 iter_impl operator--(
int)
3898 auto result = *
this;
3907 iter_impl& operator--()
3909 assert(m_object !=
nullptr);
3911 switch (m_object->m_type)
3913 case value_t::object:
3915 std::advance(m_it.object_iterator, -1);
3919 case value_t::array:
3921 std::advance(m_it.array_iterator, -1);
3927 --m_it.primitive_iterator;
3939 bool operator==(
const iter_impl& other)
const 3944 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
3947 assert(m_object !=
nullptr);
3949 switch (m_object->m_type)
3951 case value_t::object:
3952 return (m_it.object_iterator == other.m_it.object_iterator);
3954 case value_t::array:
3955 return (m_it.array_iterator == other.m_it.array_iterator);
3958 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
3966 bool operator!=(
const iter_impl& other)
const 3968 return not operator==(other);
3975 bool operator<(
const iter_impl& other)
const 3980 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
3983 assert(m_object !=
nullptr);
3985 switch (m_object->m_type)
3987 case value_t::object:
3988 JSON_THROW(invalid_iterator::create(213,
"cannot compare order of object iterators"));
3990 case value_t::array:
3991 return (m_it.array_iterator < other.m_it.array_iterator);
3994 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
4002 bool operator<=(
const iter_impl& other)
const 4004 return not other.operator < (*
this);
4011 bool operator>(
const iter_impl& other)
const 4013 return not operator<=(other);
4020 bool operator>=(
const iter_impl& other)
const 4022 return not operator<(other);
4029 iter_impl& operator+=(difference_type i)
4031 assert(m_object !=
nullptr);
4033 switch (m_object->m_type)
4035 case value_t::object:
4036 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
4038 case value_t::array:
4040 std::advance(m_it.array_iterator, i);
4046 m_it.primitive_iterator += i;
4058 iter_impl& operator-=(difference_type i)
4060 return operator+=(-i);
4067 iter_impl operator+(difference_type i)
const 4069 auto result = *
this;
4078 friend iter_impl operator+(difference_type i,
const iter_impl& it)
4089 iter_impl operator-(difference_type i)
const 4091 auto result = *
this;
4100 difference_type operator-(
const iter_impl& other)
const 4102 assert(m_object !=
nullptr);
4104 switch (m_object->m_type)
4106 case value_t::object:
4107 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
4109 case value_t::array:
4110 return m_it.array_iterator - other.m_it.array_iterator;
4113 return m_it.primitive_iterator - other.m_it.primitive_iterator;
4121 reference operator[](difference_type n)
const 4123 assert(m_object !=
nullptr);
4125 switch (m_object->m_type)
4127 case value_t::object:
4128 JSON_THROW(invalid_iterator::create(208,
"cannot use operator[] for object iterators"));
4130 case value_t::array:
4131 return *std::next(m_it.array_iterator, n);
4134 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4138 if (
JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
4143 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4152 typename object_t::key_type key()
const 4154 assert(m_object !=
nullptr);
4158 return m_it.object_iterator->first;
4161 JSON_THROW(invalid_iterator::create(207,
"cannot use key() for non-object iterators"));
4168 reference value()
const 4175 pointer m_object =
nullptr;
4177 internal_iterator<
typename std::remove_const<BasicJsonType>::type> m_it = {};
4181 template<
typename IteratorType>
class iteration_proxy
4185 class iteration_proxy_internal
4189 IteratorType anchor;
4191 std::size_t array_index = 0;
4194 explicit iteration_proxy_internal(IteratorType it)
noexcept : anchor(it) {}
4197 iteration_proxy_internal& operator*()
4203 iteration_proxy_internal& operator++()
4212 bool operator!=(
const iteration_proxy_internal& o)
const noexcept 4214 return anchor != o.anchor;
4218 std::string key()
const 4220 assert(anchor.m_object !=
nullptr);
4222 switch (anchor.m_object->type())
4225 case value_t::array:
4226 return std::to_string(array_index);
4229 case value_t::object:
4230 return anchor.key();
4239 typename IteratorType::reference value()
const 4241 return anchor.value();
4246 typename IteratorType::reference container;
4250 explicit iteration_proxy(
typename IteratorType::reference cont)
4251 : container(cont) {}
4254 iteration_proxy_internal begin()
noexcept 4256 return iteration_proxy_internal(container.begin());
4260 iteration_proxy_internal end()
noexcept 4262 return iteration_proxy_internal(container.end());
4284 template<
typename Base>
4285 class json_reverse_iterator :
public std::reverse_iterator<Base>
4288 using difference_type = std::ptrdiff_t;
4290 using base_iterator = std::reverse_iterator<Base>;
4292 using reference =
typename Base::reference;
4295 json_reverse_iterator(
const typename base_iterator::iterator_type& it)
noexcept 4296 : base_iterator(it) {}
4299 json_reverse_iterator(
const base_iterator& it)
noexcept : base_iterator(it) {}
4302 json_reverse_iterator operator++(
int)
4304 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
4308 json_reverse_iterator& operator++()
4310 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
4314 json_reverse_iterator operator--(
int)
4316 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
4320 json_reverse_iterator& operator--()
4322 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
4326 json_reverse_iterator& operator+=(difference_type i)
4328 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
4332 json_reverse_iterator operator+(difference_type i)
const 4334 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
4338 json_reverse_iterator operator-(difference_type i)
const 4340 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
4344 difference_type operator-(
const json_reverse_iterator& other)
const 4346 return base_iterator(*
this) - base_iterator(other);
4350 reference operator[](difference_type n)
const 4352 return *(
this->operator+(n));
4356 auto key()
const ->
decltype(std::declval<Base>().key())
4358 auto it = --
this->base();
4363 reference value()
const 4365 auto it = --
this->base();
4366 return it.operator * ();
4375 template<
typename CharType>
struct output_adapter_protocol
4377 virtual void write_character(CharType c) = 0;
4378 virtual void write_characters(
const CharType* s, std::size_t length) = 0;
4379 virtual ~output_adapter_protocol() =
default;
4383 template<
typename CharType>
4384 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
4387 template<
typename CharType>
4388 class output_vector_adapter :
public output_adapter_protocol<CharType>
4391 explicit output_vector_adapter(std::vector<CharType>& vec) : v(vec) {}
4393 void write_character(CharType c)
override 4398 void write_characters(
const CharType* s, std::size_t length)
override 4400 std::copy(s, s + length, std::back_inserter(v));
4404 std::vector<CharType>& v;
4408 template<
typename CharType>
4409 class output_stream_adapter :
public output_adapter_protocol<CharType>
4412 explicit output_stream_adapter(std::basic_ostream<CharType>& s) : stream(s) {}
4414 void write_character(CharType c)
override 4419 void write_characters(
const CharType* s, std::size_t length)
override 4421 stream.write(s,
static_cast<std::streamsize>(length));
4425 std::basic_ostream<CharType>& stream;
4429 template<
typename CharType>
4430 class output_string_adapter :
public output_adapter_protocol<CharType>
4433 explicit output_string_adapter(std::basic_string<CharType>& s) : str(s) {}
4435 void write_character(CharType c)
override 4440 void write_characters(
const CharType* s, std::size_t length)
override 4442 str.append(s, length);
4446 std::basic_string<CharType>& str;
4449 template<
typename CharType>
4450 class output_adapter
4453 output_adapter(std::vector<CharType>& vec)
4454 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
4456 output_adapter(std::basic_ostream<CharType>& s)
4457 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
4459 output_adapter(std::basic_string<CharType>& s)
4460 : oa(std::make_shared<output_string_adapter<CharType>>(s)) {}
4462 operator output_adapter_t<CharType>()
4468 output_adapter_t<CharType> oa =
nullptr;
4478 template<
typename BasicJsonType>
4481 using number_integer_t =
typename BasicJsonType::number_integer_t;
4482 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
4490 explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
4505 BasicJsonType parse_cbor(
const bool strict)
4507 const auto res = parse_cbor_internal();
4526 BasicJsonType parse_msgpack(
const bool strict)
4528 const auto res = parse_msgpack_internal();
4544 static constexpr bool little_endianess(
int num = 1)
noexcept 4546 return (*
reinterpret_cast<
char*>(&num) == 1);
4555 BasicJsonType parse_cbor_internal(
const bool get_char =
true)
4557 switch (get_char ? get() : current)
4560 case std::char_traits<
char>::eof():
4561 JSON_THROW(parse_error::create(110, chars_read,
"unexpected end of input"));
4588 return static_cast<number_unsigned_t>(current);
4591 return get_number<uint8_t>();
4594 return get_number<uint16_t>();
4597 return get_number<uint32_t>();
4600 return get_number<uint64_t>();
4627 return static_cast<int8_t>(0x20 - 1 - current);
4632 return static_cast<number_integer_t>(-1) - get_number<uint8_t>();
4637 return static_cast<number_integer_t>(-1) - get_number<uint16_t>();
4642 return static_cast<number_integer_t>(-1) - get_number<uint32_t>();
4647 return static_cast<number_integer_t>(-1) -
4648 static_cast<number_integer_t>(get_number<uint64_t>());
4682 return get_cbor_string();
4711 return get_cbor_array(current & 0x1F);
4716 return get_cbor_array(get_number<uint8_t>());
4721 return get_cbor_array(get_number<uint16_t>());
4726 return get_cbor_array(get_number<uint32_t>());
4731 return get_cbor_array(get_number<uint64_t>());
4736 BasicJsonType result = value_t::array;
4737 while (get() != 0xFF)
4739 result.push_back(parse_cbor_internal(
false));
4770 return get_cbor_object(current & 0x1F);
4775 return get_cbor_object(get_number<uint8_t>());
4780 return get_cbor_object(get_number<uint16_t>());
4785 return get_cbor_object(get_number<uint32_t>());
4790 return get_cbor_object(get_number<uint64_t>());
4795 BasicJsonType result = value_t::object;
4796 while (get() != 0xFF)
4798 auto key = get_cbor_string();
4799 result[key] = parse_cbor_internal();
4816 return value_t::null;
4821 const int byte1 = get();
4823 const int byte2 = get();
4834 const int half = (byte1 << 8) + byte2;
4835 const int exp = (half >> 10) & 0x1F;
4836 const int mant = half & 0x3FF;
4840 val = std::ldexp(mant, -24);
4844 val = std::ldexp(mant + 1024, exp - 25);
4848 val = (mant == 0) ? std::numeric_limits<
double>::infinity()
4849 : std::numeric_limits<
double>::quiet_NaN();
4851 return (half & 0x8000) != 0 ? -val : val;
4856 return get_number<
float>();
4861 return get_number<
double>();
4866 std::stringstream ss;
4867 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
4868 JSON_THROW(parse_error::create(112, chars_read,
"error reading CBOR; last byte: 0x" + ss.str()));
4873 BasicJsonType parse_msgpack_internal()
4878 case std::char_traits<
char>::eof():
4879 JSON_THROW(parse_error::create(110, chars_read,
"unexpected end of input"));
5010 return static_cast<number_unsigned_t>(current);
5030 return get_msgpack_object(current & 0x0F);
5051 return get_msgpack_array(current & 0x0F);
5087 return get_msgpack_string();
5090 return value_t::null;
5099 return get_number<
float>();
5102 return get_number<
double>();
5105 return get_number<uint8_t>();
5108 return get_number<uint16_t>();
5111 return get_number<uint32_t>();
5114 return get_number<uint64_t>();
5117 return get_number<int8_t>();
5120 return get_number<int16_t>();
5123 return get_number<int32_t>();
5126 return get_number<int64_t>();
5131 return get_msgpack_string();
5135 return get_msgpack_array(get_number<uint16_t>());
5140 return get_msgpack_array(get_number<uint32_t>());
5145 return get_msgpack_object(get_number<uint16_t>());
5150 return get_msgpack_object(get_number<uint32_t>());
5186 return static_cast<int8_t>(current);
5190 std::stringstream ss;
5191 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5192 JSON_THROW(parse_error::create(112, chars_read,
5193 "error reading MessagePack; last byte: 0x" + ss.str()));
5210 return (current = ia->get_character());
5226 template<
typename NumberType> NumberType get_number()
5229 std::array<uint8_t,
sizeof(NumberType)> vec;
5230 for (std::size_t i = 0; i <
sizeof(NumberType); ++i)
5236 if (is_little_endian)
5238 vec[
sizeof(NumberType) - i - 1] =
static_cast<uint8_t>(current);
5242 vec[i] =
static_cast<uint8_t>(current);
5248 std::memcpy(&result, vec.data(),
sizeof(NumberType));
5265 template<
typename NumberType>
5266 std::string get_string(
const NumberType len)
5269 std::generate_n(std::back_inserter(result), len, [
this]()
5273 return static_cast<
char>(current);
5290 std::string get_cbor_string()
5322 return get_string(current & 0x1F);
5327 return get_string(get_number<uint8_t>());
5332 return get_string(get_number<uint16_t>());
5337 return get_string(get_number<uint32_t>());
5342 return get_string(get_number<uint64_t>());
5348 while (get() != 0xFF)
5351 result.push_back(
static_cast<
char>(current));
5358 std::stringstream ss;
5359 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5360 JSON_THROW(parse_error::create(113, chars_read,
"expected a CBOR string; last byte: 0x" + ss.str()));
5365 template<
typename NumberType>
5366 BasicJsonType get_cbor_array(
const NumberType len)
5368 BasicJsonType result = value_t::array;
5369 std::generate_n(std::back_inserter(*result.m_value.array), len, [
this]()
5371 return parse_cbor_internal();
5376 template<
typename NumberType>
5377 BasicJsonType get_cbor_object(
const NumberType len)
5379 BasicJsonType result = value_t::object;
5380 std::generate_n(std::inserter(*result.m_value.object,
5381 result.m_value.object->end()),
5385 auto key = get_cbor_string();
5386 auto val = parse_cbor_internal();
5387 return std::make_pair(std::move(key), std::move(val));
5403 std::string get_msgpack_string()
5443 return get_string(current & 0x1F);
5448 return get_string(get_number<uint8_t>());
5453 return get_string(get_number<uint16_t>());
5458 return get_string(get_number<uint32_t>());
5463 std::stringstream ss;
5464 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5465 JSON_THROW(parse_error::create(113, chars_read,
5466 "expected a MessagePack string; last byte: 0x" + ss.str()));
5471 template<
typename NumberType>
5472 BasicJsonType get_msgpack_array(
const NumberType len)
5474 BasicJsonType result = value_t::array;
5475 std::generate_n(std::back_inserter(*result.m_value.array), len, [
this]()
5477 return parse_msgpack_internal();
5482 template<
typename NumberType>
5483 BasicJsonType get_msgpack_object(
const NumberType len)
5485 BasicJsonType result = value_t::object;
5486 std::generate_n(std::inserter(*result.m_value.object,
5487 result.m_value.object->end()),
5491 auto key = get_msgpack_string();
5492 auto val = parse_msgpack_internal();
5493 return std::make_pair(std::move(key), std::move(val));
5502 void check_eof(
const bool expect_eof =
false)
const 5506 if (
JSON_UNLIKELY(current != std::char_traits<
char>::eof()))
5508 JSON_THROW(parse_error::create(110, chars_read,
"expected end of input"));
5513 if (
JSON_UNLIKELY(current == std::char_traits<
char>::eof()))
5515 JSON_THROW(parse_error::create(110, chars_read,
"unexpected end of input"));
5522 input_adapter_t ia =
nullptr;
5525 int current = std::char_traits<
char>::eof();
5528 std::size_t chars_read = 0;
5531 const bool is_little_endian = little_endianess();
5537 template<
typename BasicJsonType,
typename CharType>
5546 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
5554 void write_cbor(
const BasicJsonType& j)
5560 oa->write_character(
static_cast<CharType>(0xF6));
5564 case value_t::boolean:
5566 oa->write_character(j.m_value.boolean
5567 ?
static_cast<CharType>(0xF5)
5568 :
static_cast<CharType>(0xF4));
5572 case value_t::number_integer:
5574 if (j.m_value.number_integer >= 0)
5579 if (j.m_value.number_integer <= 0x17)
5581 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
5583 else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
5585 oa->write_character(
static_cast<CharType>(0x18));
5586 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
5588 else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
5590 oa->write_character(
static_cast<CharType>(0x19));
5591 write_number(
static_cast<uint16_t>(j.m_value.number_integer));
5593 else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
5595 oa->write_character(
static_cast<CharType>(0x1A));
5596 write_number(
static_cast<uint32_t>(j.m_value.number_integer));
5600 oa->write_character(
static_cast<CharType>(0x1B));
5601 write_number(
static_cast<uint64_t>(j.m_value.number_integer));
5608 const auto positive_number = -1 - j.m_value.number_integer;
5609 if (j.m_value.number_integer >= -24)
5611 write_number(
static_cast<uint8_t>(0x20 + positive_number));
5613 else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
5615 oa->write_character(
static_cast<CharType>(0x38));
5616 write_number(
static_cast<uint8_t>(positive_number));
5618 else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
5620 oa->write_character(
static_cast<CharType>(0x39));
5621 write_number(
static_cast<uint16_t>(positive_number));
5623 else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
5625 oa->write_character(
static_cast<CharType>(0x3A));
5626 write_number(
static_cast<uint32_t>(positive_number));
5630 oa->write_character(
static_cast<CharType>(0x3B));
5631 write_number(
static_cast<uint64_t>(positive_number));
5637 case value_t::number_unsigned:
5639 if (j.m_value.number_unsigned <= 0x17)
5641 write_number(
static_cast<uint8_t>(j.m_value.number_unsigned));
5643 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
5645 oa->write_character(
static_cast<CharType>(0x18));
5646 write_number(
static_cast<uint8_t>(j.m_value.number_unsigned));
5648 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
5650 oa->write_character(
static_cast<CharType>(0x19));
5651 write_number(
static_cast<uint16_t>(j.m_value.number_unsigned));
5653 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
5655 oa->write_character(
static_cast<CharType>(0x1A));
5656 write_number(
static_cast<uint32_t>(j.m_value.number_unsigned));
5660 oa->write_character(
static_cast<CharType>(0x1B));
5661 write_number(
static_cast<uint64_t>(j.m_value.number_unsigned));
5666 case value_t::number_float:
5668 oa->write_character(
static_cast<CharType>(0xFB));
5669 write_number(j.m_value.number_float);
5673 case value_t::string:
5676 const auto N = j.m_value.string->size();
5679 write_number(
static_cast<uint8_t>(0x60 + N));
5683 oa->write_character(
static_cast<CharType>(0x78));
5684 write_number(
static_cast<uint8_t>(N));
5686 else if (N <= 0xFFFF)
5688 oa->write_character(
static_cast<CharType>(0x79));
5689 write_number(
static_cast<uint16_t>(N));
5691 else if (N <= 0xFFFFFFFF)
5693 oa->write_character(
static_cast<CharType>(0x7A));
5694 write_number(
static_cast<uint32_t>(N));
5697 else if (N <= 0xFFFFFFFFFFFFFFFF)
5699 oa->write_character(
static_cast<CharType>(0x7B));
5700 write_number(
static_cast<uint64_t>(N));
5705 oa->write_characters(
5706 reinterpret_cast<
const CharType*>(j.m_value.string->c_str()),
5707 j.m_value.string->size());
5711 case value_t::array:
5714 const auto N = j.m_value.array->size();
5717 write_number(
static_cast<uint8_t>(0x80 + N));
5721 oa->write_character(
static_cast<CharType>(0x98));
5722 write_number(
static_cast<uint8_t>(N));
5724 else if (N <= 0xFFFF)
5726 oa->write_character(
static_cast<CharType>(0x99));
5727 write_number(
static_cast<uint16_t>(N));
5729 else if (N <= 0xFFFFFFFF)
5731 oa->write_character(
static_cast<CharType>(0x9A));
5732 write_number(
static_cast<uint32_t>(N));
5735 else if (N <= 0xFFFFFFFFFFFFFFFF)
5737 oa->write_character(
static_cast<CharType>(0x9B));
5738 write_number(
static_cast<uint64_t>(N));
5743 for (
const auto& el : *j.m_value.array)
5750 case value_t::object:
5753 const auto N = j.m_value.object->size();
5756 write_number(
static_cast<uint8_t>(0xA0 + N));
5760 oa->write_character(
static_cast<CharType>(0xB8));
5761 write_number(
static_cast<uint8_t>(N));
5763 else if (N <= 0xFFFF)
5765 oa->write_character(
static_cast<CharType>(0xB9));
5766 write_number(
static_cast<uint16_t>(N));
5768 else if (N <= 0xFFFFFFFF)
5770 oa->write_character(
static_cast<CharType>(0xBA));
5771 write_number(
static_cast<uint32_t>(N));
5774 else if (N <= 0xFFFFFFFFFFFFFFFF)
5776 oa->write_character(
static_cast<CharType>(0xBB));
5777 write_number(
static_cast<uint64_t>(N));
5782 for (
const auto& el : *j.m_value.object)
5784 write_cbor(el.first);
5785 write_cbor(el.second);
5798 void write_msgpack(
const BasicJsonType& j)
5804 oa->write_character(
static_cast<CharType>(0xC0));
5808 case value_t::boolean:
5810 oa->write_character(j.m_value.boolean
5811 ?
static_cast<CharType>(0xC3)
5812 :
static_cast<CharType>(0xC2));
5816 case value_t::number_integer:
5818 if (j.m_value.number_integer >= 0)
5823 if (j.m_value.number_unsigned < 128)
5826 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
5828 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
5831 oa->write_character(
static_cast<CharType>(0xCC));
5832 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
5834 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
5837 oa->write_character(
static_cast<CharType>(0xCD));
5838 write_number(
static_cast<uint16_t>(j.m_value.number_integer));
5840 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
5843 oa->write_character(
static_cast<CharType>(0xCE));
5844 write_number(
static_cast<uint32_t>(j.m_value.number_integer));
5846 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
5849 oa->write_character(
static_cast<CharType>(0xCF));
5850 write_number(
static_cast<uint64_t>(j.m_value.number_integer));
5855 if (j.m_value.number_integer >= -32)
5858 write_number(
static_cast<int8_t>(j.m_value.number_integer));
5860 else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)()
and 5861 j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
5864 oa->write_character(
static_cast<CharType>(0xD0));
5865 write_number(
static_cast<int8_t>(j.m_value.number_integer));
5867 else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)()
and 5868 j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
5871 oa->write_character(
static_cast<CharType>(0xD1));
5872 write_number(
static_cast<int16_t>(j.m_value.number_integer));
5874 else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)()
and 5875 j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
5878 oa->write_character(
static_cast<CharType>(0xD2));
5879 write_number(
static_cast<int32_t>(j.m_value.number_integer));
5881 else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)()
and 5882 j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
5885 oa->write_character(
static_cast<CharType>(0xD3));
5886 write_number(
static_cast<int64_t>(j.m_value.number_integer));
5892 case value_t::number_unsigned:
5894 if (j.m_value.number_unsigned < 128)
5897 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
5899 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
5902 oa->write_character(
static_cast<CharType>(0xCC));
5903 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
5905 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
5908 oa->write_character(
static_cast<CharType>(0xCD));
5909 write_number(
static_cast<uint16_t>(j.m_value.number_integer));
5911 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
5914 oa->write_character(
static_cast<CharType>(0xCE));
5915 write_number(
static_cast<uint32_t>(j.m_value.number_integer));
5917 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
5920 oa->write_character(
static_cast<CharType>(0xCF));
5921 write_number(
static_cast<uint64_t>(j.m_value.number_integer));
5926 case value_t::number_float:
5928 oa->write_character(
static_cast<CharType>(0xCB));
5929 write_number(j.m_value.number_float);
5933 case value_t::string:
5936 const auto N = j.m_value.string->size();
5940 write_number(
static_cast<uint8_t>(0xA0 | N));
5945 oa->write_character(
static_cast<CharType>(0xD9));
5946 write_number(
static_cast<uint8_t>(N));
5948 else if (N <= 65535)
5951 oa->write_character(
static_cast<CharType>(0xDA));
5952 write_number(
static_cast<uint16_t>(N));
5954 else if (N <= 4294967295)
5957 oa->write_character(
static_cast<CharType>(0xDB));
5958 write_number(
static_cast<uint32_t>(N));
5962 oa->write_characters(
5963 reinterpret_cast<
const CharType*>(j.m_value.string->c_str()),
5964 j.m_value.string->size());
5968 case value_t::array:
5971 const auto N = j.m_value.array->size();
5975 write_number(
static_cast<uint8_t>(0x90 | N));
5977 else if (N <= 0xFFFF)
5980 oa->write_character(
static_cast<CharType>(0xDC));
5981 write_number(
static_cast<uint16_t>(N));
5983 else if (N <= 0xFFFFFFFF)
5986 oa->write_character(
static_cast<CharType>(0xDD));
5987 write_number(
static_cast<uint32_t>(N));
5991 for (
const auto& el : *j.m_value.array)
5998 case value_t::object:
6001 const auto N = j.m_value.object->size();
6005 write_number(
static_cast<uint8_t>(0x80 | (N & 0xF)));
6007 else if (N <= 65535)
6010 oa->write_character(
static_cast<CharType>(0xDE));
6011 write_number(
static_cast<uint16_t>(N));
6013 else if (N <= 4294967295)
6016 oa->write_character(
static_cast<CharType>(0xDF));
6017 write_number(
static_cast<uint32_t>(N));
6021 for (
const auto& el : *j.m_value.object)
6023 write_msgpack(el.first);
6024 write_msgpack(el.second);
6045 template<
typename NumberType>
void write_number(NumberType n)
6048 std::array<CharType,
sizeof(NumberType)> vec;
6049 std::memcpy(vec.data(), &n,
sizeof(NumberType));
6052 if (is_little_endian)
6055 std::reverse(vec.begin(), vec.end());
6058 oa->write_characters(vec.data(),
sizeof(NumberType));
6063 const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
6066 output_adapter_t<CharType> oa =
nullptr;
6073 template<
typename BasicJsonType>
6076 using string_t =
typename BasicJsonType::string_t;
6077 using number_float_t =
typename BasicJsonType::number_float_t;
6078 using number_integer_t =
typename BasicJsonType::number_integer_t;
6079 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
6085 serializer(output_adapter_t<
char> s,
const char ichar)
6086 : o(std::move(s)), loc(std::localeconv()),
6087 thousands_sep(loc->thousands_sep ==
nullptr ?
'\0' : * (loc->thousands_sep)),
6088 decimal_point(loc->decimal_point ==
nullptr ?
'\0' : * (loc->decimal_point)),
6089 indent_char(ichar), indent_string(512, indent_char) {}
6092 serializer(
const serializer&) =
delete;
6093 serializer& operator=(
const serializer&) =
delete;
6112 void dump(
const BasicJsonType& val,
const bool pretty_print,
6113 const bool ensure_ascii,
6114 const unsigned int indent_step,
6115 const unsigned int current_indent = 0)
6119 case value_t::object:
6121 if (val.m_value.object->empty())
6123 o->write_characters(
"{}", 2);
6129 o->write_characters(
"{\n", 2);
6132 const auto new_indent = current_indent + indent_step;
6135 indent_string.resize(indent_string.size() * 2,
' ');
6139 auto i = val.m_value.object->cbegin();
6140 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
6142 o->write_characters(indent_string.c_str(), new_indent);
6143 o->write_character(
'\"');
6144 dump_escaped(i->first, ensure_ascii);
6145 o->write_characters(
"\": ", 3);
6146 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
6147 o->write_characters(
",\n", 2);
6151 assert(i != val.m_value.object->cend());
6152 assert(std::next(i) == val.m_value.object->cend());
6153 o->write_characters(indent_string.c_str(), new_indent);
6154 o->write_character(
'\"');
6155 dump_escaped(i->first, ensure_ascii);
6156 o->write_characters(
"\": ", 3);
6157 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
6159 o->write_character(
'\n');
6160 o->write_characters(indent_string.c_str(), current_indent);
6161 o->write_character(
'}');
6165 o->write_character(
'{');
6168 auto i = val.m_value.object->cbegin();
6169 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
6171 o->write_character(
'\"');
6172 dump_escaped(i->first, ensure_ascii);
6173 o->write_characters(
"\":", 2);
6174 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
6175 o->write_character(
',');
6179 assert(i != val.m_value.object->cend());
6180 assert(std::next(i) == val.m_value.object->cend());
6181 o->write_character(
'\"');
6182 dump_escaped(i->first, ensure_ascii);
6183 o->write_characters(
"\":", 2);
6184 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
6186 o->write_character(
'}');
6192 case value_t::array:
6194 if (val.m_value.array->empty())
6196 o->write_characters(
"[]", 2);
6202 o->write_characters(
"[\n", 2);
6205 const auto new_indent = current_indent + indent_step;
6208 indent_string.resize(indent_string.size() * 2,
' ');
6212 for (
auto i = val.m_value.array->cbegin();
6213 i != val.m_value.array->cend() - 1; ++i)
6215 o->write_characters(indent_string.c_str(), new_indent);
6216 dump(*i,
true, ensure_ascii, indent_step, new_indent);
6217 o->write_characters(
",\n", 2);
6221 assert(
not val.m_value.array->empty());
6222 o->write_characters(indent_string.c_str(), new_indent);
6223 dump(val.m_value.array->back(),
true, ensure_ascii, indent_step, new_indent);
6225 o->write_character(
'\n');
6226 o->write_characters(indent_string.c_str(), current_indent);
6227 o->write_character(
']');
6231 o->write_character(
'[');
6234 for (
auto i = val.m_value.array->cbegin();
6235 i != val.m_value.array->cend() - 1; ++i)
6237 dump(*i,
false, ensure_ascii, indent_step, current_indent);
6238 o->write_character(
',');
6242 assert(
not val.m_value.array->empty());
6243 dump(val.m_value.array->back(),
false, ensure_ascii, indent_step, current_indent);
6245 o->write_character(
']');
6251 case value_t::string:
6253 o->write_character(
'\"');
6254 dump_escaped(*val.m_value.string, ensure_ascii);
6255 o->write_character(
'\"');
6259 case value_t::boolean:
6261 if (val.m_value.boolean)
6263 o->write_characters(
"true", 4);
6267 o->write_characters(
"false", 5);
6272 case value_t::number_integer:
6274 dump_integer(val.m_value.number_integer);
6278 case value_t::number_unsigned:
6280 dump_integer(val.m_value.number_unsigned);
6284 case value_t::number_float:
6286 dump_float(val.m_value.number_float);
6290 case value_t::discarded:
6292 o->write_characters(
"<discarded>", 11);
6298 o->write_characters(
"null", 4);
6311 static constexpr std::size_t bytes_following(
const uint8_t u)
6313 return ((u <= 127) ? 0
6314 : ((192 <= u
and u <= 223) ? 1
6315 : ((224 <= u
and u <= 239) ? 2
6316 : ((240 <= u
and u <= 247) ? 3 : std::string::npos))));
6329 static std::size_t extra_space(
const string_t& s,
6330 const bool ensure_ascii)
noexcept 6332 std::size_t res = 0;
6334 for (std::size_t i = 0; i < s.size(); ++i)
6388 if (ensure_ascii
and (s[i] & 0x80
or s[i] == 0x7F))
6390 const auto bytes = bytes_following(
static_cast<uint8_t>(s[i]));
6392 assert (bytes != std::string::npos);
6400 res += (12 - bytes - 1);
6405 res += (6 - bytes - 1);
6419 static void escape_codepoint(
int codepoint, string_t& result, std::size_t& pos)
6422 assert(0x00 <= codepoint
and codepoint <= 0x10FFFF);
6425 assert(result[pos] ==
'\\');
6428 result[++pos] =
'u';
6431 static const std::array<
char, 16> hexify =
6434 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
6435 '8',
'9',
'a',
'b',
'c',
'd',
'e',
'f' 6439 if (codepoint < 0x10000)
6442 result[++pos] = hexify[(codepoint >> 12) & 0x0F];
6443 result[++pos] = hexify[(codepoint >> 8) & 0x0F];
6444 result[++pos] = hexify[(codepoint >> 4) & 0x0F];
6445 result[++pos] = hexify[codepoint & 0x0F];
6452 codepoint -= 0x10000;
6453 const int high_surrogate = 0xD800 | ((codepoint >> 10) & 0x3FF);
6454 const int low_surrogate = 0xDC00 | (codepoint & 0x3FF);
6455 result[++pos] = hexify[(high_surrogate >> 12) & 0x0F];
6456 result[++pos] = hexify[(high_surrogate >> 8) & 0x0F];
6457 result[++pos] = hexify[(high_surrogate >> 4) & 0x0F];
6458 result[++pos] = hexify[high_surrogate & 0x0F];
6460 result[++pos] =
'u';
6461 result[++pos] = hexify[(low_surrogate >> 12) & 0x0F];
6462 result[++pos] = hexify[(low_surrogate >> 8) & 0x0F];
6463 result[++pos] = hexify[(low_surrogate >> 4) & 0x0F];
6464 result[++pos] = hexify[low_surrogate & 0x0F];
6484 void dump_escaped(
const string_t& s,
const bool ensure_ascii)
const 6486 throw_if_invalid_utf8(s);
6488 const auto space = extra_space(s, ensure_ascii);
6491 o->write_characters(s.c_str(), s.size());
6496 string_t result(s.size() + space,
'\\');
6497 std::size_t pos = 0;
6499 for (std::size_t i = 0; i < s.size(); ++i)
6505 result[pos + 1] =
'"';
6519 result[pos + 1] =
'b';
6526 result[pos + 1] =
'f';
6533 result[pos + 1] =
'n';
6540 result[pos + 1] =
'r';
6547 result[pos + 1] =
't';
6556 if ((0x00 <= s[i]
and s[i] <= 0x1F)
or 6557 (ensure_ascii
and (s[i] & 0x80
or s[i] == 0x7F)))
6559 const auto bytes = bytes_following(
static_cast<uint8_t>(s[i]));
6561 assert (bytes != std::string::npos);
6564 assert(i + bytes < s.size());
6570 assert(0 <= bytes
and bytes <= 3);
6575 codepoint = s[i] & 0xFF;
6581 codepoint = ((s[i] & 0x3F) << 6)
6582 + (s[i + 1] & 0x7F);
6588 codepoint = ((s[i] & 0x1F) << 12)
6589 + ((s[i + 1] & 0x7F) << 6)
6590 + (s[i + 2] & 0x7F);
6596 codepoint = ((s[i] & 0xF) << 18)
6597 + ((s[i + 1] & 0x7F) << 12)
6598 + ((s[i + 2] & 0x7F) << 6)
6599 + (s[i + 3] & 0x7F);
6607 escape_codepoint(codepoint, result, pos);
6613 result[pos++] = s[i];
6620 assert(pos == result.size());
6621 o->write_characters(result.c_str(), result.size());
6633 template<
typename NumberType, detail::enable_if_t<
6634 std::is_same<NumberType, number_unsigned_t>::value
or 6635 std::is_same<NumberType, number_integer_t>::value,
6637 void dump_integer(NumberType x)
6642 o->write_character(
'0');
6646 const bool is_negative = (x <= 0)
and (x != 0);
6652 assert(i < number_buffer.size() - 1);
6654 const auto digit = std::labs(
static_cast<
long>(x % 10));
6655 number_buffer[i++] =
static_cast<
char>(
'0' + digit);
6662 assert(i < number_buffer.size() - 2);
6663 number_buffer[i++] =
'-';
6666 std::reverse(number_buffer.begin(), number_buffer.begin() + i);
6667 o->write_characters(number_buffer.data(), i);
6678 void dump_float(number_float_t x)
6681 if (
not std::isfinite(x)
or std::isnan(x))
6683 o->write_characters(
"null", 4);
6688 static constexpr auto d = std::numeric_limits<number_float_t>::digits10;
6691 std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(),
"%.*g", d, x);
6696 assert(
static_cast<std::size_t>(len) < number_buffer.size());
6699 if (thousands_sep !=
'\0')
6701 const auto end = std::remove(number_buffer.begin(),
6702 number_buffer.begin() + len, thousands_sep);
6703 std::fill(end, number_buffer.end(),
'\0');
6704 assert((end - number_buffer.begin()) <= len);
6705 len = (end - number_buffer.begin());
6709 if (decimal_point !=
'\0' and decimal_point !=
'.')
6711 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
6712 if (dec_pos != number_buffer.end())
6718 o->write_characters(number_buffer.data(),
static_cast<std::size_t>(len));
6721 const bool value_is_int_like =
6722 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
6725 return (c ==
'.' or c ==
'e');
6728 if (value_is_int_like)
6730 o->write_characters(
".0", 2);
6754 static void decode(uint8_t& state,
const uint8_t byte)
6756 static const std::array<uint8_t, 400> utf8d =
6759 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,
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 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,
6764 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,
6765 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,
6766 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
6767 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
6768 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
6769 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,
6770 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,
6771 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,
6772 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
6776 const uint8_t type = utf8d[byte];
6777 state = utf8d[256u + state * 16u + type];
6788 static void throw_if_invalid_utf8(
const std::string& str)
6793 for (size_t i = 0; i < str.size(); ++i)
6795 const auto byte =
static_cast<uint8_t>(str[i]);
6796 decode(state, byte);
6800 std::stringstream ss;
6801 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex <<
static_cast<
int>(byte);
6802 JSON_THROW(type_error::create(316,
"invalid UTF-8 byte at index " + std::to_string(i) +
": 0x" + ss.str()));
6809 std::stringstream ss;
6810 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex <<
static_cast<
int>(
static_cast<uint8_t>(str.back()));
6811 JSON_THROW(type_error::create(316,
"incomplete UTF-8 string; last byte: 0x" + ss.str()));
6817 output_adapter_t<
char> o =
nullptr;
6820 std::array<
char, 64> number_buffer{{}};
6823 const std::lconv* loc =
nullptr;
6825 const char thousands_sep =
'\0';
6827 const char decimal_point =
'\0';
6830 const char indent_char;
6833 string_t indent_string;
6836 template<
typename BasicJsonType>
6840 using value_type = BasicJsonType;
6842 json_ref(value_type&& value)
6843 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(
true)
6846 json_ref(
const value_type& value)
6847 : value_ref(
const_cast<value_type*>(&value)), is_rvalue(
false)
6850 json_ref(std::initializer_list<json_ref> init)
6851 : owned_value(init), value_ref(&owned_value), is_rvalue(
true)
6854 template<
class... Args>
6855 json_ref(Args&& ... args)
6856 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value), is_rvalue(
true)
6860 json_ref(json_ref&&) =
default;
6861 json_ref(
const json_ref&) =
delete;
6862 json_ref& operator=(
const json_ref&) =
delete;
6864 value_type moved_or_copied()
const 6868 return std::move(*value_ref);
6873 value_type
const& operator*()
const 6875 return *
static_cast<value_type
const*>(value_ref);
6878 value_type
const* operator->()
const 6880 return static_cast<value_type
const*>(value_ref);
6884 mutable value_type owned_value =
nullptr;
6885 value_type* value_ref =
nullptr;
6886 const bool is_rvalue;
6894 constexpr const auto&
to_json = detail::static_const<detail::to_json_fn>::value;
6895 constexpr const auto&
from_json = detail::static_const<detail::from_json_fn>::value;
6906 template<
typename,
typename>
6907 struct adl_serializer
6918 template<
typename BasicJsonType,
typename ValueType>
6919 static void from_json(BasicJsonType&& j, ValueType& val)
noexcept(
6934 template<
typename BasicJsonType,
typename ValueType>
6935 static void to_json(BasicJsonType& j, ValueType&& val)
noexcept(
6981 explicit json_pointer(
const std::string& s =
"") : reference_tokens(split(s)) {}
6998 std::string to_string()
const noexcept 7000 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
7002 [](
const std::string & a,
const std::string & b)
7004 return a +
"/" + escape(b);
7009 operator std::string()
const 7019 std::string pop_back()
7023 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
7026 auto last = reference_tokens.back();
7027 reference_tokens.pop_back();
7032 bool is_root()
const 7034 return reference_tokens.empty();
7041 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
7045 result.reference_tokens = {reference_tokens[0]};
7126 static std::vector<std::string> split(
const std::string& reference_string)
7128 std::vector<std::string> result;
7131 if (reference_string.empty())
7139 JSON_THROW(detail::parse_error::create(107, 1,
7140 "JSON pointer must be empty or begin with '/' - was: '" +
7141 reference_string +
"'"));
7149 std::size_t slash = reference_string.find_first_of(
'/', 1),
7158 slash = reference_string.find_first_of(
'/', start))
7162 auto reference_token = reference_string.substr(start, slash - start);
7165 for (std::size_t pos = reference_token.find_first_of(
'~');
7166 pos != std::string::npos;
7167 pos = reference_token.find_first_of(
'~', pos + 1))
7169 assert(reference_token[pos] ==
'~');
7173 (reference_token[pos + 1] !=
'0' and 7174 reference_token[pos + 1] !=
'1')))
7176 JSON_THROW(detail::parse_error::create(108, 0,
"escape character '~' must be followed with '0' or '1'"));
7181 unescape(reference_token);
7182 result.push_back(reference_token);
7201 static void replace_substring(std::string& s,
const std::string& f,
7202 const std::string& t)
7204 assert(
not f.empty());
7205 for (
auto pos = s.find(f);
7206 pos != std::string::npos;
7207 s.replace(pos, f.size(), t),
7208 pos = s.find(f, pos + t.size()))
7213 static std::string escape(std::string s)
7215 replace_substring(s,
"~",
"~0");
7216 replace_substring(s,
"/",
"~1");
7221 static void unescape(std::string& s)
7223 replace_substring(s,
"~1",
"/");
7224 replace_substring(s,
"~0",
"~");
7235 static void flatten(
const std::string& reference_string,
7260 std::vector<std::string> reference_tokens;
7348 template<detail::value_t>
friend struct detail::external_constructor;
7352 template<
typename BasicJsonType>
7354 template<
typename BasicJsonType,
typename CharType>
7355 friend class ::
nlohmann::detail::binary_writer;
7356 template<
typename BasicJsonType>
7357 friend class ::
nlohmann::detail::binary_reader;
7366 using primitive_iterator_t = ::
nlohmann::detail::primitive_iterator_t;
7367 template<
typename BasicJsonType>
7368 using internal_iterator = ::
nlohmann::detail::internal_iterator<BasicJsonType>;
7369 template<
typename BasicJsonType>
7370 using iter_impl = ::
nlohmann::detail::iter_impl<BasicJsonType>;
7371 template<
typename Iterator>
7372 using iteration_proxy = ::
nlohmann::detail::iteration_proxy<Iterator>;
7373 template<
typename Base>
using json_reverse_iterator = ::
nlohmann::detail::json_reverse_iterator<Base>;
7375 template<
typename CharType>
7376 using output_adapter_t = ::
nlohmann::detail::output_adapter_t<CharType>;
7379 template<
typename CharType>
using binary_writer = ::
nlohmann::detail::binary_writer<
basic_json, CharType>;
7384 using value_t = detail::value_t;
7387 template<
typename T,
typename SFINAE>
7388 using json_serializer = JSONSerializer<T, SFINAE>;
7390 using initializer_list_t = std::initializer_list<detail::json_ref<
basic_json>>;
7401 using exception = detail::exception;
7403 using parse_error = detail::parse_error;
7405 using invalid_iterator = detail::invalid_iterator;
7407 using type_error = detail::type_error;
7409 using out_of_range = detail::out_of_range;
7411 using other_error = detail::other_error;
7429 using reference = value_type&;
7431 using const_reference =
const value_type&;
7434 using difference_type = std::ptrdiff_t;
7436 using size_type = std::size_t;
7442 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
7444 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
7451 using reverse_iterator = json_reverse_iterator<
typename basic_json::iterator>;
7453 using const_reverse_iterator = json_reverse_iterator<
typename basic_json::const_iterator>;
7461 static allocator_type get_allocator()
7463 return allocator_type();
7496 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
7497 result[
"name"] =
"JSON for Modern C++";
7498 result[
"url"] =
"https://github.com/nlohmann/json";
7501 {
"string",
"3.0.0"}, {
"major", 3}, {
"minor", 0}, {
"patch", 0}
7505 result[
"platform"] =
"win32";
7506 #elif defined __linux__ 7507 result[
"platform"] =
"linux";
7508 #elif defined __APPLE__
7509 result[
"platform"] =
"apple";
7510 #elif defined __unix__ 7511 result[
"platform"] =
"unix";
7513 result[
"platform"] =
"unknown";
7516 #if defined(__ICC) || defined(__INTEL_COMPILER) 7517 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
7518 #elif defined(__clang__
) 7519 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
7520 #elif defined(__GNUC__) || defined(__GNUG__) 7521 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(__GNUC_PATCHLEVEL__)}};
7522 #elif defined(__HP_cc) || defined(__HP_aCC) 7523 result[
"compiler"] =
"hp" 7524 #elif defined(__IBMCPP__) 7525 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
7526 #elif defined(_MSC_VER) 7527 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
7528 #elif defined(__PGI) 7529 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
7530 #elif defined(__SUNPRO_CC) 7531 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
7533 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
7537 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
7539 result[
"compiler"][
"c++"] =
"unknown";
7554 #if defined(JSON_HAS_CPP_14) 7559 using object_comparator_t = std::less<StringType>;
7645 using object_t = ObjectType<StringType,
7647 object_comparator_t,
7648 AllocatorType<std::pair<
const StringType,
7748 using string_t = StringType;
7774 using boolean_t = BooleanType;
7846 using number_integer_t = NumberIntegerType;
7917 using number_unsigned_t = NumberUnsignedType;
7985 using number_float_t = NumberFloatType;
7992 template<
typename T,
typename... Args>
7993 static T* create(Args&& ... args)
7995 AllocatorType<T> alloc;
7996 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
7998 auto deleter = [&](T * object)
8000 AllocatorTraits::deallocate(alloc, object, 1);
8002 std::unique_ptr<T,
decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
8003 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
8004 assert(object !=
nullptr);
8005 return object.release();
8047 number_integer_t number_integer;
8049 number_unsigned_t number_unsigned;
8051 number_float_t number_float;
8054 json_value() =
default;
8056 json_value(boolean_t v)
noexcept : boolean(v) {}
8058 json_value(number_integer_t v)
noexcept : number_integer(v) {}
8060 json_value(number_unsigned_t v)
noexcept : number_unsigned(v) {}
8062 json_value(number_float_t v)
noexcept : number_float(v) {}
8064 json_value(value_t t)
8068 case value_t::object:
8070 object = create<object_t>();
8074 case value_t::array:
8076 array = create<array_t>();
8080 case value_t::string:
8082 string = create<string_t>(
"");
8086 case value_t::boolean:
8088 boolean = boolean_t(
false);
8092 case value_t::number_integer:
8094 number_integer = number_integer_t(0);
8098 case value_t::number_unsigned:
8100 number_unsigned = number_unsigned_t(0);
8104 case value_t::number_float:
8106 number_float = number_float_t(0.0);
8121 JSON_THROW(other_error::create(500,
"961c151d2e87f2686a955a9be24d316f1362bf21 3.0.0"));
8129 json_value(
const string_t& value)
8131 string = create<string_t>(value);
8135 json_value(string_t&& value)
8137 string = create<string_t>(std::move(value));
8141 json_value(
const object_t& value)
8143 object = create<object_t>(value);
8147 json_value(object_t&& value)
8149 object = create<object_t>(std::move(value));
8153 json_value(
const array_t& value)
8155 array = create<array_t>(value);
8159 json_value(array_t&& value)
8161 array = create<array_t>(std::move(value));
8164 void destroy(value_t t)
8168 case value_t::object:
8170 AllocatorType<object_t> alloc;
8171 std::allocator_traits<
decltype(alloc)>::destroy(alloc, object);
8172 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, object, 1);
8176 case value_t::array:
8178 AllocatorType<array_t> alloc;
8179 std::allocator_traits<
decltype(alloc)>::destroy(alloc, array);
8180 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, array, 1);
8184 case value_t::string:
8186 AllocatorType<string_t> alloc;
8187 std::allocator_traits<
decltype(alloc)>::destroy(alloc, string);
8188 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, string, 1);
8209 void assert_invariant()
const 8211 assert(m_type != value_t::object
or m_value.object !=
nullptr);
8212 assert(m_type != value_t::array
or m_value.array !=
nullptr);
8213 assert(m_type != value_t::string
or m_value.string !=
nullptr);
8236 using parse_event_t =
typename parser::parse_event_t;
8287 using parser_callback_t =
typename parser::parser_callback_t;
8328 basic_json(
const value_t v)
8329 : m_type(v), m_value(v)
8352 basic_json(std::nullptr_t =
nullptr)
noexcept 8414 template<
typename CompatibleType,
typename U = detail::uncvref_t<CompatibleType>,
8415 detail::enable_if_t<
not std::is_base_of<std::istream, U>::value
and 8416 not std::is_same<U, basic_json_t>::value
and 8417 not detail::is_basic_json_nested_type<
8418 basic_json_t, U>::value
and 8421 basic_json(CompatibleType && val)
noexcept(
noexcept(JSONSerializer<U>::to_json(
8422 std::declval<basic_json_t&>(), std::forward<CompatibleType>(val))))
8424 JSONSerializer<U>::to_json(*
this, std::forward<CompatibleType>(val));
8502 basic_json(initializer_list_t init,
8503 bool type_deduction =
true,
8504 value_t manual_type = value_t::array)
8508 bool is_an_object = std::all_of(init.begin(), init.end(),
8509 [](
const detail::json_ref<
basic_json>& element_ref)
8511 return (element_ref->is_array()
and element_ref->size() == 2
and (*element_ref)[0].is_string());
8515 if (
not type_deduction)
8518 if (manual_type == value_t::array)
8520 is_an_object =
false;
8524 if (
JSON_UNLIKELY(manual_type == value_t::object
and not is_an_object))
8526 JSON_THROW(type_error::create(301,
"cannot create object from initializer list"));
8533 m_type = value_t::object;
8534 m_value = value_t::object;
8536 std::for_each(init.begin(), init.end(), [
this](
const detail::json_ref<
basic_json>& element_ref)
8538 auto element = element_ref.moved_or_copied();
8539 m_value.object->emplace(
8540 std::move(*((*element.m_value.array)[0].m_value.string)),
8541 std::move((*element.m_value.array)[1]));
8547 m_type = value_t::array;
8548 m_value.array = create<array_t>(init.begin(), init.end());
8591 static basic_json array(initializer_list_t init = {})
8593 return basic_json(init,
false, value_t::array);
8634 static basic_json object(initializer_list_t init = {})
8636 return basic_json(init,
false, value_t::object);
8661 basic_json(size_type cnt,
const basic_json& val)
8662 : m_type(value_t::array)
8664 m_value.array = create<array_t>(cnt, val);
8723 template<
class InputIT,
typename std::enable_if<
8724 std::is_same<InputIT,
typename basic_json_t::iterator>::value
or 8725 std::is_same<InputIT,
typename basic_json_t::const_iterator>::value,
int>::type = 0>
8726 basic_json(InputIT first, InputIT last)
8728 assert(first.m_object !=
nullptr);
8729 assert(last.m_object !=
nullptr);
8734 JSON_THROW(invalid_iterator::create(201,
"iterators are not compatible"));
8738 m_type = first.m_object->m_type;
8743 case value_t::boolean:
8744 case value_t::number_float:
8745 case value_t::number_integer:
8746 case value_t::number_unsigned:
8747 case value_t::string:
8749 if (
JSON_UNLIKELY(
not first.m_it.primitive_iterator.is_begin()
8750 or not last.m_it.primitive_iterator.is_end()))
8752 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
8763 case value_t::number_integer:
8765 m_value.number_integer = first.m_object->m_value.number_integer;
8769 case value_t::number_unsigned:
8771 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
8775 case value_t::number_float:
8777 m_value.number_float = first.m_object->m_value.number_float;
8781 case value_t::boolean:
8783 m_value.boolean = first.m_object->m_value.boolean;
8787 case value_t::string:
8789 m_value = *first.m_object->m_value.string;
8793 case value_t::object:
8795 m_value.object = create<object_t>(first.m_it.object_iterator,
8796 last.m_it.object_iterator);
8800 case value_t::array:
8802 m_value.array = create<array_t>(first.m_it.array_iterator,
8803 last.m_it.array_iterator);
8808 JSON_THROW(invalid_iterator::create(206,
"cannot construct with iterators from " +
8809 std::string(first.m_object->type_name())));
8821 basic_json(
const detail::json_ref<
basic_json>& ref)
8851 : m_type(other.m_type)
8854 other.assert_invariant();
8858 case value_t::object:
8860 m_value = *other.m_value.object;
8864 case value_t::array:
8866 m_value = *other.m_value.array;
8870 case value_t::string:
8872 m_value = *other.m_value.string;
8876 case value_t::boolean:
8878 m_value = other.m_value.boolean;
8882 case value_t::number_integer:
8884 m_value = other.m_value.number_integer;
8888 case value_t::number_unsigned:
8890 m_value = other.m_value.number_unsigned;
8894 case value_t::number_float:
8896 m_value = other.m_value.number_float;
8934 : m_type(std::move(other.m_type)),
8935 m_value(std::move(other.m_value))
8938 other.assert_invariant();
8941 other.m_type = value_t::null;
8970 reference& operator=(
basic_json other)
noexcept (
8971 std::is_nothrow_move_constructible<value_t>::value
and 8972 std::is_nothrow_move_assignable<value_t>::value
and 8973 std::is_nothrow_move_constructible<json_value>::value
and 8974 std::is_nothrow_move_assignable<json_value>::value
8978 other.assert_invariant();
8981 swap(m_type, other.m_type);
8982 swap(m_value, other.m_value);
9006 m_value.destroy(m_type);
9056 string_t dump(
const int indent = -1,
const char indent_char =
' ',
9057 const bool ensure_ascii =
false)
const 9060 serializer s(detail::output_adapter<
char>(result), indent_char);
9064 s.dump(*
this,
true, ensure_ascii,
static_cast<
unsigned int>(indent));
9068 s.dump(*
this,
false, ensure_ascii, 0);
9106 constexpr value_t type()
const noexcept 9136 constexpr bool is_primitive()
const noexcept 9138 return is_null()
or is_string()
or is_boolean()
or is_number();
9163 constexpr bool is_structured()
const noexcept 9165 return is_array()
or is_object();
9185 constexpr bool is_null()
const noexcept 9187 return (m_type == value_t::null);
9207 constexpr bool is_boolean()
const noexcept 9209 return (m_type == value_t::boolean);
9237 constexpr bool is_number()
const noexcept 9239 return is_number_integer()
or is_number_float();
9266 constexpr bool is_number_integer()
const noexcept 9268 return (m_type == value_t::number_integer
or m_type == value_t::number_unsigned);
9294 constexpr bool is_number_unsigned()
const noexcept 9296 return (m_type == value_t::number_unsigned);
9322 constexpr bool is_number_float()
const noexcept 9324 return (m_type == value_t::number_float);
9344 constexpr bool is_object()
const noexcept 9346 return (m_type == value_t::object);
9366 constexpr bool is_array()
const noexcept 9368 return (m_type == value_t::array);
9388 constexpr bool is_string()
const noexcept 9390 return (m_type == value_t::string);
9415 constexpr bool is_discarded()
const noexcept 9417 return (m_type == value_t::discarded);
9441 constexpr operator value_t()
const noexcept 9454 boolean_t get_impl(boolean_t* )
const 9458 return m_value.boolean;
9461 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(type_name())));
9465 object_t* get_impl_ptr(object_t* )
noexcept 9467 return is_object() ? m_value.object :
nullptr;
9471 constexpr const object_t* get_impl_ptr(
const object_t* )
const noexcept 9473 return is_object() ? m_value.object :
nullptr;
9477 array_t* get_impl_ptr(array_t* )
noexcept 9479 return is_array() ? m_value.array :
nullptr;
9483 constexpr const array_t* get_impl_ptr(
const array_t* )
const noexcept 9485 return is_array() ? m_value.array :
nullptr;
9489 string_t* get_impl_ptr(string_t* )
noexcept 9491 return is_string() ? m_value.string :
nullptr;
9495 constexpr const string_t* get_impl_ptr(
const string_t* )
const noexcept 9497 return is_string() ? m_value.string :
nullptr;
9501 boolean_t* get_impl_ptr(boolean_t* )
noexcept 9503 return is_boolean() ? &m_value.boolean :
nullptr;
9507 constexpr const boolean_t* get_impl_ptr(
const boolean_t* )
const noexcept 9509 return is_boolean() ? &m_value.boolean :
nullptr;
9513 number_integer_t* get_impl_ptr(number_integer_t* )
noexcept 9515 return is_number_integer() ? &m_value.number_integer :
nullptr;
9519 constexpr const number_integer_t* get_impl_ptr(
const number_integer_t* )
const noexcept 9521 return is_number_integer() ? &m_value.number_integer :
nullptr;
9525 number_unsigned_t* get_impl_ptr(number_unsigned_t* )
noexcept 9527 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
9531 constexpr const number_unsigned_t* get_impl_ptr(
const number_unsigned_t* )
const noexcept 9533 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
9537 number_float_t* get_impl_ptr(number_float_t* )
noexcept 9539 return is_number_float() ? &m_value.number_float :
nullptr;
9543 constexpr const number_float_t* get_impl_ptr(
const number_float_t* )
const noexcept 9545 return is_number_float() ? &m_value.number_float :
nullptr;
9559 template<
typename ReferenceType,
typename ThisType>
9560 static ReferenceType get_ref_impl(ThisType& obj)
9563 auto ptr = obj.
template get_ptr<
typename std::add_pointer<ReferenceType>::type>();
9570 JSON_THROW(type_error::create(303,
"incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
9592 template<
typename BasicJsonType, detail::enable_if_t<
9593 std::is_same<
typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
9639 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
9640 detail::enable_if_t <
9641 not std::is_same<basic_json_t, ValueType>::value
and 9642 detail::has_from_json<basic_json_t, ValueType>::value
and 9643 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
9645 ValueType get()
const noexcept(
noexcept(
9646 JSONSerializer<ValueType>::from_json(std::declval<
const basic_json_t&>(), std::declval<ValueType&>())))
9651 static_assert(
not std::is_reference<ValueTypeCV>::value,
9652 "get() cannot be used with reference types, you might want to use get_ref()");
9653 static_assert(std::is_default_constructible<ValueType>::value,
9654 "types must be DefaultConstructible when used with get()");
9657 JSONSerializer<ValueType>::from_json(*
this, ret);
9692 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
9693 detail::enable_if_t<
not std::is_same<basic_json_t, ValueType>::value
and 9694 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
9696 ValueType get()
const noexcept(
noexcept(
9697 JSONSerializer<ValueTypeCV>::from_json(std::declval<
const basic_json_t&>())))
9699 static_assert(
not std::is_reference<ValueTypeCV>::value,
9700 "get() cannot be used with reference types, you might want to use get_ref()");
9701 return JSONSerializer<ValueTypeCV>::from_json(*
this);
9731 template<
typename PointerType,
typename std::enable_if<
9732 std::is_pointer<PointerType>::value,
int>::type = 0>
9733 PointerType get()
noexcept 9736 return get_ptr<PointerType>();
9743 template<
typename PointerType,
typename std::enable_if<
9744 std::is_pointer<PointerType>::value,
int>::type = 0>
9745 constexpr const PointerType get()
const noexcept 9748 return get_ptr<PointerType>();
9777 template<
typename PointerType,
typename std::enable_if<
9778 std::is_pointer<PointerType>::value,
int>::type = 0>
9779 PointerType get_ptr()
noexcept 9782 using pointee_t =
typename std::remove_const<
typename 9783 std::remove_pointer<
typename 9784 std::remove_const<PointerType>::type>::type>::type;
9787 std::is_same<object_t, pointee_t>::value
9788 or std::is_same<array_t, pointee_t>::value
9789 or std::is_same<string_t, pointee_t>::value
9790 or std::is_same<boolean_t, pointee_t>::value
9791 or std::is_same<number_integer_t, pointee_t>::value
9792 or std::is_same<number_unsigned_t, pointee_t>::value
9793 or std::is_same<number_float_t, pointee_t>::value
9794 ,
"incompatible pointer type");
9797 return get_impl_ptr(
static_cast<PointerType>(
nullptr));
9804 template<
typename PointerType,
typename std::enable_if<
9805 std::is_pointer<PointerType>::value
and 9806 std::is_const<
typename std::remove_pointer<PointerType>::type>::value,
int>::type = 0>
9807 constexpr const PointerType get_ptr()
const noexcept 9810 using pointee_t =
typename std::remove_const<
typename 9811 std::remove_pointer<
typename 9812 std::remove_const<PointerType>::type>::type>::type;
9815 std::is_same<object_t, pointee_t>::value
9816 or std::is_same<array_t, pointee_t>::value
9817 or std::is_same<string_t, pointee_t>::value
9818 or std::is_same<boolean_t, pointee_t>::value
9819 or std::is_same<number_integer_t, pointee_t>::value
9820 or std::is_same<number_unsigned_t, pointee_t>::value
9821 or std::is_same<number_float_t, pointee_t>::value
9822 ,
"incompatible pointer type");
9825 return get_impl_ptr(
static_cast<PointerType>(
nullptr));
9854 template<
typename ReferenceType,
typename std::enable_if<
9855 std::is_reference<ReferenceType>::value,
int>::type = 0>
9856 ReferenceType get_ref()
9859 return get_ref_impl<ReferenceType>(*
this);
9866 template<
typename ReferenceType,
typename std::enable_if<
9867 std::is_reference<ReferenceType>::value
and 9868 std::is_const<
typename std::remove_reference<ReferenceType>::type>::value,
int>::type = 0>
9869 ReferenceType get_ref()
const 9872 return get_ref_impl<ReferenceType>(*
this);
9904 template <
typename ValueType,
typename std::enable_if <
9905 not std::is_pointer<ValueType>::value
and 9906 not std::is_same<ValueType, detail::json_ref<
basic_json>>::value
and 9907 not std::is_same<ValueType,
typename string_t::value_type>::value
9909 and not std::is_same<ValueType, std::initializer_list<
typename string_t::value_type>>::value
9911 #if defined(JSON_HAS_CPP_17) 9912 and not std::is_same<ValueType,
typename std::string_view>::value
9915 operator ValueType()
const 9918 return get<ValueType>();
9958 reference at(size_type idx)
9965 return m_value.array->at(idx);
9970 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
9975 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
10005 const_reference at(size_type idx)
const 10012 return m_value.array->at(idx);
10017 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
10022 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
10056 reference at(
const typename object_t::key_type& key)
10063 return m_value.object->at(key);
10068 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
10073 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
10107 const_reference at(
const typename object_t::key_type& key)
const 10114 return m_value.object->at(key);
10119 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
10124 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
10153 reference operator[](size_type idx)
10158 m_type = value_t::array;
10159 m_value.array = create<array_t>();
10160 assert_invariant();
10167 if (idx >= m_value.array->size())
10169 m_value.array->insert(m_value.array->end(),
10170 idx - m_value.array->size() + 1,
10174 return m_value.array->operator[](idx);
10177 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10199 const_reference operator[](size_type idx)
const 10204 return m_value.array->operator[](idx);
10207 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10237 reference operator[](
const typename object_t::key_type& key)
10242 m_type = value_t::object;
10243 m_value.object = create<object_t>();
10244 assert_invariant();
10250 return m_value.object->operator[](key);
10253 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10286 const_reference operator[](
const typename object_t::key_type& key)
const 10291 assert(m_value.object->find(key) != m_value.object->end());
10292 return m_value.object->find(key)->second;
10295 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10325 template<
typename T>
10326 reference operator[](T* key)
10331 m_type = value_t::object;
10332 m_value = value_t::object;
10333 assert_invariant();
10339 return m_value.object->operator[](key);
10342 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10375 template<
typename T>
10376 const_reference operator[](T* key)
const 10381 assert(m_value.object->find(key) != m_value.object->end());
10382 return m_value.object->find(key)->second;
10385 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10436 template<
class ValueType,
typename std::enable_if<
10437 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
10438 ValueType value(
const typename object_t::key_type& key,
const ValueType& default_value)
const 10444 const auto it = find(key);
10450 return default_value;
10453 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
10460 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 10462 return value(key, string_t(default_value));
10506 template<
class ValueType,
typename std::enable_if<
10507 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
10508 ValueType value(
const json_pointer& ptr,
const ValueType& default_value)
const 10516 return ptr.get_checked(
this);
10520 return default_value;
10524 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
10531 string_t value(
const json_pointer& ptr,
const char* default_value)
const 10533 return value(ptr, string_t(default_value));
10569 const_reference front()
const 10615 const_reference back()
const 10668 template<
class IteratorType,
typename std::enable_if<
10669 std::is_same<IteratorType,
typename basic_json_t::iterator>::value
or 10670 std::is_same<IteratorType,
typename basic_json_t::const_iterator>::value,
int>::type
10672 IteratorType erase(IteratorType pos)
10677 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
10680 IteratorType result = end();
10684 case value_t::boolean:
10685 case value_t::number_float:
10686 case value_t::number_integer:
10687 case value_t::number_unsigned:
10688 case value_t::string:
10690 if (
JSON_UNLIKELY(
not pos.m_it.primitive_iterator.is_begin()))
10692 JSON_THROW(invalid_iterator::create(205,
"iterator out of range"));
10697 AllocatorType<string_t> alloc;
10698 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_value.string);
10699 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_value.string, 1);
10700 m_value.string =
nullptr;
10703 m_type = value_t::null;
10704 assert_invariant();
10708 case value_t::object:
10710 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
10714 case value_t::array:
10716 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
10721 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
10773 template<
class IteratorType,
typename std::enable_if<
10774 std::is_same<IteratorType,
typename basic_json_t::iterator>::value
or 10775 std::is_same<IteratorType,
typename basic_json_t::const_iterator>::value,
int>::type
10777 IteratorType erase(IteratorType first, IteratorType last)
10780 if (
JSON_UNLIKELY(
this != first.m_object
or this != last.m_object))
10782 JSON_THROW(invalid_iterator::create(203,
"iterators do not fit current value"));
10785 IteratorType result = end();
10789 case value_t::boolean:
10790 case value_t::number_float:
10791 case value_t::number_integer:
10792 case value_t::number_unsigned:
10793 case value_t::string:
10795 if (
JSON_LIKELY(
not first.m_it.primitive_iterator.is_begin()
10796 or not last.m_it.primitive_iterator.is_end()))
10798 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
10803 AllocatorType<string_t> alloc;
10804 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_value.string);
10805 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_value.string, 1);
10806 m_value.string =
nullptr;
10809 m_type = value_t::null;
10810 assert_invariant();
10814 case value_t::object:
10816 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
10817 last.m_it.object_iterator);
10821 case value_t::array:
10823 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
10824 last.m_it.array_iterator);
10829 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
10864 size_type erase(
const typename object_t::key_type& key)
10869 return m_value.object->erase(key);
10872 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
10899 void erase(
const size_type idx)
10906 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
10909 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
10913 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
10949 template<
typename KeyT>
10950 iterator find(KeyT&& key)
10952 auto result = end();
10956 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
10966 template<
typename KeyT>
10967 const_iterator find(KeyT&& key)
const 10969 auto result = cend();
10973 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
11000 template<
typename KeyT>
11001 size_type count(KeyT&& key)
const 11004 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
11041 iterator begin()
noexcept 11043 iterator result(
this);
11044 result.set_begin();
11051 const_iterator begin()
const noexcept 11081 const_iterator cbegin()
const noexcept 11083 const_iterator result(
this);
11084 result.set_begin();
11112 iterator end()
noexcept 11114 iterator result(
this);
11122 const_iterator end()
const noexcept 11152 const_iterator cend()
const noexcept 11154 const_iterator result(
this);
11182 reverse_iterator rbegin()
noexcept 11184 return reverse_iterator(end());
11190 const_reverse_iterator rbegin()
const noexcept 11219 reverse_iterator rend()
noexcept 11221 return reverse_iterator(begin());
11227 const_reverse_iterator rend()
const noexcept 11256 const_reverse_iterator crbegin()
const noexcept 11258 return const_reverse_iterator(cend());
11285 const_reverse_iterator crend()
const noexcept 11287 return const_reverse_iterator(cbegin());
11344 static iteration_proxy<iterator> iterator_wrapper(reference ref)
11346 return iteration_proxy<iterator>(ref);
11352 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref)
11354 return iteration_proxy<const_iterator>(ref);
11408 bool empty()
const noexcept 11412 case value_t::null:
11418 case value_t::array:
11421 return m_value.array->empty();
11424 case value_t::object:
11427 return m_value.object->empty();
11480 size_type size()
const noexcept 11484 case value_t::null:
11490 case value_t::array:
11493 return m_value.array->size();
11496 case value_t::object:
11499 return m_value.object->size();
11550 size_type max_size()
const noexcept 11554 case value_t::array:
11557 return m_value.array->max_size();
11560 case value_t::object:
11563 return m_value.object->max_size();
11620 void clear()
noexcept 11624 case value_t::number_integer:
11626 m_value.number_integer = 0;
11630 case value_t::number_unsigned:
11632 m_value.number_unsigned = 0;
11636 case value_t::number_float:
11638 m_value.number_float = 0.0;
11642 case value_t::boolean:
11644 m_value.boolean =
false;
11648 case value_t::string:
11650 m_value.string->clear();
11654 case value_t::array:
11656 m_value.array->clear();
11660 case value_t::object:
11662 m_value.object->clear();
11696 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
11702 m_type = value_t::array;
11703 m_value = value_t::array;
11704 assert_invariant();
11708 m_value.array->push_back(std::move(val));
11710 val.m_type = value_t::null;
11719 push_back(std::move(val));
11732 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
11738 m_type = value_t::array;
11739 m_value = value_t::array;
11740 assert_invariant();
11744 m_value.array->push_back(val);
11777 void push_back(
const typename object_t::value_type& val)
11782 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
11788 m_type = value_t::object;
11789 m_value = value_t::object;
11790 assert_invariant();
11794 m_value.object->insert(val);
11801 reference operator+=(
const typename object_t::value_type& val)
11832 void push_back(initializer_list_t init)
11834 if (is_object()
and init.size() == 2
and (*init.begin())->is_string())
11836 basic_json&& key = init.begin()->moved_or_copied();
11837 push_back(
typename object_t::value_type(
11838 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
11850 reference operator+=(initializer_list_t init)
11877 template<
class... Args>
11878 void emplace_back(Args&& ... args)
11883 JSON_THROW(type_error::create(311,
"cannot use emplace_back() with " + std::string(type_name())));
11889 m_type = value_t::array;
11890 m_value = value_t::array;
11891 assert_invariant();
11895 m_value.array->emplace_back(std::forward<Args>(args)...);
11925 template<
class... Args>
11926 std::pair<iterator,
bool> emplace(Args&& ... args)
11931 JSON_THROW(type_error::create(311,
"cannot use emplace() with " + std::string(type_name())));
11937 m_type = value_t::object;
11938 m_value = value_t::object;
11939 assert_invariant();
11943 auto res = m_value.object->emplace(std::forward<Args>(args)...);
11946 it.m_it.object_iterator = res.first;
11949 return {it, res.second};
11974 iterator insert(const_iterator pos,
const basic_json& val)
11982 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
11986 iterator result(
this);
11987 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
11991 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
11998 iterator insert(const_iterator pos,
basic_json&& val)
12000 return insert(pos, val);
12027 iterator insert(const_iterator pos, size_type cnt,
const basic_json& val)
12035 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
12039 iterator result(
this);
12040 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
12044 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12077 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
12082 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12088 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
12094 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
12099 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container"));
12103 iterator result(
this);
12104 result.m_it.array_iterator = m_value.array->insert(
12105 pos.m_it.array_iterator,
12106 first.m_it.array_iterator,
12107 last.m_it.array_iterator);
12135 iterator insert(const_iterator pos, initializer_list_t ilist)
12140 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12146 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
12150 iterator result(
this);
12151 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
12178 void insert(const_iterator first, const_iterator last)
12183 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12189 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
12195 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
12198 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
12220 void update(const_reference j)
12225 m_type = value_t::object;
12226 m_value.object = create<object_t>();
12227 assert_invariant();
12232 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
12236 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(j.type_name())));
12239 for (
auto it = j.begin(); it != j.end(); ++it)
12241 m_value.object->operator[](it.key()) = it.value();
12271 void update(const_iterator first, const_iterator last)
12276 m_type = value_t::object;
12277 m_value.object = create<object_t>();
12278 assert_invariant();
12283 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
12289 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
12294 or not first.m_object->is_object()))
12296 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
12299 for (
auto it = first; it != last; ++it)
12301 m_value.object->operator[](it.key()) = it.value();
12322 void swap(reference other)
noexcept (
12323 std::is_nothrow_move_constructible<value_t>::value
and 12324 std::is_nothrow_move_assignable<value_t>::value
and 12325 std::is_nothrow_move_constructible<json_value>::value
and 12326 std::is_nothrow_move_assignable<json_value>::value
12329 std::swap(m_type, other.m_type);
12330 std::swap(m_value, other.m_value);
12331 assert_invariant();
12354 void swap(array_t& other)
12359 std::swap(*(m_value.array), other);
12363 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
12387 void swap(object_t& other)
12392 std::swap(*(m_value.object), other);
12396 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
12420 void swap(string_t& other)
12425 std::swap(*(m_value.string), other);
12429 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
12482 friend bool operator==(const_reference lhs, const_reference rhs)
noexcept 12484 const auto lhs_type = lhs.type();
12485 const auto rhs_type = rhs.type();
12487 if (lhs_type == rhs_type)
12491 case value_t::array:
12492 return (*lhs.m_value.array == *rhs.m_value.array);
12494 case value_t::object:
12495 return (*lhs.m_value.object == *rhs.m_value.object);
12497 case value_t::null:
12500 case value_t::string:
12501 return (*lhs.m_value.string == *rhs.m_value.string);
12503 case value_t::boolean:
12504 return (lhs.m_value.boolean == rhs.m_value.boolean);
12506 case value_t::number_integer:
12507 return (lhs.m_value.number_integer == rhs.m_value.number_integer);
12509 case value_t::number_unsigned:
12510 return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
12512 case value_t::number_float:
12513 return (lhs.m_value.number_float == rhs.m_value.number_float);
12519 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_float)
12521 return (
static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
12523 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_integer)
12525 return (lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer));
12527 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_float)
12529 return (
static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
12531 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_unsigned)
12533 return (lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned));
12535 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_integer)
12537 return (
static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
12539 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_unsigned)
12541 return (lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned));
12551 template<
typename ScalarType,
typename std::enable_if<
12552 std::is_scalar<ScalarType>::value,
int>::type = 0>
12553 friend bool operator==(const_reference lhs,
const ScalarType rhs)
noexcept 12562 template<
typename ScalarType,
typename std::enable_if<
12563 std::is_scalar<ScalarType>::value,
int>::type = 0>
12564 friend bool operator==(
const ScalarType lhs, const_reference rhs)
noexcept 12587 friend bool operator!=(const_reference lhs, const_reference rhs)
noexcept 12589 return not (lhs == rhs);
12596 template<
typename ScalarType,
typename std::enable_if<
12597 std::is_scalar<ScalarType>::value,
int>::type = 0>
12598 friend bool operator!=(const_reference lhs,
const ScalarType rhs)
noexcept 12607 template<
typename ScalarType,
typename std::enable_if<
12608 std::is_scalar<ScalarType>::value,
int>::type = 0>
12609 friend bool operator!=(
const ScalarType lhs, const_reference rhs)
noexcept 12640 friend bool operator<(const_reference lhs, const_reference rhs)
noexcept 12642 const auto lhs_type = lhs.type();
12643 const auto rhs_type = rhs.type();
12645 if (lhs_type == rhs_type)
12649 case value_t::array:
12650 return (*lhs.m_value.array) < (*rhs.m_value.array);
12652 case value_t::object:
12653 return *lhs.m_value.object < *rhs.m_value.object;
12655 case value_t::null:
12658 case value_t::string:
12659 return *lhs.m_value.string < *rhs.m_value.string;
12661 case value_t::boolean:
12662 return lhs.m_value.boolean < rhs.m_value.boolean;
12664 case value_t::number_integer:
12665 return lhs.m_value.number_integer < rhs.m_value.number_integer;
12667 case value_t::number_unsigned:
12668 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
12670 case value_t::number_float:
12671 return lhs.m_value.number_float < rhs.m_value.number_float;
12677 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_float)
12679 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
12681 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_integer)
12683 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
12685 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_float)
12687 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
12689 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_unsigned)
12691 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
12693 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_unsigned)
12695 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
12697 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_integer)
12699 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
12705 return operator<(lhs_type, rhs_type);
12712 template<
typename ScalarType,
typename std::enable_if<
12713 std::is_scalar<ScalarType>::value,
int>::type = 0>
12714 friend bool operator<(const_reference lhs,
const ScalarType rhs)
noexcept 12723 template<
typename ScalarType,
typename std::enable_if<
12724 std::is_scalar<ScalarType>::value,
int>::type = 0>
12725 friend bool operator<(
const ScalarType lhs, const_reference rhs)
noexcept 12749 friend bool operator<=(const_reference lhs, const_reference rhs)
noexcept 12751 return not (rhs < lhs);
12758 template<
typename ScalarType,
typename std::enable_if<
12759 std::is_scalar<ScalarType>::value,
int>::type = 0>
12760 friend bool operator<=(const_reference lhs,
const ScalarType rhs)
noexcept 12769 template<
typename ScalarType,
typename std::enable_if<
12770 std::is_scalar<ScalarType>::value,
int>::type = 0>
12771 friend bool operator<=(
const ScalarType lhs, const_reference rhs)
noexcept 12795 friend bool operator>(const_reference lhs, const_reference rhs)
noexcept 12797 return not (lhs <= rhs);
12804 template<
typename ScalarType,
typename std::enable_if<
12805 std::is_scalar<ScalarType>::value,
int>::type = 0>
12806 friend bool operator>(const_reference lhs,
const ScalarType rhs)
noexcept 12815 template<
typename ScalarType,
typename std::enable_if<
12816 std::is_scalar<ScalarType>::value,
int>::type = 0>
12817 friend bool operator>(
const ScalarType lhs, const_reference rhs)
noexcept 12841 friend bool operator>=(const_reference lhs, const_reference rhs)
noexcept 12843 return not (lhs < rhs);
12850 template<
typename ScalarType,
typename std::enable_if<
12851 std::is_scalar<ScalarType>::value,
int>::type = 0>
12852 friend bool operator>=(const_reference lhs,
const ScalarType rhs)
noexcept 12861 template<
typename ScalarType,
typename std::enable_if<
12862 std::is_scalar<ScalarType>::value,
int>::type = 0>
12863 friend bool operator>=(
const ScalarType lhs, const_reference rhs)
noexcept 12908 friend std::ostream& operator<<(std::ostream& o,
const basic_json& j)
12911 const bool pretty_print = (o.width() > 0);
12912 const auto indentation = (pretty_print ? o.width() : 0);
12918 serializer s(detail::output_adapter<
char>(o), o.fill());
12919 s.dump(j, pretty_print,
false,
static_cast<
unsigned int>(indentation));
12932 friend std::ostream& operator>>(
const basic_json& j, std::ostream& o)
13009 static basic_json parse(detail::input_adapter i,
13010 const parser_callback_t cb =
nullptr,
13011 const bool allow_exceptions =
true)
13014 parser(i, cb, allow_exceptions).parse(
true, result);
13021 static basic_json parse(detail::input_adapter& i,
13022 const parser_callback_t cb =
nullptr,
13023 const bool allow_exceptions =
true)
13026 parser(i, cb, allow_exceptions).parse(
true, result);
13030 static bool accept(detail::input_adapter i)
13032 return parser(i).accept(
true);
13035 static bool accept(detail::input_adapter& i)
13037 return parser(i).accept(
true);
13087 template<
class IteratorType,
typename std::enable_if<
13089 std::random_access_iterator_tag,
13090 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
13091 static basic_json parse(IteratorType first, IteratorType last,
13092 const parser_callback_t cb =
nullptr,
13093 const bool allow_exceptions =
true)
13096 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(
true, result);
13100 template<
class IteratorType,
typename std::enable_if<
13102 std::random_access_iterator_tag,
13103 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
13104 static bool accept(IteratorType first, IteratorType last)
13106 return parser(detail::input_adapter(first, last)).accept(
true);
13118 friend std::istream& operator<<(
basic_json& j, std::istream& i)
13120 return operator>>(i, j);
13148 friend std::istream& operator>>(std::istream& i,
basic_json& j)
13150 parser(detail::input_adapter(i)).parse(
false, j);
13190 const char* type_name()
const noexcept 13195 case value_t::null:
13197 case value_t::object:
13199 case value_t::array:
13201 case value_t::string:
13203 case value_t::boolean:
13205 case value_t::discarded:
13206 return "discarded";
13220 value_t m_type = value_t::null;
13223 json_value m_value = {};
13319 static std::vector<uint8_t> to_cbor(
const basic_json& j)
13321 std::vector<uint8_t> result;
13322 to_cbor(j, result);
13326 static void to_cbor(
const basic_json& j, detail::output_adapter<uint8_t> o)
13328 binary_writer<uint8_t>(o).write_cbor(j);
13331 static void to_cbor(
const basic_json& j, detail::output_adapter<
char> o)
13333 binary_writer<
char>(o).write_cbor(j);
13414 static std::vector<uint8_t> to_msgpack(
const basic_json& j)
13416 std::vector<uint8_t> result;
13417 to_msgpack(j, result);
13421 static void to_msgpack(
const basic_json& j, detail::output_adapter<uint8_t> o)
13423 binary_writer<uint8_t>(o).write_msgpack(j);
13426 static void to_msgpack(
const basic_json& j, detail::output_adapter<
char> o)
13428 binary_writer<
char>(o).write_msgpack(j);
13522 static basic_json from_cbor(detail::input_adapter i,
13523 const bool strict =
true)
13525 return binary_reader(i).parse_cbor(strict);
13531 template<
typename A1,
typename A2,
13532 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
13533 static basic_json from_cbor(A1 && a1, A2 && a2,
const bool strict =
true)
13535 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_cbor(strict);
13609 static basic_json from_msgpack(detail::input_adapter i,
13610 const bool strict =
true)
13612 return binary_reader(i).parse_msgpack(strict);
13618 template<
typename A1,
typename A2,
13619 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
13620 static basic_json from_msgpack(A1 && a1, A2 && a2,
const bool strict =
true)
13622 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_msgpack(strict);
13667 reference operator[](
const json_pointer& ptr)
13669 return ptr.get_unchecked(
this);
13695 const_reference operator[](
const json_pointer& ptr)
const 13697 return ptr.get_unchecked(
this);
13738 reference at(
const json_pointer& ptr)
13740 return ptr.get_checked(
this);
13781 const_reference at(
const json_pointer& ptr)
const 13783 return ptr.get_checked(
this);
13811 json_pointer::flatten(
"", *
this, result);
13847 return json_pointer::unflatten(*
this);
13912 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
13914 const auto get_op = [](
const std::string & op)
13918 return patch_operations::add;
13920 if (op ==
"remove")
13922 return patch_operations::remove;
13924 if (op ==
"replace")
13926 return patch_operations::replace;
13930 return patch_operations::move;
13934 return patch_operations::copy;
13938 return patch_operations::test;
13941 return patch_operations::invalid;
13945 const auto operation_add = [&result](json_pointer & ptr,
basic_json val)
13955 json_pointer top_pointer = ptr.top();
13956 if (top_pointer != ptr)
13958 result.at(top_pointer);
13962 const auto last_path = ptr.pop_back();
13965 switch (parent.m_type)
13967 case value_t::null:
13968 case value_t::object:
13971 parent[last_path] = val;
13975 case value_t::array:
13977 if (last_path ==
"-")
13980 parent.push_back(val);
13984 const auto idx = std::stoi(last_path);
13985 if (
JSON_UNLIKELY(
static_cast<size_type>(idx) > parent.size()))
13988 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
13993 parent.insert(parent.begin() +
static_cast<difference_type>(idx), val);
14009 const auto operation_remove = [&result](json_pointer & ptr)
14012 const auto last_path = ptr.pop_back();
14016 if (parent.is_object())
14019 auto it = parent.find(last_path);
14026 JSON_THROW(out_of_range::create(403,
"key '" + last_path +
"' not found"));
14029 else if (parent.is_array())
14032 parent.erase(
static_cast<size_type>(std::stoi(last_path)));
14039 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
14043 for (
const auto& val : json_patch)
14046 const auto get_value = [&val](
const std::string & op,
14047 const std::string & member,
14051 auto it = val.m_value.object->find(member);
14054 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
14059 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have member '" + member +
"'"));
14063 if (
JSON_UNLIKELY(string_type
and not it->second.is_string()))
14065 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have string member '" + member +
"'"));
14075 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
14079 const std::string op = get_value(
"op",
"op",
true);
14080 const std::string path = get_value(op,
"path",
true);
14081 json_pointer ptr
(path
);
14083 switch (get_op(op))
14085 case patch_operations::add:
14087 operation_add(ptr, get_value(
"add",
"value",
false));
14091 case patch_operations::remove:
14093 operation_remove(ptr);
14097 case patch_operations::replace:
14100 result.at(ptr) = get_value(
"replace",
"value",
false);
14104 case patch_operations::move:
14106 const std::string from_path = get_value(
"move",
"from",
true);
14107 json_pointer from_ptr
(from_path
);
14116 operation_remove(from_ptr);
14117 operation_add(ptr, v);
14121 case patch_operations::copy:
14123 const std::string from_path = get_value(
"copy",
"from",
true);
14124 const json_pointer from_ptr
(from_path
);
14127 result[ptr] = result.at(from_ptr);
14131 case patch_operations::test:
14133 bool success =
false;
14138 success = (result.at(ptr) == get_value(
"test",
"value",
false));
14148 JSON_THROW(other_error::create(501,
"unsuccessful: " + val.dump()));
14154 case patch_operations::invalid:
14158 JSON_THROW(parse_error::create(105, 0,
"operation value '" + op +
"' is invalid"));
14199 const std::string& path =
"")
14205 if (source == target)
14210 if (source.type() != target.type())
14215 {
"op",
"replace"}, {
"path", path}, {
"value", target}
14220 switch (source.type())
14222 case value_t::array:
14226 while (i < source.size()
and i < target.size())
14229 auto temp_diff = diff(source[i], target[i], path +
"/" + std::to_string(i));
14230 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
14238 const auto end_index =
static_cast<difference_type>(result.size());
14239 while (i < source.size())
14243 result.insert(result.begin() + end_index, object(
14246 {
"path", path +
"/" + std::to_string(i)}
14252 while (i < target.size())
14257 {
"path", path +
"/" + std::to_string(i)},
14258 {
"value", target[i]}
14266 case value_t::object:
14269 for (
auto it = source.begin(); it != source.end(); ++it)
14272 const auto key = json_pointer::escape(it.key());
14274 if (target.find(it.key()) != target.end())
14277 auto temp_diff = diff(it.value(), target[it.key()], path +
"/" + key);
14278 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
14283 result.push_back(object(
14285 {
"op",
"remove"}, {
"path", path +
"/" + key}
14291 for (
auto it = target.begin(); it != target.end(); ++it)
14293 if (source.find(it.key()) == source.end())
14296 const auto key = json_pointer::escape(it.key());
14299 {
"op",
"add"}, {
"path", path +
"/" + key},
14300 {
"value", it.value()}
14313 {
"op",
"replace"}, {
"path", path}, {
"value", target}
14353 for (
const auto& reference_token : reference_tokens)
14355 switch (result->m_type)
14357 case detail::value_t::null:
14359 if (reference_token ==
"0")
14362 result = &result->operator[](0);
14367 result = &result->operator[](reference_token);
14372 case detail::value_t::object:
14375 result = &result->operator[](reference_token);
14379 case detail::value_t::array:
14384 result = &result->operator[](
static_cast<size_type>(std::stoi(reference_token)));
14388 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14400 JSON_THROW(detail::type_error::create(313,
"invalid value to unflatten"));
14412 for (
const auto& reference_token : reference_tokens)
14415 if (ptr->m_type == detail::value_t::null)
14419 std::all_of(reference_token.begin(), reference_token.end(),
14422 return (x >=
'0' and x <=
'9');
14426 *ptr = (nums
or reference_token ==
"-")
14427 ? detail::value_t::array
14428 : detail::value_t::object;
14431 switch (ptr->m_type)
14433 case detail::value_t::object:
14436 ptr = &ptr->operator[](reference_token);
14440 case detail::value_t::array:
14443 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
14445 JSON_THROW(detail::parse_error::create(106, 0,
14446 "array index '" + reference_token +
14447 "' must not begin with '0'"));
14450 if (reference_token ==
"-")
14453 ptr = &ptr->operator[](ptr->m_value.array->size());
14460 ptr = &ptr->operator[](
14461 static_cast<size_type>(std::stoi(reference_token)));
14465 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14472 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
14484 for (
const auto& reference_token : reference_tokens)
14486 switch (ptr->m_type)
14488 case detail::value_t::object:
14491 ptr = &ptr->at(reference_token);
14495 case detail::value_t::array:
14500 JSON_THROW(detail::out_of_range::create(402,
14501 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
14502 ") is out of range"));
14506 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
14508 JSON_THROW(detail::parse_error::create(106, 0,
14509 "array index '" + reference_token +
14510 "' must not begin with '0'"));
14516 ptr = &ptr->at(
static_cast<size_type>(std::stoi(reference_token)));
14520 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14526 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
14538 for (
const auto& reference_token : reference_tokens)
14540 switch (ptr->m_type)
14542 case detail::value_t::object:
14545 ptr = &ptr->operator[](reference_token);
14549 case detail::value_t::array:
14554 JSON_THROW(detail::out_of_range::create(402,
14555 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
14556 ") is out of range"));
14560 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
14562 JSON_THROW(detail::parse_error::create(106, 0,
14563 "array index '" + reference_token +
14564 "' must not begin with '0'"));
14570 ptr = &ptr->operator[](
14571 static_cast<size_type>(std::stoi(reference_token)));
14575 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14581 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
14593 for (
const auto& reference_token : reference_tokens)
14595 switch (ptr->m_type)
14597 case detail::value_t::object:
14600 ptr = &ptr->at(reference_token);
14604 case detail::value_t::array:
14609 JSON_THROW(detail::out_of_range::create(402,
14610 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
14611 ") is out of range"));
14615 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
14617 JSON_THROW(detail::parse_error::create(106, 0,
14618 "array index '" + reference_token +
14619 "' must not begin with '0'"));
14625 ptr = &ptr->at(
static_cast<size_type>(std::stoi(reference_token)));
14629 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14635 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
14643 void json_pointer::flatten(
const std::string& reference_string,
14647 switch (value.m_type)
14649 case detail::value_t::array:
14651 if (value.m_value.array->empty())
14654 result[reference_string] =
nullptr;
14659 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
14661 flatten(reference_string +
"/" + std::to_string(i),
14662 value.m_value.array->operator[](i), result);
14668 case detail::value_t::object:
14670 if (value.m_value.object->empty())
14673 result[reference_string] =
nullptr;
14678 for (
const auto& element : *value.m_value.object)
14680 flatten(reference_string +
"/" + escape(element.first), element.second, result);
14689 result[reference_string] = value;
14701 JSON_THROW(detail::type_error::create(314,
"only objects can be unflattened"));
14707 for (
const auto& element : *value.m_value.object)
14711 JSON_THROW(detail::type_error::create(315,
"values in object must be primitive"));
14718 json_pointer(element.first).get_and_create(result) = element.second;
14726 return (lhs.reference_tokens == rhs.reference_tokens);
14731 return not (lhs == rhs);
14749 inline void swap(
nlohmann::json& j1,
14751 is_nothrow_move_constructible<nlohmann::json>::value
and 14752 is_nothrow_move_assignable<nlohmann::json>::value
14767 std::size_t operator()(
const nlohmann::json& j)
const 14770 const auto& h = hash<
nlohmann::json::string_t>();
14771 return h(j.dump());
14779 struct less< ::
nlohmann::detail::value_t>
14785 bool operator()(
nlohmann::detail::value_t lhs,
14786 nlohmann::detail::value_t rhs)
const noexcept 14788 return nlohmann::detail::operator<(lhs, rhs);
14807 inline nlohmann::json operator
"" _json(
const char* s, std::size_t n)
14809 return nlohmann::json::parse(s, s + n);
14825 inline nlohmann::json::json_pointer operator
"" _json_pointer(
const char* s, std::size_t n)
14827 return nlohmann::json::json_pointer
(std::string(s, n)
);
14831 #if defined(__clang__
) || defined(__GNUC__
) || defined(__GNUG__
) 14832 #pragma GCC diagnostic pop 14834 #if defined(__clang__
) 14835 #pragma GCC diagnostic pop 14843 #undef JSON_UNLIKELY 14844 #undef JSON_DEPRECATED 14845 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION 14846 #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