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(
6935 template<
typename BasicJsonType,
typename ValueType>
6936 static void to_json(BasicJsonType& j, ValueType&& val)
noexcept(
6982 explicit json_pointer(
const std::string& s =
"") : reference_tokens(split(s)) {}
6999 std::string to_string()
const noexcept 7001 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
7003 [](
const std::string & a,
const std::string & b)
7005 return a +
"/" + escape(b);
7010 operator std::string()
const 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();
7063 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
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,
7281 std::vector<std::string> reference_tokens;
7369 template<detail::value_t>
friend struct detail::external_constructor;
7373 template<
typename BasicJsonType>
7375 template<
typename BasicJsonType,
typename CharType>
7376 friend class ::
nlohmann::detail::binary_writer;
7377 template<
typename BasicJsonType>
7378 friend class ::
nlohmann::detail::binary_reader;
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>;
7400 template<
typename CharType>
using binary_writer = ::
nlohmann::detail::binary_writer<
basic_json, CharType>;
7405 using value_t = detail::value_t;
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;
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;
7463 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
7465 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
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();
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) 7580 using object_comparator_t = std::less<StringType>;
7666 using object_t = ObjectType<StringType,
7668 object_comparator_t,
7669 AllocatorType<std::pair<
const StringType,
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 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 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)
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;
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,
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);
11429 bool empty()
const noexcept 11433 case value_t::null:
11439 case value_t::array:
11442 return m_value.array->empty();
11445 case value_t::object:
11448 return m_value.object->empty();
11501 size_type size()
const noexcept 11505 case value_t::null:
11511 case value_t::array:
11514 return m_value.array->size();
11517 case value_t::object:
11520 return m_value.object->size();
11571 size_type max_size()
const noexcept 11575 case value_t::array:
11578 return m_value.array->max_size();
11581 case value_t::object:
11584 return m_value.object->max_size();
11641 void clear()
noexcept 11645 case value_t::number_integer:
11647 m_value.number_integer = 0;
11651 case value_t::number_unsigned:
11653 m_value.number_unsigned = 0;
11657 case value_t::number_float:
11659 m_value.number_float = 0.0;
11663 case value_t::boolean:
11665 m_value.boolean =
false;
11669 case value_t::string:
11671 m_value.string->clear();
11675 case value_t::array:
11677 m_value.array->clear();
11681 case value_t::object:
11683 m_value.object->clear();
11717 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
11723 m_type = value_t::array;
11724 m_value = value_t::array;
11725 assert_invariant();
11729 m_value.array->push_back(std::move(val));
11731 val.m_type = value_t::null;
11740 push_back(std::move(val));
11753 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
11759 m_type = value_t::array;
11760 m_value = value_t::array;
11761 assert_invariant();
11765 m_value.array->push_back(val);
11798 void push_back(
const typename object_t::value_type& val)
11803 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
11809 m_type = value_t::object;
11810 m_value = value_t::object;
11811 assert_invariant();
11815 m_value.object->insert(val);
11822 reference operator+=(
const typename object_t::value_type& val)
11853 void push_back(initializer_list_t init)
11855 if (is_object()
and init.size() == 2
and (*init.begin())->is_string())
11857 basic_json&& key = init.begin()->moved_or_copied();
11858 push_back(
typename object_t::value_type(
11859 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
11871 reference operator+=(initializer_list_t init)
11898 template<
class... Args>
11899 void emplace_back(Args&& ... args)
11904 JSON_THROW(type_error::create(311,
"cannot use emplace_back() with " + std::string(type_name())));
11910 m_type = value_t::array;
11911 m_value = value_t::array;
11912 assert_invariant();
11916 m_value.array->emplace_back(std::forward<Args>(args)...);
11946 template<
class... Args>
11947 std::pair<iterator,
bool> emplace(Args&& ... args)
11952 JSON_THROW(type_error::create(311,
"cannot use emplace() with " + std::string(type_name())));
11958 m_type = value_t::object;
11959 m_value = value_t::object;
11960 assert_invariant();
11964 auto res = m_value.object->emplace(std::forward<Args>(args)...);
11967 it.m_it.object_iterator = res.first;
11970 return {it, res.second};
11995 iterator insert(const_iterator pos,
const basic_json& val)
12003 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
12007 iterator result(
this);
12008 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
12012 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12019 iterator insert(const_iterator pos,
basic_json&& val)
12021 return insert(pos, val);
12048 iterator insert(const_iterator pos, size_type cnt,
const basic_json& val)
12056 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
12060 iterator result(
this);
12061 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
12065 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12098 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
12103 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12109 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
12115 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
12120 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container"));
12124 iterator result(
this);
12125 result.m_it.array_iterator = m_value.array->insert(
12126 pos.m_it.array_iterator,
12127 first.m_it.array_iterator,
12128 last.m_it.array_iterator);
12156 iterator insert(const_iterator pos, initializer_list_t ilist)
12161 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12167 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
12171 iterator result(
this);
12172 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
12199 void insert(const_iterator first, const_iterator last)
12204 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
12210 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
12216 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
12219 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
12241 void update(const_reference j)
12246 m_type = value_t::object;
12247 m_value.object = create<object_t>();
12248 assert_invariant();
12253 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
12257 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(j.type_name())));
12260 for (
auto it = j.cbegin(); it != j.cend(); ++it)
12262 m_value.object->operator[](it.key()) = it.value();
12292 void update(const_iterator first, const_iterator last)
12297 m_type = value_t::object;
12298 m_value.object = create<object_t>();
12299 assert_invariant();
12304 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
12310 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
12315 or not first.m_object->is_object()))
12317 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
12320 for (
auto it = first; it != last; ++it)
12322 m_value.object->operator[](it.key()) = it.value();
12343 void swap(reference other)
noexcept (
12344 std::is_nothrow_move_constructible<value_t>::value
and 12345 std::is_nothrow_move_assignable<value_t>::value
and 12346 std::is_nothrow_move_constructible<json_value>::value
and 12347 std::is_nothrow_move_assignable<json_value>::value
12350 std::swap(m_type, other.m_type);
12351 std::swap(m_value, other.m_value);
12352 assert_invariant();
12375 void swap(array_t& other)
12380 std::swap(*(m_value.array), other);
12384 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
12408 void swap(object_t& other)
12413 std::swap(*(m_value.object), other);
12417 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
12441 void swap(string_t& other)
12446 std::swap(*(m_value.string), other);
12450 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
12503 friend bool operator==(const_reference lhs, const_reference rhs)
noexcept 12505 const auto lhs_type = lhs.type();
12506 const auto rhs_type = rhs.type();
12508 if (lhs_type == rhs_type)
12512 case value_t::array:
12513 return (*lhs.m_value.array == *rhs.m_value.array);
12515 case value_t::object:
12516 return (*lhs.m_value.object == *rhs.m_value.object);
12518 case value_t::null:
12521 case value_t::string:
12522 return (*lhs.m_value.string == *rhs.m_value.string);
12524 case value_t::boolean:
12525 return (lhs.m_value.boolean == rhs.m_value.boolean);
12527 case value_t::number_integer:
12528 return (lhs.m_value.number_integer == rhs.m_value.number_integer);
12530 case value_t::number_unsigned:
12531 return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
12533 case value_t::number_float:
12534 return (lhs.m_value.number_float == rhs.m_value.number_float);
12540 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_float)
12542 return (
static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
12544 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_integer)
12546 return (lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer));
12548 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_float)
12550 return (
static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
12552 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_unsigned)
12554 return (lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned));
12556 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_integer)
12558 return (
static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
12560 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_unsigned)
12562 return (lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned));
12572 template<
typename ScalarType,
typename std::enable_if<
12573 std::is_scalar<ScalarType>::value,
int>::type = 0>
12574 friend bool operator==(const_reference lhs,
const ScalarType rhs)
noexcept 12583 template<
typename ScalarType,
typename std::enable_if<
12584 std::is_scalar<ScalarType>::value,
int>::type = 0>
12585 friend bool operator==(
const ScalarType lhs, const_reference rhs)
noexcept 12608 friend bool operator!=(const_reference lhs, const_reference rhs)
noexcept 12610 return not (lhs == rhs);
12617 template<
typename ScalarType,
typename std::enable_if<
12618 std::is_scalar<ScalarType>::value,
int>::type = 0>
12619 friend bool operator!=(const_reference lhs,
const ScalarType rhs)
noexcept 12628 template<
typename ScalarType,
typename std::enable_if<
12629 std::is_scalar<ScalarType>::value,
int>::type = 0>
12630 friend bool operator!=(
const ScalarType lhs, const_reference rhs)
noexcept 12661 friend bool operator<(const_reference lhs, const_reference rhs)
noexcept 12663 const auto lhs_type = lhs.type();
12664 const auto rhs_type = rhs.type();
12666 if (lhs_type == rhs_type)
12670 case value_t::array:
12671 return (*lhs.m_value.array) < (*rhs.m_value.array);
12673 case value_t::object:
12674 return *lhs.m_value.object < *rhs.m_value.object;
12676 case value_t::null:
12679 case value_t::string:
12680 return *lhs.m_value.string < *rhs.m_value.string;
12682 case value_t::boolean:
12683 return lhs.m_value.boolean < rhs.m_value.boolean;
12685 case value_t::number_integer:
12686 return lhs.m_value.number_integer < rhs.m_value.number_integer;
12688 case value_t::number_unsigned:
12689 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
12691 case value_t::number_float:
12692 return lhs.m_value.number_float < rhs.m_value.number_float;
12698 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_float)
12700 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
12702 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_integer)
12704 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
12706 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_float)
12708 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
12710 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_unsigned)
12712 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
12714 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_unsigned)
12716 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
12718 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_integer)
12720 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
12726 return operator<(lhs_type, rhs_type);
12733 template<
typename ScalarType,
typename std::enable_if<
12734 std::is_scalar<ScalarType>::value,
int>::type = 0>
12735 friend bool operator<(const_reference lhs,
const ScalarType rhs)
noexcept 12744 template<
typename ScalarType,
typename std::enable_if<
12745 std::is_scalar<ScalarType>::value,
int>::type = 0>
12746 friend bool operator<(
const ScalarType lhs, const_reference rhs)
noexcept 12770 friend bool operator<=(const_reference lhs, const_reference rhs)
noexcept 12772 return not (rhs < lhs);
12779 template<
typename ScalarType,
typename std::enable_if<
12780 std::is_scalar<ScalarType>::value,
int>::type = 0>
12781 friend bool operator<=(const_reference lhs,
const ScalarType rhs)
noexcept 12790 template<
typename ScalarType,
typename std::enable_if<
12791 std::is_scalar<ScalarType>::value,
int>::type = 0>
12792 friend bool operator<=(
const ScalarType lhs, const_reference rhs)
noexcept 12816 friend bool operator>(const_reference lhs, const_reference rhs)
noexcept 12818 return not (lhs <= rhs);
12825 template<
typename ScalarType,
typename std::enable_if<
12826 std::is_scalar<ScalarType>::value,
int>::type = 0>
12827 friend bool operator>(const_reference lhs,
const ScalarType rhs)
noexcept 12836 template<
typename ScalarType,
typename std::enable_if<
12837 std::is_scalar<ScalarType>::value,
int>::type = 0>
12838 friend bool operator>(
const ScalarType lhs, const_reference rhs)
noexcept 12862 friend bool operator>=(const_reference lhs, const_reference rhs)
noexcept 12864 return not (lhs < rhs);
12871 template<
typename ScalarType,
typename std::enable_if<
12872 std::is_scalar<ScalarType>::value,
int>::type = 0>
12873 friend bool operator>=(const_reference lhs,
const ScalarType rhs)
noexcept 12882 template<
typename ScalarType,
typename std::enable_if<
12883 std::is_scalar<ScalarType>::value,
int>::type = 0>
12884 friend bool operator>=(
const ScalarType lhs, const_reference rhs)
noexcept 12929 friend std::ostream& operator<<(std::ostream& o,
const basic_json& j)
12932 const bool pretty_print = (o.width() > 0);
12933 const auto indentation = (pretty_print ? o.width() : 0);
12939 serializer s(detail::output_adapter<
char>(o), o.fill());
12940 s.dump(j, pretty_print,
false,
static_cast<
unsigned int>(indentation));
12953 friend std::ostream& operator>>(
const basic_json& j, std::ostream& o)
13030 static basic_json parse(detail::input_adapter i,
13031 const parser_callback_t cb =
nullptr,
13032 const bool allow_exceptions =
true)
13035 parser(i, cb, allow_exceptions).parse(
true, result);
13042 static basic_json parse(detail::input_adapter& i,
13043 const parser_callback_t cb =
nullptr,
13044 const bool allow_exceptions =
true)
13047 parser(i, cb, allow_exceptions).parse(
true, result);
13051 static bool accept(detail::input_adapter i)
13053 return parser(i).accept(
true);
13056 static bool accept(detail::input_adapter& i)
13058 return parser(i).accept(
true);
13108 template<
class IteratorType,
typename std::enable_if<
13110 std::random_access_iterator_tag,
13111 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
13112 static basic_json parse(IteratorType first, IteratorType last,
13113 const parser_callback_t cb =
nullptr,
13114 const bool allow_exceptions =
true)
13117 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(
true, result);
13121 template<
class IteratorType,
typename std::enable_if<
13123 std::random_access_iterator_tag,
13124 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
13125 static bool accept(IteratorType first, IteratorType last)
13127 return parser(detail::input_adapter(first, last)).accept(
true);
13139 friend std::istream& operator<<(
basic_json& j, std::istream& i)
13141 return operator>>(i, j);
13169 friend std::istream& operator>>(std::istream& i,
basic_json& j)
13171 parser(detail::input_adapter(i)).parse(
false, j);
13211 const char* type_name()
const noexcept 13216 case value_t::null:
13218 case value_t::object:
13220 case value_t::array:
13222 case value_t::string:
13224 case value_t::boolean:
13226 case value_t::discarded:
13227 return "discarded";
13241 value_t m_type = value_t::null;
13244 json_value m_value = {};
13340 static std::vector<uint8_t> to_cbor(
const basic_json& j)
13342 std::vector<uint8_t> result;
13343 to_cbor(j, result);
13347 static void to_cbor(
const basic_json& j, detail::output_adapter<uint8_t> o)
13349 binary_writer<uint8_t>(o).write_cbor(j);
13352 static void to_cbor(
const basic_json& j, detail::output_adapter<
char> o)
13354 binary_writer<
char>(o).write_cbor(j);
13435 static std::vector<uint8_t> to_msgpack(
const basic_json& j)
13437 std::vector<uint8_t> result;
13438 to_msgpack(j, result);
13442 static void to_msgpack(
const basic_json& j, detail::output_adapter<uint8_t> o)
13444 binary_writer<uint8_t>(o).write_msgpack(j);
13447 static void to_msgpack(
const basic_json& j, detail::output_adapter<
char> o)
13449 binary_writer<
char>(o).write_msgpack(j);
13543 static basic_json from_cbor(detail::input_adapter i,
13544 const bool strict =
true)
13546 return binary_reader(i).parse_cbor(strict);
13552 template<
typename A1,
typename A2,
13553 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
13554 static basic_json from_cbor(A1 && a1, A2 && a2,
const bool strict =
true)
13556 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_cbor(strict);
13630 static basic_json from_msgpack(detail::input_adapter i,
13631 const bool strict =
true)
13633 return binary_reader(i).parse_msgpack(strict);
13639 template<
typename A1,
typename A2,
13640 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
13641 static basic_json from_msgpack(A1 && a1, A2 && a2,
const bool strict =
true)
13643 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_msgpack(strict);
13688 reference operator[](
const json_pointer& ptr)
13690 return ptr.get_unchecked(
this);
13716 const_reference operator[](
const json_pointer& ptr)
const 13718 return ptr.get_unchecked(
this);
13759 reference at(
const json_pointer& ptr)
13761 return ptr.get_checked(
this);
13802 const_reference at(
const json_pointer& ptr)
const 13804 return ptr.get_checked(
this);
13832 json_pointer::flatten(
"", *
this, result);
13868 return json_pointer::unflatten(*
this);
13933 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
13935 const auto get_op = [](
const std::string & op)
13939 return patch_operations::add;
13941 if (op ==
"remove")
13943 return patch_operations::remove;
13945 if (op ==
"replace")
13947 return patch_operations::replace;
13951 return patch_operations::move;
13955 return patch_operations::copy;
13959 return patch_operations::test;
13962 return patch_operations::invalid;
13966 const auto operation_add = [&result](json_pointer & ptr,
basic_json val)
13976 json_pointer top_pointer = ptr.top();
13977 if (top_pointer != ptr)
13979 result.at(top_pointer);
13983 const auto last_path = ptr.pop_back();
13986 switch (parent.m_type)
13988 case value_t::null:
13989 case value_t::object:
13992 parent[last_path] = val;
13996 case value_t::array:
13998 if (last_path ==
"-")
14001 parent.push_back(val);
14005 const auto idx = json_pointer::array_index(last_path);
14006 if (
JSON_UNLIKELY(
static_cast<size_type>(idx) > parent.size()))
14009 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
14014 parent.insert(parent.begin() +
static_cast<difference_type>(idx), val);
14030 const auto operation_remove = [&result](json_pointer & ptr)
14033 const auto last_path = ptr.pop_back();
14037 if (parent.is_object())
14040 auto it = parent.find(last_path);
14047 JSON_THROW(out_of_range::create(403,
"key '" + last_path +
"' not found"));
14050 else if (parent.is_array())
14053 parent.erase(
static_cast<size_type>(json_pointer::array_index(last_path)));
14060 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
14064 for (
const auto& val : json_patch)
14067 const auto get_value = [&val](
const std::string & op,
14068 const std::string & member,
14072 auto it = val.m_value.object->find(member);
14075 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
14080 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have member '" + member +
"'"));
14084 if (
JSON_UNLIKELY(string_type
and not it->second.is_string()))
14086 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have string member '" + member +
"'"));
14096 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
14100 const std::string op = get_value(
"op",
"op",
true);
14101 const std::string path = get_value(op,
"path",
true);
14102 json_pointer ptr
(path
);
14104 switch (get_op(op))
14106 case patch_operations::add:
14108 operation_add(ptr, get_value(
"add",
"value",
false));
14112 case patch_operations::remove:
14114 operation_remove(ptr);
14118 case patch_operations::replace:
14121 result.at(ptr) = get_value(
"replace",
"value",
false);
14125 case patch_operations::move:
14127 const std::string from_path = get_value(
"move",
"from",
true);
14128 json_pointer from_ptr
(from_path
);
14137 operation_remove(from_ptr);
14138 operation_add(ptr, v);
14142 case patch_operations::copy:
14144 const std::string from_path = get_value(
"copy",
"from",
true);
14145 const json_pointer from_ptr
(from_path
);
14153 operation_add(ptr, v);
14157 case patch_operations::test:
14159 bool success =
false;
14164 success = (result.at(ptr) == get_value(
"test",
"value",
false));
14174 JSON_THROW(other_error::create(501,
"unsuccessful: " + val.dump()));
14180 case patch_operations::invalid:
14184 JSON_THROW(parse_error::create(105, 0,
"operation value '" + op +
"' is invalid"));
14225 const std::string& path =
"")
14231 if (source == target)
14236 if (source.type() != target.type())
14241 {
"op",
"replace"}, {
"path", path}, {
"value", target}
14246 switch (source.type())
14248 case value_t::array:
14252 while (i < source.size()
and i < target.size())
14255 auto temp_diff = diff(source[i], target[i], path +
"/" + std::to_string(i));
14256 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
14264 const auto end_index =
static_cast<difference_type>(result.size());
14265 while (i < source.size())
14269 result.insert(result.begin() + end_index, object(
14272 {
"path", path +
"/" + std::to_string(i)}
14278 while (i < target.size())
14283 {
"path", path +
"/" + std::to_string(i)},
14284 {
"value", target[i]}
14292 case value_t::object:
14295 for (
auto it = source.cbegin(); it != source.cend(); ++it)
14298 const auto key = json_pointer::escape(it.key());
14300 if (target.find(it.key()) != target.end())
14303 auto temp_diff = diff(it.value(), target[it.key()], path +
"/" + key);
14304 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
14309 result.push_back(object(
14311 {
"op",
"remove"}, {
"path", path +
"/" + key}
14317 for (
auto it = target.cbegin(); it != target.cend(); ++it)
14319 if (source.find(it.key()) == source.end())
14322 const auto key = json_pointer::escape(it.key());
14325 {
"op",
"add"}, {
"path", path +
"/" + key},
14326 {
"value", it.value()}
14339 {
"op",
"replace"}, {
"path", path}, {
"value", target}
14379 for (
const auto& reference_token : reference_tokens)
14381 switch (result->m_type)
14383 case detail::value_t::null:
14385 if (reference_token ==
"0")
14388 result = &result->operator[](0);
14393 result = &result->operator[](reference_token);
14398 case detail::value_t::object:
14401 result = &result->operator[](reference_token);
14405 case detail::value_t::array:
14410 result = &result->operator[](
static_cast<size_type>(array_index(reference_token)));
14414 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14426 JSON_THROW(detail::type_error::create(313,
"invalid value to unflatten"));
14438 for (
const auto& reference_token : reference_tokens)
14441 if (ptr->m_type == detail::value_t::null)
14445 std::all_of(reference_token.begin(), reference_token.end(),
14448 return (x >=
'0' and x <=
'9');
14452 *ptr = (nums
or reference_token ==
"-")
14453 ? detail::value_t::array
14454 : detail::value_t::object;
14457 switch (ptr->m_type)
14459 case detail::value_t::object:
14462 ptr = &ptr->operator[](reference_token);
14466 case detail::value_t::array:
14469 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
14471 JSON_THROW(detail::parse_error::create(106, 0,
14472 "array index '" + reference_token +
14473 "' must not begin with '0'"));
14476 if (reference_token ==
"-")
14479 ptr = &ptr->operator[](ptr->m_value.array->size());
14486 ptr = &ptr->operator[](
14487 static_cast<size_type>(array_index(reference_token)));
14491 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14498 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
14510 for (
const auto& reference_token : reference_tokens)
14512 switch (ptr->m_type)
14514 case detail::value_t::object:
14517 ptr = &ptr->at(reference_token);
14521 case detail::value_t::array:
14526 JSON_THROW(detail::out_of_range::create(402,
14527 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
14528 ") is out of range"));
14532 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
14534 JSON_THROW(detail::parse_error::create(106, 0,
14535 "array index '" + reference_token +
14536 "' must not begin with '0'"));
14542 ptr = &ptr->at(
static_cast<size_type>(array_index(reference_token)));
14546 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14552 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
14564 for (
const auto& reference_token : reference_tokens)
14566 switch (ptr->m_type)
14568 case detail::value_t::object:
14571 ptr = &ptr->operator[](reference_token);
14575 case detail::value_t::array:
14580 JSON_THROW(detail::out_of_range::create(402,
14581 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
14582 ") is out of range"));
14586 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
14588 JSON_THROW(detail::parse_error::create(106, 0,
14589 "array index '" + reference_token +
14590 "' must not begin with '0'"));
14596 ptr = &ptr->operator[](
14597 static_cast<size_type>(array_index(reference_token)));
14601 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14607 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
14619 for (
const auto& reference_token : reference_tokens)
14621 switch (ptr->m_type)
14623 case detail::value_t::object:
14626 ptr = &ptr->at(reference_token);
14630 case detail::value_t::array:
14635 JSON_THROW(detail::out_of_range::create(402,
14636 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
14637 ") is out of range"));
14641 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
14643 JSON_THROW(detail::parse_error::create(106, 0,
14644 "array index '" + reference_token +
14645 "' must not begin with '0'"));
14651 ptr = &ptr->at(
static_cast<size_type>(array_index(reference_token)));
14655 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
14661 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
14669 void json_pointer::flatten(
const std::string& reference_string,
14673 switch (value.m_type)
14675 case detail::value_t::array:
14677 if (value.m_value.array->empty())
14680 result[reference_string] =
nullptr;
14685 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
14687 flatten(reference_string +
"/" + std::to_string(i),
14688 value.m_value.array->operator[](i), result);
14694 case detail::value_t::object:
14696 if (value.m_value.object->empty())
14699 result[reference_string] =
nullptr;
14704 for (
const auto& element : *value.m_value.object)
14706 flatten(reference_string +
"/" + escape(element.first), element.second, result);
14715 result[reference_string] = value;
14727 JSON_THROW(detail::type_error::create(314,
"only objects can be unflattened"));
14733 for (
const auto& element : *value.m_value.object)
14737 JSON_THROW(detail::type_error::create(315,
"values in object must be primitive"));
14744 json_pointer(element.first).get_and_create(result) = element.second;
14752 return (lhs.reference_tokens == rhs.reference_tokens);
14757 return not (lhs == rhs);
14775 inline void swap(
nlohmann::json& j1,
14777 is_nothrow_move_constructible<nlohmann::json>::value
and 14778 is_nothrow_move_assignable<nlohmann::json>::value
14793 std::size_t operator()(
const nlohmann::json& j)
const 14796 const auto& h = hash<
nlohmann::json::string_t>();
14797 return h(j.dump());
14805 struct less< ::
nlohmann::detail::value_t>
14811 bool operator()(
nlohmann::detail::value_t lhs,
14812 nlohmann::detail::value_t rhs)
const noexcept 14814 return nlohmann::detail::operator<(lhs, rhs);
14833 inline nlohmann::json operator
"" _json(
const char* s, std::size_t n)
14835 return nlohmann::json::parse(s, s + n);
14851 inline nlohmann::json::json_pointer operator
"" _json_pointer(
const char* s, std::size_t n)
14853 return nlohmann::json::json_pointer
(std::string(s, n)
);
14857 #if defined(__clang__
) || defined(__GNUC__
) || defined(__GNUG__
) 14858 #pragma GCC diagnostic pop 14860 #if defined(__clang__
) 14861 #pragma GCC diagnostic pop 14869 #undef JSON_UNLIKELY 14870 #undef JSON_DEPRECATED 14871 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION 14872 #undef NLOHMANN_BASIC_JSON_TPL #define NLOHMANN_BASIC_JSON_TPL_DECLARATION
#define NLOHMANN_JSON_HAS_HELPER(type)
Helper to determine whether there's a key_type for T.
friend class basic_json
allow basic_json to access private members
static void from_json(BasicJsonType &&j, ValueType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val)))
convert a JSON value to any value type
constexpr const auto & from_json
#define JSON_CATCH(exception)
namespace for Niels Lohmann
#define NLOHMANN_BASIC_JSON_TPL
static void to_json(BasicJsonType &j, ValueType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< ValueType >(val))))
convert any value type to a JSON value
#define JSON_THROW(exception)
constexpr const auto & to_json
json_pointer(const std::string &s="")
create JSON pointer