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());
735 for (
const bool x : arr)
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 (
const 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
const operator++(
int)
3531 auto result = *
this;
3536 primitive_iterator_t& operator--()
3542 primitive_iterator_t
const 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
const 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
const 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
const 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
const 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());
6576 codepoint = s[i] & 0xFF;
6582 codepoint = ((s[i] & 0x3F) << 6)
6583 + (s[i + 1] & 0x7F);
6589 codepoint = ((s[i] & 0x1F) << 12)
6590 + ((s[i + 1] & 0x7F) << 6)
6591 + (s[i + 2] & 0x7F);
6597 codepoint = ((s[i] & 0xF) << 18)
6598 + ((s[i + 1] & 0x7F) << 12)
6599 + ((s[i + 2] & 0x7F) << 6)
6600 + (s[i + 3] & 0x7F);
6608 escape_codepoint(codepoint, result, pos);
6614 result[pos++] = s[i];
6621 assert(pos == result.size());
6622 o->write_characters(result.c_str(), result.size());
6634 template<
typename NumberType, detail::enable_if_t<
6635 std::is_same<NumberType, number_unsigned_t>::value
or 6636 std::is_same<NumberType, number_integer_t>::value,
6638 void dump_integer(NumberType x)
6643 o->write_character(
'0');
6647 const bool is_negative = (x <= 0)
and (x != 0);
6653 assert(i < number_buffer.size() - 1);
6655 const auto digit = std::labs(
static_cast<
long>(x % 10));
6656 number_buffer[i++] =
static_cast<
char>(
'0' + digit);
6663 assert(i < number_buffer.size() - 2);
6664 number_buffer[i++] =
'-';
6667 std::reverse(number_buffer.begin(), number_buffer.begin() + i);
6668 o->write_characters(number_buffer.data(), i);
6679 void dump_float(number_float_t x)
6682 if (
not std::isfinite(x)
or std::isnan(x))
6684 o->write_characters(
"null", 4);
6689 static constexpr auto d = std::numeric_limits<number_float_t>::digits10;
6692 std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(),
"%.*g", d, x);
6697 assert(
static_cast<std::size_t>(len) < number_buffer.size());
6700 if (thousands_sep !=
'\0')
6702 const auto end = std::remove(number_buffer.begin(),
6703 number_buffer.begin() + len, thousands_sep);
6704 std::fill(end, number_buffer.end(),
'\0');
6705 assert((end - number_buffer.begin()) <= len);
6706 len = (end - number_buffer.begin());
6710 if (decimal_point !=
'\0' and decimal_point !=
'.')
6712 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
6713 if (dec_pos != number_buffer.end())
6719 o->write_characters(number_buffer.data(),
static_cast<std::size_t>(len));
6722 const bool value_is_int_like =
6723 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
6726 return (c ==
'.' or c ==
'e');
6729 if (value_is_int_like)
6731 o->write_characters(
".0", 2);
6755 static void decode(uint8_t& state,
const uint8_t byte)
6757 static const std::array<uint8_t, 400> utf8d =
6760 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6761 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6762 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6763 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6764 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
6765 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
6766 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
6767 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
6768 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
6769 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
6770 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1,
6771 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
6772 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1,
6773 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
6777 const uint8_t type = utf8d[byte];
6778 state = utf8d[256u + state * 16u + type];
6789 static void throw_if_invalid_utf8(
const std::string& str)
6794 for (size_t i = 0; i < str.size(); ++i)
6796 const auto byte =
static_cast<uint8_t>(str[i]);
6797 decode(state, byte);
6801 std::stringstream ss;
6802 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex <<
static_cast<
int>(byte);
6803 JSON_THROW(type_error::create(316,
"invalid UTF-8 byte at index " + std::to_string(i) +
": 0x" + ss.str()));
6810 std::stringstream ss;
6811 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex <<
static_cast<
int>(
static_cast<uint8_t>(str.back()));
6812 JSON_THROW(type_error::create(316,
"incomplete UTF-8 string; last byte: 0x" + ss.str()));
6818 output_adapter_t<
char> o =
nullptr;
6821 std::array<
char, 64> number_buffer{{}};
6824 const std::lconv* loc =
nullptr;
6826 const char thousands_sep =
'\0';
6828 const char decimal_point =
'\0';
6831 const char indent_char;
6834 string_t indent_string;
6837 template<
typename BasicJsonType>
6841 using value_type = BasicJsonType;
6843 json_ref(value_type&& value)
6844 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(
true)
6847 json_ref(
const value_type& value)
6848 : value_ref(
const_cast<value_type*>(&value)), is_rvalue(
false)
6851 json_ref(std::initializer_list<json_ref> init)
6852 : owned_value(init), value_ref(&owned_value), is_rvalue(
true)
6855 template<
class... Args>
6856 json_ref(Args&& ... args)
6857 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value), is_rvalue(
true)
6861 json_ref(json_ref&&) =
default;
6862 json_ref(
const json_ref&) =
delete;
6863 json_ref& operator=(
const json_ref&) =
delete;
6865 value_type moved_or_copied()
const 6869 return std::move(*value_ref);
6874 value_type
const& operator*()
const 6876 return *
static_cast<value_type
const*>(value_ref);
6879 value_type
const* operator->()
const 6881 return static_cast<value_type
const*>(value_ref);
6885 mutable value_type owned_value =
nullptr;
6886 value_type* value_ref =
nullptr;
6887 const bool is_rvalue;
6895 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
6896 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
6907 template<
typename,
typename>
6908 struct adl_serializer
6919 template<
typename BasicJsonType,
typename ValueType>
6920 static void from_json(BasicJsonType&& j, ValueType& val)
noexcept(
6921 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
6923 ::
nlohmann::from_json(std::forward<BasicJsonType>(j), val);
6935 template<
typename BasicJsonType,
typename ValueType>
6936 static void to_json(BasicJsonType& j, ValueType&& val)
noexcept(
6937 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
6939 ::
nlohmann::to_json(j, std::forward<ValueType>(val));
6958 friend class basic_json;
6982 explicit json_pointer(
const std::string& s =
"") : reference_tokens(split(s)) {}
6999 std::string to_string()
const noexcept 7001 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
7003 [](
const std::string & a,
const std::string & b)
7005 return a +
"/" + escape(b);
7010 operator std::string()
const 7022 static int array_index(
const std::string& s)
7024 size_t processed_chars = 0;
7025 const int res = std::stoi(s, &processed_chars);
7030 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + s +
"'"));
7041 std::string pop_back()
7045 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
7048 auto last = reference_tokens.back();
7049 reference_tokens.pop_back();
7054 bool is_root()
const 7056 return reference_tokens.empty();
7059 json_pointer top()
const 7063 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
7066 json_pointer result = *
this;
7067 result.reference_tokens = {reference_tokens[0]};
7147 static std::vector<std::string> split(
const std::string& reference_string)
7149 std::vector<std::string> result;
7152 if (reference_string.empty())
7160 JSON_THROW(detail::parse_error::create(107, 1,
7161 "JSON pointer must be empty or begin with '/' - was: '" +
7162 reference_string +
"'"));
7170 std::size_t slash = reference_string.find_first_of(
'/', 1),
7179 slash = reference_string.find_first_of(
'/', start))
7183 auto reference_token = reference_string.substr(start, slash - start);
7186 for (std::size_t pos = reference_token.find_first_of(
'~');
7187 pos != std::string::npos;
7188 pos = reference_token.find_first_of(
'~', pos + 1))
7190 assert(reference_token[pos] ==
'~');
7194 (reference_token[pos + 1] !=
'0' and 7195 reference_token[pos + 1] !=
'1')))
7197 JSON_THROW(detail::parse_error::create(108, 0,
"escape character '~' must be followed with '0' or '1'"));
7202 unescape(reference_token);
7203 result.push_back(reference_token);
7222 static void replace_substring(std::string& s,
const std::string& f,
7223 const std::string& t)
7225 assert(
not f.empty());
7226 for (
auto pos = s.find(f);
7227 pos != std::string::npos;
7228 s.replace(pos, f.size(), t),
7229 pos = s.find(f, pos + t.size()))
7234 static std::string escape(std::string s)
7236 replace_substring(s,
"~",
"~0");
7237 replace_substring(s,
"/",
"~1");
7242 static void unescape(std::string& s)
7244 replace_substring(s,
"~1",
"/");
7245 replace_substring(s,
"~0",
"~");
7256 static void flatten(
const std::string& reference_string,
7274 friend bool operator==(json_pointer
const& lhs,
7275 json_pointer
const& rhs)
noexcept;
7277 friend bool operator!=(json_pointer
const& lhs,
7278 json_pointer
const& rhs)
noexcept;
7281 std::vector<std::string> reference_tokens;
7369 template<detail::value_t>
friend struct detail::external_constructor;
7371 friend ::
nlohmann::detail::parser<basic_json>;
7372 friend ::
nlohmann::detail::serializer<basic_json>;
7373 template<
typename BasicJsonType>
7374 friend class ::
nlohmann::detail::iter_impl;
7375 template<
typename BasicJsonType,
typename CharType>
7376 friend class ::
nlohmann::detail::binary_writer;
7377 template<
typename BasicJsonType>
7378 friend class ::
nlohmann::detail::binary_reader;
7384 using lexer = ::
nlohmann::detail::lexer<basic_json>;
7385 using parser = ::
nlohmann::detail::parser<basic_json>;
7387 using primitive_iterator_t = ::
nlohmann::detail::primitive_iterator_t;
7388 template<
typename BasicJsonType>
7389 using internal_iterator = ::
nlohmann::detail::internal_iterator<BasicJsonType>;
7390 template<
typename BasicJsonType>
7391 using iter_impl = ::
nlohmann::detail::iter_impl<BasicJsonType>;
7392 template<
typename Iterator>
7393 using iteration_proxy = ::
nlohmann::detail::iteration_proxy<Iterator>;
7394 template<
typename Base>
using json_reverse_iterator = ::
nlohmann::detail::json_reverse_iterator<Base>;
7396 template<
typename CharType>
7397 using output_adapter_t = ::
nlohmann::detail::output_adapter_t<CharType>;
7399 using binary_reader = ::
nlohmann::detail::binary_reader<basic_json>;
7400 template<
typename CharType>
using binary_writer = ::
nlohmann::detail::binary_writer<basic_json, CharType>;
7402 using serializer = ::
nlohmann::detail::serializer<basic_json>;
7405 using value_t = detail::value_t;
7407 using json_pointer = ::
nlohmann::json_pointer;
7408 template<
typename T,
typename SFINAE>
7409 using json_serializer = JSONSerializer<T, SFINAE>;
7411 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
7422 using exception = detail::exception;
7424 using parse_error = detail::parse_error;
7426 using invalid_iterator = detail::invalid_iterator;
7428 using type_error = detail::type_error;
7430 using out_of_range = detail::out_of_range;
7432 using other_error = detail::other_error;
7447 using value_type = basic_json;
7450 using reference = value_type&;
7452 using const_reference =
const value_type&;
7455 using difference_type = std::ptrdiff_t;
7457 using size_type = std::size_t;
7460 using allocator_type = AllocatorType<basic_json>;
7463 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
7465 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
7468 using iterator = iter_impl<basic_json>;
7470 using const_iterator = iter_impl<
const basic_json>;
7472 using reverse_iterator = json_reverse_iterator<
typename basic_json::iterator>;
7474 using const_reverse_iterator = json_reverse_iterator<
typename basic_json::const_iterator>;
7482 static allocator_type get_allocator()
7484 return allocator_type();
7513 static basic_json meta()
7517 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
7518 result[
"name"] =
"JSON for Modern C++";
7519 result[
"url"] =
"https://github.com/nlohmann/json";
7522 {
"string",
"3.0.1"}, {
"major", 3}, {
"minor", 0}, {
"patch", 1}
7526 result[
"platform"] =
"win32";
7527 #elif defined __linux__ 7528 result[
"platform"] =
"linux";
7529 #elif defined __APPLE__
7530 result[
"platform"] =
"apple";
7531 #elif defined __unix__ 7532 result[
"platform"] =
"unix";
7534 result[
"platform"] =
"unknown";
7537 #if defined(__ICC) || defined(__INTEL_COMPILER) 7538 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
7539 #elif defined(__clang__
) 7540 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
7541 #elif defined(__GNUC__) || defined(__GNUG__) 7542 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(__GNUC_PATCHLEVEL__)}};
7543 #elif defined(__HP_cc) || defined(__HP_aCC) 7544 result[
"compiler"] =
"hp" 7545 #elif defined(__IBMCPP__) 7546 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
7547 #elif defined(_MSC_VER) 7548 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
7549 #elif defined(__PGI) 7550 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
7551 #elif defined(__SUNPRO_CC) 7552 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
7554 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
7558 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
7560 result[
"compiler"][
"c++"] =
"unknown";
7575 #if defined(JSON_HAS_CPP_14) 7578 using object_comparator_t = std::less<>;
7580 using object_comparator_t = std::less<StringType>;
7666 using object_t = ObjectType<StringType,
7668 object_comparator_t,
7669 AllocatorType<std::pair<
const StringType,
7716 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
7769 using string_t = StringType;
7795 using boolean_t = BooleanType;
7867 using number_integer_t = NumberIntegerType;
7938 using number_unsigned_t = NumberUnsignedType;
8006 using number_float_t = NumberFloatType;
8013 template<
typename T,
typename... Args>
8014 static T* create(Args&& ... args)
8016 AllocatorType<T> alloc;
8017 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
8019 auto deleter = [&](T * object)
8021 AllocatorTraits::deallocate(alloc, object, 1);
8023 std::unique_ptr<T,
decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
8024 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
8025 assert(object !=
nullptr);
8026 return object.release();
8068 number_integer_t number_integer;
8070 number_unsigned_t number_unsigned;
8072 number_float_t number_float;
8075 json_value() =
default;
8077 json_value(boolean_t v)
noexcept : boolean(v) {}
8079 json_value(number_integer_t v)
noexcept : number_integer(v) {}
8081 json_value(number_unsigned_t v)
noexcept : number_unsigned(v) {}
8083 json_value(number_float_t v)
noexcept : number_float(v) {}
8085 json_value(value_t t)
8089 case value_t::object:
8091 object = create<object_t>();
8095 case value_t::array:
8097 array = create<array_t>();
8101 case value_t::string:
8103 string = create<string_t>(
"");
8107 case value_t::boolean:
8109 boolean = boolean_t(
false);
8113 case value_t::number_integer:
8115 number_integer = number_integer_t(0);
8119 case value_t::number_unsigned:
8121 number_unsigned = number_unsigned_t(0);
8125 case value_t::number_float:
8127 number_float = number_float_t(0.0);
8142 JSON_THROW(other_error::create(500,
"961c151d2e87f2686a955a9be24d316f1362bf21 3.0.1"));
8150 json_value(
const string_t& value)
8152 string = create<string_t>(value);
8156 json_value(string_t&& value)
8158 string = create<string_t>(std::move(value));
8162 json_value(
const object_t& value)
8164 object = create<object_t>(value);
8168 json_value(object_t&& value)
8170 object = create<object_t>(std::move(value));
8174 json_value(
const array_t& value)
8176 array = create<array_t>(value);
8180 json_value(array_t&& value)
8182 array = create<array_t>(std::move(value));
8185 void destroy(value_t t)
8189 case value_t::object:
8191 AllocatorType<object_t> alloc;
8192 std::allocator_traits<
decltype(alloc)>::destroy(alloc, object);
8193 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, object, 1);
8197 case value_t::array:
8199 AllocatorType<array_t> alloc;
8200 std::allocator_traits<
decltype(alloc)>::destroy(alloc, array);
8201 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, array, 1);
8205 case value_t::string:
8207 AllocatorType<string_t> alloc;
8208 std::allocator_traits<
decltype(alloc)>::destroy(alloc, string);
8209 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, string, 1);
8230 void assert_invariant()
const 8232 assert(m_type != value_t::object
or m_value.object !=
nullptr);
8233 assert(m_type != value_t::array
or m_value.array !=
nullptr);
8234 assert(m_type != value_t::string
or m_value.string !=
nullptr);
8257 using parse_event_t =
typename parser::parse_event_t;
8308 using parser_callback_t =
typename parser::parser_callback_t;
8349 basic_json(
const value_t v)
8350 : m_type(v), m_value(v)
8373 basic_json(std::nullptr_t =
nullptr)
noexcept 8374 : basic_json(value_t::null)
8435 template<
typename CompatibleType,
typename U = detail::uncvref_t<CompatibleType>,
8436 detail::enable_if_t<
not std::is_base_of<std::istream, U>::value
and 8437 not std::is_same<U, basic_json_t>::value
and 8438 not detail::is_basic_json_nested_type<
8439 basic_json_t, U>::value
and 8440 detail::has_to_json<basic_json, U>::value,
8442 basic_json(CompatibleType && val)
noexcept(
noexcept(JSONSerializer<U>::to_json(
8443 std::declval<basic_json_t&>(), std::forward<CompatibleType>(val))))
8445 JSONSerializer<U>::to_json(*
this, std::forward<CompatibleType>(val));
8523 basic_json(initializer_list_t init,
8524 bool type_deduction =
true,
8525 value_t manual_type = value_t::array)
8529 bool is_an_object = std::all_of(init.begin(), init.end(),
8530 [](
const detail::json_ref<basic_json>& element_ref)
8532 return (element_ref->is_array()
and element_ref->size() == 2
and (*element_ref)[0].is_string());
8536 if (
not type_deduction)
8539 if (manual_type == value_t::array)
8541 is_an_object =
false;
8545 if (
JSON_UNLIKELY(manual_type == value_t::object
and not is_an_object))
8547 JSON_THROW(type_error::create(301,
"cannot create object from initializer list"));
8554 m_type = value_t::object;
8555 m_value = value_t::object;
8557 std::for_each(init.begin(), init.end(), [
this](
const detail::json_ref<basic_json>& element_ref)
8559 auto element = element_ref.moved_or_copied();
8560 m_value.object->emplace(
8561 std::move(*((*element.m_value.array)[0].m_value.string)),
8562 std::move((*element.m_value.array)[1]));
8568 m_type = value_t::array;
8569 m_value.array = create<array_t>(init.begin(), init.end());
8612 static basic_json array(initializer_list_t init = {})
8614 return basic_json(init,
false, value_t::array);
8655 static basic_json object(initializer_list_t init = {})
8657 return basic_json(init,
false, value_t::object);
8682 basic_json(size_type cnt,
const basic_json& val)
8683 : m_type(value_t::array)
8685 m_value.array = create<array_t>(cnt, val);
8744 template<
class InputIT,
typename std::enable_if<
8745 std::is_same<InputIT,
typename basic_json_t::iterator>::value
or 8746 std::is_same<InputIT,
typename basic_json_t::const_iterator>::value,
int>::type = 0>
8747 basic_json(InputIT first, InputIT last)
8749 assert(first.m_object !=
nullptr);
8750 assert(last.m_object !=
nullptr);
8755 JSON_THROW(invalid_iterator::create(201,
"iterators are not compatible"));
8759 m_type = first.m_object->m_type;
8764 case value_t::boolean:
8765 case value_t::number_float:
8766 case value_t::number_integer:
8767 case value_t::number_unsigned:
8768 case value_t::string:
8770 if (
JSON_UNLIKELY(
not first.m_it.primitive_iterator.is_begin()
8771 or not last.m_it.primitive_iterator.is_end()))
8773 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
8784 case value_t::number_integer:
8786 m_value.number_integer = first.m_object->m_value.number_integer;
8790 case value_t::number_unsigned:
8792 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
8796 case value_t::number_float:
8798 m_value.number_float = first.m_object->m_value.number_float;
8802 case value_t::boolean:
8804 m_value.boolean = first.m_object->m_value.boolean;
8808 case value_t::string:
8810 m_value = *first.m_object->m_value.string;
8814 case value_t::object:
8816 m_value.object = create<object_t>(first.m_it.object_iterator,
8817 last.m_it.object_iterator);
8821 case value_t::array:
8823 m_value.array = create<array_t>(first.m_it.array_iterator,
8824 last.m_it.array_iterator);
8829 JSON_THROW(invalid_iterator::create(206,
"cannot construct with iterators from " +
8830 std::string(first.m_object->type_name())));
8842 basic_json(
const detail::json_ref<basic_json>& ref)
8843 : basic_json(ref.moved_or_copied())
8871 basic_json(
const basic_json& other)
8872 : m_type(other.m_type)
8875 other.assert_invariant();
8879 case value_t::object:
8881 m_value = *other.m_value.object;
8885 case value_t::array:
8887 m_value = *other.m_value.array;
8891 case value_t::string:
8893 m_value = *other.m_value.string;
8897 case value_t::boolean:
8899 m_value = other.m_value.boolean;
8903 case value_t::number_integer:
8905 m_value = other.m_value.number_integer;
8909 case value_t::number_unsigned:
8911 m_value = other.m_value.number_unsigned;
8915 case value_t::number_float:
8917 m_value = other.m_value.number_float;
8954 basic_json(basic_json&& other)
noexcept 8955 : m_type(std::move(other.m_type)),
8956 m_value(std::move(other.m_value))
8959 other.assert_invariant();
8962 other.m_type = value_t::null;
8991 reference& operator=(basic_json other)
noexcept (
8992 std::is_nothrow_move_constructible<value_t>::value
and 8993 std::is_nothrow_move_assignable<value_t>::value
and 8994 std::is_nothrow_move_constructible<json_value>::value
and 8995 std::is_nothrow_move_assignable<json_value>::value
8999 other.assert_invariant();
9002 swap(m_type, other.m_type);
9003 swap(m_value, other.m_value);
9027 m_value.destroy(m_type);
9077 string_t dump(
const int indent = -1,
const char indent_char =
' ',
9078 const bool ensure_ascii =
false)
const 9081 serializer s(detail::output_adapter<
char>(result), indent_char);
9085 s.dump(*
this,
true, ensure_ascii,
static_cast<
unsigned int>(indent));
9089 s.dump(*
this,
false, ensure_ascii, 0);
9127 constexpr value_t type()
const noexcept 9157 constexpr bool is_primitive()
const noexcept 9159 return is_null()
or is_string()
or is_boolean()
or is_number();
9184 constexpr bool is_structured()
const noexcept 9186 return is_array()
or is_object();
9206 constexpr bool is_null()
const noexcept 9208 return (m_type == value_t::null);
9228 constexpr bool is_boolean()
const noexcept 9230 return (m_type == value_t::boolean);
9258 constexpr bool is_number()
const noexcept 9260 return is_number_integer()
or is_number_float();
9287 constexpr bool is_number_integer()
const noexcept 9289 return (m_type == value_t::number_integer
or m_type == value_t::number_unsigned);
9315 constexpr bool is_number_unsigned()
const noexcept 9317 return (m_type == value_t::number_unsigned);
9343 constexpr bool is_number_float()
const noexcept 9345 return (m_type == value_t::number_float);
9365 constexpr bool is_object()
const noexcept 9367 return (m_type == value_t::object);
9387 constexpr bool is_array()
const noexcept 9389 return (m_type == value_t::array);
9409 constexpr bool is_string()
const noexcept 9411 return (m_type == value_t::string);
9436 constexpr bool is_discarded()
const noexcept 9438 return (m_type == value_t::discarded);
9462 constexpr operator value_t()
const noexcept 9475 boolean_t get_impl(boolean_t* )
const 9479 return m_value.boolean;
9482 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(type_name())));
9486 object_t* get_impl_ptr(object_t* )
noexcept 9488 return is_object() ? m_value.object :
nullptr;
9492 constexpr const object_t* get_impl_ptr(
const object_t* )
const noexcept 9494 return is_object() ? m_value.object :
nullptr;
9498 array_t* get_impl_ptr(array_t* )
noexcept 9500 return is_array() ? m_value.array :
nullptr;
9504 constexpr const array_t* get_impl_ptr(
const array_t* )
const noexcept 9506 return is_array() ? m_value.array :
nullptr;
9510 string_t* get_impl_ptr(string_t* )
noexcept 9512 return is_string() ? m_value.string :
nullptr;
9516 constexpr const string_t* get_impl_ptr(
const string_t* )
const noexcept 9518 return is_string() ? m_value.string :
nullptr;
9522 boolean_t* get_impl_ptr(boolean_t* )
noexcept 9524 return is_boolean() ? &m_value.boolean :
nullptr;
9528 constexpr const boolean_t* get_impl_ptr(
const boolean_t* )
const noexcept 9530 return is_boolean() ? &m_value.boolean :
nullptr;
9534 number_integer_t* get_impl_ptr(number_integer_t* )
noexcept 9536 return is_number_integer() ? &m_value.number_integer :
nullptr;
9540 constexpr const number_integer_t* get_impl_ptr(
const number_integer_t* )
const noexcept 9542 return is_number_integer() ? &m_value.number_integer :
nullptr;
9546 number_unsigned_t* get_impl_ptr(number_unsigned_t* )
noexcept 9548 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
9552 constexpr const number_unsigned_t* get_impl_ptr(
const number_unsigned_t* )
const noexcept 9554 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
9558 number_float_t* get_impl_ptr(number_float_t* )
noexcept 9560 return is_number_float() ? &m_value.number_float :
nullptr;
9564 constexpr const number_float_t* get_impl_ptr(
const number_float_t* )
const noexcept 9566 return is_number_float() ? &m_value.number_float :
nullptr;
9580 template<
typename ReferenceType,
typename ThisType>
9581 static ReferenceType get_ref_impl(ThisType& obj)
9584 auto ptr = obj.
template get_ptr<
typename std::add_pointer<ReferenceType>::type>();
9591 JSON_THROW(type_error::create(303,
"incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
9613 template<
typename BasicJsonType, detail::enable_if_t<
9614 std::is_same<
typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
9616 basic_json get()
const 9660 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
9661 detail::enable_if_t <
9662 not std::is_same<basic_json_t, ValueType>::value
and 9663 detail::has_from_json<basic_json_t, ValueType>::value
and 9664 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
9666 ValueType get()
const noexcept(
noexcept(
9667 JSONSerializer<ValueType>::from_json(std::declval<
const basic_json_t&>(), std::declval<ValueType&>())))
9672 static_assert(
not std::is_reference<ValueTypeCV>::value,
9673 "get() cannot be used with reference types, you might want to use get_ref()");
9674 static_assert(std::is_default_constructible<ValueType>::value,
9675 "types must be DefaultConstructible when used with get()");
9678 JSONSerializer<ValueType>::from_json(*
this, ret);
9713 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
9714 detail::enable_if_t<
not std::is_same<basic_json_t, ValueType>::value
and 9715 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
9717 ValueType get()
const noexcept(
noexcept(
9718 JSONSerializer<ValueTypeCV>::from_json(std::declval<
const basic_json_t&>())))
9720 static_assert(
not std::is_reference<ValueTypeCV>::value,
9721 "get() cannot be used with reference types, you might want to use get_ref()");
9722 return JSONSerializer<ValueTypeCV>::from_json(*
this);
9752 template<
typename PointerType,
typename std::enable_if<
9753 std::is_pointer<PointerType>::value,
int>::type = 0>
9754 PointerType get()
noexcept 9757 return get_ptr<PointerType>();
9764 template<
typename PointerType,
typename std::enable_if<
9765 std::is_pointer<PointerType>::value,
int>::type = 0>
9766 constexpr const PointerType get()
const noexcept 9769 return get_ptr<PointerType>();
9798 template<
typename PointerType,
typename std::enable_if<
9799 std::is_pointer<PointerType>::value,
int>::type = 0>
9800 PointerType get_ptr()
noexcept 9803 using pointee_t =
typename std::remove_const<
typename 9804 std::remove_pointer<
typename 9805 std::remove_const<PointerType>::type>::type>::type;
9808 std::is_same<object_t, pointee_t>::value
9809 or std::is_same<array_t, pointee_t>::value
9810 or std::is_same<string_t, pointee_t>::value
9811 or std::is_same<boolean_t, pointee_t>::value
9812 or std::is_same<number_integer_t, pointee_t>::value
9813 or std::is_same<number_unsigned_t, pointee_t>::value
9814 or std::is_same<number_float_t, pointee_t>::value
9815 ,
"incompatible pointer type");
9818 return get_impl_ptr(
static_cast<PointerType>(
nullptr));
9825 template<
typename PointerType,
typename std::enable_if<
9826 std::is_pointer<PointerType>::value
and 9827 std::is_const<
typename std::remove_pointer<PointerType>::type>::value,
int>::type = 0>
9828 constexpr const PointerType get_ptr()
const noexcept 9831 using pointee_t =
typename std::remove_const<
typename 9832 std::remove_pointer<
typename 9833 std::remove_const<PointerType>::type>::type>::type;
9836 std::is_same<object_t, pointee_t>::value
9837 or std::is_same<array_t, pointee_t>::value
9838 or std::is_same<string_t, pointee_t>::value
9839 or std::is_same<boolean_t, pointee_t>::value
9840 or std::is_same<number_integer_t, pointee_t>::value
9841 or std::is_same<number_unsigned_t, pointee_t>::value
9842 or std::is_same<number_float_t, pointee_t>::value
9843 ,
"incompatible pointer type");
9846 return get_impl_ptr(
static_cast<PointerType>(
nullptr));
9875 template<
typename ReferenceType,
typename std::enable_if<
9876 std::is_reference<ReferenceType>::value,
int>::type = 0>
9877 ReferenceType get_ref()
9880 return get_ref_impl<ReferenceType>(*
this);
9887 template<
typename ReferenceType,
typename std::enable_if<
9888 std::is_reference<ReferenceType>::value
and 9889 std::is_const<
typename std::remove_reference<ReferenceType>::type>::value,
int>::type = 0>
9890 ReferenceType get_ref()
const 9893 return get_ref_impl<ReferenceType>(*
this);
9925 template <
typename ValueType,
typename std::enable_if <
9926 not std::is_pointer<ValueType>::value
and 9927 not std::is_same<ValueType, detail::json_ref<basic_json>>::value
and 9928 not std::is_same<ValueType,
typename string_t::value_type>::value
9930 and not std::is_same<ValueType, std::initializer_list<
typename string_t::value_type>>::value
9932 #if defined(JSON_HAS_CPP_17) 9933 and not std::is_same<ValueType,
typename std::string_view>::value
9936 operator ValueType()
const 9939 return get<ValueType>();
9979 reference at(size_type idx)
9986 return m_value.array->at(idx);
9991 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
9996 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
10026 const_reference at(size_type idx)
const 10033 return m_value.array->at(idx);
10038 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
10043 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
10077 reference at(
const typename object_t::key_type& key)
10084 return m_value.object->at(key);
10089 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
10094 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
10128 const_reference at(
const typename object_t::key_type& key)
const 10135 return m_value.object->at(key);
10140 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
10145 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
10174 reference operator[](size_type idx)
10179 m_type = value_t::array;
10180 m_value.array = create<array_t>();
10181 assert_invariant();
10188 if (idx >= m_value.array->size())
10190 m_value.array->insert(m_value.array->end(),
10191 idx - m_value.array->size() + 1,
10195 return m_value.array->operator[](idx);
10198 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10220 const_reference operator[](size_type idx)
const 10225 return m_value.array->operator[](idx);
10228 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10258 reference operator[](
const typename object_t::key_type& key)
10263 m_type = value_t::object;
10264 m_value.object = create<object_t>();
10265 assert_invariant();
10271 return m_value.object->operator[](key);
10274 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10307 const_reference operator[](
const typename object_t::key_type& key)
const 10312 assert(m_value.object->find(key) != m_value.object->end());
10313 return m_value.object->find(key)->second;
10316 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10346 template<
typename T>
10347 reference operator[](T* key)
10352 m_type = value_t::object;
10353 m_value = value_t::object;
10354 assert_invariant();
10360 return m_value.object->operator[](key);
10363 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10396 template<
typename T>
10397 const_reference operator[](T* key)
const 10402 assert(m_value.object->find(key) != m_value.object->end());
10403 return m_value.object->find(key)->second;
10406 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
10457 template<
class ValueType,
typename std::enable_if<
10458 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
10459 ValueType value(
const typename object_t::key_type& key,
const ValueType& default_value)
const 10465 const auto it = find(key);
10471 return default_value;
10474 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
10481 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 10483 return value(key, string_t(default_value));
10527 template<
class ValueType,
typename std::enable_if<
10528 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
10529 ValueType value(
const json_pointer& ptr,
const ValueType& default_value)
const 10537 return ptr.get_checked(
this);
10541 return default_value;
10545 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
10552 string_t value(
const json_pointer& ptr,
const char* default_value)
const 10554 return value(ptr, string_t(default_value));
10590 const_reference front()
const 10636 const_reference back()
const 10689 template<
class IteratorType,
typename std::enable_if<
10690 std::is_same<IteratorType,
typename basic_json_t::iterator>::value
or 10691 std::is_same<IteratorType,
typename basic_json_t::const_iterator>::value,
int>::type
10693 IteratorType erase(IteratorType pos)
10698 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
10701 IteratorType result = end();
10705 case value_t::boolean:
10706 case value_t::number_float:
10707 case value_t::number_integer:
10708 case value_t::number_unsigned:
10709 case value_t::string:
10711 if (
JSON_UNLIKELY(
not pos.m_it.primitive_iterator.is_begin()))
10713 JSON_THROW(invalid_iterator::create(205,
"iterator out of range"));
10718 AllocatorType<string_t> alloc;
10719 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_value.string);
10720 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_value.string, 1);
10721 m_value.string =
nullptr;
10724 m_type = value_t::null;
10725 assert_invariant();
10729 case value_t::object:
10731 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
10735 case value_t::array:
10737 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
10742 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
10794 template<
class IteratorType,
typename std::enable_if<
10795 std::is_same<IteratorType,
typename basic_json_t::iterator>::value
or 10796 std::is_same<IteratorType,
typename basic_json_t::const_iterator>::value,
int>::type
10798 IteratorType erase(IteratorType first, IteratorType last)
10801 if (
JSON_UNLIKELY(
this != first.m_object
or this != last.m_object))
10803 JSON_THROW(invalid_iterator::create(203,
"iterators do not fit current value"));
10806 IteratorType result = end();
10810 case value_t::boolean:
10811 case value_t::number_float:
10812 case value_t::number_integer:
10813 case value_t::number_unsigned:
10814 case value_t::string:
10816 if (
JSON_LIKELY(
not first.m_it.primitive_iterator.is_begin()
10817 or not last.m_it.primitive_iterator.is_end()))
10819 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
10824 AllocatorType<string_t> alloc;
10825 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_value.string);
10826 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_value.string, 1);
10827 m_value.string =
nullptr;
10830 m_type = value_t::null;
10831 assert_invariant();
10835 case value_t::object:
10837 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
10838 last.m_it.object_iterator);
10842 case value_t::array:
10844 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
10845 last.m_it.array_iterator);
10850 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
10885 size_type erase(
const typename object_t::key_type& key)
10890 return m_value.object->erase(key);
10893 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
10920 void erase(
const size_type idx)
10927 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
10930 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
10934 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
10970 template<
typename KeyT>
10971 iterator find(KeyT&& key)
10973 auto result = end();
10977 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
10987 template<
typename KeyT>
10988 const_iterator find(KeyT&& key)
const 10990 auto result = cend();
10994 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
11021 template<
typename KeyT>
11022 size_type count(KeyT&& key)
const 11025 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
11062 iterator begin()
noexcept 11064 iterator result(
this);
11065 result.set_begin();
11072 const_iterator begin()
const noexcept 11102 const_iterator cbegin()
const noexcept 11104 const_iterator result(
this);
11105 result.set_begin();
11133 iterator end()
noexcept 11135 iterator result(
this);
11143 const_iterator end()
const noexcept 11173 const_iterator cend()
const noexcept 11175 const_iterator result(
this);
11203 reverse_iterator rbegin()
noexcept 11205 return reverse_iterator(end());
11211 const_reverse_iterator rbegin()
const noexcept 11240 reverse_iterator rend()
noexcept 11242 return reverse_iterator(begin());
11248 const_reverse_iterator rend()
const noexcept 11277 const_reverse_iterator crbegin()
const noexcept 11279 return const_reverse_iterator(cend());
11306 const_reverse_iterator crend()
const noexcept 11308 return const_reverse_iterator(cbegin());
11365 static iteration_proxy<iterator> iterator_wrapper(reference ref)
11367 return iteration_proxy<iterator>(ref);
11373 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref)
11375 return iteration_proxy<const_iterator>(ref);
11427 iteration_proxy<iterator> items()
11429 return iteration_proxy<iterator>(*
this);
11435 iteration_proxy<const_iterator> items()
const 11437 return iteration_proxy<const_iterator>(*
this);
11491 bool empty()
const noexcept 11495 case value_t::null:
11501 case value_t::array:
11504 return m_value.array->empty();
11507 case value_t::object:
11510 return m_value.object->empty();
11563 size_type size()
const noexcept 11567 case value_t::null:
11573 case value_t::array:
11576 return m_value.array->size();
11579 case value_t::object:
11582 return m_value.object->size();
11633 size_type max_size()
const noexcept 11637 case value_t::array:
11640 return m_value.array->max_size();
11643 case value_t::object:
11646 return m_value.object->max_size();
11703 void clear()
noexcept 11707 case value_t::number_integer:
11709 m_value.number_integer = 0;
11713 case value_t::number_unsigned:
11715 m_value.number_unsigned = 0;
11719 case value_t::number_float:
11721 m_value.number_float = 0.0;
11725 case value_t::boolean:
11727 m_value.boolean =
false;
11731 case value_t::string:
11733 m_value.string->clear();
11737 case value_t::array:
11739 m_value.array->clear();
11743 case value_t::object:
11745 m_value.object->clear();
11774 void push_back(basic_json&& val)
11779 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
11785 m_type = value_t::array;
11786 m_value = value_t::array;
11787 assert_invariant();
11791 m_value.array->push_back(std::move(val));
11793 val.m_type = value_t::null;
11800 reference operator+=(basic_json&& val)
11802 push_back(std::move(val));
11810 void push_back(
const basic_json& val)
11815 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
11821 m_type = value_t::array;
11822 m_value = value_t::array;
11823 assert_invariant();
11827 m_value.array->push_back(val);
11834 reference operator+=(
const basic_json& val)
11860 void push_back(
const typename object_t::value_type& val)
11865 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
11871 m_type = value_t::object;
11872 m_value = value_t::object;
11873 assert_invariant();
11877 m_value.object->insert(val);
11884 reference operator+=(
const typename object_t::value_type& val)
11915 void push_back(initializer_list_t init)
11917 if (is_object()
and init.size() == 2
and (*init.begin())->is_string())
11919 basic_json&& key = init.begin()->moved_or_copied();
11920 push_back(
typename object_t::value_type(
11921 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
11925 push_back(basic_json(init));
11933 reference operator+=(initializer_list_t init)
11960 template<
class... Args>
11961 void emplace_back(Args&& ... args)
11966 JSON_THROW(type_error::create(311,
"cannot use emplace_back() with " + std::string(type_name())));
11972 m_type = value_t::array;
11973 m_value = value_t::array;
11974 assert_invariant();
11978 m_value.array->emplace_back(std::forward<Args>(args)...);
12008 template<
class... Args>
12009 std::pair<iterator,
bool> emplace(Args&& ... args)
12014 JSON_THROW(type_error::create(311,
"cannot use emplace() with " + std::string(type_name())));
12020 m_type = value_t::object;
12021 m_value = value_t::object;
12022 assert_invariant();
12026 auto res = m_value.object->emplace(std::forward<Args>(args)...);
12029 it.m_it.object_iterator = res.first;
12032 return {it, res.second};
12057 iterator insert(const_iterator pos,
const basic_json& val)
12065 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
12069 iterator result(
this);
12070 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
12074 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12081 iterator insert(const_iterator pos, basic_json&& val)
12083 return insert(pos, val);
12110 iterator insert(const_iterator pos, size_type cnt,
const basic_json& val)
12118 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
12122 iterator result(
this);
12123 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
12127 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12160 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
12165 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12171 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
12177 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
12182 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container"));
12186 iterator result(
this);
12187 result.m_it.array_iterator = m_value.array->insert(
12188 pos.m_it.array_iterator,
12189 first.m_it.array_iterator,
12190 last.m_it.array_iterator);
12218 iterator insert(const_iterator pos, initializer_list_t ilist)
12223 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12229 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
12233 iterator result(
this);
12234 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
12261 void insert(const_iterator first, const_iterator last)
12266 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12272 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
12278 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
12281 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
12303 void update(const_reference j)
12308 m_type = value_t::object;
12309 m_value.object = create<object_t>();
12310 assert_invariant();
12315 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
12319 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(j.type_name())));
12322 for (
auto it = j.cbegin(); it != j.cend(); ++it)
12324 m_value.object->operator[](it.key()) = it.value();
12354 void update(const_iterator first, const_iterator last)
12359 m_type = value_t::object;
12360 m_value.object = create<object_t>();
12361 assert_invariant();
12366 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
12372 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
12377 or not first.m_object->is_object()))
12379 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
12382 for (
auto it = first; it != last; ++it)
12384 m_value.object->operator[](it.key()) = it.value();
12405 void swap(reference other)
noexcept (
12406 std::is_nothrow_move_constructible<value_t>::value
and 12407 std::is_nothrow_move_assignable<value_t>::value
and 12408 std::is_nothrow_move_constructible<json_value>::value
and 12409 std::is_nothrow_move_assignable<json_value>::value
12412 std::swap(m_type, other.m_type);
12413 std::swap(m_value, other.m_value);
12414 assert_invariant();
12437 void swap(array_t& other)
12442 std::swap(*(m_value.array), other);
12446 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
12470 void swap(object_t& other)
12475 std::swap(*(m_value.object), other);
12479 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
12503 void swap(string_t& other)
12508 std::swap(*(m_value.string), other);
12512 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
12565 friend bool operator==(const_reference lhs, const_reference rhs)
noexcept 12567 const auto lhs_type = lhs.type();
12568 const auto rhs_type = rhs.type();
12570 if (lhs_type == rhs_type)
12574 case value_t::array:
12575 return (*lhs.m_value.array == *rhs.m_value.array);
12577 case value_t::object:
12578 return (*lhs.m_value.object == *rhs.m_value.object);
12580 case value_t::null:
12583 case value_t::string:
12584 return (*lhs.m_value.string == *rhs.m_value.string);
12586 case value_t::boolean:
12587 return (lhs.m_value.boolean == rhs.m_value.boolean);
12589 case value_t::number_integer:
12590 return (lhs.m_value.number_integer == rhs.m_value.number_integer);
12592 case value_t::number_unsigned:
12593 return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
12595 case value_t::number_float:
12596 return (lhs.m_value.number_float == rhs.m_value.number_float);
12602 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_float)
12604 return (
static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
12606 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_integer)
12608 return (lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer));
12610 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_float)
12612 return (
static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
12614 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_unsigned)
12616 return (lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned));
12618 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_integer)
12620 return (
static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
12622 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_unsigned)
12624 return (lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned));
12634 template<
typename ScalarType,
typename std::enable_if<
12635 std::is_scalar<ScalarType>::value,
int>::type = 0>
12636 friend bool operator==(const_reference lhs,
const ScalarType rhs)
noexcept 12638 return (lhs == basic_json(rhs));
12645 template<
typename ScalarType,
typename std::enable_if<
12646 std::is_scalar<ScalarType>::value,
int>::type = 0>
12647 friend bool operator==(
const ScalarType lhs, const_reference rhs)
noexcept 12649 return (basic_json(lhs) == rhs);
12670 friend bool operator!=(const_reference lhs, const_reference rhs)
noexcept 12672 return not (lhs == rhs);
12679 template<
typename ScalarType,
typename std::enable_if<
12680 std::is_scalar<ScalarType>::value,
int>::type = 0>
12681 friend bool operator!=(const_reference lhs,
const ScalarType rhs)
noexcept 12683 return (lhs != basic_json(rhs));
12690 template<
typename ScalarType,
typename std::enable_if<
12691 std::is_scalar<ScalarType>::value,
int>::type = 0>
12692 friend bool operator!=(
const ScalarType lhs, const_reference rhs)
noexcept 12694 return (basic_json(lhs) != rhs);
12723 friend bool operator<(const_reference lhs, const_reference rhs)
noexcept 12725 const auto lhs_type = lhs.type();
12726 const auto rhs_type = rhs.type();
12728 if (lhs_type == rhs_type)
12732 case value_t::array:
12733 return (*lhs.m_value.array) < (*rhs.m_value.array);
12735 case value_t::object:
12736 return *lhs.m_value.object < *rhs.m_value.object;
12738 case value_t::null:
12741 case value_t::string:
12742 return *lhs.m_value.string < *rhs.m_value.string;
12744 case value_t::boolean:
12745 return lhs.m_value.boolean < rhs.m_value.boolean;
12747 case value_t::number_integer:
12748 return lhs.m_value.number_integer < rhs.m_value.number_integer;
12750 case value_t::number_unsigned:
12751 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
12753 case value_t::number_float:
12754 return lhs.m_value.number_float < rhs.m_value.number_float;
12760 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_float)
12762 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
12764 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_integer)
12766 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
12768 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_float)
12770 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
12772 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_unsigned)
12774 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
12776 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_unsigned)
12778 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
12780 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_integer)
12782 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
12788 return operator<(lhs_type, rhs_type);
12795 template<
typename ScalarType,
typename std::enable_if<
12796 std::is_scalar<ScalarType>::value,
int>::type = 0>
12797 friend bool operator<(const_reference lhs,
const ScalarType rhs)
noexcept 12799 return (lhs < basic_json(rhs));
12806 template<
typename ScalarType,
typename std::enable_if<
12807 std::is_scalar<ScalarType>::value,
int>::type = 0>
12808 friend bool operator<(
const ScalarType lhs, const_reference rhs)
noexcept 12810 return (basic_json(lhs) < rhs);
12832 friend bool operator<=(const_reference lhs, const_reference rhs)
noexcept 12834 return not (rhs < lhs);
12841 template<
typename ScalarType,
typename std::enable_if<
12842 std::is_scalar<ScalarType>::value,
int>::type = 0>
12843 friend bool operator<=(const_reference lhs,
const ScalarType rhs)
noexcept 12845 return (lhs <= basic_json(rhs));
12852 template<
typename ScalarType,
typename std::enable_if<
12853 std::is_scalar<ScalarType>::value,
int>::type = 0>
12854 friend bool operator<=(
const ScalarType lhs, const_reference rhs)
noexcept 12856 return (basic_json(lhs) <= rhs);
12878 friend bool operator>(const_reference lhs, const_reference rhs)
noexcept 12880 return not (lhs <= rhs);
12887 template<
typename ScalarType,
typename std::enable_if<
12888 std::is_scalar<ScalarType>::value,
int>::type = 0>
12889 friend bool operator>(const_reference lhs,
const ScalarType rhs)
noexcept 12891 return (lhs > basic_json(rhs));
12898 template<
typename ScalarType,
typename std::enable_if<
12899 std::is_scalar<ScalarType>::value,
int>::type = 0>
12900 friend bool operator>(
const ScalarType lhs, const_reference rhs)
noexcept 12902 return (basic_json(lhs) > rhs);
12924 friend bool operator>=(const_reference lhs, const_reference rhs)
noexcept 12926 return not (lhs < rhs);
12933 template<
typename ScalarType,
typename std::enable_if<
12934 std::is_scalar<ScalarType>::value,
int>::type = 0>
12935 friend bool operator>=(const_reference lhs,
const ScalarType rhs)
noexcept 12937 return (lhs >= basic_json(rhs));
12944 template<
typename ScalarType,
typename std::enable_if<
12945 std::is_scalar<ScalarType>::value,
int>::type = 0>
12946 friend bool operator>=(
const ScalarType lhs, const_reference rhs)
noexcept 12948 return (basic_json(lhs) >= rhs);
12991 friend std::ostream& operator<<(std::ostream& o,
const basic_json& j)
12994 const bool pretty_print = (o.width() > 0);
12995 const auto indentation = (pretty_print ? o.width() : 0);
13001 serializer s(detail::output_adapter<
char>(o), o.fill());
13002 s.dump(j, pretty_print,
false,
static_cast<
unsigned int>(indentation));
13015 friend std::ostream& operator>>(
const basic_json& j, std::ostream& o)
13092 static basic_json parse(detail::input_adapter i,
13093 const parser_callback_t cb =
nullptr,
13094 const bool allow_exceptions =
true)
13097 parser(i, cb, allow_exceptions).parse(
true, result);
13104 static basic_json parse(detail::input_adapter& i,
13105 const parser_callback_t cb =
nullptr,
13106 const bool allow_exceptions =
true)
13109 parser(i, cb, allow_exceptions).parse(
true, result);
13113 static bool accept(detail::input_adapter i)
13115 return parser(i).accept(
true);
13118 static bool accept(detail::input_adapter& i)
13120 return parser(i).accept(
true);
13170 template<
class IteratorType,
typename std::enable_if<
13172 std::random_access_iterator_tag,
13173 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
13174 static basic_json parse(IteratorType first, IteratorType last,
13175 const parser_callback_t cb =
nullptr,
13176 const bool allow_exceptions =
true)
13179 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(
true, result);
13183 template<
class IteratorType,
typename std::enable_if<
13185 std::random_access_iterator_tag,
13186 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
13187 static bool accept(IteratorType first, IteratorType last)
13189 return parser(detail::input_adapter(first, last)).accept(
true);
13201 friend std::istream& operator<<(basic_json& j, std::istream& i)
13203 return operator>>(i, j);
13231 friend std::istream& operator>>(std::istream& i, basic_json& j)
13233 parser(detail::input_adapter(i)).parse(
false, j);
13273 const char* type_name()
const noexcept 13278 case value_t::null:
13280 case value_t::object:
13282 case value_t::array:
13284 case value_t::string:
13286 case value_t::boolean:
13288 case value_t::discarded:
13289 return "discarded";
13303 value_t m_type = value_t::null;
13306 json_value m_value = {};
13402 static std::vector<uint8_t> to_cbor(
const basic_json& j)
13404 std::vector<uint8_t> result;
13405 to_cbor(j, result);
13409 static void to_cbor(
const basic_json& j, detail::output_adapter<uint8_t> o)
13411 binary_writer<uint8_t>(o).write_cbor(j);
13414 static void to_cbor(
const basic_json& j, detail::output_adapter<
char> o)
13416 binary_writer<
char>(o).write_cbor(j);
13497 static std::vector<uint8_t> to_msgpack(
const basic_json& j)
13499 std::vector<uint8_t> result;
13500 to_msgpack(j, result);
13504 static void to_msgpack(
const basic_json& j, detail::output_adapter<uint8_t> o)
13506 binary_writer<uint8_t>(o).write_msgpack(j);
13509 static void to_msgpack(
const basic_json& j, detail::output_adapter<
char> o)
13511 binary_writer<
char>(o).write_msgpack(j);
13605 static basic_json from_cbor(detail::input_adapter i,
13606 const bool strict =
true)
13608 return binary_reader(i).parse_cbor(strict);
13614 template<
typename A1,
typename A2,
13615 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
13616 static basic_json from_cbor(A1 && a1, A2 && a2,
const bool strict =
true)
13618 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_cbor(strict);
13692 static basic_json from_msgpack(detail::input_adapter i,
13693 const bool strict =
true)
13695 return binary_reader(i).parse_msgpack(strict);
13701 template<
typename A1,
typename A2,
13702 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
13703 static basic_json from_msgpack(A1 && a1, A2 && a2,
const bool strict =
true)
13705 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_msgpack(strict);
13750 reference operator[](
const json_pointer& ptr)
13752 return ptr.get_unchecked(
this);
13778 const_reference operator[](
const json_pointer& ptr)
const 13780 return ptr.get_unchecked(
this);
13821 reference at(
const json_pointer& ptr)
13823 return ptr.get_checked(
this);
13864 const_reference at(
const json_pointer& ptr)
const 13866 return ptr.get_checked(
this);
13891 basic_json flatten()
const 13893 basic_json result(value_t::object);
13894 json_pointer::flatten(
"", *
this, result);
13928 basic_json unflatten()
const 13930 return json_pointer::unflatten(*
this);
13989 basic_json patch(
const basic_json& json_patch)
const 13992 basic_json result = *
this;
13995 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
13997 const auto get_op = [](
const std::string & op)
14001 return patch_operations::add;
14003 if (op ==
"remove")
14005 return patch_operations::remove;
14007 if (op ==
"replace")
14009 return patch_operations::replace;
14013 return patch_operations::move;
14017 return patch_operations::copy;
14021 return patch_operations::test;
14024 return patch_operations::invalid;
14028 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
14038 json_pointer top_pointer = ptr.top();
14039 if (top_pointer != ptr)
14041 result.at(top_pointer);
14045 const auto last_path = ptr.pop_back();
14046 basic_json& parent = result[ptr];
14048 switch (parent.m_type)
14050 case value_t::null:
14051 case value_t::object:
14054 parent[last_path] = val;
14058 case value_t::array:
14060 if (last_path ==
"-")
14063 parent.push_back(val);
14067 const auto idx = json_pointer::array_index(last_path);
14068 if (
JSON_UNLIKELY(
static_cast<size_type>(idx) > parent.size()))
14071 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
14076 parent.insert(parent.begin() +
static_cast<difference_type>(idx), val);
14092 const auto operation_remove = [&result](json_pointer & ptr)
14095 const auto last_path = ptr.pop_back();
14096 basic_json& parent = result.at(ptr);
14099 if (parent.is_object())
14102 auto it = parent.find(last_path);
14109 JSON_THROW(out_of_range::create(403,
"key '" + last_path +
"' not found"));
14112 else if (parent.is_array())
14115 parent.erase(
static_cast<size_type>(json_pointer::array_index(last_path)));
14122 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
14126 for (
const auto& val : json_patch)
14129 const auto get_value = [&val](
const std::string & op,
14130 const std::string & member,
14131 bool string_type) -> basic_json&
14134 auto it = val.m_value.object->find(member);
14137 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
14142 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have member '" + member +
"'"));
14146 if (
JSON_UNLIKELY(string_type
and not it->second.is_string()))
14148 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have string member '" + member +
"'"));
14158 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
14162 const std::string op = get_value(
"op",
"op",
true);
14163 const std::string path = get_value(op,
"path",
true);
14164 json_pointer ptr
(path
);
14166 switch (get_op(op))
14168 case patch_operations::add:
14170 operation_add(ptr, get_value(
"add",
"value",
false));
14174 case patch_operations::remove:
14176 operation_remove(ptr);
14180 case patch_operations::replace:
14183 result.at(ptr) = get_value(
"replace",
"value",
false);
14187 case patch_operations::move:
14189 const std::string from_path = get_value(
"move",
"from",
true);
14190 json_pointer from_ptr
(from_path
);
14193 basic_json v = result.at(from_ptr);
14199 operation_remove(from_ptr);
14200 operation_add(ptr, v);
14204 case patch_operations::copy:
14206 const std::string from_path = get_value(
"copy",
"from",
true);
14207 const json_pointer from_ptr
(from_path
);
14210 basic_json v = result.at(from_ptr);
14215 operation_add(ptr, v);
14219 case patch_operations::test:
14221 bool success =
false;
14226 success = (result.at(ptr) == get_value(
"test",
"value",
false));
14236 JSON_THROW(other_error::create(501,
"unsuccessful: " + val.dump()));
14242 case patch_operations::invalid:
14246 JSON_THROW(parse_error::create(105, 0,
"operation value '" + op +
"' is invalid"));
14286 static basic_json diff(
const basic_json& source,
const basic_json& target,
14287 const std::string& path =
"")
14290 basic_json result(value_t::array);
14293 if (source == target)
14298 if (source.type() != target.type())
14303 {
"op",
"replace"}, {
"path", path}, {
"value", target}
14308 switch (source.type())
14310 case value_t::array:
14314 while (i < source.size()
and i < target.size())
14317 auto temp_diff = diff(source[i], target[i], path +
"/" + std::to_string(i));
14318 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
14326 const auto end_index =
static_cast<difference_type>(result.size());
14327 while (i < source.size())
14331 result.insert(result.begin() + end_index, object(
14334 {
"path", path +
"/" + std::to_string(i)}
14340 while (i < target.size())
14345 {
"path", path +
"/" + std::to_string(i)},
14346 {
"value", target[i]}
14354 case value_t::object:
14357 for (
auto it = source.cbegin(); it != source.cend(); ++it)
14360 const auto key = json_pointer::escape(it.key());
14362 if (target.find(it.key()) != target.end())
14365 auto temp_diff = diff(it.value(), target[it.key()], path +
"/" + key);
14366 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
14371 result.push_back(object(
14373 {
"op",
"remove"}, {
"path", path +
"/" + key}
14379 for (
auto it = target.cbegin(); it != target.cend(); ++it)
14381 if (source.find(it.key()) == source.end())
14384 const auto key = json_pointer::escape(it.key());
14387 {
"op",
"add"}, {
"path", path +
"/" + key},
14388 {
"value", it.value()}
14401 {
"op",
"replace"}, {
"path", path}, {
"value", target}
14426 using json = basic_json<>;
14441 for (
const auto& reference_token : reference_tokens)
14443 switch (result->m_type)
14445 case detail::value_t::null:
14447 if (reference_token ==
"0")
14450 result = &result->operator[](0);
14455 result = &result->operator[](reference_token);
14460 case detail::value_t::object:
14463 result = &result->operator[](reference_token);
14467 case detail::value_t::array:
14472 result = &result->operator[](
static_cast<size_type>(array_index(reference_token)));
14476 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14488 JSON_THROW(detail::type_error::create(313,
"invalid value to unflatten"));
14500 for (
const auto& reference_token : reference_tokens)
14503 if (ptr->m_type == detail::value_t::null)
14507 std::all_of(reference_token.begin(), reference_token.end(),
14510 return (x >=
'0' and x <=
'9');
14514 *ptr = (nums
or reference_token ==
"-")
14515 ? detail::value_t::array
14516 : detail::value_t::object;
14519 switch (ptr->m_type)
14521 case detail::value_t::object:
14524 ptr = &ptr->operator[](reference_token);
14528 case detail::value_t::array:
14531 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
14533 JSON_THROW(detail::parse_error::create(106, 0,
14534 "array index '" + reference_token +
14535 "' must not begin with '0'"));
14538 if (reference_token ==
"-")
14541 ptr = &ptr->operator[](ptr->m_value.array->size());
14548 ptr = &ptr->operator[](
14549 static_cast<size_type>(array_index(reference_token)));
14553 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14560 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
14572 for (
const auto& reference_token : reference_tokens)
14574 switch (ptr->m_type)
14576 case detail::value_t::object:
14579 ptr = &ptr->at(reference_token);
14583 case detail::value_t::array:
14588 JSON_THROW(detail::out_of_range::create(402,
14589 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
14590 ") is out of range"));
14594 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
14596 JSON_THROW(detail::parse_error::create(106, 0,
14597 "array index '" + reference_token +
14598 "' must not begin with '0'"));
14604 ptr = &ptr->at(
static_cast<size_type>(array_index(reference_token)));
14608 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14614 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
14626 for (
const auto& reference_token : reference_tokens)
14628 switch (ptr->m_type)
14630 case detail::value_t::object:
14633 ptr = &ptr->operator[](reference_token);
14637 case detail::value_t::array:
14642 JSON_THROW(detail::out_of_range::create(402,
14643 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
14644 ") is out of range"));
14648 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
14650 JSON_THROW(detail::parse_error::create(106, 0,
14651 "array index '" + reference_token +
14652 "' must not begin with '0'"));
14658 ptr = &ptr->operator[](
14659 static_cast<size_type>(array_index(reference_token)));
14663 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14669 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
14681 for (
const auto& reference_token : reference_tokens)
14683 switch (ptr->m_type)
14685 case detail::value_t::object:
14688 ptr = &ptr->at(reference_token);
14692 case detail::value_t::array:
14697 JSON_THROW(detail::out_of_range::create(402,
14698 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
14699 ") is out of range"));
14703 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
14705 JSON_THROW(detail::parse_error::create(106, 0,
14706 "array index '" + reference_token +
14707 "' must not begin with '0'"));
14713 ptr = &ptr->at(
static_cast<size_type>(array_index(reference_token)));
14717 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14723 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
14731 void json_pointer::flatten(
const std::string& reference_string,
14735 switch (value.m_type)
14737 case detail::value_t::array:
14739 if (value.m_value.array->empty())
14742 result[reference_string] =
nullptr;
14747 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
14749 flatten(reference_string +
"/" + std::to_string(i),
14750 value.m_value.array->operator[](i), result);
14756 case detail::value_t::object:
14758 if (value.m_value.object->empty())
14761 result[reference_string] =
nullptr;
14766 for (
const auto& element : *value.m_value.object)
14768 flatten(reference_string +
"/" + escape(element.first), element.second, result);
14777 result[reference_string] = value;
14789 JSON_THROW(detail::type_error::create(314,
"only objects can be unflattened"));
14795 for (
const auto& element : *value.m_value.object)
14799 JSON_THROW(detail::type_error::create(315,
"values in object must be primitive"));
14806 json_pointer(element.first).get_and_create(result) = element.second;
14812 inline bool operator==(json_pointer
const& lhs, json_pointer
const& rhs)
noexcept 14814 return (lhs.reference_tokens == rhs.reference_tokens);
14817 inline bool operator!=(json_pointer
const& lhs, json_pointer
const& rhs)
noexcept 14819 return not (lhs == rhs);
14837 inline void swap(
nlohmann::json& j1,
14839 is_nothrow_move_constructible<nlohmann::json>::value
and 14840 is_nothrow_move_assignable<nlohmann::json>::value
14855 std::size_t operator()(
const nlohmann::json& j)
const 14858 const auto& h = hash<
nlohmann::json::string_t>();
14859 return h(j.dump());
14867 struct less< ::
nlohmann::detail::value_t>
14873 bool operator()(
nlohmann::detail::value_t lhs,
14874 nlohmann::detail::value_t rhs)
const noexcept 14876 return nlohmann::detail::operator<(lhs, rhs);
14895 inline nlohmann::json operator
"" _json(
const char* s, std::size_t n)
14897 return nlohmann::json::parse(s, s + n);
14913 inline nlohmann::json::json_pointer operator
"" _json_pointer(
const char* s, std::size_t n)
14915 return nlohmann::json::json_pointer
(std::string(s, n)
);
14919 #if defined(__clang__
) || defined(__GNUC__
) || defined(__GNUG__
) 14920 #pragma GCC diagnostic pop 14922 #if defined(__clang__
) 14923 #pragma GCC diagnostic pop 14931 #undef JSON_UNLIKELY 14932 #undef JSON_DEPRECATED 14933 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION 14934 #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.
#define JSON_CATCH(exception)
namespace for Niels Lohmann
#define NLOHMANN_BASIC_JSON_TPL
#define JSON_THROW(exception)