29 #ifndef NLOHMANN_JSON_HPP 30 #define NLOHMANN_JSON_HPP 32 #define NLOHMANN_JSON_VERSION_MAJOR 3
33 #define NLOHMANN_JSON_VERSION_MINOR 1
34 #define NLOHMANN_JSON_VERSION_PATCH 2
41 #include <initializer_list> 49 #ifndef NLOHMANN_JSON_FWD_HPP 50 #define NLOHMANN_JSON_FWD_HPP 72 template<
typename =
void,
typename =
void>
73 struct adl_serializer;
75 template<
template<
typename U,
typename V,
typename... Args>
class ObjectType =
77 template<
typename U,
typename... Args>
class ArrayType = std::vector,
78 class StringType = std::string,
class BooleanType =
bool,
79 class NumberIntegerType = std::int64_t,
80 class NumberUnsignedType = std::uint64_t,
81 class NumberFloatType =
double,
82 template<
typename U>
class AllocatorType = std::allocator,
83 template<
typename T,
typename SFINAE =
void>
class JSONSerializer =
98 template<
typename BasicJsonType>
109 using json = basic_json<>;
121 #if defined(__clang__
) 122 #if (__clang_major__
* 10000
+ __clang_minor__
* 100
+ __clang_patchlevel__
) < 30400
123 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" 125 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) 126 #if (__GNUC__ * 10000
+ __GNUC_MINOR__ * 100
+ __GNUC_PATCHLEVEL__) < 40900
127 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" 132 #if defined(__clang__
) || defined(__GNUC__
) || defined(__GNUG__
) 133 #pragma GCC diagnostic push 134 #pragma GCC diagnostic ignored "-Wfloat-equal" 138 #if defined(__clang__
) 139 #pragma GCC diagnostic push 140 #pragma GCC diagnostic ignored "-Wdocumentation" 144 #if defined(__clang__
) || defined(__GNUC__
) || defined(__GNUG__
) 145 #define JSON_DEPRECATED __attribute__((deprecated)) 146 #elif defined(_MSC_VER) 147 #define JSON_DEPRECATED __declspec(deprecated) 149 #define JSON_DEPRECATED 153 #if (defined(__cpp_exceptions
) || defined(__EXCEPTIONS
) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) 154 #define JSON_THROW(exception) throw exception 156 #define JSON_CATCH(exception) catch(exception) 158 #define JSON_THROW(exception) std::abort() 159 #define JSON_TRY if(true) 160 #define JSON_CATCH(exception) if(false) 164 #if defined(JSON_THROW_USER) 166 #define JSON_THROW JSON_THROW_USER 168 #if defined(JSON_TRY_USER) 170 #define JSON_TRY JSON_TRY_USER 172 #if defined(JSON_CATCH_USER) 174 #define JSON_CATCH JSON_CATCH_USER 178 #if defined(__clang__
) || defined(__GNUC__
) || defined(__GNUG__
) 179 #define JSON_LIKELY(x) __builtin_expect(!!(x), 1
) 180 #define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0
) 182 #define JSON_LIKELY(x) x 183 #define JSON_UNLIKELY(x) x 187 #if (defined(__cplusplus
) && __cplusplus
>= 201703L
) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1
) 188 #define JSON_HAS_CPP_17 189 #define JSON_HAS_CPP_14 190 #elif (defined(__cplusplus
) && __cplusplus
>= 201402L
) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1
) 191 #define JSON_HAS_CPP_14 197 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION 198 template<template<typename, typename, typename...> class ObjectType, 199 template<typename, typename...> class ArrayType, 200 class StringType, class BooleanType, class NumberIntegerType, 201 class NumberUnsignedType, class NumberFloatType, 202 template<typename> class AllocatorType, 203 template<typename, typename = void> class JSONSerializer> 205 #define NLOHMANN_BASIC_JSON_TPL 206 basic_json<ObjectType, ArrayType, StringType, BooleanType, 207 NumberIntegerType, NumberUnsignedType, NumberFloatType, 208 AllocatorType, JSONSerializer> 220 #define NLOHMANN_JSON_HAS_HELPER(type) 221 template<typename T> struct has_##type { 223 template<typename U, typename = typename U::type> 224 static int detect(U &&); 225 static void detect(...); 227 static constexpr bool value = 228 std::is_integral<decltype(detect(std::declval<T>()))>::value; 237 #include <type_traits> 261 template<
typename>
struct is_basic_json : std::false_type {};
267 template<
bool B,
typename T =
void>
268 using enable_if_t =
typename std::enable_if<B, T>::type;
271 using uncvref_t =
typename std::remove_cv<
typename std::remove_reference<T>::type>::type;
275 template<std::size_t... Ints>
276 struct index_sequence
278 using type = index_sequence;
279 using value_type = std::size_t;
280 static constexpr std::size_t size()
noexcept 282 return sizeof...(Ints);
286 template<
class Sequence1,
class Sequence2>
287 struct merge_and_renumber;
289 template<std::size_t... I1, std::size_t... I2>
290 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
291 : index_sequence < I1..., (
sizeof...(I1) + I2)... > {};
293 template<std::size_t N>
294 struct make_index_sequence
295 : merge_and_renumber <
typename make_index_sequence < N / 2 >::type,
296 typename make_index_sequence < N - N / 2 >::type > {};
298 template<>
struct make_index_sequence<0> : index_sequence<> {};
299 template<>
struct make_index_sequence<1> : index_sequence<0> {};
301 template<
typename... Ts>
302 using index_sequence_for = make_index_sequence<
sizeof...(Ts)>;
317 template<
class...>
struct conjunction : std::true_type {};
318 template<
class B1>
struct conjunction<B1> : B1 {};
319 template<
class B1,
class... Bn>
320 struct conjunction<B1, Bn...> : std::conditional<
bool(B1::value), conjunction<Bn...>, B1>::type {};
322 template<
class B>
struct negation : std::integral_constant<
bool,
not B::value> {};
325 template<
unsigned N>
struct priority_tag : priority_tag < N - 1 > {};
326 template<>
struct priority_tag<0> {};
334 template <
typename T,
typename =
void>
335 struct is_complete_type : std::false_type {};
337 template <
typename T>
338 struct is_complete_type<T,
decltype(
void(
sizeof(T)))> : std::true_type {};
345 template<
bool B,
class RealType,
class CompatibleObjectType>
346 struct is_compatible_object_type_impl : std::false_type {};
348 template<
class RealType,
class CompatibleObjectType>
349 struct is_compatible_object_type_impl<
true, RealType, CompatibleObjectType>
351 static constexpr auto value =
352 std::is_constructible<
typename RealType::key_type,
typename CompatibleObjectType::key_type>::value
and 353 std::is_constructible<
typename RealType::mapped_type,
typename CompatibleObjectType::mapped_type>::value;
356 template<
class BasicJsonType,
class CompatibleObjectType>
357 struct is_compatible_object_type
359 static auto constexpr value = is_compatible_object_type_impl <
360 conjunction<negation<std::is_same<
void, CompatibleObjectType>>,
361 has_mapped_type<CompatibleObjectType>,
362 has_key_type<CompatibleObjectType>>::value,
363 typename BasicJsonType::object_t, CompatibleObjectType >::value;
366 template<
typename BasicJsonType,
typename T>
367 struct is_basic_json_nested_type
369 static auto constexpr value = std::is_same<T,
typename BasicJsonType::iterator>::value
or 370 std::is_same<T,
typename BasicJsonType::const_iterator>::value
or 371 std::is_same<T,
typename BasicJsonType::reverse_iterator>::value
or 372 std::is_same<T,
typename BasicJsonType::const_reverse_iterator>::value;
375 template<
class BasicJsonType,
class CompatibleArrayType>
376 struct is_compatible_array_type
378 static auto constexpr value =
379 conjunction<negation<std::is_same<
void, CompatibleArrayType>>,
380 negation<is_compatible_object_type<
381 BasicJsonType, CompatibleArrayType>>,
382 negation<std::is_constructible<
typename BasicJsonType::string_t,
383 CompatibleArrayType>>,
384 negation<is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>>,
385 has_value_type<CompatibleArrayType>,
386 has_iterator<CompatibleArrayType>>::value;
389 template<
bool,
typename,
typename>
390 struct is_compatible_integer_type_impl : std::false_type {};
392 template<
typename RealIntegerType,
typename CompatibleNumberIntegerType>
393 struct is_compatible_integer_type_impl<
true, RealIntegerType, CompatibleNumberIntegerType>
396 using RealLimits = std::numeric_limits<RealIntegerType>;
397 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
399 static constexpr auto value =
400 std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value
and 401 CompatibleLimits::is_integer
and 402 RealLimits::is_signed == CompatibleLimits::is_signed;
405 template<
typename RealIntegerType,
typename CompatibleNumberIntegerType>
406 struct is_compatible_integer_type
408 static constexpr auto value =
409 is_compatible_integer_type_impl <
410 std::is_integral<CompatibleNumberIntegerType>::value
and 411 not std::is_same<
bool, CompatibleNumberIntegerType>::value,
412 RealIntegerType, CompatibleNumberIntegerType > ::value;
416 template<
typename BasicJsonType,
typename T>
421 template<
typename U,
typename = enable_if_t<std::is_same<
void,
decltype(uncvref_t<U>::from_json(
422 std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
423 static int detect(U&&);
424 static void detect(...);
427 static constexpr bool value = std::is_integral<
decltype(
428 detect(std::declval<
typename BasicJsonType::
template json_serializer<T,
void>>()))>::value;
433 template<
typename BasicJsonType,
typename T>
434 struct has_non_default_from_json
439 typename = enable_if_t<std::is_same<
440 T,
decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
441 static int detect(U&&);
442 static void detect(...);
445 static constexpr bool value = std::is_integral<
decltype(detect(
446 std::declval<
typename BasicJsonType::
template json_serializer<T,
void>>()))>::value;
450 template<
typename BasicJsonType,
typename T>
454 template<
typename U,
typename =
decltype(uncvref_t<U>::to_json(
455 std::declval<BasicJsonType&>(), std::declval<T>()))>
456 static int detect(U&&);
457 static void detect(...);
460 static constexpr bool value = std::is_integral<
decltype(detect(
461 std::declval<
typename BasicJsonType::
template json_serializer<T,
void>>()))>::value;
464 template <
typename BasicJsonType,
typename CompatibleCompleteType>
465 struct is_compatible_complete_type
467 static constexpr bool value =
468 not std::is_base_of<std::istream, CompatibleCompleteType>::value
and 469 not is_basic_json<CompatibleCompleteType>::value
and 470 not is_basic_json_nested_type<BasicJsonType, CompatibleCompleteType>::value
and 471 has_to_json<BasicJsonType, CompatibleCompleteType>::value;
474 template <
typename BasicJsonType,
typename CompatibleType>
475 struct is_compatible_type
476 : conjunction<is_complete_type<CompatibleType>,
477 is_compatible_complete_type<BasicJsonType, CompatibleType>>
485 static constexpr T value{};
489 constexpr T static_const<T>::value;
536 class exception :
public std::exception
540 const char* what()
const noexcept override
549 exception(
int id_,
const char* what_arg) : id(id_), m(what_arg) {}
551 static std::string name(
const std::string& ename,
int id_)
553 return "[json.exception." + ename +
"." + std::to_string(id_) +
"] ";
558 std::runtime_error m;
604 class parse_error :
public exception
615 static parse_error create(
int id_, std::size_t byte_,
const std::string& what_arg)
617 std::string w = exception::name(
"parse_error", id_) +
"parse error" +
618 (byte_ != 0 ? (
" at " + std::to_string(byte_)) :
"") +
620 return parse_error(id_, byte_, w.c_str());
632 const std::size_t byte;
635 parse_error(
int id_, std::size_t byte_,
const char* what_arg)
636 : exception(id_, what_arg), byte(byte_) {}
676 class invalid_iterator :
public exception
679 static invalid_iterator create(
int id_,
const std::string& what_arg)
681 std::string w = exception::name(
"invalid_iterator", id_) + what_arg;
682 return invalid_iterator(id_, w.c_str());
686 invalid_iterator(
int id_,
const char* what_arg)
687 : exception(id_, what_arg) {}
728 class type_error :
public exception
731 static type_error create(
int id_,
const std::string& what_arg)
733 std::string w = exception::name(
"type_error", id_) + what_arg;
734 return type_error(id_, w.c_str());
738 type_error(
int id_,
const char* what_arg) : exception(id_, what_arg) {}
773 class out_of_range :
public exception
776 static out_of_range create(
int id_,
const std::string& what_arg)
778 std::string w = exception::name(
"out_of_range", id_) + what_arg;
779 return out_of_range(id_, w.c_str());
783 out_of_range(
int id_,
const char* what_arg) : exception(id_, what_arg) {}
810 class other_error :
public exception
813 static other_error create(
int id_,
const std::string& what_arg)
815 std::string w = exception::name(
"other_error", id_) + what_arg;
816 return other_error(id_, w.c_str());
820 other_error(
int id_,
const char* what_arg) : exception(id_, what_arg) {}
865 enum class value_t : std::uint8_t
888 inline bool operator<(
const value_t lhs,
const value_t rhs)
noexcept 890 static constexpr std::array<std::uint8_t, 8> order = {{
896 const auto l_index =
static_cast<std::size_t>(lhs);
897 const auto r_index =
static_cast<std::size_t>(rhs);
898 return l_index < order.size()
and r_index < order.size()
and order[l_index] < order[r_index];
909 #include <forward_list> 913 #include <type_traits> 931 template<
typename BasicJsonType,
typename ArithmeticType,
932 enable_if_t<std::is_arithmetic<ArithmeticType>::value
and 933 not std::is_same<ArithmeticType,
typename BasicJsonType::boolean_t>::value,
935 void get_arithmetic_value(
const BasicJsonType& j, ArithmeticType& val)
937 switch (
static_cast<value_t>(j))
939 case value_t::number_unsigned:
941 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_unsigned_t*>());
944 case value_t::number_integer:
946 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_integer_t*>());
949 case value_t::number_float:
951 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_float_t*>());
956 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
960 template<
typename BasicJsonType>
961 void from_json(
const BasicJsonType& j,
typename BasicJsonType::boolean_t& b)
965 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(j.type_name())));
967 b = *j.
template get_ptr<
const typename BasicJsonType::boolean_t*>();
970 template<
typename BasicJsonType>
971 void from_json(
const BasicJsonType& j,
typename BasicJsonType::string_t& s)
975 JSON_THROW(type_error::create(302,
"type must be string, but is " + std::string(j.type_name())));
977 s = *j.
template get_ptr<
const typename BasicJsonType::string_t*>();
980 template<
typename BasicJsonType>
981 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_float_t& val)
983 get_arithmetic_value(j, val);
986 template<
typename BasicJsonType>
987 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_unsigned_t& val)
989 get_arithmetic_value(j, val);
992 template<
typename BasicJsonType>
993 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_integer_t& val)
995 get_arithmetic_value(j, val);
998 template<
typename BasicJsonType,
typename EnumType,
999 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
1000 void from_json(
const BasicJsonType& j, EnumType& e)
1002 typename std::underlying_type<EnumType>::type val;
1003 get_arithmetic_value(j, val);
1004 e =
static_cast<EnumType>(val);
1007 template<
typename BasicJsonType>
1008 void from_json(
const BasicJsonType& j,
typename BasicJsonType::array_t& arr)
1012 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1014 arr = *j.
template get_ptr<
const typename BasicJsonType::array_t*>();
1018 template<
typename BasicJsonType,
typename T,
typename Allocator,
1019 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1020 void from_json(
const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1024 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1026 std::transform(j.rbegin(), j.rend(),
1027 std::front_inserter(l), [](
const BasicJsonType & i)
1029 return i.
template get<T>();
1034 template<
typename BasicJsonType,
typename T,
1035 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1036 void from_json(
const BasicJsonType& j, std::valarray<T>& l)
1040 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1043 std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1046 template<
typename BasicJsonType,
typename CompatibleArrayType>
1047 void from_json_array_impl(
const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0> )
1051 std::transform(j.begin(), j.end(),
1052 std::inserter(arr, end(arr)), [](
const BasicJsonType & i)
1056 return i.
template get<
typename CompatibleArrayType::value_type>();
1060 template<
typename BasicJsonType,
typename CompatibleArrayType>
1061 auto from_json_array_impl(
const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1> )
1063 arr.reserve(std::declval<
typename CompatibleArrayType::size_type>()),
1068 arr.reserve(j.size());
1069 std::transform(j.begin(), j.end(),
1070 std::inserter(arr, end(arr)), [](
const BasicJsonType & i)
1074 return i.
template get<
typename CompatibleArrayType::value_type>();
1078 template<
typename BasicJsonType,
typename T, std::size_t N>
1079 void from_json_array_impl(
const BasicJsonType& j, std::array<T, N>& arr, priority_tag<2> )
1081 for (std::size_t i = 0; i < N; ++i)
1083 arr[i] = j.at(i).
template get<T>();
1088 typename BasicJsonType,
typename CompatibleArrayType,
1090 is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value
and 1091 not std::is_same<
typename BasicJsonType::array_t,
1092 CompatibleArrayType>::value
and 1093 std::is_constructible <
1094 BasicJsonType,
typename CompatibleArrayType::value_type >::value,
1096 void from_json(
const BasicJsonType& j, CompatibleArrayType& arr)
1100 JSON_THROW(type_error::create(302,
"type must be array, but is " +
1101 std::string(j.type_name())));
1104 from_json_array_impl(j, arr, priority_tag<2> {});
1107 template<
typename BasicJsonType,
typename CompatibleObjectType,
1108 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
int> = 0>
1109 void from_json(
const BasicJsonType& j, CompatibleObjectType& obj)
1113 JSON_THROW(type_error::create(302,
"type must be object, but is " + std::string(j.type_name())));
1116 auto inner_object = j.
template get_ptr<
const typename BasicJsonType::object_t*>();
1117 using value_type =
typename CompatibleObjectType::value_type;
1119 inner_object->begin(), inner_object->end(),
1120 std::inserter(obj, obj.begin()),
1121 [](
typename BasicJsonType::object_t::value_type
const & p)
1123 return value_type(p.first, p.second.
template get<
typename CompatibleObjectType::mapped_type>());
1131 template<
typename BasicJsonType,
typename ArithmeticType,
1133 std::is_arithmetic<ArithmeticType>::value
and 1134 not std::is_same<ArithmeticType,
typename BasicJsonType::number_unsigned_t>::value
and 1135 not std::is_same<ArithmeticType,
typename BasicJsonType::number_integer_t>::value
and 1136 not std::is_same<ArithmeticType,
typename BasicJsonType::number_float_t>::value
and 1137 not std::is_same<ArithmeticType,
typename BasicJsonType::boolean_t>::value,
1139 void from_json(
const BasicJsonType& j, ArithmeticType& val)
1141 switch (
static_cast<value_t>(j))
1143 case value_t::number_unsigned:
1145 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_unsigned_t*>());
1148 case value_t::number_integer:
1150 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_integer_t*>());
1153 case value_t::number_float:
1155 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_float_t*>());
1158 case value_t::boolean:
1160 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::boolean_t*>());
1165 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
1169 template<
typename BasicJsonType,
typename A1,
typename A2>
1170 void from_json(
const BasicJsonType& j, std::pair<A1, A2>& p)
1172 p = {j.at(0).
template get<A1>(), j.at(1).
template get<A2>()};
1175 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1176 void from_json_tuple_impl(
const BasicJsonType& j, Tuple& t, index_sequence<Idx...>)
1178 t = std::make_tuple(j.at(Idx).
template get<
typename std::tuple_element<Idx, Tuple>::type>()...);
1181 template<
typename BasicJsonType,
typename... Args>
1182 void from_json(
const BasicJsonType& j, std::tuple<Args...>& t)
1184 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1190 template<
typename BasicJsonType,
typename T>
1191 auto call(
const BasicJsonType& j, T& val, priority_tag<1> )
const 1192 noexcept(
noexcept(from_json(j, val)))
1193 ->
decltype(from_json(j, val),
void())
1195 return from_json(j, val);
1198 template<
typename BasicJsonType,
typename T>
1199 void call(
const BasicJsonType& , T& , priority_tag<0> )
const noexcept 1201 static_assert(
sizeof(BasicJsonType) == 0,
1202 "could not find from_json() method in T's namespace");
1205 using decayed = uncvref_t<T>;
1206 static_assert(
sizeof(
typename decayed::force_msvc_stacktrace) == 0,
1207 "forcing MSVC stacktrace to show which T we're talking about.");
1212 template<
typename BasicJsonType,
typename T>
1213 void operator()(
const BasicJsonType& j, T& val)
const 1214 noexcept(
noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
1216 return call(j, val, priority_tag<1> {});
1226 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
1236 #include <type_traits> 1254 template<value_t>
struct external_constructor;
1257 struct external_constructor<value_t::boolean>
1259 template<
typename BasicJsonType>
1260 static void construct(BasicJsonType& j,
typename BasicJsonType::boolean_t b)
noexcept 1262 j.m_type = value_t::boolean;
1264 j.assert_invariant();
1269 struct external_constructor<value_t::string>
1271 template<
typename BasicJsonType>
1272 static void construct(BasicJsonType& j,
const typename BasicJsonType::string_t& s)
1274 j.m_type = value_t::string;
1276 j.assert_invariant();
1279 template<
typename BasicJsonType>
1280 static void construct(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
1282 j.m_type = value_t::string;
1283 j.m_value = std::move(s);
1284 j.assert_invariant();
1289 struct external_constructor<value_t::number_float>
1291 template<
typename BasicJsonType>
1292 static void construct(BasicJsonType& j,
typename BasicJsonType::number_float_t val)
noexcept 1294 j.m_type = value_t::number_float;
1296 j.assert_invariant();
1301 struct external_constructor<value_t::number_unsigned>
1303 template<
typename BasicJsonType>
1304 static void construct(BasicJsonType& j,
typename BasicJsonType::number_unsigned_t val)
noexcept 1306 j.m_type = value_t::number_unsigned;
1308 j.assert_invariant();
1313 struct external_constructor<value_t::number_integer>
1315 template<
typename BasicJsonType>
1316 static void construct(BasicJsonType& j,
typename BasicJsonType::number_integer_t val)
noexcept 1318 j.m_type = value_t::number_integer;
1320 j.assert_invariant();
1325 struct external_constructor<value_t::array>
1327 template<
typename BasicJsonType>
1328 static void construct(BasicJsonType& j,
const typename BasicJsonType::array_t& arr)
1330 j.m_type = value_t::array;
1332 j.assert_invariant();
1335 template<
typename BasicJsonType>
1336 static void construct(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
1338 j.m_type = value_t::array;
1339 j.m_value = std::move(arr);
1340 j.assert_invariant();
1343 template<
typename BasicJsonType,
typename CompatibleArrayType,
1344 enable_if_t<
not std::is_same<CompatibleArrayType,
typename BasicJsonType::array_t>::value,
1346 static void construct(BasicJsonType& j,
const CompatibleArrayType& arr)
1350 j.m_type = value_t::array;
1351 j.m_value.array = j.
template create<
typename BasicJsonType::array_t>(begin(arr), end(arr));
1352 j.assert_invariant();
1355 template<
typename BasicJsonType>
1356 static void construct(BasicJsonType& j,
const std::vector<
bool>& arr)
1358 j.m_type = value_t::array;
1359 j.m_value = value_t::array;
1360 j.m_value.array->reserve(arr.size());
1361 for (
const bool x : arr)
1363 j.m_value.array->push_back(x);
1365 j.assert_invariant();
1368 template<
typename BasicJsonType,
typename T,
1369 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
1370 static void construct(BasicJsonType& j,
const std::valarray<T>& arr)
1372 j.m_type = value_t::array;
1373 j.m_value = value_t::array;
1374 j.m_value.array->resize(arr.size());
1375 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
1376 j.assert_invariant();
1381 struct external_constructor<value_t::object>
1383 template<
typename BasicJsonType>
1384 static void construct(BasicJsonType& j,
const typename BasicJsonType::object_t& obj)
1386 j.m_type = value_t::object;
1388 j.assert_invariant();
1391 template<
typename BasicJsonType>
1392 static void construct(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
1394 j.m_type = value_t::object;
1395 j.m_value = std::move(obj);
1396 j.assert_invariant();
1399 template<
typename BasicJsonType,
typename CompatibleObjectType,
1400 enable_if_t<
not std::is_same<CompatibleObjectType,
typename BasicJsonType::object_t>::value,
int> = 0>
1401 static void construct(BasicJsonType& j,
const CompatibleObjectType& obj)
1406 j.m_type = value_t::object;
1407 j.m_value.object = j.
template create<
typename BasicJsonType::object_t>(begin(obj), end(obj));
1408 j.assert_invariant();
1416 template<
typename BasicJsonType,
typename T,
1417 enable_if_t<std::is_same<T,
typename BasicJsonType::boolean_t>::value,
int> = 0>
1418 void to_json(BasicJsonType& j, T b)
noexcept 1420 external_constructor<value_t::boolean>::construct(j, b);
1423 template<
typename BasicJsonType,
typename CompatibleString,
1424 enable_if_t<std::is_constructible<
typename BasicJsonType::string_t, CompatibleString>::value,
int> = 0>
1425 void to_json(BasicJsonType& j,
const CompatibleString& s)
1427 external_constructor<value_t::string>::construct(j, s);
1430 template<
typename BasicJsonType>
1431 void to_json(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
1433 external_constructor<value_t::string>::construct(j, std::move(s));
1436 template<
typename BasicJsonType,
typename FloatType,
1437 enable_if_t<std::is_floating_point<FloatType>::value,
int> = 0>
1438 void to_json(BasicJsonType& j, FloatType val)
noexcept 1440 external_constructor<value_t::number_float>::construct(j,
static_cast<
typename BasicJsonType::number_float_t>(val));
1443 template<
typename BasicJsonType,
typename CompatibleNumberUnsignedType,
1444 enable_if_t<is_compatible_integer_type<
typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value,
int> = 0>
1445 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val)
noexcept 1447 external_constructor<value_t::number_unsigned>::construct(j,
static_cast<
typename BasicJsonType::number_unsigned_t>(val));
1450 template<
typename BasicJsonType,
typename CompatibleNumberIntegerType,
1451 enable_if_t<is_compatible_integer_type<
typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value,
int> = 0>
1452 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val)
noexcept 1454 external_constructor<value_t::number_integer>::construct(j,
static_cast<
typename BasicJsonType::number_integer_t>(val));
1457 template<
typename BasicJsonType,
typename EnumType,
1458 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
1459 void to_json(BasicJsonType& j, EnumType e)
noexcept 1461 using underlying_type =
typename std::underlying_type<EnumType>::type;
1462 external_constructor<value_t::number_integer>::construct(j,
static_cast<underlying_type>(e));
1465 template<
typename BasicJsonType>
1466 void to_json(BasicJsonType& j,
const std::vector<
bool>& e)
1468 external_constructor<value_t::array>::construct(j, e);
1471 template<
typename BasicJsonType,
typename CompatibleArrayType,
1472 enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value
or 1473 std::is_same<
typename BasicJsonType::array_t, CompatibleArrayType>::value,
1475 void to_json(BasicJsonType& j,
const CompatibleArrayType& arr)
1477 external_constructor<value_t::array>::construct(j, arr);
1480 template<
typename BasicJsonType,
typename T,
1481 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
1482 void to_json(BasicJsonType& j, std::valarray<T> arr)
1484 external_constructor<value_t::array>::construct(j, std::move(arr));
1487 template<
typename BasicJsonType>
1488 void to_json(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
1490 external_constructor<value_t::array>::construct(j, std::move(arr));
1493 template<
typename BasicJsonType,
typename CompatibleObjectType,
1494 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
int> = 0>
1495 void to_json(BasicJsonType& j,
const CompatibleObjectType& obj)
1497 external_constructor<value_t::object>::construct(j, obj);
1500 template<
typename BasicJsonType>
1501 void to_json(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
1503 external_constructor<value_t::object>::construct(j, std::move(obj));
1506 template<
typename BasicJsonType,
typename T, std::size_t N,
1507 enable_if_t<
not std::is_constructible<
typename BasicJsonType::string_t, T (&)[N]>::value,
int> = 0>
1508 void to_json(BasicJsonType& j, T (&arr)[N])
1510 external_constructor<value_t::array>::construct(j, arr);
1513 template<
typename BasicJsonType,
typename... Args>
1514 void to_json(BasicJsonType& j,
const std::pair<Args...>& p)
1516 j = {p.first, p.second};
1519 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1520 void to_json_tuple_impl(BasicJsonType& j,
const Tuple& t, index_sequence<Idx...>)
1522 j = {std::get<Idx>(t)...};
1525 template<
typename BasicJsonType,
typename... Args>
1526 void to_json(BasicJsonType& j,
const std::tuple<Args...>& t)
1528 to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1534 template<
typename BasicJsonType,
typename T>
1535 auto call(BasicJsonType& j, T&& val, priority_tag<1> )
const noexcept(
noexcept(to_json(j, std::forward<T>(val))))
1536 ->
decltype(to_json(j, std::forward<T>(val)),
void())
1538 return to_json(j, std::forward<T>(val));
1541 template<
typename BasicJsonType,
typename T>
1542 void call(BasicJsonType& , T&& , priority_tag<0> )
const noexcept 1544 static_assert(
sizeof(BasicJsonType) == 0,
1545 "could not find to_json() method in T's namespace");
1549 using decayed = uncvref_t<T>;
1550 static_assert(
sizeof(
typename decayed::force_msvc_stacktrace) == 0,
1551 "forcing MSVC stacktrace to show which T we're talking about.");
1556 template<
typename BasicJsonType,
typename T>
1557 void operator()(BasicJsonType& j, T&& val)
const 1558 noexcept(
noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1> {})))
1560 return call(j, std::forward<T>(val), priority_tag<1> {});
1568 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
1575 #include <algorithm> 1586 #include <type_traits> 1611 struct input_adapter_protocol
1614 virtual std::char_traits<
char>::int_type get_character() = 0;
1616 virtual void unget_character() = 0;
1617 virtual ~input_adapter_protocol() =
default;
1621 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
1632 class input_stream_adapter :
public input_adapter_protocol
1635 ~input_stream_adapter() override
1642 explicit input_stream_adapter(std::istream& i)
1643 : is(i), sb(*i.rdbuf())
1646 std::char_traits<
char>::int_type c;
1647 if ((c = get_character()) == 0xEF)
1649 if ((c = get_character()) == 0xBB)
1651 if ((c = get_character()) == 0xBF)
1655 else if (c != std::char_traits<
char>::eof())
1661 else if (c != std::char_traits<
char>::eof())
1667 else if (c != std::char_traits<
char>::eof())
1674 input_stream_adapter(
const input_stream_adapter&) =
delete;
1675 input_stream_adapter& operator=(input_stream_adapter&) =
delete;
1680 std::char_traits<
char>::int_type get_character() override
1685 void unget_character() override
1697 class input_buffer_adapter :
public input_adapter_protocol
1700 input_buffer_adapter(
const char* b,
const std::size_t l)
1701 : cursor(b), limit(b + l), start(b)
1704 if (l >= 3
and b[0] ==
'\xEF' and b[1] ==
'\xBB' and b[2] ==
'\xBF')
1711 input_buffer_adapter(
const input_buffer_adapter&) =
delete;
1712 input_buffer_adapter& operator=(input_buffer_adapter&) =
delete;
1714 std::char_traits<
char>::int_type get_character()
noexcept override
1718 return std::char_traits<
char>::to_int_type(*(cursor++));
1721 return std::char_traits<
char>::eof();
1724 void unget_character()
noexcept override
1747 input_adapter(std::istream& i)
1748 : ia(std::make_shared<input_stream_adapter>(i)) {}
1751 input_adapter(std::istream&& i)
1752 : ia(std::make_shared<input_stream_adapter>(i)) {}
1755 template<
typename CharT,
1756 typename std::enable_if<
1757 std::is_pointer<CharT>::value
and 1758 std::is_integral<
typename std::remove_pointer<CharT>::type>::value
and 1759 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
1761 input_adapter(CharT b, std::size_t l)
1762 : ia(std::make_shared<input_buffer_adapter>(
reinterpret_cast<
const char*>(b), l)) {}
1767 template<
typename CharT,
1768 typename std::enable_if<
1769 std::is_pointer<CharT>::value
and 1770 std::is_integral<
typename std::remove_pointer<CharT>::type>::value
and 1771 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
1773 input_adapter(CharT b)
1774 : input_adapter(
reinterpret_cast<
const char*>(b),
1775 std::strlen(
reinterpret_cast<
const char*>(b))) {}
1778 template<
class IteratorType,
1779 typename std::enable_if<
1780 std::is_same<
typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
1782 input_adapter(IteratorType first, IteratorType last)
1786 assert(std::accumulate(
1787 first, last, std::pair<
bool,
int>(
true, 0),
1788 [&first](std::pair<
bool,
int> res,
decltype(*first) val)
1790 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
1796 sizeof(
typename std::iterator_traits<IteratorType>::value_type) == 1,
1797 "each element in the iterator range must have the size of 1 byte");
1799 const auto len =
static_cast<size_t>(std::distance(first, last));
1803 ia = std::make_shared<input_buffer_adapter>(
reinterpret_cast<
const char*>(&(*first)), len);
1808 ia = std::make_shared<input_buffer_adapter>(
nullptr, len);
1813 template<
class T, std::size_t N>
1814 input_adapter(T (&array)[N])
1815 : input_adapter(std::begin(array), std::end(array)) {}
1818 template<
class ContiguousContainer,
typename 1819 std::enable_if<
not std::is_pointer<ContiguousContainer>::value
and 1820 std::is_base_of<std::random_access_iterator_tag,
typename std::iterator_traits<
decltype(std::begin(std::declval<ContiguousContainer
const>()))>::iterator_category>::value,
1822 input_adapter(
const ContiguousContainer& c)
1823 : input_adapter(std::begin(c), std::end(c)) {}
1825 operator input_adapter_t()
1832 input_adapter_t ia =
nullptr;
1843 #include <initializer_list> 1868 template<
typename BasicJsonType>
1871 using number_integer_t =
typename BasicJsonType::number_integer_t;
1872 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
1873 using number_float_t =
typename BasicJsonType::number_float_t;
1874 using string_t =
typename BasicJsonType::string_t;
1878 enum class token_type
1900 static const char* token_type_name(
const token_type t)
noexcept 1904 case token_type::uninitialized:
1905 return "<uninitialized>";
1906 case token_type::literal_true:
1907 return "true literal";
1908 case token_type::literal_false:
1909 return "false literal";
1910 case token_type::literal_null:
1911 return "null literal";
1912 case token_type::value_string:
1913 return "string literal";
1914 case lexer::token_type::value_unsigned:
1915 case lexer::token_type::value_integer:
1916 case lexer::token_type::value_float:
1917 return "number literal";
1918 case token_type::begin_array:
1920 case token_type::begin_object:
1922 case token_type::end_array:
1924 case token_type::end_object:
1926 case token_type::name_separator:
1928 case token_type::value_separator:
1930 case token_type::parse_error:
1931 return "<parse error>";
1932 case token_type::end_of_input:
1933 return "end of input";
1934 case token_type::literal_or_value:
1935 return "'[', '{', or a literal";
1937 return "unknown token";
1941 explicit lexer(detail::input_adapter_t adapter)
1942 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
1945 lexer(
const lexer&) =
delete;
1946 lexer& operator=(lexer&) =
delete;
1954 static char get_decimal_point()
noexcept 1956 const auto loc = localeconv();
1957 assert(loc !=
nullptr);
1958 return (loc->decimal_point ==
nullptr) ?
'.' : *(loc->decimal_point);
1983 assert(current ==
'u');
1986 const auto factors = { 12, 8, 4, 0 };
1987 for (
const auto factor : factors)
1991 if (current >=
'0' and current <=
'9')
1993 codepoint += ((current - 0x30) << factor);
1995 else if (current >=
'A' and current <=
'F')
1997 codepoint += ((current - 0x37) << factor);
1999 else if (current >=
'a' and current <=
'f')
2001 codepoint += ((current - 0x57) << factor);
2009 assert(0x0000 <= codepoint
and codepoint <= 0xFFFF);
2028 bool next_byte_in_range(std::initializer_list<
int> ranges)
2030 assert(ranges.size() == 2
or ranges.size() == 4
or ranges.size() == 6);
2033 for (
auto range = ranges.begin(); range != ranges.end(); ++range)
2036 if (
JSON_LIKELY(*range <= current
and current <= *(++range)))
2042 error_message =
"invalid string: ill-formed UTF-8 byte";
2065 token_type scan_string()
2071 assert(current ==
'\"');
2079 case std::char_traits<
char>::eof():
2081 error_message =
"invalid string: missing closing quote";
2082 return token_type::parse_error;
2088 return token_type::value_string;
2132 const int codepoint1 = get_codepoint();
2133 int codepoint = codepoint1;
2137 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
2138 return token_type::parse_error;
2142 if (0xD800 <= codepoint1
and codepoint1 <= 0xDBFF)
2147 const int codepoint2 = get_codepoint();
2151 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
2152 return token_type::parse_error;
2156 if (
JSON_LIKELY(0xDC00 <= codepoint2
and codepoint2 <= 0xDFFF))
2171 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2172 return token_type::parse_error;
2177 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2178 return token_type::parse_error;
2183 if (
JSON_UNLIKELY(0xDC00 <= codepoint1
and codepoint1 <= 0xDFFF))
2185 error_message =
"invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
2186 return token_type::parse_error;
2191 assert(0x00 <= codepoint
and codepoint <= 0x10FFFF);
2194 if (codepoint < 0x80)
2199 else if (codepoint <= 0x7FF)
2202 add(0xC0 | (codepoint >> 6));
2203 add(0x80 | (codepoint & 0x3F));
2205 else if (codepoint <= 0xFFFF)
2208 add(0xE0 | (codepoint >> 12));
2209 add(0x80 | ((codepoint >> 6) & 0x3F));
2210 add(0x80 | (codepoint & 0x3F));
2215 add(0xF0 | (codepoint >> 18));
2216 add(0x80 | ((codepoint >> 12) & 0x3F));
2217 add(0x80 | ((codepoint >> 6) & 0x3F));
2218 add(0x80 | (codepoint & 0x3F));
2226 error_message =
"invalid string: forbidden character after backslash";
2227 return token_type::parse_error;
2267 error_message =
"invalid string: control character must be escaped";
2268 return token_type::parse_error;
2405 return token_type::parse_error;
2413 if (
JSON_UNLIKELY(
not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
2415 return token_type::parse_error;
2437 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
2439 return token_type::parse_error;
2447 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
2449 return token_type::parse_error;
2457 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2459 return token_type::parse_error;
2469 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2471 return token_type::parse_error;
2479 if (
JSON_UNLIKELY(
not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
2481 return token_type::parse_error;
2489 error_message =
"invalid string: ill-formed UTF-8 byte";
2490 return token_type::parse_error;
2496 static void strtof(
float& f,
const char* str,
char** endptr)
noexcept 2498 f = std::strtof(str, endptr);
2501 static void strtof(
double& f,
const char* str,
char** endptr)
noexcept 2503 f = std::strtod(str, endptr);
2506 static void strtof(
long double& f,
const char* str,
char** endptr)
noexcept 2508 f = std::strtold(str, endptr);
2551 token_type scan_number()
2558 token_type number_type = token_type::value_unsigned;
2566 goto scan_number_minus;
2572 goto scan_number_zero;
2586 goto scan_number_any1;
2598 number_type = token_type::value_integer;
2604 goto scan_number_zero;
2618 goto scan_number_any1;
2623 error_message =
"invalid number; expected digit after '-'";
2624 return token_type::parse_error;
2634 add(decimal_point_char);
2635 goto scan_number_decimal1;
2642 goto scan_number_exponent;
2646 goto scan_number_done;
2665 goto scan_number_any1;
2670 add(decimal_point_char);
2671 goto scan_number_decimal1;
2678 goto scan_number_exponent;
2682 goto scan_number_done;
2685 scan_number_decimal1:
2687 number_type = token_type::value_float;
2702 goto scan_number_decimal2;
2707 error_message =
"invalid number; expected digit after '.'";
2708 return token_type::parse_error;
2712 scan_number_decimal2:
2728 goto scan_number_decimal2;
2735 goto scan_number_exponent;
2739 goto scan_number_done;
2742 scan_number_exponent:
2744 number_type = token_type::value_float;
2751 goto scan_number_sign;
2766 goto scan_number_any2;
2772 "invalid number; expected '+', '-', or digit after exponent";
2773 return token_type::parse_error;
2793 goto scan_number_any2;
2798 error_message =
"invalid number; expected digit after exponent sign";
2799 return token_type::parse_error;
2819 goto scan_number_any2;
2823 goto scan_number_done;
2831 char* endptr =
nullptr;
2835 if (number_type == token_type::value_unsigned)
2837 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
2840 assert(endptr == token_buffer.data() + token_buffer.size());
2844 value_unsigned =
static_cast<number_unsigned_t>(x);
2845 if (value_unsigned == x)
2847 return token_type::value_unsigned;
2851 else if (number_type == token_type::value_integer)
2853 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
2856 assert(endptr == token_buffer.data() + token_buffer.size());
2860 value_integer =
static_cast<number_integer_t>(x);
2861 if (value_integer == x)
2863 return token_type::value_integer;
2870 strtof(value_float, token_buffer.data(), &endptr);
2873 assert(endptr == token_buffer.data() + token_buffer.size());
2875 return token_type::value_float;
2883 token_type scan_literal(
const char* literal_text,
const std::size_t length,
2884 token_type return_type)
2886 assert(current == literal_text[0]);
2887 for (std::size_t i = 1; i < length; ++i)
2891 error_message =
"invalid literal";
2892 return token_type::parse_error;
2903 void reset()
noexcept 2905 token_buffer.clear();
2906 token_string.clear();
2907 token_string.push_back(std::char_traits<
char>::to_char_type(current));
2920 std::char_traits<
char>::int_type get()
2923 current = ia->get_character();
2924 if (
JSON_LIKELY(current != std::char_traits<
char>::eof()))
2926 token_string.push_back(std::char_traits<
char>::to_char_type(current));
2935 if (
JSON_LIKELY(current != std::char_traits<
char>::eof()))
2937 ia->unget_character();
2938 assert(token_string.size() != 0);
2939 token_string.pop_back();
2946 token_buffer.push_back(std::char_traits<
char>::to_char_type(c));
2955 constexpr number_integer_t get_number_integer()
const noexcept 2957 return value_integer;
2961 constexpr number_unsigned_t get_number_unsigned()
const noexcept 2963 return value_unsigned;
2967 constexpr number_float_t get_number_float()
const noexcept 2973 string_t&& move_string()
2975 return std::move(token_buffer);
2983 constexpr std::size_t get_position()
const noexcept 2991 std::string get_token_string()
const 2995 for (
const auto c : token_string)
2997 if (
'\x00' <= c
and c <=
'\x1F')
3000 std::stringstream ss;
3001 ss <<
"<U+" << std::setw(4) << std::uppercase << std::setfill(
'0')
3002 << std::hex <<
static_cast<
int>(c) <<
">";
3008 result.push_back(c);
3016 constexpr const char* get_error_message()
const noexcept 3018 return error_message;
3032 while (current ==
' ' or current ==
'\t' or current ==
'\n' or current ==
'\r');
3038 return token_type::begin_array;
3040 return token_type::end_array;
3042 return token_type::begin_object;
3044 return token_type::end_object;
3046 return token_type::name_separator;
3048 return token_type::value_separator;
3052 return scan_literal(
"true", 4, token_type::literal_true);
3054 return scan_literal(
"false", 5, token_type::literal_false);
3056 return scan_literal(
"null", 4, token_type::literal_null);
3060 return scan_string();
3074 return scan_number();
3079 case std::char_traits<
char>::eof():
3080 return token_type::end_of_input;
3084 error_message =
"invalid literal";
3085 return token_type::parse_error;
3091 detail::input_adapter_t ia =
nullptr;
3094 std::char_traits<
char>::int_type current = std::char_traits<
char>::eof();
3097 std::size_t chars_read = 0;
3100 std::vector<
char> token_string {};
3103 string_t token_buffer {};
3106 const char* error_message =
"";
3109 number_integer_t value_integer = 0;
3110 number_unsigned_t value_unsigned = 0;
3111 number_float_t value_float = 0;
3114 const char decimal_point_char =
'.';
3125 #include <functional> 3153 template<
typename BasicJsonType>
3156 using number_integer_t =
typename BasicJsonType::number_integer_t;
3157 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
3158 using number_float_t =
typename BasicJsonType::number_float_t;
3159 using string_t =
typename BasicJsonType::string_t;
3160 using lexer_t = lexer<BasicJsonType>;
3161 using token_type =
typename lexer_t::token_type;
3164 enum class parse_event_t : uint8_t
3180 using parser_callback_t =
3181 std::function<
bool(
int depth, parse_event_t event, BasicJsonType& parsed)>;
3184 explicit parser(detail::input_adapter_t adapter,
3185 const parser_callback_t cb =
nullptr,
3186 const bool allow_exceptions_ =
true)
3187 : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_)
3200 void parse(
const bool strict, BasicJsonType& result)
3205 parse_internal(
true, result);
3206 result.assert_invariant();
3212 expect(token_type::end_of_input);
3218 result = value_t::discarded;
3224 if (result.is_discarded())
3236 bool accept(
const bool strict =
true)
3241 if (
not accept_internal())
3247 return not strict
or (get_token() == token_type::end_of_input);
3257 void parse_internal(
bool keep, BasicJsonType& result)
3260 assert(
not errored);
3263 if (
not result.is_discarded())
3265 result.m_value.destroy(result.m_type);
3266 result.m_type = value_t::discarded;
3271 case token_type::begin_object:
3277 keep = callback(depth++, parse_event_t::object_start, result);
3280 if (
not callback
or keep)
3283 result.m_type = value_t::object;
3284 result.m_value = value_t::object;
3292 if (last_token == token_type::end_object)
3294 if (keep
and callback
and not callback(--depth, parse_event_t::object_end, result))
3296 result.m_value.destroy(result.m_type);
3297 result.m_type = value_t::discarded;
3304 BasicJsonType value;
3308 if (
not expect(token_type::value_string))
3312 key = m_lexer.move_string();
3314 bool keep_tag =
false;
3319 BasicJsonType k(key);
3320 keep_tag = callback(depth, parse_event_t::key, k);
3330 if (
not expect(token_type::name_separator))
3337 value.m_value.destroy(value.m_type);
3338 value.m_type = value_t::discarded;
3339 parse_internal(keep, value);
3346 if (keep
and keep_tag
and not value.is_discarded())
3348 result.m_value.object->emplace(std::move(key), std::move(value));
3353 if (last_token == token_type::value_separator)
3360 if (
not expect(token_type::end_object))
3367 if (keep
and callback
and not callback(--depth, parse_event_t::object_end, result))
3369 result.m_value.destroy(result.m_type);
3370 result.m_type = value_t::discarded;
3375 case token_type::begin_array:
3381 keep = callback(depth++, parse_event_t::array_start, result);
3384 if (
not callback
or keep)
3387 result.m_type = value_t::array;
3388 result.m_value = value_t::array;
3396 if (last_token == token_type::end_array)
3398 if (callback
and not callback(--depth, parse_event_t::array_end, result))
3400 result.m_value.destroy(result.m_type);
3401 result.m_type = value_t::discarded;
3407 BasicJsonType value;
3411 value.m_value.destroy(value.m_type);
3412 value.m_type = value_t::discarded;
3413 parse_internal(keep, value);
3420 if (keep
and not value.is_discarded())
3422 result.m_value.array->push_back(std::move(value));
3427 if (last_token == token_type::value_separator)
3434 if (
not expect(token_type::end_array))
3441 if (keep
and callback
and not callback(--depth, parse_event_t::array_end, result))
3443 result.m_value.destroy(result.m_type);
3444 result.m_type = value_t::discarded;
3449 case token_type::literal_null:
3451 result.m_type = value_t::null;
3455 case token_type::value_string:
3457 result.m_type = value_t::string;
3458 result.m_value = m_lexer.move_string();
3462 case token_type::literal_true:
3464 result.m_type = value_t::boolean;
3465 result.m_value =
true;
3469 case token_type::literal_false:
3471 result.m_type = value_t::boolean;
3472 result.m_value =
false;
3476 case token_type::value_unsigned:
3478 result.m_type = value_t::number_unsigned;
3479 result.m_value = m_lexer.get_number_unsigned();
3483 case token_type::value_integer:
3485 result.m_type = value_t::number_integer;
3486 result.m_value = m_lexer.get_number_integer();
3490 case token_type::value_float:
3492 result.m_type = value_t::number_float;
3493 result.m_value = m_lexer.get_number_float();
3496 if (
JSON_UNLIKELY(
not std::isfinite(result.m_value.number_float)))
3498 if (allow_exceptions)
3500 JSON_THROW(out_of_range::create(406,
"number overflow parsing '" +
3501 m_lexer.get_token_string() +
"'"));
3503 expect(token_type::uninitialized);
3508 case token_type::parse_error:
3511 if (
not expect(token_type::uninitialized))
3521 if (
not expect(token_type::literal_or_value))
3529 if (keep
and callback
and not callback(depth, parse_event_t::value, result))
3531 result.m_value.destroy(result.m_type);
3532 result.m_type = value_t::discarded;
3546 bool accept_internal()
3550 case token_type::begin_object:
3556 if (last_token == token_type::end_object)
3565 if (last_token != token_type::value_string)
3572 if (last_token != token_type::name_separator)
3579 if (
not accept_internal())
3586 if (last_token == token_type::value_separator)
3593 return (last_token == token_type::end_object);
3597 case token_type::begin_array:
3603 if (last_token == token_type::end_array)
3612 if (
not accept_internal())
3619 if (last_token == token_type::value_separator)
3626 return (last_token == token_type::end_array);
3630 case token_type::value_float:
3633 return std::isfinite(m_lexer.get_number_float());
3636 case token_type::literal_false:
3637 case token_type::literal_null:
3638 case token_type::literal_true:
3639 case token_type::value_integer:
3640 case token_type::value_string:
3641 case token_type::value_unsigned:
3650 token_type get_token()
3652 return (last_token = m_lexer.scan());
3658 bool expect(token_type t)
3664 if (allow_exceptions)
3677 [[noreturn]]
void throw_exception()
const 3679 std::string error_msg =
"syntax error - ";
3680 if (last_token == token_type::parse_error)
3682 error_msg += std::string(m_lexer.get_error_message()) +
"; last read: '" +
3683 m_lexer.get_token_string() +
"'";
3687 error_msg +=
"unexpected " + std::string(lexer_t::token_type_name(last_token));
3690 if (expected != token_type::uninitialized)
3692 error_msg +=
"; expected " + std::string(lexer_t::token_type_name(expected));
3695 JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
3702 const parser_callback_t callback =
nullptr;
3704 token_type last_token = token_type::uninitialized;
3708 bool errored =
false;
3710 token_type expected = token_type::uninitialized;
3712 const bool allow_exceptions =
true;
3736 class primitive_iterator_t
3739 using difference_type = std::ptrdiff_t;
3740 static constexpr difference_type begin_value = 0;
3741 static constexpr difference_type end_value = begin_value + 1;
3744 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
3747 constexpr difference_type get_value()
const noexcept 3753 void set_begin()
noexcept 3759 void set_end()
noexcept 3765 constexpr bool is_begin()
const noexcept 3767 return m_it == begin_value;
3771 constexpr bool is_end()
const noexcept 3773 return m_it == end_value;
3776 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs)
noexcept 3778 return lhs.m_it == rhs.m_it;
3781 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs)
noexcept 3783 return lhs.m_it < rhs.m_it;
3786 primitive_iterator_t operator+(difference_type n)
noexcept 3788 auto result = *
this;
3793 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs)
noexcept 3795 return lhs.m_it - rhs.m_it;
3798 primitive_iterator_t& operator++()
noexcept 3804 primitive_iterator_t
const operator++(
int)
noexcept 3806 auto result = *
this;
3811 primitive_iterator_t& operator--()
noexcept 3817 primitive_iterator_t
const operator--(
int)
noexcept 3819 auto result = *
this;
3824 primitive_iterator_t& operator+=(difference_type n)
noexcept 3830 primitive_iterator_t& operator-=(difference_type n)
noexcept 3855 template<
typename BasicJsonType>
struct internal_iterator
3858 typename BasicJsonType::object_t::iterator object_iterator {};
3860 typename BasicJsonType::array_t::iterator array_iterator {};
3862 primitive_iterator_t primitive_iterator {};
3872 #include <type_traits> 3892 template<
typename IteratorType>
class iteration_proxy;
3914 template<
typename BasicJsonType>
3918 friend iter_impl<
typename std::conditional<std::is_const<BasicJsonType>::value,
typename std::remove_const<BasicJsonType>::type,
const BasicJsonType>::type>;
3919 friend BasicJsonType;
3920 friend iteration_proxy<iter_impl>;
3922 using object_t =
typename BasicJsonType::object_t;
3923 using array_t =
typename BasicJsonType::array_t;
3925 static_assert(is_basic_json<
typename std::remove_const<BasicJsonType>::type>::value,
3926 "iter_impl only accepts (const) basic_json");
3935 using iterator_category = std::bidirectional_iterator_tag;
3938 using value_type =
typename BasicJsonType::value_type;
3940 using difference_type =
typename BasicJsonType::difference_type;
3942 using pointer =
typename std::conditional<std::is_const<BasicJsonType>::value,
3943 typename BasicJsonType::const_pointer,
3944 typename BasicJsonType::pointer>::type;
3947 typename std::conditional<std::is_const<BasicJsonType>::value,
3948 typename BasicJsonType::const_reference,
3949 typename BasicJsonType::reference>::type;
3952 iter_impl() =
default;
3960 explicit iter_impl(pointer object)
noexcept : m_object(object)
3962 assert(m_object !=
nullptr);
3964 switch (m_object->m_type)
3966 case value_t::object:
3968 m_it.object_iterator =
typename object_t::iterator();
3972 case value_t::array:
3974 m_it.array_iterator =
typename array_t::iterator();
3980 m_it.primitive_iterator = primitive_iterator_t();
4000 iter_impl(
const iter_impl<
typename std::remove_const<BasicJsonType>::type>& other)
noexcept 4001 : m_object(other.m_object), m_it(other.m_it) {}
4009 iter_impl& operator=(
const iter_impl<
typename std::remove_const<BasicJsonType>::type>& other)
noexcept 4011 m_object = other.m_object;
4021 void set_begin()
noexcept 4023 assert(m_object !=
nullptr);
4025 switch (m_object->m_type)
4027 case value_t::object:
4029 m_it.object_iterator = m_object->m_value.object->begin();
4033 case value_t::array:
4035 m_it.array_iterator = m_object->m_value.array->begin();
4042 m_it.primitive_iterator.set_end();
4048 m_it.primitive_iterator.set_begin();
4058 void set_end()
noexcept 4060 assert(m_object !=
nullptr);
4062 switch (m_object->m_type)
4064 case value_t::object:
4066 m_it.object_iterator = m_object->m_value.object->end();
4070 case value_t::array:
4072 m_it.array_iterator = m_object->m_value.array->end();
4078 m_it.primitive_iterator.set_end();
4089 reference operator*()
const 4091 assert(m_object !=
nullptr);
4093 switch (m_object->m_type)
4095 case value_t::object:
4097 assert(m_it.object_iterator != m_object->m_value.object->end());
4098 return m_it.object_iterator->second;
4101 case value_t::array:
4103 assert(m_it.array_iterator != m_object->m_value.array->end());
4104 return *m_it.array_iterator;
4108 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4112 if (
JSON_LIKELY(m_it.primitive_iterator.is_begin()))
4117 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4126 pointer operator->()
const 4128 assert(m_object !=
nullptr);
4130 switch (m_object->m_type)
4132 case value_t::object:
4134 assert(m_it.object_iterator != m_object->m_value.object->end());
4135 return &(m_it.object_iterator->second);
4138 case value_t::array:
4140 assert(m_it.array_iterator != m_object->m_value.array->end());
4141 return &*m_it.array_iterator;
4146 if (
JSON_LIKELY(m_it.primitive_iterator.is_begin()))
4151 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4160 iter_impl
const operator++(
int)
4162 auto result = *
this;
4171 iter_impl& operator++()
4173 assert(m_object !=
nullptr);
4175 switch (m_object->m_type)
4177 case value_t::object:
4179 std::advance(m_it.object_iterator, 1);
4183 case value_t::array:
4185 std::advance(m_it.array_iterator, 1);
4191 ++m_it.primitive_iterator;
4203 iter_impl
const operator--(
int)
4205 auto result = *
this;
4214 iter_impl& operator--()
4216 assert(m_object !=
nullptr);
4218 switch (m_object->m_type)
4220 case value_t::object:
4222 std::advance(m_it.object_iterator, -1);
4226 case value_t::array:
4228 std::advance(m_it.array_iterator, -1);
4234 --m_it.primitive_iterator;
4246 bool operator==(
const iter_impl& other)
const 4251 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
4254 assert(m_object !=
nullptr);
4256 switch (m_object->m_type)
4258 case value_t::object:
4259 return (m_it.object_iterator == other.m_it.object_iterator);
4261 case value_t::array:
4262 return (m_it.array_iterator == other.m_it.array_iterator);
4265 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
4273 bool operator!=(
const iter_impl& other)
const 4275 return not operator==(other);
4282 bool operator<(
const iter_impl& other)
const 4287 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
4290 assert(m_object !=
nullptr);
4292 switch (m_object->m_type)
4294 case value_t::object:
4295 JSON_THROW(invalid_iterator::create(213,
"cannot compare order of object iterators"));
4297 case value_t::array:
4298 return (m_it.array_iterator < other.m_it.array_iterator);
4301 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
4309 bool operator<=(
const iter_impl& other)
const 4311 return not other.operator < (*
this);
4318 bool operator>(
const iter_impl& other)
const 4320 return not operator<=(other);
4327 bool operator>=(
const iter_impl& other)
const 4329 return not operator<(other);
4336 iter_impl& operator+=(difference_type i)
4338 assert(m_object !=
nullptr);
4340 switch (m_object->m_type)
4342 case value_t::object:
4343 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
4345 case value_t::array:
4347 std::advance(m_it.array_iterator, i);
4353 m_it.primitive_iterator += i;
4365 iter_impl& operator-=(difference_type i)
4367 return operator+=(-i);
4374 iter_impl operator+(difference_type i)
const 4376 auto result = *
this;
4385 friend iter_impl operator+(difference_type i,
const iter_impl& it)
4396 iter_impl operator-(difference_type i)
const 4398 auto result = *
this;
4407 difference_type operator-(
const iter_impl& other)
const 4409 assert(m_object !=
nullptr);
4411 switch (m_object->m_type)
4413 case value_t::object:
4414 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
4416 case value_t::array:
4417 return m_it.array_iterator - other.m_it.array_iterator;
4420 return m_it.primitive_iterator - other.m_it.primitive_iterator;
4428 reference operator[](difference_type n)
const 4430 assert(m_object !=
nullptr);
4432 switch (m_object->m_type)
4434 case value_t::object:
4435 JSON_THROW(invalid_iterator::create(208,
"cannot use operator[] for object iterators"));
4437 case value_t::array:
4438 return *std::next(m_it.array_iterator, n);
4441 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4445 if (
JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
4450 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4459 typename object_t::key_type key()
const 4461 assert(m_object !=
nullptr);
4465 return m_it.object_iterator->first;
4468 JSON_THROW(invalid_iterator::create(207,
"cannot use key() for non-object iterators"));
4475 reference value()
const 4482 pointer m_object =
nullptr;
4484 internal_iterator<
typename std::remove_const<BasicJsonType>::type> m_it;
4503 template<
typename IteratorType>
class iteration_proxy
4507 class iteration_proxy_internal
4511 IteratorType anchor;
4513 std::size_t array_index = 0;
4516 explicit iteration_proxy_internal(IteratorType it)
noexcept : anchor(it) {}
4519 iteration_proxy_internal& operator*()
4525 iteration_proxy_internal& operator++()
4534 bool operator!=(
const iteration_proxy_internal& o)
const noexcept 4536 return anchor != o.anchor;
4540 std::string key()
const 4542 assert(anchor.m_object !=
nullptr);
4544 switch (anchor.m_object->type())
4547 case value_t::array:
4548 return std::to_string(array_index);
4551 case value_t::object:
4552 return anchor.key();
4561 typename IteratorType::reference value()
const 4563 return anchor.value();
4568 typename IteratorType::reference container;
4572 explicit iteration_proxy(
typename IteratorType::reference cont)
noexcept 4573 : container(cont) {}
4576 iteration_proxy_internal begin()
noexcept 4578 return iteration_proxy_internal(container.begin());
4582 iteration_proxy_internal end()
noexcept 4584 return iteration_proxy_internal(container.end());
4623 template<
typename Base>
4624 class json_reverse_iterator :
public std::reverse_iterator<Base>
4627 using difference_type = std::ptrdiff_t;
4629 using base_iterator = std::reverse_iterator<Base>;
4631 using reference =
typename Base::reference;
4634 json_reverse_iterator(
const typename base_iterator::iterator_type& it)
noexcept 4635 : base_iterator(it) {}
4638 json_reverse_iterator(
const base_iterator& it)
noexcept : base_iterator(it) {}
4641 json_reverse_iterator
const operator++(
int)
4643 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
4647 json_reverse_iterator& operator++()
4649 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
4653 json_reverse_iterator
const operator--(
int)
4655 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
4659 json_reverse_iterator& operator--()
4661 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
4665 json_reverse_iterator& operator+=(difference_type i)
4667 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
4671 json_reverse_iterator operator+(difference_type i)
const 4673 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
4677 json_reverse_iterator operator-(difference_type i)
const 4679 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
4683 difference_type operator-(
const json_reverse_iterator& other)
const 4685 return base_iterator(*
this) - base_iterator(other);
4689 reference operator[](difference_type n)
const 4691 return *(
this->operator+(n));
4695 auto key()
const ->
decltype(std::declval<Base>().key())
4697 auto it = --
this->base();
4702 reference value()
const 4704 auto it = --
this->base();
4705 return it.operator * ();
4714 #include <algorithm> 4728 template<
typename CharType>
struct output_adapter_protocol
4730 virtual void write_character(CharType c) = 0;
4731 virtual void write_characters(
const CharType* s, std::size_t length) = 0;
4732 virtual ~output_adapter_protocol() =
default;
4736 template<
typename CharType>
4737 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
4740 template<
typename CharType>
4741 class output_vector_adapter :
public output_adapter_protocol<CharType>
4744 explicit output_vector_adapter(std::vector<CharType>& vec) : v(vec) {}
4746 void write_character(CharType c) override
4751 void write_characters(
const CharType* s, std::size_t length) override
4753 std::copy(s, s + length, std::back_inserter(v));
4757 std::vector<CharType>& v;
4761 template<
typename CharType>
4762 class output_stream_adapter :
public output_adapter_protocol<CharType>
4765 explicit output_stream_adapter(std::basic_ostream<CharType>& s) : stream(s) {}
4767 void write_character(CharType c) override
4772 void write_characters(
const CharType* s, std::size_t length) override
4774 stream.write(s,
static_cast<std::streamsize>(length));
4778 std::basic_ostream<CharType>& stream;
4782 template<
typename CharType,
typename StringType = std::basic_string<CharType>>
4783 class output_string_adapter :
public output_adapter_protocol<CharType>
4786 explicit output_string_adapter(StringType& s) : str(s) {}
4788 void write_character(CharType c) override
4793 void write_characters(
const CharType* s, std::size_t length) override
4795 str.append(s, length);
4802 template<
typename CharType,
typename StringType = std::basic_string<CharType>>
4803 class output_adapter
4806 output_adapter(std::vector<CharType>& vec)
4807 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
4809 output_adapter(std::basic_ostream<CharType>& s)
4810 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
4812 output_adapter(StringType& s)
4813 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
4815 operator output_adapter_t<CharType>()
4821 output_adapter_t<CharType> oa =
nullptr;
4829 #include <algorithm> 4864 template<
typename BasicJsonType>
4867 using number_integer_t =
typename BasicJsonType::number_integer_t;
4868 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
4869 using string_t =
typename BasicJsonType::string_t;
4877 explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
4892 BasicJsonType parse_cbor(
const bool strict)
4894 const auto res = parse_cbor_internal();
4913 BasicJsonType parse_msgpack(
const bool strict)
4915 const auto res = parse_msgpack_internal();
4934 BasicJsonType parse_ubjson(
const bool strict)
4936 const auto res = parse_ubjson_internal();
4952 static constexpr bool little_endianess(
int num = 1)
noexcept 4954 return (*
reinterpret_cast<
char*>(&num) == 1);
4963 BasicJsonType parse_cbor_internal(
const bool get_char =
true)
4965 switch (get_char ? get() : current)
4968 case std::char_traits<
char>::eof():
4969 JSON_THROW(parse_error::create(110, chars_read,
"unexpected end of input"));
4996 return static_cast<number_unsigned_t>(current);
4999 return get_number<uint8_t>();
5002 return get_number<uint16_t>();
5005 return get_number<uint32_t>();
5008 return get_number<uint64_t>();
5035 return static_cast<int8_t>(0x20 - 1 - current);
5039 return static_cast<number_integer_t>(-1) - get_number<uint8_t>();
5044 return static_cast<number_integer_t>(-1) - get_number<uint16_t>();
5049 return static_cast<number_integer_t>(-1) - get_number<uint32_t>();
5054 return static_cast<number_integer_t>(-1) -
5055 static_cast<number_integer_t>(get_number<uint64_t>());
5089 return get_cbor_string();
5118 return get_cbor_array(current & 0x1F);
5123 return get_cbor_array(get_number<uint8_t>());
5128 return get_cbor_array(get_number<uint16_t>());
5133 return get_cbor_array(get_number<uint32_t>());
5138 return get_cbor_array(get_number<uint64_t>());
5143 BasicJsonType result = value_t::array;
5144 while (get() != 0xFF)
5146 result.push_back(parse_cbor_internal(
false));
5177 return get_cbor_object(current & 0x1F);
5182 return get_cbor_object(get_number<uint8_t>());
5187 return get_cbor_object(get_number<uint16_t>());
5192 return get_cbor_object(get_number<uint32_t>());
5197 return get_cbor_object(get_number<uint64_t>());
5202 BasicJsonType result = value_t::object;
5203 while (get() != 0xFF)
5205 auto key = get_cbor_string();
5206 result[key] = parse_cbor_internal();
5223 return value_t::null;
5228 const int byte1 = get();
5230 const int byte2 = get();
5241 const int half = (byte1 << 8) + byte2;
5242 const int exp = (half >> 10) & 0x1F;
5243 const int mant = half & 0x3FF;
5247 val = std::ldexp(mant, -24);
5251 val = std::ldexp(mant + 1024, exp - 25);
5255 val = (mant == 0) ? std::numeric_limits<
double>::infinity()
5256 : std::numeric_limits<
double>::quiet_NaN();
5258 return (half & 0x8000) != 0 ? -val : val;
5263 return get_number<
float>();
5268 return get_number<
double>();
5273 std::stringstream ss;
5274 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5275 JSON_THROW(parse_error::create(112, chars_read,
"error reading CBOR; last byte: 0x" + ss.str()));
5280 BasicJsonType parse_msgpack_internal()
5285 case std::char_traits<
char>::eof():
5286 JSON_THROW(parse_error::create(110, chars_read,
"unexpected end of input"));
5417 return static_cast<number_unsigned_t>(current);
5437 return get_msgpack_object(current & 0x0F);
5458 return get_msgpack_array(current & 0x0F);
5494 return get_msgpack_string();
5497 return value_t::null;
5506 return get_number<
float>();
5509 return get_number<
double>();
5512 return get_number<uint8_t>();
5515 return get_number<uint16_t>();
5518 return get_number<uint32_t>();
5521 return get_number<uint64_t>();
5524 return get_number<int8_t>();
5527 return get_number<int16_t>();
5530 return get_number<int32_t>();
5533 return get_number<int64_t>();
5538 return get_msgpack_string();
5542 return get_msgpack_array(get_number<uint16_t>());
5547 return get_msgpack_array(get_number<uint32_t>());
5552 return get_msgpack_object(get_number<uint16_t>());
5557 return get_msgpack_object(get_number<uint32_t>());
5593 return static_cast<int8_t>(current);
5597 std::stringstream ss;
5598 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5599 JSON_THROW(parse_error::create(112, chars_read,
5600 "error reading MessagePack; last byte: 0x" + ss.str()));
5610 BasicJsonType parse_ubjson_internal(
const bool get_char =
true)
5612 return get_ubjson_value(get_char ? get_ignore_noop() : current);
5627 return (current = ia->get_character());
5633 int get_ignore_noop()
5639 while (current ==
'N');
5657 template<
typename NumberType> NumberType get_number()
5660 std::array<uint8_t,
sizeof(NumberType)> vec;
5661 for (std::size_t i = 0; i <
sizeof(NumberType); ++i)
5667 if (is_little_endian)
5669 vec[
sizeof(NumberType) - i - 1] =
static_cast<uint8_t>(current);
5673 vec[i] =
static_cast<uint8_t>(current);
5679 std::memcpy(&result, vec.data(),
sizeof(NumberType));
5696 template<
typename NumberType>
5697 string_t get_string(
const NumberType len)
5700 std::generate_n(std::back_inserter(result), len, [
this]()
5704 return static_cast<
char>(current);
5721 string_t get_cbor_string()
5753 return get_string(current & 0x1F);
5758 return get_string(get_number<uint8_t>());
5763 return get_string(get_number<uint16_t>());
5768 return get_string(get_number<uint32_t>());
5773 return get_string(get_number<uint64_t>());
5779 while (get() != 0xFF)
5781 result.append(get_cbor_string());
5788 std::stringstream ss;
5789 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5790 JSON_THROW(parse_error::create(113, chars_read,
"expected a CBOR string; last byte: 0x" + ss.str()));
5795 template<
typename NumberType>
5796 BasicJsonType get_cbor_array(
const NumberType len)
5798 BasicJsonType result = value_t::array;
5799 std::generate_n(std::back_inserter(*result.m_value.array), len, [
this]()
5801 return parse_cbor_internal();
5806 template<
typename NumberType>
5807 BasicJsonType get_cbor_object(
const NumberType len)
5809 BasicJsonType result = value_t::object;
5810 std::generate_n(std::inserter(*result.m_value.object,
5811 result.m_value.object->end()),
5815 auto key = get_cbor_string();
5816 auto val = parse_cbor_internal();
5817 return std::make_pair(std::move(key), std::move(val));
5833 string_t get_msgpack_string()
5873 return get_string(current & 0x1F);
5878 return get_string(get_number<uint8_t>());
5883 return get_string(get_number<uint16_t>());
5888 return get_string(get_number<uint32_t>());
5893 std::stringstream ss;
5894 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5895 JSON_THROW(parse_error::create(113, chars_read,
5896 "expected a MessagePack string; last byte: 0x" + ss.str()));
5901 template<
typename NumberType>
5902 BasicJsonType get_msgpack_array(
const NumberType len)
5904 BasicJsonType result = value_t::array;
5905 std::generate_n(std::back_inserter(*result.m_value.array), len, [
this]()
5907 return parse_msgpack_internal();
5912 template<
typename NumberType>
5913 BasicJsonType get_msgpack_object(
const NumberType len)
5915 BasicJsonType result = value_t::object;
5916 std::generate_n(std::inserter(*result.m_value.object,
5917 result.m_value.object->end()),
5921 auto key = get_msgpack_string();
5922 auto val = parse_msgpack_internal();
5923 return std::make_pair(std::move(key), std::move(val));
5944 string_t get_ubjson_string(
const bool get_char =
true)
5956 return get_string(get_number<uint8_t>());
5958 return get_string(get_number<int8_t>());
5960 return get_string(get_number<int16_t>());
5962 return get_string(get_number<int32_t>());
5964 return get_string(get_number<int64_t>());
5966 std::stringstream ss;
5967 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5968 JSON_THROW(parse_error::create(113, chars_read,
5969 "expected a UBJSON string; last byte: 0x" + ss.str()));
5981 std::pair<std::size_t,
int> get_ubjson_size_type()
5983 std::size_t sz = string_t::npos;
5996 std::stringstream ss;
5997 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5998 JSON_THROW(parse_error::create(112, chars_read,
5999 "expected '#' after UBJSON type information; last byte: 0x" + ss.str()));
6001 sz = parse_ubjson_internal();
6003 else if (current ==
'#')
6005 sz = parse_ubjson_internal();
6008 return std::make_pair(sz, tc);
6011 BasicJsonType get_ubjson_value(
const int prefix)
6015 case std::char_traits<
char>::eof():
6016 JSON_THROW(parse_error::create(110, chars_read,
"unexpected end of input"));
6027 return get_number<uint8_t>();
6029 return get_number<int8_t>();
6031 return get_number<int16_t>();
6033 return get_number<int32_t>();
6035 return get_number<int64_t>();
6037 return get_number<
float>();
6039 return get_number<
double>();
6047 std::stringstream ss;
6048 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
6049 JSON_THROW(parse_error::create(113, chars_read,
6050 "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + ss.str()));
6052 return string_t(1,
static_cast<
char>(current));
6056 return get_ubjson_string();
6059 return get_ubjson_array();
6062 return get_ubjson_object();
6065 std::stringstream ss;
6066 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
6067 JSON_THROW(parse_error::create(112, chars_read,
6068 "error reading UBJSON; last byte: 0x" + ss.str()));
6072 BasicJsonType get_ubjson_array()
6074 BasicJsonType result = value_t::array;
6075 const auto size_and_type = get_ubjson_size_type();
6077 if (size_and_type.first != string_t::npos)
6082 "excessive array size: " + std::to_string(size_and_type.first)));
6085 if (size_and_type.second != 0)
6087 if (size_and_type.second !=
'N')
6089 std::generate_n(std::back_inserter(*result.m_value.array),
6090 size_and_type.first, [
this, size_and_type]()
6092 return get_ubjson_value(size_and_type.second);
6098 std::generate_n(std::back_inserter(*result.m_value.array),
6099 size_and_type.first, [
this]()
6101 return parse_ubjson_internal();
6107 while (current !=
']')
6109 result.push_back(parse_ubjson_internal(
false));
6117 BasicJsonType get_ubjson_object()
6119 BasicJsonType result = value_t::object;
6120 const auto size_and_type = get_ubjson_size_type();
6122 if (size_and_type.first != string_t::npos)
6127 "excessive object size: " + std::to_string(size_and_type.first)));
6130 if (size_and_type.second != 0)
6132 std::generate_n(std::inserter(*result.m_value.object,
6133 result.m_value.object->end()),
6134 size_and_type.first, [
this, size_and_type]()
6136 auto key = get_ubjson_string();
6137 auto val = get_ubjson_value(size_and_type.second);
6138 return std::make_pair(std::move(key), std::move(val));
6143 std::generate_n(std::inserter(*result.m_value.object,
6144 result.m_value.object->end()),
6145 size_and_type.first, [
this]()
6147 auto key = get_ubjson_string();
6148 auto val = parse_ubjson_internal();
6149 return std::make_pair(std::move(key), std::move(val));
6155 while (current !=
'}')
6157 auto key = get_ubjson_string(
false);
6158 result[std::move(key)] = parse_ubjson_internal();
6170 void expect_eof()
const 6172 if (
JSON_UNLIKELY(current != std::char_traits<
char>::eof()))
6174 JSON_THROW(parse_error::create(110, chars_read,
"expected end of input"));
6182 void unexpect_eof()
const 6184 if (
JSON_UNLIKELY(current == std::char_traits<
char>::eof()))
6186 JSON_THROW(parse_error::create(110, chars_read,
"unexpected end of input"));
6192 input_adapter_t ia =
nullptr;
6195 int current = std::char_traits<
char>::eof();
6198 std::size_t chars_read = 0;
6201 const bool is_little_endian = little_endianess();
6209 #include <algorithm> 6231 template<
typename BasicJsonType,
typename CharType>
6240 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
6248 void write_cbor(
const BasicJsonType& j)
6254 oa->write_character(
static_cast<CharType>(0xF6));
6258 case value_t::boolean:
6260 oa->write_character(j.m_value.boolean
6261 ?
static_cast<CharType>(0xF5)
6262 :
static_cast<CharType>(0xF4));
6266 case value_t::number_integer:
6268 if (j.m_value.number_integer >= 0)
6273 if (j.m_value.number_integer <= 0x17)
6275 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
6277 else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
6279 oa->write_character(
static_cast<CharType>(0x18));
6280 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
6282 else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
6284 oa->write_character(
static_cast<CharType>(0x19));
6285 write_number(
static_cast<uint16_t>(j.m_value.number_integer));
6287 else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
6289 oa->write_character(
static_cast<CharType>(0x1A));
6290 write_number(
static_cast<uint32_t>(j.m_value.number_integer));
6294 oa->write_character(
static_cast<CharType>(0x1B));
6295 write_number(
static_cast<uint64_t>(j.m_value.number_integer));
6302 const auto positive_number = -1 - j.m_value.number_integer;
6303 if (j.m_value.number_integer >= -24)
6305 write_number(
static_cast<uint8_t>(0x20 + positive_number));
6307 else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
6309 oa->write_character(
static_cast<CharType>(0x38));
6310 write_number(
static_cast<uint8_t>(positive_number));
6312 else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
6314 oa->write_character(
static_cast<CharType>(0x39));
6315 write_number(
static_cast<uint16_t>(positive_number));
6317 else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
6319 oa->write_character(
static_cast<CharType>(0x3A));
6320 write_number(
static_cast<uint32_t>(positive_number));
6324 oa->write_character(
static_cast<CharType>(0x3B));
6325 write_number(
static_cast<uint64_t>(positive_number));
6331 case value_t::number_unsigned:
6333 if (j.m_value.number_unsigned <= 0x17)
6335 write_number(
static_cast<uint8_t>(j.m_value.number_unsigned));
6337 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
6339 oa->write_character(
static_cast<CharType>(0x18));
6340 write_number(
static_cast<uint8_t>(j.m_value.number_unsigned));
6342 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
6344 oa->write_character(
static_cast<CharType>(0x19));
6345 write_number(
static_cast<uint16_t>(j.m_value.number_unsigned));
6347 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
6349 oa->write_character(
static_cast<CharType>(0x1A));
6350 write_number(
static_cast<uint32_t>(j.m_value.number_unsigned));
6354 oa->write_character(
static_cast<CharType>(0x1B));
6355 write_number(
static_cast<uint64_t>(j.m_value.number_unsigned));
6360 case value_t::number_float:
6362 oa->write_character(
static_cast<CharType>(0xFB));
6363 write_number(j.m_value.number_float);
6367 case value_t::string:
6370 const auto N = j.m_value.string->size();
6373 write_number(
static_cast<uint8_t>(0x60 + N));
6375 else if (N <= (std::numeric_limits<uint8_t>::max)())
6377 oa->write_character(
static_cast<CharType>(0x78));
6378 write_number(
static_cast<uint8_t>(N));
6380 else if (N <= (std::numeric_limits<uint16_t>::max)())
6382 oa->write_character(
static_cast<CharType>(0x79));
6383 write_number(
static_cast<uint16_t>(N));
6385 else if (N <= (std::numeric_limits<uint32_t>::max)())
6387 oa->write_character(
static_cast<CharType>(0x7A));
6388 write_number(
static_cast<uint32_t>(N));
6391 else if (N <= (std::numeric_limits<uint64_t>::max)())
6393 oa->write_character(
static_cast<CharType>(0x7B));
6394 write_number(
static_cast<uint64_t>(N));
6399 oa->write_characters(
6400 reinterpret_cast<
const CharType*>(j.m_value.string->c_str()),
6401 j.m_value.string->size());
6405 case value_t::array:
6408 const auto N = j.m_value.array->size();
6411 write_number(
static_cast<uint8_t>(0x80 + N));
6413 else if (N <= (std::numeric_limits<uint8_t>::max)())
6415 oa->write_character(
static_cast<CharType>(0x98));
6416 write_number(
static_cast<uint8_t>(N));
6418 else if (N <= (std::numeric_limits<uint16_t>::max)())
6420 oa->write_character(
static_cast<CharType>(0x99));
6421 write_number(
static_cast<uint16_t>(N));
6423 else if (N <= (std::numeric_limits<uint32_t>::max)())
6425 oa->write_character(
static_cast<CharType>(0x9A));
6426 write_number(
static_cast<uint32_t>(N));
6429 else if (N <= (std::numeric_limits<uint64_t>::max)())
6431 oa->write_character(
static_cast<CharType>(0x9B));
6432 write_number(
static_cast<uint64_t>(N));
6437 for (
const auto& el : *j.m_value.array)
6444 case value_t::object:
6447 const auto N = j.m_value.object->size();
6450 write_number(
static_cast<uint8_t>(0xA0 + N));
6452 else if (N <= (std::numeric_limits<uint8_t>::max)())
6454 oa->write_character(
static_cast<CharType>(0xB8));
6455 write_number(
static_cast<uint8_t>(N));
6457 else if (N <= (std::numeric_limits<uint16_t>::max)())
6459 oa->write_character(
static_cast<CharType>(0xB9));
6460 write_number(
static_cast<uint16_t>(N));
6462 else if (N <= (std::numeric_limits<uint32_t>::max)())
6464 oa->write_character(
static_cast<CharType>(0xBA));
6465 write_number(
static_cast<uint32_t>(N));
6468 else if (N <= (std::numeric_limits<uint64_t>::max)())
6470 oa->write_character(
static_cast<CharType>(0xBB));
6471 write_number(
static_cast<uint64_t>(N));
6476 for (
const auto& el : *j.m_value.object)
6478 write_cbor(el.first);
6479 write_cbor(el.second);
6492 void write_msgpack(
const BasicJsonType& j)
6498 oa->write_character(
static_cast<CharType>(0xC0));
6502 case value_t::boolean:
6504 oa->write_character(j.m_value.boolean
6505 ?
static_cast<CharType>(0xC3)
6506 :
static_cast<CharType>(0xC2));
6510 case value_t::number_integer:
6512 if (j.m_value.number_integer >= 0)
6517 if (j.m_value.number_unsigned < 128)
6520 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
6522 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
6525 oa->write_character(
static_cast<CharType>(0xCC));
6526 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
6528 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
6531 oa->write_character(
static_cast<CharType>(0xCD));
6532 write_number(
static_cast<uint16_t>(j.m_value.number_integer));
6534 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
6537 oa->write_character(
static_cast<CharType>(0xCE));
6538 write_number(
static_cast<uint32_t>(j.m_value.number_integer));
6540 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
6543 oa->write_character(
static_cast<CharType>(0xCF));
6544 write_number(
static_cast<uint64_t>(j.m_value.number_integer));
6549 if (j.m_value.number_integer >= -32)
6552 write_number(
static_cast<int8_t>(j.m_value.number_integer));
6554 else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)()
and 6555 j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
6558 oa->write_character(
static_cast<CharType>(0xD0));
6559 write_number(
static_cast<int8_t>(j.m_value.number_integer));
6561 else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)()
and 6562 j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
6565 oa->write_character(
static_cast<CharType>(0xD1));
6566 write_number(
static_cast<int16_t>(j.m_value.number_integer));
6568 else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)()
and 6569 j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
6572 oa->write_character(
static_cast<CharType>(0xD2));
6573 write_number(
static_cast<int32_t>(j.m_value.number_integer));
6575 else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)()
and 6576 j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
6579 oa->write_character(
static_cast<CharType>(0xD3));
6580 write_number(
static_cast<int64_t>(j.m_value.number_integer));
6586 case value_t::number_unsigned:
6588 if (j.m_value.number_unsigned < 128)
6591 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
6593 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
6596 oa->write_character(
static_cast<CharType>(0xCC));
6597 write_number(
static_cast<uint8_t>(j.m_value.number_integer));
6599 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
6602 oa->write_character(
static_cast<CharType>(0xCD));
6603 write_number(
static_cast<uint16_t>(j.m_value.number_integer));
6605 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
6608 oa->write_character(
static_cast<CharType>(0xCE));
6609 write_number(
static_cast<uint32_t>(j.m_value.number_integer));
6611 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
6614 oa->write_character(
static_cast<CharType>(0xCF));
6615 write_number(
static_cast<uint64_t>(j.m_value.number_integer));
6620 case value_t::number_float:
6622 oa->write_character(
static_cast<CharType>(0xCB));
6623 write_number(j.m_value.number_float);
6627 case value_t::string:
6630 const auto N = j.m_value.string->size();
6634 write_number(
static_cast<uint8_t>(0xA0 | N));
6636 else if (N <= (std::numeric_limits<uint8_t>::max)())
6639 oa->write_character(
static_cast<CharType>(0xD9));
6640 write_number(
static_cast<uint8_t>(N));
6642 else if (N <= (std::numeric_limits<uint16_t>::max)())
6645 oa->write_character(
static_cast<CharType>(0xDA));
6646 write_number(
static_cast<uint16_t>(N));
6648 else if (N <= (std::numeric_limits<uint32_t>::max)())
6651 oa->write_character(
static_cast<CharType>(0xDB));
6652 write_number(
static_cast<uint32_t>(N));
6656 oa->write_characters(
6657 reinterpret_cast<
const CharType*>(j.m_value.string->c_str()),
6658 j.m_value.string->size());
6662 case value_t::array:
6665 const auto N = j.m_value.array->size();
6669 write_number(
static_cast<uint8_t>(0x90 | N));
6671 else if (N <= (std::numeric_limits<uint16_t>::max)())
6674 oa->write_character(
static_cast<CharType>(0xDC));
6675 write_number(
static_cast<uint16_t>(N));
6677 else if (N <= (std::numeric_limits<uint32_t>::max)())
6680 oa->write_character(
static_cast<CharType>(0xDD));
6681 write_number(
static_cast<uint32_t>(N));
6685 for (
const auto& el : *j.m_value.array)
6692 case value_t::object:
6695 const auto N = j.m_value.object->size();
6699 write_number(
static_cast<uint8_t>(0x80 | (N & 0xF)));
6701 else if (N <= (std::numeric_limits<uint16_t>::max)())
6704 oa->write_character(
static_cast<CharType>(0xDE));
6705 write_number(
static_cast<uint16_t>(N));
6707 else if (N <= (std::numeric_limits<uint32_t>::max)())
6710 oa->write_character(
static_cast<CharType>(0xDF));
6711 write_number(
static_cast<uint32_t>(N));
6715 for (
const auto& el : *j.m_value.object)
6717 write_msgpack(el.first);
6718 write_msgpack(el.second);
6734 void write_ubjson(
const BasicJsonType& j,
const bool use_count,
6735 const bool use_type,
const bool add_prefix =
true)
6743 oa->write_character(
static_cast<CharType>(
'Z'));
6748 case value_t::boolean:
6751 oa->write_character(j.m_value.boolean
6752 ?
static_cast<CharType>(
'T')
6753 :
static_cast<CharType>(
'F'));
6757 case value_t::number_integer:
6759 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
6763 case value_t::number_unsigned:
6765 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
6769 case value_t::number_float:
6771 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
6775 case value_t::string:
6779 oa->write_character(
static_cast<CharType>(
'S'));
6781 write_number_with_ubjson_prefix(j.m_value.string->size(),
true);
6782 oa->write_characters(
6783 reinterpret_cast<
const CharType*>(j.m_value.string->c_str()),
6784 j.m_value.string->size());
6788 case value_t::array:
6792 oa->write_character(
static_cast<CharType>(
'['));
6795 bool prefix_required =
true;
6796 if (use_type
and not j.m_value.array->empty())
6799 const char first_prefix = ubjson_prefix(j.front());
6800 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
6801 [
this, first_prefix](
const BasicJsonType & v)
6803 return ubjson_prefix(v) == first_prefix;
6808 prefix_required =
false;
6809 oa->write_character(
static_cast<CharType>(
'$'));
6810 oa->write_character(
static_cast<CharType>(first_prefix));
6816 oa->write_character(
static_cast<CharType>(
'#'));
6817 write_number_with_ubjson_prefix(j.m_value.array->size(),
true);
6820 for (
const auto& el : *j.m_value.array)
6822 write_ubjson(el, use_count, use_type, prefix_required);
6827 oa->write_character(
static_cast<CharType>(
']'));
6833 case value_t::object:
6837 oa->write_character(
static_cast<CharType>(
'{'));
6840 bool prefix_required =
true;
6841 if (use_type
and not j.m_value.object->empty())
6844 const char first_prefix = ubjson_prefix(j.front());
6845 const bool same_prefix = std::all_of(j.begin(), j.end(),
6846 [
this, first_prefix](
const BasicJsonType & v)
6848 return ubjson_prefix(v) == first_prefix;
6853 prefix_required =
false;
6854 oa->write_character(
static_cast<CharType>(
'$'));
6855 oa->write_character(
static_cast<CharType>(first_prefix));
6861 oa->write_character(
static_cast<CharType>(
'#'));
6862 write_number_with_ubjson_prefix(j.m_value.object->size(),
true);
6865 for (
const auto& el : *j.m_value.object)
6867 write_number_with_ubjson_prefix(el.first.size(),
true);
6868 oa->write_characters(
6869 reinterpret_cast<
const CharType*>(el.first.c_str()),
6871 write_ubjson(el.second, use_count, use_type, prefix_required);
6876 oa->write_character(
static_cast<CharType>(
'}'));
6898 template<
typename NumberType>
6899 void write_number(
const NumberType n)
6902 std::array<CharType,
sizeof(NumberType)> vec;
6903 std::memcpy(vec.data(), &n,
sizeof(NumberType));
6906 if (is_little_endian)
6909 std::reverse(vec.begin(), vec.end());
6912 oa->write_characters(vec.data(),
sizeof(NumberType));
6916 template<
typename NumberType,
typename std::enable_if<
6917 std::is_floating_point<NumberType>::value,
int>::type = 0>
6918 void write_number_with_ubjson_prefix(
const NumberType n,
6919 const bool add_prefix)
6923 oa->write_character(
static_cast<CharType>(
'D'));
6929 template<
typename NumberType,
typename std::enable_if<
6930 std::is_unsigned<NumberType>::value,
int>::type = 0>
6931 void write_number_with_ubjson_prefix(
const NumberType n,
6932 const bool add_prefix)
6934 if (n <=
static_cast<uint64_t>((std::numeric_limits<int8_t>::max)()))
6938 oa->write_character(
static_cast<CharType>(
'i'));
6940 write_number(
static_cast<uint8_t>(n));
6942 else if (n <= (std::numeric_limits<uint8_t>::max)())
6946 oa->write_character(
static_cast<CharType>(
'U'));
6948 write_number(
static_cast<uint8_t>(n));
6950 else if (n <=
static_cast<uint64_t>((std::numeric_limits<int16_t>::max)()))
6954 oa->write_character(
static_cast<CharType>(
'I'));
6956 write_number(
static_cast<int16_t>(n));
6958 else if (n <=
static_cast<uint64_t>((std::numeric_limits<int32_t>::max)()))
6962 oa->write_character(
static_cast<CharType>(
'l'));
6964 write_number(
static_cast<int32_t>(n));
6966 else if (n <=
static_cast<uint64_t>((std::numeric_limits<int64_t>::max)()))
6970 oa->write_character(
static_cast<CharType>(
'L'));
6972 write_number(
static_cast<int64_t>(n));
6976 JSON_THROW(out_of_range::create(407,
"number overflow serializing " + std::to_string(n)));
6981 template<
typename NumberType,
typename std::enable_if<
6982 std::is_signed<NumberType>::value
and 6983 not std::is_floating_point<NumberType>::value,
int>::type = 0>
6984 void write_number_with_ubjson_prefix(
const NumberType n,
6985 const bool add_prefix)
6987 if ((std::numeric_limits<int8_t>::min)() <= n
and n <= (std::numeric_limits<int8_t>::max)())
6991 oa->write_character(
static_cast<CharType>(
'i'));
6993 write_number(
static_cast<int8_t>(n));
6995 else if (
static_cast<int64_t>((std::numeric_limits<uint8_t>::min)()) <= n
and n <=
static_cast<int64_t>((std::numeric_limits<uint8_t>::max)()))
6999 oa->write_character(
static_cast<CharType>(
'U'));
7001 write_number(
static_cast<uint8_t>(n));
7003 else if ((std::numeric_limits<int16_t>::min)() <= n
and n <= (std::numeric_limits<int16_t>::max)())
7007 oa->write_character(
static_cast<CharType>(
'I'));
7009 write_number(
static_cast<int16_t>(n));
7011 else if ((std::numeric_limits<int32_t>::min)() <= n
and n <= (std::numeric_limits<int32_t>::max)())
7015 oa->write_character(
static_cast<CharType>(
'l'));
7017 write_number(
static_cast<int32_t>(n));
7019 else if ((std::numeric_limits<int64_t>::min)() <= n
and n <= (std::numeric_limits<int64_t>::max)())
7023 oa->write_character(
static_cast<CharType>(
'L'));
7025 write_number(
static_cast<int64_t>(n));
7030 JSON_THROW(out_of_range::create(407,
"number overflow serializing " + std::to_string(n)));
7044 char ubjson_prefix(
const BasicJsonType& j)
const noexcept 7051 case value_t::boolean:
7052 return j.m_value.boolean ?
'T' :
'F';
7054 case value_t::number_integer:
7056 if ((std::numeric_limits<int8_t>::min)() <= j.m_value.number_integer
and j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
7060 else if ((std::numeric_limits<uint8_t>::min)() <= j.m_value.number_integer
and j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
7064 else if ((std::numeric_limits<int16_t>::min)() <= j.m_value.number_integer
and j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
7068 else if ((std::numeric_limits<int32_t>::min)() <= j.m_value.number_integer
and j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
7078 case value_t::number_unsigned:
7080 if (j.m_value.number_unsigned <= (std::numeric_limits<int8_t>::max)())
7084 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
7088 else if (j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max)())
7092 else if (j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max)())
7102 case value_t::number_float:
7105 case value_t::string:
7108 case value_t::array:
7111 case value_t::object:
7121 const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
7124 output_adapter_t<CharType> oa =
nullptr;
7132 #include <algorithm> 7146 #include <type_traits> 7186 template <
typename Target,
typename Source>
7187 Target reinterpret_bits(
const Source source)
7189 static_assert(
sizeof(Target) ==
sizeof(Source),
"size mismatch");
7192 std::memcpy(&target, &source,
sizeof(Source));
7198 static constexpr int kPrecision = 64;
7203 constexpr diyfp()
noexcept : f(0), e(0) {}
7204 constexpr diyfp(uint64_t f_,
int e_)
noexcept : f(f_), e(e_) {}
7210 static diyfp sub(
const diyfp& x,
const diyfp& y)
noexcept 7215 return diyfp(x.f - y.f, x.e);
7222 static diyfp mul(
const diyfp& x,
const diyfp& y)
noexcept 7224 static_assert(kPrecision == 64,
"internal error");
7249 const uint64_t u_lo = x.f & 0xFFFFFFFF;
7250 const uint64_t u_hi = x.f >> 32;
7251 const uint64_t v_lo = y.f & 0xFFFFFFFF;
7252 const uint64_t v_hi = y.f >> 32;
7254 const uint64_t p0 = u_lo * v_lo;
7255 const uint64_t p1 = u_lo * v_hi;
7256 const uint64_t p2 = u_hi * v_lo;
7257 const uint64_t p3 = u_hi * v_hi;
7259 const uint64_t p0_hi = p0 >> 32;
7260 const uint64_t p1_lo = p1 & 0xFFFFFFFF;
7261 const uint64_t p1_hi = p1 >> 32;
7262 const uint64_t p2_lo = p2 & 0xFFFFFFFF;
7263 const uint64_t p2_hi = p2 >> 32;
7265 uint64_t Q = p0_hi + p1_lo + p2_lo;
7276 Q += uint64_t{1} << (64 - 32 - 1);
7278 const uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32);
7280 return diyfp(h, x.e + y.e + 64);
7287 static diyfp normalize(diyfp x)
noexcept 7291 while ((x.f >> 63) == 0)
7304 static diyfp normalize_to(
const diyfp& x,
const int target_exponent)
noexcept 7306 const int delta = x.e - target_exponent;
7309 assert(((x.f << delta) >> delta) == x.f);
7311 return diyfp(x.f << delta, target_exponent);
7328 template <
typename FloatType>
7329 boundaries compute_boundaries(FloatType value)
7331 assert(std::isfinite(value));
7341 static_assert(std::numeric_limits<FloatType>::is_iec559,
7342 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
7344 constexpr int kPrecision = std::numeric_limits<FloatType>::digits;
7345 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
7346 constexpr int kMinExp = 1 - kBias;
7347 constexpr uint64_t kHiddenBit = uint64_t{1} << (kPrecision - 1);
7349 using bits_type =
typename std::conditional< kPrecision == 24, uint32_t, uint64_t >::type;
7351 const uint64_t bits = reinterpret_bits<bits_type>(value);
7352 const uint64_t E = bits >> (kPrecision - 1);
7353 const uint64_t F = bits & (kHiddenBit - 1);
7355 const bool is_denormal = (E == 0);
7356 const diyfp v = is_denormal
7358 : diyfp(F + kHiddenBit,
static_cast<
int>(E) - kBias);
7381 const bool lower_boundary_is_closer = (F == 0
and E > 1);
7382 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
7383 const diyfp m_minus = lower_boundary_is_closer
7384 ? diyfp(4 * v.f - 1, v.e - 2)
7385 : diyfp(2 * v.f - 1, v.e - 1);
7388 const diyfp w_plus = diyfp::normalize(m_plus);
7391 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
7393 return {diyfp::normalize(v), w_minus, w_plus};
7451 constexpr int kAlpha = -60;
7452 constexpr int kGamma = -32;
7468 inline cached_power get_cached_power_for_binary_exponent(
int e)
7520 constexpr int kCachedPowersSize = 79;
7521 constexpr int kCachedPowersMinDecExp = -300;
7522 constexpr int kCachedPowersDecStep = 8;
7524 static constexpr cached_power kCachedPowers[] =
7526 { 0xAB70FE17C79AC6CA, -1060, -300 },
7527 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
7528 { 0xBE5691EF416BD60C, -1007, -284 },
7529 { 0x8DD01FAD907FFC3C, -980, -276 },
7530 { 0xD3515C2831559A83, -954, -268 },
7531 { 0x9D71AC8FADA6C9B5, -927, -260 },
7532 { 0xEA9C227723EE8BCB, -901, -252 },
7533 { 0xAECC49914078536D, -874, -244 },
7534 { 0x823C12795DB6CE57, -847, -236 },
7535 { 0xC21094364DFB5637, -821, -228 },
7536 { 0x9096EA6F3848984F, -794, -220 },
7537 { 0xD77485CB25823AC7, -768, -212 },
7538 { 0xA086CFCD97BF97F4, -741, -204 },
7539 { 0xEF340A98172AACE5, -715, -196 },
7540 { 0xB23867FB2A35B28E, -688, -188 },
7541 { 0x84C8D4DFD2C63F3B, -661, -180 },
7542 { 0xC5DD44271AD3CDBA, -635, -172 },
7543 { 0x936B9FCEBB25C996, -608, -164 },
7544 { 0xDBAC6C247D62A584, -582, -156 },
7545 { 0xA3AB66580D5FDAF6, -555, -148 },
7546 { 0xF3E2F893DEC3F126, -529, -140 },
7547 { 0xB5B5ADA8AAFF80B8, -502, -132 },
7548 { 0x87625F056C7C4A8B, -475, -124 },
7549 { 0xC9BCFF6034C13053, -449, -116 },
7550 { 0x964E858C91BA2655, -422, -108 },
7551 { 0xDFF9772470297EBD, -396, -100 },
7552 { 0xA6DFBD9FB8E5B88F, -369, -92 },
7553 { 0xF8A95FCF88747D94, -343, -84 },
7554 { 0xB94470938FA89BCF, -316, -76 },
7555 { 0x8A08F0F8BF0F156B, -289, -68 },
7556 { 0xCDB02555653131B6, -263, -60 },
7557 { 0x993FE2C6D07B7FAC, -236, -52 },
7558 { 0xE45C10C42A2B3B06, -210, -44 },
7559 { 0xAA242499697392D3, -183, -36 },
7560 { 0xFD87B5F28300CA0E, -157, -28 },
7561 { 0xBCE5086492111AEB, -130, -20 },
7562 { 0x8CBCCC096F5088CC, -103, -12 },
7563 { 0xD1B71758E219652C, -77, -4 },
7564 { 0x9C40000000000000, -50, 4 },
7565 { 0xE8D4A51000000000, -24, 12 },
7566 { 0xAD78EBC5AC620000, 3, 20 },
7567 { 0x813F3978F8940984, 30, 28 },
7568 { 0xC097CE7BC90715B3, 56, 36 },
7569 { 0x8F7E32CE7BEA5C70, 83, 44 },
7570 { 0xD5D238A4ABE98068, 109, 52 },
7571 { 0x9F4F2726179A2245, 136, 60 },
7572 { 0xED63A231D4C4FB27, 162, 68 },
7573 { 0xB0DE65388CC8ADA8, 189, 76 },
7574 { 0x83C7088E1AAB65DB, 216, 84 },
7575 { 0xC45D1DF942711D9A, 242, 92 },
7576 { 0x924D692CA61BE758, 269, 100 },
7577 { 0xDA01EE641A708DEA, 295, 108 },
7578 { 0xA26DA3999AEF774A, 322, 116 },
7579 { 0xF209787BB47D6B85, 348, 124 },
7580 { 0xB454E4A179DD1877, 375, 132 },
7581 { 0x865B86925B9BC5C2, 402, 140 },
7582 { 0xC83553C5C8965D3D, 428, 148 },
7583 { 0x952AB45CFA97A0B3, 455, 156 },
7584 { 0xDE469FBD99A05FE3, 481, 164 },
7585 { 0xA59BC234DB398C25, 508, 172 },
7586 { 0xF6C69A72A3989F5C, 534, 180 },
7587 { 0xB7DCBF5354E9BECE, 561, 188 },
7588 { 0x88FCF317F22241E2, 588, 196 },
7589 { 0xCC20CE9BD35C78A5, 614, 204 },
7590 { 0x98165AF37B2153DF, 641, 212 },
7591 { 0xE2A0B5DC971F303A, 667, 220 },
7592 { 0xA8D9D1535CE3B396, 694, 228 },
7593 { 0xFB9B7CD9A4A7443C, 720, 236 },
7594 { 0xBB764C4CA7A44410, 747, 244 },
7595 { 0x8BAB8EEFB6409C1A, 774, 252 },
7596 { 0xD01FEF10A657842C, 800, 260 },
7597 { 0x9B10A4E5E9913129, 827, 268 },
7598 { 0xE7109BFBA19C0C9D, 853, 276 },
7599 { 0xAC2820D9623BF429, 880, 284 },
7600 { 0x80444B5E7AA7CF85, 907, 292 },
7601 { 0xBF21E44003ACDD2D, 933, 300 },
7602 { 0x8E679C2F5E44FF8F, 960, 308 },
7603 { 0xD433179D9C8CB841, 986, 316 },
7604 { 0x9E19DB92B4E31BA9, 1013, 324 },
7613 const int f = kAlpha - e - 1;
7614 const int k = (f * 78913) / (1 << 18) + (f > 0);
7616 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
7618 assert(index < kCachedPowersSize);
7619 static_cast<
void>(kCachedPowersSize);
7621 const cached_power cached = kCachedPowers[index];
7622 assert(kAlpha <= cached.e + e + 64);
7623 assert(kGamma >= cached.e + e + 64);
7632 inline int find_largest_pow10(
const uint32_t n, uint32_t& pow10)
7635 if (n >= 1000000000)
7641 else if (n >= 100000000)
7646 else if (n >= 10000000)
7651 else if (n >= 1000000)
7656 else if (n >= 100000)
7661 else if (n >= 10000)
7688 inline void grisu2_round(
char* buf,
int len, uint64_t dist, uint64_t delta,
7689 uint64_t rest, uint64_t ten_k)
7692 assert(dist <= delta);
7693 assert(rest <= delta);
7716 and delta - rest >= ten_k
7717 and (rest + ten_k < dist
or dist - rest > rest + ten_k - dist))
7719 assert(buf[len - 1] !=
'0');
7729 inline void grisu2_digit_gen(
char* buffer,
int& length,
int& decimal_exponent,
7730 diyfp M_minus, diyfp w, diyfp M_plus)
7732 static_assert(kAlpha >= -60,
"internal error");
7733 static_assert(kGamma <= -32,
"internal error");
7747 assert(M_plus.e >= kAlpha);
7748 assert(M_plus.e <= kGamma);
7750 uint64_t delta = diyfp::sub(M_plus, M_minus).f;
7751 uint64_t dist = diyfp::sub(M_plus, w ).f;
7760 const diyfp one(uint64_t{1} << -M_plus.e, M_plus.e);
7762 uint32_t p1 =
static_cast<uint32_t>(M_plus.f >> -one.e);
7763 uint64_t p2 = M_plus.f & (one.f - 1);
7772 const int k = find_largest_pow10(p1, pow10);
7799 const uint32_t d = p1 / pow10;
7800 const uint32_t r = p1 % pow10;
7806 buffer[length++] =
static_cast<
char>(
'0' + d);
7825 const uint64_t rest = (uint64_t{p1} << -one.e) + p2;
7830 decimal_exponent += n;
7841 const uint64_t ten_n = uint64_t{pow10} << -one.e;
7842 grisu2_round(buffer, length, dist, delta, rest, ten_n);
7903 assert(p2 <= UINT64_MAX / 10);
7905 const uint64_t d = p2 >> -one.e;
7906 const uint64_t r = p2 & (one.f - 1);
7913 buffer[length++] =
static_cast<
char>(
'0' + d);
7938 decimal_exponent -= m;
7946 const uint64_t ten_m = one.f;
7947 grisu2_round(buffer, length, dist, delta, p2, ten_m);
7969 inline void grisu2(
char* buf,
int& len,
int& decimal_exponent,
7970 diyfp m_minus, diyfp v, diyfp m_plus)
7972 assert(m_plus.e == m_minus.e);
7973 assert(m_plus.e == v.e);
7984 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
7986 const diyfp c_minus_k(cached.f, cached.e);
7989 const diyfp w = diyfp::mul(v, c_minus_k);
7990 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
7991 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
8014 const diyfp M_minus(w_minus.f + 1, w_minus.e);
8015 const diyfp M_plus (w_plus.f - 1, w_plus.e );
8017 decimal_exponent = -cached.k;
8019 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
8027 template <
typename FloatType>
8028 void grisu2(
char* buf,
int& len,
int& decimal_exponent, FloatType value)
8030 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
8031 "internal error: not enough precision");
8033 assert(std::isfinite(value));
8053 const boundaries w = compute_boundaries(
static_cast<
double>(value));
8055 const boundaries w = compute_boundaries(value);
8058 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
8066 inline char* append_exponent(
char* buf,
int e)
8081 uint32_t k =
static_cast<uint32_t>(e);
8087 *buf++ =
static_cast<
char>(
'0' + k);
8091 *buf++ =
static_cast<
char>(
'0' + k / 10);
8093 *buf++ =
static_cast<
char>(
'0' + k);
8097 *buf++ =
static_cast<
char>(
'0' + k / 100);
8099 *buf++ =
static_cast<
char>(
'0' + k / 10);
8101 *buf++ =
static_cast<
char>(
'0' + k);
8116 inline char* format_buffer(
char* buf,
int len,
int decimal_exponent,
8117 int min_exp,
int max_exp)
8119 assert(min_exp < 0);
8120 assert(max_exp > 0);
8123 const int n = len + decimal_exponent;
8129 if (k <= n
and n <= max_exp)
8134 std::memset(buf + k,
'0',
static_cast<size_t>(n - k));
8138 return buf + (n + 2);
8141 if (0 < n
and n <= max_exp)
8148 std::memmove(buf + (n + 1), buf + n,
static_cast<size_t>(k - n));
8150 return buf + (k + 1);
8153 if (min_exp < n
and n <= 0)
8158 std::memmove(buf + (2 + -n), buf,
static_cast<size_t>(k));
8161 std::memset(buf + 2,
'0',
static_cast<size_t>(-n));
8162 return buf + (2 + (-n) + k);
8177 std::memmove(buf + 2, buf + 1,
static_cast<size_t>(k - 1));
8183 return append_exponent(buf, n - 1);
8198 template <
typename FloatType>
8199 char* to_chars(
char* first,
char* last, FloatType value)
8201 static_cast<
void>(last);
8202 assert(std::isfinite(value));
8205 if (std::signbit(value))
8220 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
8227 int decimal_exponent = 0;
8228 dtoa_impl::grisu2(first, len, decimal_exponent, value);
8230 assert(len <= std::numeric_limits<FloatType>::max_digits10);
8233 constexpr int kMinExp = -4;
8235 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
8237 assert(last - first >= kMaxExp + 2);
8238 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
8239 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
8241 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
8264 template<
typename BasicJsonType>
8267 using string_t =
typename BasicJsonType::string_t;
8268 using number_float_t =
typename BasicJsonType::number_float_t;
8269 using number_integer_t =
typename BasicJsonType::number_integer_t;
8270 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
8271 static constexpr uint8_t UTF8_ACCEPT = 0;
8272 static constexpr uint8_t UTF8_REJECT = 1;
8279 serializer(output_adapter_t<
char> s,
const char ichar)
8280 : o(std::move(s)), loc(std::localeconv()),
8281 thousands_sep(loc->thousands_sep ==
nullptr ?
'\0' : * (loc->thousands_sep)),
8282 decimal_point(loc->decimal_point ==
nullptr ?
'\0' : * (loc->decimal_point)),
8283 indent_char(ichar), indent_string(512, indent_char)
8287 serializer(
const serializer&) =
delete;
8288 serializer& operator=(
const serializer&) =
delete;
8307 void dump(
const BasicJsonType& val,
const bool pretty_print,
8308 const bool ensure_ascii,
8309 const unsigned int indent_step,
8310 const unsigned int current_indent = 0)
8314 case value_t::object:
8316 if (val.m_value.object->empty())
8318 o->write_characters(
"{}", 2);
8324 o->write_characters(
"{\n", 2);
8327 const auto new_indent = current_indent + indent_step;
8330 indent_string.resize(indent_string.size() * 2,
' ');
8334 auto i = val.m_value.object->cbegin();
8335 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
8337 o->write_characters(indent_string.c_str(), new_indent);
8338 o->write_character(
'\"');
8339 dump_escaped(i->first, ensure_ascii);
8340 o->write_characters(
"\": ", 3);
8341 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
8342 o->write_characters(
",\n", 2);
8346 assert(i != val.m_value.object->cend());
8347 assert(std::next(i) == val.m_value.object->cend());
8348 o->write_characters(indent_string.c_str(), new_indent);
8349 o->write_character(
'\"');
8350 dump_escaped(i->first, ensure_ascii);
8351 o->write_characters(
"\": ", 3);
8352 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
8354 o->write_character(
'\n');
8355 o->write_characters(indent_string.c_str(), current_indent);
8356 o->write_character(
'}');
8360 o->write_character(
'{');
8363 auto i = val.m_value.object->cbegin();
8364 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
8366 o->write_character(
'\"');
8367 dump_escaped(i->first, ensure_ascii);
8368 o->write_characters(
"\":", 2);
8369 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
8370 o->write_character(
',');
8374 assert(i != val.m_value.object->cend());
8375 assert(std::next(i) == val.m_value.object->cend());
8376 o->write_character(
'\"');
8377 dump_escaped(i->first, ensure_ascii);
8378 o->write_characters(
"\":", 2);
8379 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
8381 o->write_character(
'}');
8387 case value_t::array:
8389 if (val.m_value.array->empty())
8391 o->write_characters(
"[]", 2);
8397 o->write_characters(
"[\n", 2);
8400 const auto new_indent = current_indent + indent_step;
8403 indent_string.resize(indent_string.size() * 2,
' ');
8407 for (
auto i = val.m_value.array->cbegin();
8408 i != val.m_value.array->cend() - 1; ++i)
8410 o->write_characters(indent_string.c_str(), new_indent);
8411 dump(*i,
true, ensure_ascii, indent_step, new_indent);
8412 o->write_characters(
",\n", 2);
8416 assert(
not val.m_value.array->empty());
8417 o->write_characters(indent_string.c_str(), new_indent);
8418 dump(val.m_value.array->back(),
true, ensure_ascii, indent_step, new_indent);
8420 o->write_character(
'\n');
8421 o->write_characters(indent_string.c_str(), current_indent);
8422 o->write_character(
']');
8426 o->write_character(
'[');
8429 for (
auto i = val.m_value.array->cbegin();
8430 i != val.m_value.array->cend() - 1; ++i)
8432 dump(*i,
false, ensure_ascii, indent_step, current_indent);
8433 o->write_character(
',');
8437 assert(
not val.m_value.array->empty());
8438 dump(val.m_value.array->back(),
false, ensure_ascii, indent_step, current_indent);
8440 o->write_character(
']');
8446 case value_t::string:
8448 o->write_character(
'\"');
8449 dump_escaped(*val.m_value.string, ensure_ascii);
8450 o->write_character(
'\"');
8454 case value_t::boolean:
8456 if (val.m_value.boolean)
8458 o->write_characters(
"true", 4);
8462 o->write_characters(
"false", 5);
8467 case value_t::number_integer:
8469 dump_integer(val.m_value.number_integer);
8473 case value_t::number_unsigned:
8475 dump_integer(val.m_value.number_unsigned);
8479 case value_t::number_float:
8481 dump_float(val.m_value.number_float);
8485 case value_t::discarded:
8487 o->write_characters(
"<discarded>", 11);
8493 o->write_characters(
"null", 4);
8514 void dump_escaped(
const string_t& s,
const bool ensure_ascii)
8517 uint8_t state = UTF8_ACCEPT;
8518 std::size_t bytes = 0;
8520 for (std::size_t i = 0; i < s.size(); ++i)
8522 const auto byte =
static_cast<uint8_t>(s[i]);
8524 switch (decode(state, codepoint, byte))
8532 string_buffer[bytes++] =
'\\';
8533 string_buffer[bytes++] =
'b';
8539 string_buffer[bytes++] =
'\\';
8540 string_buffer[bytes++] =
't';
8546 string_buffer[bytes++] =
'\\';
8547 string_buffer[bytes++] =
'n';
8553 string_buffer[bytes++] =
'\\';
8554 string_buffer[bytes++] =
'f';
8560 string_buffer[bytes++] =
'\\';
8561 string_buffer[bytes++] =
'r';
8567 string_buffer[bytes++] =
'\\';
8568 string_buffer[bytes++] =
'\"';
8574 string_buffer[bytes++] =
'\\';
8575 string_buffer[bytes++] =
'\\';
8583 if ((codepoint <= 0x1F)
or (ensure_ascii
and (codepoint >= 0x7F)))
8585 if (codepoint <= 0xFFFF)
8587 std::snprintf(string_buffer.data() + bytes, 7,
"\\u%04x",
8588 static_cast<uint16_t>(codepoint));
8593 std::snprintf(string_buffer.data() + bytes, 13,
"\\u%04x\\u%04x",
8594 static_cast<uint16_t>(0xD7C0 + (codepoint >> 10)),
8595 static_cast<uint16_t>(0xDC00 + (codepoint & 0x3FF)));
8603 string_buffer[bytes++] = s[i];
8612 if (string_buffer.size() - bytes < 13)
8614 o->write_characters(string_buffer.data(), bytes);
8622 std::stringstream ss;
8623 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex <<
static_cast<
int>(byte);
8624 JSON_THROW(type_error::create(316,
"invalid UTF-8 byte at index " + std::to_string(i) +
": 0x" + ss.str()));
8629 if (
not ensure_ascii)
8632 string_buffer[bytes++] = s[i];
8644 o->write_characters(string_buffer.data(), bytes);
8650 std::stringstream ss;
8651 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex <<
static_cast<
int>(
static_cast<uint8_t>(s.back()));
8652 JSON_THROW(type_error::create(316,
"incomplete UTF-8 string; last byte: 0x" + ss.str()));
8665 template<
typename NumberType, detail::enable_if_t<
8666 std::is_same<NumberType, number_unsigned_t>::value
or 8667 std::is_same<NumberType, number_integer_t>::value,
8669 void dump_integer(NumberType x)
8674 o->write_character(
'0');
8678 const bool is_negative = (x <= 0)
and (x != 0);
8684 assert(i < number_buffer.size() - 1);
8686 const auto digit = std::labs(
static_cast<
long>(x % 10));
8687 number_buffer[i++] =
static_cast<
char>(
'0' + digit);
8694 assert(i < number_buffer.size() - 2);
8695 number_buffer[i++] =
'-';
8698 std::reverse(number_buffer.begin(), number_buffer.begin() + i);
8699 o->write_characters(number_buffer.data(), i);
8710 void dump_float(number_float_t x)
8713 if (
not std::isfinite(x))
8715 o->write_characters(
"null", 4);
8724 static constexpr bool is_ieee_single_or_double
8725 = (std::numeric_limits<number_float_t>::is_iec559
and std::numeric_limits<number_float_t>::digits == 24
and std::numeric_limits<number_float_t>::max_exponent == 128)
or 8726 (std::numeric_limits<number_float_t>::is_iec559
and std::numeric_limits<number_float_t>::digits == 53
and std::numeric_limits<number_float_t>::max_exponent == 1024);
8728 dump_float(x, std::integral_constant<
bool, is_ieee_single_or_double>());
8731 void dump_float(number_float_t x, std::true_type )
8733 char* begin = number_buffer.data();
8734 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
8736 o->write_characters(begin,
static_cast<size_t>(end - begin));
8739 void dump_float(number_float_t x, std::false_type )
8742 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
8745 std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(),
"%.*g", d, x);
8750 assert(
static_cast<std::size_t>(len) < number_buffer.size());
8753 if (thousands_sep !=
'\0')
8755 const auto end = std::remove(number_buffer.begin(),
8756 number_buffer.begin() + len, thousands_sep);
8757 std::fill(end, number_buffer.end(),
'\0');
8758 assert((end - number_buffer.begin()) <= len);
8759 len = (end - number_buffer.begin());
8763 if (decimal_point !=
'\0' and decimal_point !=
'.')
8765 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
8766 if (dec_pos != number_buffer.end())
8772 o->write_characters(number_buffer.data(),
static_cast<std::size_t>(len));
8775 const bool value_is_int_like =
8776 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
8779 return (c ==
'.' or c ==
'e');
8782 if (value_is_int_like)
8784 o->write_characters(
".0", 2);
8809 static uint8_t decode(uint8_t& state, uint32_t& codep,
const uint8_t byte)
noexcept 8811 static const std::array<uint8_t, 400> utf8d =
8814 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,
8815 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,
8816 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,
8817 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,
8818 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,
8819 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,
8820 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,
8821 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
8822 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
8823 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
8824 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,
8825 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,
8826 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,
8827 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
8831 const uint8_t type = utf8d[byte];
8833 codep = (state != UTF8_ACCEPT)
8834 ? (byte & 0x3fu) | (codep << 6)
8835 :
static_cast<uint32_t>(0xff >> type) & (byte);
8837 state = utf8d[256u + state * 16u + type];
8843 output_adapter_t<
char> o =
nullptr;
8846 std::array<
char, 64> number_buffer{{}};
8849 const std::lconv* loc =
nullptr;
8851 const char thousands_sep =
'\0';
8853 const char decimal_point =
'\0';
8856 std::array<
char, 512> string_buffer{{}};
8859 const char indent_char;
8861 string_t indent_string;
8869 #include <initializer_list> 8876 template<
typename BasicJsonType>
8880 using value_type = BasicJsonType;
8882 json_ref(value_type&& value)
8883 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(
true)
8886 json_ref(
const value_type& value)
8887 : value_ref(
const_cast<value_type*>(&value)), is_rvalue(
false)
8890 json_ref(std::initializer_list<json_ref> init)
8891 : owned_value(init), value_ref(&owned_value), is_rvalue(
true)
8894 template<
class... Args>
8895 json_ref(Args&& ... args)
8896 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value), is_rvalue(
true)
8900 json_ref(json_ref&&) =
default;
8901 json_ref(
const json_ref&) =
delete;
8902 json_ref& operator=(
const json_ref&) =
delete;
8904 value_type moved_or_copied()
const 8908 return std::move(*value_ref);
8913 value_type
const& operator*()
const 8915 return *
static_cast<value_type
const*>(value_ref);
8918 value_type
const* operator->()
const 8920 return static_cast<value_type
const*>(value_ref);
8924 mutable value_type owned_value =
nullptr;
8925 value_type* value_ref =
nullptr;
8926 const bool is_rvalue;
8948 template<
typename BasicJsonType>
8953 friend class basic_json;
8977 explicit json_pointer(
const std::string& s =
"")
8978 : reference_tokens(split(s))
8996 std::string to_string()
const noexcept 8998 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
9000 [](
const std::string & a,
const std::string & b)
9002 return a +
"/" + escape(b);
9007 operator std::string()
const 9019 static int array_index(
const std::string& s)
9021 std::size_t processed_chars = 0;
9022 const int res = std::stoi(s, &processed_chars);
9027 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + s +
"'"));
9038 std::string pop_back()
9042 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
9045 auto last = reference_tokens.back();
9046 reference_tokens.pop_back();
9051 bool is_root()
const 9053 return reference_tokens.empty();
9056 json_pointer top()
const 9060 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
9063 json_pointer result = *
this;
9064 result.reference_tokens = {reference_tokens[0]};
9076 BasicJsonType& get_and_create(BasicJsonType& j)
const 9078 using size_type =
typename BasicJsonType::size_type;
9083 for (
const auto& reference_token : reference_tokens)
9085 switch (result->m_type)
9087 case detail::value_t::null:
9089 if (reference_token ==
"0")
9092 result = &result->operator[](0);
9097 result = &result->operator[](reference_token);
9102 case detail::value_t::object:
9105 result = &result->operator[](reference_token);
9109 case detail::value_t::array:
9114 result = &result->operator[](
static_cast<size_type>(array_index(reference_token)));
9118 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
9130 JSON_THROW(detail::type_error::create(313,
"invalid value to unflatten"));
9156 BasicJsonType& get_unchecked(BasicJsonType* ptr)
const 9158 using size_type =
typename BasicJsonType::size_type;
9159 for (
const auto& reference_token : reference_tokens)
9162 if (ptr->m_type == detail::value_t::null)
9166 std::all_of(reference_token.begin(), reference_token.end(),
9169 return (x >=
'0' and x <=
'9');
9173 *ptr = (nums
or reference_token ==
"-")
9174 ? detail::value_t::array
9175 : detail::value_t::object;
9178 switch (ptr->m_type)
9180 case detail::value_t::object:
9183 ptr = &ptr->operator[](reference_token);
9187 case detail::value_t::array:
9190 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
9192 JSON_THROW(detail::parse_error::create(106, 0,
9193 "array index '" + reference_token +
9194 "' must not begin with '0'"));
9197 if (reference_token ==
"-")
9200 ptr = &ptr->operator[](ptr->m_value.array->size());
9207 ptr = &ptr->operator[](
9208 static_cast<size_type>(array_index(reference_token)));
9212 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
9219 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
9232 BasicJsonType& get_checked(BasicJsonType* ptr)
const 9234 using size_type =
typename BasicJsonType::size_type;
9235 for (
const auto& reference_token : reference_tokens)
9237 switch (ptr->m_type)
9239 case detail::value_t::object:
9242 ptr = &ptr->at(reference_token);
9246 case detail::value_t::array:
9252 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
9253 ") is out of range"));
9257 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
9259 JSON_THROW(detail::parse_error::create(106, 0,
9260 "array index '" + reference_token +
9261 "' must not begin with '0'"));
9267 ptr = &ptr->at(
static_cast<size_type>(array_index(reference_token)));
9271 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
9277 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
9297 const BasicJsonType& get_unchecked(
const BasicJsonType* ptr)
const 9299 using size_type =
typename BasicJsonType::size_type;
9300 for (
const auto& reference_token : reference_tokens)
9302 switch (ptr->m_type)
9304 case detail::value_t::object:
9307 ptr = &ptr->operator[](reference_token);
9311 case detail::value_t::array:
9317 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
9318 ") is out of range"));
9322 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
9324 JSON_THROW(detail::parse_error::create(106, 0,
9325 "array index '" + reference_token +
9326 "' must not begin with '0'"));
9332 ptr = &ptr->operator[](
9333 static_cast<size_type>(array_index(reference_token)));
9337 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
9343 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
9356 const BasicJsonType& get_checked(
const BasicJsonType* ptr)
const 9358 using size_type =
typename BasicJsonType::size_type;
9359 for (
const auto& reference_token : reference_tokens)
9361 switch (ptr->m_type)
9363 case detail::value_t::object:
9366 ptr = &ptr->at(reference_token);
9370 case detail::value_t::array:
9376 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
9377 ") is out of range"));
9381 if (
JSON_UNLIKELY(reference_token.size() > 1
and reference_token[0] ==
'0'))
9383 JSON_THROW(detail::parse_error::create(106, 0,
9384 "array index '" + reference_token +
9385 "' must not begin with '0'"));
9391 ptr = &ptr->at(
static_cast<size_type>(array_index(reference_token)));
9395 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
9401 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
9417 static std::vector<std::string> split(
const std::string& reference_string)
9419 std::vector<std::string> result;
9422 if (reference_string.empty())
9430 JSON_THROW(detail::parse_error::create(107, 1,
9431 "JSON pointer must be empty or begin with '/' - was: '" +
9432 reference_string +
"'"));
9440 std::size_t slash = reference_string.find_first_of(
'/', 1),
9449 slash = reference_string.find_first_of(
'/', start))
9453 auto reference_token = reference_string.substr(start, slash - start);
9456 for (std::size_t pos = reference_token.find_first_of(
'~');
9457 pos != std::string::npos;
9458 pos = reference_token.find_first_of(
'~', pos + 1))
9460 assert(reference_token[pos] ==
'~');
9464 (reference_token[pos + 1] !=
'0' and 9465 reference_token[pos + 1] !=
'1')))
9467 JSON_THROW(detail::parse_error::create(108, 0,
"escape character '~' must be followed with '0' or '1'"));
9472 unescape(reference_token);
9473 result.push_back(reference_token);
9492 static void replace_substring(std::string& s,
const std::string& f,
9493 const std::string& t)
9495 assert(
not f.empty());
9496 for (
auto pos = s.find(f);
9497 pos != std::string::npos;
9498 s.replace(pos, f.size(), t),
9499 pos = s.find(f, pos + t.size()))
9504 static std::string escape(std::string s)
9506 replace_substring(s,
"~",
"~0");
9507 replace_substring(s,
"/",
"~1");
9512 static void unescape(std::string& s)
9514 replace_substring(s,
"~1",
"/");
9515 replace_substring(s,
"~0",
"~");
9525 static void flatten(
const std::string& reference_string,
9526 const BasicJsonType& value,
9527 BasicJsonType& result)
9529 switch (value.m_type)
9531 case detail::value_t::array:
9533 if (value.m_value.array->empty())
9536 result[reference_string] =
nullptr;
9541 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
9543 flatten(reference_string +
"/" + std::to_string(i),
9544 value.m_value.array->operator[](i), result);
9550 case detail::value_t::object:
9552 if (value.m_value.object->empty())
9555 result[reference_string] =
nullptr;
9560 for (
const auto& element : *value.m_value.object)
9562 flatten(reference_string +
"/" + escape(element.first), element.second, result);
9571 result[reference_string] = value;
9587 static BasicJsonType
9588 unflatten(
const BasicJsonType& value)
9592 JSON_THROW(detail::type_error::create(314,
"only objects can be unflattened"));
9595 BasicJsonType result;
9598 for (
const auto& element : *value.m_value.object)
9602 JSON_THROW(detail::type_error::create(315,
"values in object must be primitive"));
9609 json_pointer(element.first).get_and_create(result) = element.second;
9615 friend bool operator==(json_pointer
const& lhs,
9616 json_pointer
const& rhs)
noexcept 9618 return (lhs.reference_tokens == rhs.reference_tokens);
9621 friend bool operator!=(json_pointer
const& lhs,
9622 json_pointer
const& rhs)
noexcept 9624 return not (lhs == rhs);
9628 std::vector<std::string> reference_tokens;
9644 template<
typename,
typename>
9645 struct adl_serializer
9656 template<
typename BasicJsonType,
typename ValueType>
9657 static void from_json(BasicJsonType&& j, ValueType& val)
noexcept(
9658 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
9660 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
9672 template<
typename BasicJsonType,
typename ValueType>
9673 static void to_json(BasicJsonType& j, ValueType&& val)
noexcept(
9674 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
9676 ::nlohmann::to_json(j, std::forward<ValueType>(val));
9775 template<detail::value_t>
friend struct detail::external_constructor;
9776 friend ::nlohmann::json_pointer<basic_json>;
9777 friend ::nlohmann::detail::parser<basic_json>;
9778 friend ::nlohmann::detail::serializer<basic_json>;
9779 template<
typename BasicJsonType>
9780 friend class ::nlohmann::detail::iter_impl;
9781 template<
typename BasicJsonType,
typename CharType>
9782 friend class ::nlohmann::detail::binary_writer;
9783 template<
typename BasicJsonType>
9784 friend class ::nlohmann::detail::binary_reader;
9790 using lexer = ::nlohmann::detail::lexer<basic_json>;
9791 using parser = ::nlohmann::detail::parser<basic_json>;
9793 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
9794 template<
typename BasicJsonType>
9795 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
9796 template<
typename BasicJsonType>
9797 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
9798 template<
typename Iterator>
9799 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
9800 template<
typename Base>
using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
9802 template<
typename CharType>
9803 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
9805 using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
9806 template<
typename CharType>
using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
9808 using serializer = ::nlohmann::detail::serializer<basic_json>;
9811 using value_t = detail::value_t;
9813 using json_pointer = ::nlohmann::json_pointer<basic_json>;
9814 template<
typename T,
typename SFINAE>
9815 using json_serializer = JSONSerializer<T, SFINAE>;
9817 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
9828 using exception = detail::exception;
9830 using parse_error = detail::parse_error;
9832 using invalid_iterator = detail::invalid_iterator;
9834 using type_error = detail::type_error;
9836 using out_of_range = detail::out_of_range;
9838 using other_error = detail::other_error;
9853 using value_type = basic_json;
9856 using reference = value_type&;
9858 using const_reference =
const value_type&;
9861 using difference_type = std::ptrdiff_t;
9863 using size_type = std::size_t;
9866 using allocator_type = AllocatorType<basic_json>;
9869 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
9871 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
9874 using iterator = iter_impl<basic_json>;
9876 using const_iterator = iter_impl<
const basic_json>;
9878 using reverse_iterator = json_reverse_iterator<
typename basic_json::iterator>;
9880 using const_reverse_iterator = json_reverse_iterator<
typename basic_json::const_iterator>;
9888 static allocator_type get_allocator()
9890 return allocator_type();
9919 static basic_json meta()
9923 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
9924 result[
"name"] =
"JSON for Modern C++";
9925 result[
"url"] =
"https://github.com/nlohmann/json";
9926 result[
"version"][
"string"] =
9935 result[
"platform"] =
"win32";
9936 #elif defined __linux__
9937 result[
"platform"] =
"linux";
9938 #elif defined __APPLE__ 9939 result[
"platform"] =
"apple";
9940 #elif defined __unix__ 9941 result[
"platform"] =
"unix";
9943 result[
"platform"] =
"unknown";
9946 #if defined(__ICC) || defined(__INTEL_COMPILER) 9947 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
9948 #elif defined(__clang__
) 9949 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
9950 #elif defined(__GNUC__) || defined(__GNUG__) 9951 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(__GNUC_PATCHLEVEL__)}};
9952 #elif defined(__HP_cc) || defined(__HP_aCC) 9953 result[
"compiler"] =
"hp" 9954 #elif defined(__IBMCPP__) 9955 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
9956 #elif defined(_MSC_VER) 9957 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
9958 #elif defined(__PGI) 9959 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
9960 #elif defined(__SUNPRO_CC) 9961 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
9963 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
9967 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
9969 result[
"compiler"][
"c++"] =
"unknown";
9984 #if defined(JSON_HAS_CPP_14) 9987 using object_comparator_t = std::less<>;
9989 using object_comparator_t = std::less<StringType>;
10075 using object_t = ObjectType<StringType,
10077 object_comparator_t,
10078 AllocatorType<std::pair<
const StringType,
10125 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
10178 using string_t = StringType;
10204 using boolean_t = BooleanType;
10276 using number_integer_t = NumberIntegerType;
10347 using number_unsigned_t = NumberUnsignedType;
10415 using number_float_t = NumberFloatType;
10422 template<
typename T,
typename... Args>
10423 static T* create(Args&& ... args)
10425 AllocatorType<T> alloc;
10426 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
10428 auto deleter = [&](T * object)
10430 AllocatorTraits::deallocate(alloc, object, 1);
10432 std::unique_ptr<T,
decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
10433 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
10434 assert(object !=
nullptr);
10435 return object.release();
10477 number_integer_t number_integer;
10479 number_unsigned_t number_unsigned;
10481 number_float_t number_float;
10484 json_value() =
default;
10486 json_value(boolean_t v)
noexcept : boolean(v) {}
10488 json_value(number_integer_t v)
noexcept : number_integer(v) {}
10490 json_value(number_unsigned_t v)
noexcept : number_unsigned(v) {}
10492 json_value(number_float_t v)
noexcept : number_float(v) {}
10494 json_value(value_t t)
10498 case value_t::object:
10500 object = create<object_t>();
10504 case value_t::array:
10506 array = create<array_t>();
10510 case value_t::string:
10512 string = create<string_t>(
"");
10516 case value_t::boolean:
10518 boolean = boolean_t(
false);
10522 case value_t::number_integer:
10524 number_integer = number_integer_t(0);
10528 case value_t::number_unsigned:
10530 number_unsigned = number_unsigned_t(0);
10534 case value_t::number_float:
10536 number_float = number_float_t(0.0);
10540 case value_t::null:
10551 JSON_THROW(other_error::create(500,
"961c151d2e87f2686a955a9be24d316f1362bf21 3.1.2"));
10559 json_value(
const string_t& value)
10561 string = create<string_t>(value);
10565 json_value(string_t&& value)
10567 string = create<string_t>(std::move(value));
10571 json_value(
const object_t& value)
10573 object = create<object_t>(value);
10577 json_value(object_t&& value)
10579 object = create<object_t>(std::move(value));
10583 json_value(
const array_t& value)
10585 array = create<array_t>(value);
10589 json_value(array_t&& value)
10591 array = create<array_t>(std::move(value));
10594 void destroy(value_t t)
noexcept 10598 case value_t::object:
10600 AllocatorType<object_t> alloc;
10601 std::allocator_traits<
decltype(alloc)>::destroy(alloc, object);
10602 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, object, 1);
10606 case value_t::array:
10608 AllocatorType<array_t> alloc;
10609 std::allocator_traits<
decltype(alloc)>::destroy(alloc, array);
10610 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, array, 1);
10614 case value_t::string:
10616 AllocatorType<string_t> alloc;
10617 std::allocator_traits<
decltype(alloc)>::destroy(alloc, string);
10618 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, string, 1);
10639 void assert_invariant()
const noexcept 10641 assert(m_type != value_t::object
or m_value.object !=
nullptr);
10642 assert(m_type != value_t::array
or m_value.array !=
nullptr);
10643 assert(m_type != value_t::string
or m_value.string !=
nullptr);
10666 using parse_event_t =
typename parser::parse_event_t;
10717 using parser_callback_t =
typename parser::parser_callback_t;
10758 basic_json(
const value_t v)
10759 : m_type(v), m_value(v)
10761 assert_invariant();
10782 basic_json(std::nullptr_t =
nullptr)
noexcept 10783 : basic_json(value_t::null)
10785 assert_invariant();
10845 template <
typename CompatibleType,
10846 typename U = detail::uncvref_t<CompatibleType>,
10847 detail::enable_if_t<
10848 detail::is_compatible_type<basic_json_t, U>::value,
int> = 0>
10849 basic_json(CompatibleType && val)
noexcept(
noexcept(
10850 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
10851 std::forward<CompatibleType>(val))))
10853 JSONSerializer<U>::to_json(*
this, std::forward<CompatibleType>(val));
10854 assert_invariant();
10883 template <
typename BasicJsonType,
10884 detail::enable_if_t<
10885 detail::is_basic_json<BasicJsonType>::value
and not std::is_same<basic_json, BasicJsonType>::value,
int> = 0>
10886 basic_json(
const BasicJsonType& val)
10888 using other_boolean_t =
typename BasicJsonType::boolean_t;
10889 using other_number_float_t =
typename BasicJsonType::number_float_t;
10890 using other_number_integer_t =
typename BasicJsonType::number_integer_t;
10891 using other_number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
10892 using other_string_t =
typename BasicJsonType::string_t;
10893 using other_object_t =
typename BasicJsonType::object_t;
10894 using other_array_t =
typename BasicJsonType::array_t;
10896 switch (val.type())
10898 case value_t::boolean:
10899 JSONSerializer<other_boolean_t>::to_json(*
this, val.
template get<other_boolean_t>());
10901 case value_t::number_float:
10902 JSONSerializer<other_number_float_t>::to_json(*
this, val.
template get<other_number_float_t>());
10904 case value_t::number_integer:
10905 JSONSerializer<other_number_integer_t>::to_json(*
this, val.
template get<other_number_integer_t>());
10907 case value_t::number_unsigned:
10908 JSONSerializer<other_number_unsigned_t>::to_json(*
this, val.
template get<other_number_unsigned_t>());
10910 case value_t::string:
10911 JSONSerializer<other_string_t>::to_json(*
this, val.
template get_ref<
const other_string_t&>());
10913 case value_t::object:
10914 JSONSerializer<other_object_t>::to_json(*
this, val.
template get_ref<
const other_object_t&>());
10916 case value_t::array:
10917 JSONSerializer<other_array_t>::to_json(*
this, val.
template get_ref<
const other_array_t&>());
10919 case value_t::null:
10922 case value_t::discarded:
10923 m_type = value_t::discarded;
10926 assert_invariant();
11003 basic_json(initializer_list_t init,
11004 bool type_deduction =
true,
11005 value_t manual_type = value_t::array)
11009 bool is_an_object = std::all_of(init.begin(), init.end(),
11010 [](
const detail::json_ref<basic_json>& element_ref)
11012 return (element_ref->is_array()
and element_ref->size() == 2
and (*element_ref)[0].is_string());
11016 if (
not type_deduction)
11019 if (manual_type == value_t::array)
11021 is_an_object =
false;
11025 if (
JSON_UNLIKELY(manual_type == value_t::object
and not is_an_object))
11027 JSON_THROW(type_error::create(301,
"cannot create object from initializer list"));
11034 m_type = value_t::object;
11035 m_value = value_t::object;
11037 std::for_each(init.begin(), init.end(), [
this](
const detail::json_ref<basic_json>& element_ref)
11039 auto element = element_ref.moved_or_copied();
11040 m_value.object->emplace(
11041 std::move(*((*element.m_value.array)[0].m_value.string)),
11042 std::move((*element.m_value.array)[1]));
11048 m_type = value_t::array;
11049 m_value.array = create<array_t>(init.begin(), init.end());
11052 assert_invariant();
11092 static basic_json array(initializer_list_t init = {})
11094 return basic_json(init,
false, value_t::array);
11135 static basic_json object(initializer_list_t init = {})
11137 return basic_json(init,
false, value_t::object);
11162 basic_json(size_type cnt,
const basic_json& val)
11163 : m_type(value_t::array)
11165 m_value.array = create<array_t>(cnt, val);
11166 assert_invariant();
11224 template<
class InputIT,
typename std::enable_if<
11225 std::is_same<InputIT,
typename basic_json_t::iterator>::value
or 11226 std::is_same<InputIT,
typename basic_json_t::const_iterator>::value,
int>::type = 0>
11227 basic_json(InputIT first, InputIT last)
11229 assert(first.m_object !=
nullptr);
11230 assert(last.m_object !=
nullptr);
11235 JSON_THROW(invalid_iterator::create(201,
"iterators are not compatible"));
11239 m_type = first.m_object->m_type;
11244 case value_t::boolean:
11245 case value_t::number_float:
11246 case value_t::number_integer:
11247 case value_t::number_unsigned:
11248 case value_t::string:
11250 if (
JSON_UNLIKELY(
not first.m_it.primitive_iterator.is_begin()
11251 or not last.m_it.primitive_iterator.is_end()))
11253 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
11264 case value_t::number_integer:
11266 m_value.number_integer = first.m_object->m_value.number_integer;
11270 case value_t::number_unsigned:
11272 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
11276 case value_t::number_float:
11278 m_value.number_float = first.m_object->m_value.number_float;
11282 case value_t::boolean:
11284 m_value.boolean = first.m_object->m_value.boolean;
11288 case value_t::string:
11290 m_value = *first.m_object->m_value.string;
11294 case value_t::object:
11296 m_value.object = create<object_t>(first.m_it.object_iterator,
11297 last.m_it.object_iterator);
11301 case value_t::array:
11303 m_value.array = create<array_t>(first.m_it.array_iterator,
11304 last.m_it.array_iterator);
11309 JSON_THROW(invalid_iterator::create(206,
"cannot construct with iterators from " +
11310 std::string(first.m_object->type_name())));
11313 assert_invariant();
11322 basic_json(
const detail::json_ref<basic_json>& ref)
11323 : basic_json(ref.moved_or_copied())
11351 basic_json(
const basic_json& other)
11352 : m_type(other.m_type)
11355 other.assert_invariant();
11359 case value_t::object:
11361 m_value = *other.m_value.object;
11365 case value_t::array:
11367 m_value = *other.m_value.array;
11371 case value_t::string:
11373 m_value = *other.m_value.string;
11377 case value_t::boolean:
11379 m_value = other.m_value.boolean;
11383 case value_t::number_integer:
11385 m_value = other.m_value.number_integer;
11389 case value_t::number_unsigned:
11391 m_value = other.m_value.number_unsigned;
11395 case value_t::number_float:
11397 m_value = other.m_value.number_float;
11405 assert_invariant();
11434 basic_json(basic_json&& other)
noexcept 11435 : m_type(std::move(other.m_type)),
11436 m_value(std::move(other.m_value))
11439 other.assert_invariant();
11442 other.m_type = value_t::null;
11443 other.m_value = {};
11445 assert_invariant();
11471 reference& operator=(basic_json other)
noexcept (
11472 std::is_nothrow_move_constructible<value_t>::value
and 11473 std::is_nothrow_move_assignable<value_t>::value
and 11474 std::is_nothrow_move_constructible<json_value>::value
and 11475 std::is_nothrow_move_assignable<json_value>::value
11479 other.assert_invariant();
11482 swap(m_type, other.m_type);
11483 swap(m_value, other.m_value);
11485 assert_invariant();
11504 ~basic_json()
noexcept 11506 assert_invariant();
11507 m_value.destroy(m_type);
11557 string_t dump(
const int indent = -1,
const char indent_char =
' ',
11558 const bool ensure_ascii =
false)
const 11561 serializer s(detail::output_adapter<
char, string_t>(result), indent_char);
11565 s.dump(*
this,
true, ensure_ascii,
static_cast<
unsigned int>(indent));
11569 s.dump(*
this,
false, ensure_ascii, 0);
11607 constexpr value_t type()
const noexcept 11637 constexpr bool is_primitive()
const noexcept 11639 return is_null()
or is_string()
or is_boolean()
or is_number();
11664 constexpr bool is_structured()
const noexcept 11666 return is_array()
or is_object();
11686 constexpr bool is_null()
const noexcept 11688 return (m_type == value_t::null);
11708 constexpr bool is_boolean()
const noexcept 11710 return (m_type == value_t::boolean);
11738 constexpr bool is_number()
const noexcept 11740 return is_number_integer()
or is_number_float();
11767 constexpr bool is_number_integer()
const noexcept 11769 return (m_type == value_t::number_integer
or m_type == value_t::number_unsigned);
11795 constexpr bool is_number_unsigned()
const noexcept 11797 return (m_type == value_t::number_unsigned);
11823 constexpr bool is_number_float()
const noexcept 11825 return (m_type == value_t::number_float);
11845 constexpr bool is_object()
const noexcept 11847 return (m_type == value_t::object);
11867 constexpr bool is_array()
const noexcept 11869 return (m_type == value_t::array);
11889 constexpr bool is_string()
const noexcept 11891 return (m_type == value_t::string);
11916 constexpr bool is_discarded()
const noexcept 11918 return (m_type == value_t::discarded);
11942 constexpr operator value_t()
const noexcept 11955 boolean_t get_impl(boolean_t* )
const 11959 return m_value.boolean;
11962 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(type_name())));
11966 object_t* get_impl_ptr(object_t* )
noexcept 11968 return is_object() ? m_value.object :
nullptr;
11972 constexpr const object_t* get_impl_ptr(
const object_t* )
const noexcept 11974 return is_object() ? m_value.object :
nullptr;
11978 array_t* get_impl_ptr(array_t* )
noexcept 11980 return is_array() ? m_value.array :
nullptr;
11984 constexpr const array_t* get_impl_ptr(
const array_t* )
const noexcept 11986 return is_array() ? m_value.array :
nullptr;
11990 string_t* get_impl_ptr(string_t* )
noexcept 11992 return is_string() ? m_value.string :
nullptr;
11996 constexpr const string_t* get_impl_ptr(
const string_t* )
const noexcept 11998 return is_string() ? m_value.string :
nullptr;
12002 boolean_t* get_impl_ptr(boolean_t* )
noexcept 12004 return is_boolean() ? &m_value.boolean :
nullptr;
12008 constexpr const boolean_t* get_impl_ptr(
const boolean_t* )
const noexcept 12010 return is_boolean() ? &m_value.boolean :
nullptr;
12014 number_integer_t* get_impl_ptr(number_integer_t* )
noexcept 12016 return is_number_integer() ? &m_value.number_integer :
nullptr;
12020 constexpr const number_integer_t* get_impl_ptr(
const number_integer_t* )
const noexcept 12022 return is_number_integer() ? &m_value.number_integer :
nullptr;
12026 number_unsigned_t* get_impl_ptr(number_unsigned_t* )
noexcept 12028 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
12032 constexpr const number_unsigned_t* get_impl_ptr(
const number_unsigned_t* )
const noexcept 12034 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
12038 number_float_t* get_impl_ptr(number_float_t* )
noexcept 12040 return is_number_float() ? &m_value.number_float :
nullptr;
12044 constexpr const number_float_t* get_impl_ptr(
const number_float_t* )
const noexcept 12046 return is_number_float() ? &m_value.number_float :
nullptr;
12060 template<
typename ReferenceType,
typename ThisType>
12061 static ReferenceType get_ref_impl(ThisType& obj)
12064 auto ptr = obj.
template get_ptr<
typename std::add_pointer<ReferenceType>::type>();
12071 JSON_THROW(type_error::create(303,
"incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
12093 template<
typename BasicJsonType, detail::enable_if_t<
12094 std::is_same<
typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
12096 basic_json get()
const 12116 template<
typename BasicJsonType, detail::enable_if_t<
12117 not std::is_same<BasicJsonType, basic_json>::value
and 12118 detail::is_basic_json<BasicJsonType>::value,
int> = 0>
12119 BasicJsonType get()
const 12163 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
12164 detail::enable_if_t <
12165 not detail::is_basic_json<ValueType>::value
and 12166 detail::has_from_json<basic_json_t, ValueType>::value
and 12167 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
12169 ValueType get()
const noexcept(
noexcept(
12170 JSONSerializer<ValueType>::from_json(std::declval<
const basic_json_t&>(), std::declval<ValueType&>())))
12175 static_assert(
not std::is_reference<ValueTypeCV>::value,
12176 "get() cannot be used with reference types, you might want to use get_ref()");
12177 static_assert(std::is_default_constructible<ValueType>::value,
12178 "types must be DefaultConstructible when used with get()");
12181 JSONSerializer<ValueType>::from_json(*
this, ret);
12216 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
12217 detail::enable_if_t<
not std::is_same<basic_json_t, ValueType>::value
and 12218 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
12220 ValueType get()
const noexcept(
noexcept(
12221 JSONSerializer<ValueTypeCV>::from_json(std::declval<
const basic_json_t&>())))
12223 static_assert(
not std::is_reference<ValueTypeCV>::value,
12224 "get() cannot be used with reference types, you might want to use get_ref()");
12225 return JSONSerializer<ValueTypeCV>::from_json(*
this);
12255 template<
typename PointerType,
typename std::enable_if<
12256 std::is_pointer<PointerType>::value,
int>::type = 0>
12257 PointerType get()
noexcept 12260 return get_ptr<PointerType>();
12267 template<
typename PointerType,
typename std::enable_if<
12268 std::is_pointer<PointerType>::value,
int>::type = 0>
12269 constexpr const PointerType get()
const noexcept 12272 return get_ptr<PointerType>();
12301 template<
typename PointerType,
typename std::enable_if<
12302 std::is_pointer<PointerType>::value,
int>::type = 0>
12303 PointerType get_ptr()
noexcept 12306 using pointee_t =
typename std::remove_const<
typename 12307 std::remove_pointer<
typename 12308 std::remove_const<PointerType>::type>::type>::type;
12311 std::is_same<object_t, pointee_t>::value
12312 or std::is_same<array_t, pointee_t>::value
12313 or std::is_same<string_t, pointee_t>::value
12314 or std::is_same<boolean_t, pointee_t>::value
12315 or std::is_same<number_integer_t, pointee_t>::value
12316 or std::is_same<number_unsigned_t, pointee_t>::value
12317 or std::is_same<number_float_t, pointee_t>::value
12318 ,
"incompatible pointer type");
12321 return get_impl_ptr(
static_cast<PointerType>(
nullptr));
12328 template<
typename PointerType,
typename std::enable_if<
12329 std::is_pointer<PointerType>::value
and 12330 std::is_const<
typename std::remove_pointer<PointerType>::type>::value,
int>::type = 0>
12331 constexpr const PointerType get_ptr()
const noexcept 12334 using pointee_t =
typename std::remove_const<
typename 12335 std::remove_pointer<
typename 12336 std::remove_const<PointerType>::type>::type>::type;
12339 std::is_same<object_t, pointee_t>::value
12340 or std::is_same<array_t, pointee_t>::value
12341 or std::is_same<string_t, pointee_t>::value
12342 or std::is_same<boolean_t, pointee_t>::value
12343 or std::is_same<number_integer_t, pointee_t>::value
12344 or std::is_same<number_unsigned_t, pointee_t>::value
12345 or std::is_same<number_float_t, pointee_t>::value
12346 ,
"incompatible pointer type");
12349 return get_impl_ptr(
static_cast<PointerType>(
nullptr));
12378 template<
typename ReferenceType,
typename std::enable_if<
12379 std::is_reference<ReferenceType>::value,
int>::type = 0>
12380 ReferenceType get_ref()
12383 return get_ref_impl<ReferenceType>(*
this);
12390 template<
typename ReferenceType,
typename std::enable_if<
12391 std::is_reference<ReferenceType>::value
and 12392 std::is_const<
typename std::remove_reference<ReferenceType>::type>::value,
int>::type = 0>
12393 ReferenceType get_ref()
const 12396 return get_ref_impl<ReferenceType>(*
this);
12428 template <
typename ValueType,
typename std::enable_if <
12429 not std::is_pointer<ValueType>::value
and 12430 not std::is_same<ValueType, detail::json_ref<basic_json>>::value
and 12431 not std::is_same<ValueType,
typename string_t::value_type>::value
and 12432 not detail::is_basic_json<ValueType>::value
12434 and not std::is_same<ValueType, std::initializer_list<
typename string_t::value_type>>::value
12436 #if defined(JSON_HAS_CPP_17) 12437 and not std::is_same<ValueType,
typename std::string_view>::value
12439 ,
int >::type = 0 >
12440 operator ValueType()
const 12443 return get<ValueType>();
12483 reference at(size_type idx)
12490 return m_value.array->at(idx);
12495 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
12500 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
12530 const_reference at(size_type idx)
const 12537 return m_value.array->at(idx);
12542 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
12547 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
12581 reference at(
const typename object_t::key_type& key)
12588 return m_value.object->at(key);
12593 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
12598 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
12632 const_reference at(
const typename object_t::key_type& key)
const 12639 return m_value.object->at(key);
12644 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
12649 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
12678 reference operator[](size_type idx)
12683 m_type = value_t::array;
12684 m_value.array = create<array_t>();
12685 assert_invariant();
12692 if (idx >= m_value.array->size())
12694 m_value.array->insert(m_value.array->end(),
12695 idx - m_value.array->size() + 1,
12699 return m_value.array->operator[](idx);
12702 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
12724 const_reference operator[](size_type idx)
const 12729 return m_value.array->operator[](idx);
12732 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
12762 reference operator[](
const typename object_t::key_type& key)
12767 m_type = value_t::object;
12768 m_value.object = create<object_t>();
12769 assert_invariant();
12775 return m_value.object->operator[](key);
12778 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
12811 const_reference operator[](
const typename object_t::key_type& key)
const 12816 assert(m_value.object->find(key) != m_value.object->end());
12817 return m_value.object->find(key)->second;
12820 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
12850 template<
typename T>
12851 reference operator[](T* key)
12856 m_type = value_t::object;
12857 m_value = value_t::object;
12858 assert_invariant();
12864 return m_value.object->operator[](key);
12867 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
12900 template<
typename T>
12901 const_reference operator[](T* key)
const 12906 assert(m_value.object->find(key) != m_value.object->end());
12907 return m_value.object->find(key)->second;
12910 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
12961 template<
class ValueType,
typename std::enable_if<
12962 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
12963 ValueType value(
const typename object_t::key_type& key,
const ValueType& default_value)
const 12969 const auto it = find(key);
12975 return default_value;
12978 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
12985 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 12987 return value(key, string_t(default_value));
13031 template<
class ValueType,
typename std::enable_if<
13032 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
13033 ValueType value(
const json_pointer& ptr,
const ValueType& default_value)
const 13041 return ptr.get_checked(
this);
13045 return default_value;
13049 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
13056 string_t value(
const json_pointer& ptr,
const char* default_value)
const 13058 return value(ptr, string_t(default_value));
13094 const_reference front()
const 13140 const_reference back()
const 13193 template<
class IteratorType,
typename std::enable_if<
13194 std::is_same<IteratorType,
typename basic_json_t::iterator>::value
or 13195 std::is_same<IteratorType,
typename basic_json_t::const_iterator>::value,
int>::type
13197 IteratorType erase(IteratorType pos)
13202 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
13205 IteratorType result = end();
13209 case value_t::boolean:
13210 case value_t::number_float:
13211 case value_t::number_integer:
13212 case value_t::number_unsigned:
13213 case value_t::string:
13215 if (
JSON_UNLIKELY(
not pos.m_it.primitive_iterator.is_begin()))
13217 JSON_THROW(invalid_iterator::create(205,
"iterator out of range"));
13222 AllocatorType<string_t> alloc;
13223 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_value.string);
13224 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_value.string, 1);
13225 m_value.string =
nullptr;
13228 m_type = value_t::null;
13229 assert_invariant();
13233 case value_t::object:
13235 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
13239 case value_t::array:
13241 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
13246 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
13298 template<
class IteratorType,
typename std::enable_if<
13299 std::is_same<IteratorType,
typename basic_json_t::iterator>::value
or 13300 std::is_same<IteratorType,
typename basic_json_t::const_iterator>::value,
int>::type
13302 IteratorType erase(IteratorType first, IteratorType last)
13305 if (
JSON_UNLIKELY(
this != first.m_object
or this != last.m_object))
13307 JSON_THROW(invalid_iterator::create(203,
"iterators do not fit current value"));
13310 IteratorType result = end();
13314 case value_t::boolean:
13315 case value_t::number_float:
13316 case value_t::number_integer:
13317 case value_t::number_unsigned:
13318 case value_t::string:
13320 if (
JSON_LIKELY(
not first.m_it.primitive_iterator.is_begin()
13321 or not last.m_it.primitive_iterator.is_end()))
13323 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
13328 AllocatorType<string_t> alloc;
13329 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_value.string);
13330 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_value.string, 1);
13331 m_value.string =
nullptr;
13334 m_type = value_t::null;
13335 assert_invariant();
13339 case value_t::object:
13341 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
13342 last.m_it.object_iterator);
13346 case value_t::array:
13348 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
13349 last.m_it.array_iterator);
13354 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
13389 size_type erase(
const typename object_t::key_type& key)
13394 return m_value.object->erase(key);
13397 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
13424 void erase(
const size_type idx)
13431 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
13434 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
13438 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
13474 template<
typename KeyT>
13475 iterator find(KeyT&& key)
13477 auto result = end();
13481 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
13491 template<
typename KeyT>
13492 const_iterator find(KeyT&& key)
const 13494 auto result = cend();
13498 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
13525 template<
typename KeyT>
13526 size_type count(KeyT&& key)
const 13529 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
13566 iterator begin()
noexcept 13568 iterator result(
this);
13569 result.set_begin();
13576 const_iterator begin()
const noexcept 13606 const_iterator cbegin()
const noexcept 13608 const_iterator result(
this);
13609 result.set_begin();
13637 iterator end()
noexcept 13639 iterator result(
this);
13647 const_iterator end()
const noexcept 13677 const_iterator cend()
const noexcept 13679 const_iterator result(
this);
13707 reverse_iterator rbegin()
noexcept 13709 return reverse_iterator(end());
13715 const_reverse_iterator rbegin()
const noexcept 13744 reverse_iterator rend()
noexcept 13746 return reverse_iterator(begin());
13752 const_reverse_iterator rend()
const noexcept 13781 const_reverse_iterator crbegin()
const noexcept 13783 return const_reverse_iterator(cend());
13810 const_reverse_iterator crend()
const noexcept 13812 return const_reverse_iterator(cbegin());
13874 static iteration_proxy<iterator> iterator_wrapper(reference ref)
noexcept 13876 return ref.items();
13883 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref)
noexcept 13885 return ref.items();
13940 iteration_proxy<iterator> items()
noexcept 13942 return iteration_proxy<iterator>(*
this);
13948 iteration_proxy<const_iterator> items()
const noexcept 13950 return iteration_proxy<const_iterator>(*
this);
14004 bool empty()
const noexcept 14008 case value_t::null:
14014 case value_t::array:
14017 return m_value.array->empty();
14020 case value_t::object:
14023 return m_value.object->empty();
14076 size_type size()
const noexcept 14080 case value_t::null:
14086 case value_t::array:
14089 return m_value.array->size();
14092 case value_t::object:
14095 return m_value.object->size();
14146 size_type max_size()
const noexcept 14150 case value_t::array:
14153 return m_value.array->max_size();
14156 case value_t::object:
14159 return m_value.object->max_size();
14216 void clear()
noexcept 14220 case value_t::number_integer:
14222 m_value.number_integer = 0;
14226 case value_t::number_unsigned:
14228 m_value.number_unsigned = 0;
14232 case value_t::number_float:
14234 m_value.number_float = 0.0;
14238 case value_t::boolean:
14240 m_value.boolean =
false;
14244 case value_t::string:
14246 m_value.string->clear();
14250 case value_t::array:
14252 m_value.array->clear();
14256 case value_t::object:
14258 m_value.object->clear();
14287 void push_back(basic_json&& val)
14292 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
14298 m_type = value_t::array;
14299 m_value = value_t::array;
14300 assert_invariant();
14304 m_value.array->push_back(std::move(val));
14306 val.m_type = value_t::null;
14313 reference operator+=(basic_json&& val)
14315 push_back(std::move(val));
14323 void push_back(
const basic_json& val)
14328 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
14334 m_type = value_t::array;
14335 m_value = value_t::array;
14336 assert_invariant();
14340 m_value.array->push_back(val);
14347 reference operator+=(
const basic_json& val)
14373 void push_back(
const typename object_t::value_type& val)
14378 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
14384 m_type = value_t::object;
14385 m_value = value_t::object;
14386 assert_invariant();
14390 m_value.object->insert(val);
14397 reference operator+=(
const typename object_t::value_type& val)
14428 void push_back(initializer_list_t init)
14430 if (is_object()
and init.size() == 2
and (*init.begin())->is_string())
14432 basic_json&& key = init.begin()->moved_or_copied();
14433 push_back(
typename object_t::value_type(
14434 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
14438 push_back(basic_json(init));
14446 reference operator+=(initializer_list_t init)
14473 template<
class... Args>
14474 void emplace_back(Args&& ... args)
14479 JSON_THROW(type_error::create(311,
"cannot use emplace_back() with " + std::string(type_name())));
14485 m_type = value_t::array;
14486 m_value = value_t::array;
14487 assert_invariant();
14491 m_value.array->emplace_back(std::forward<Args>(args)...);
14521 template<
class... Args>
14522 std::pair<iterator,
bool> emplace(Args&& ... args)
14527 JSON_THROW(type_error::create(311,
"cannot use emplace() with " + std::string(type_name())));
14533 m_type = value_t::object;
14534 m_value = value_t::object;
14535 assert_invariant();
14539 auto res = m_value.object->emplace(std::forward<Args>(args)...);
14542 it.m_it.object_iterator = res.first;
14545 return {it, res.second};
14570 iterator insert(const_iterator pos,
const basic_json& val)
14578 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
14582 iterator result(
this);
14583 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
14587 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
14594 iterator insert(const_iterator pos, basic_json&& val)
14596 return insert(pos, val);
14623 iterator insert(const_iterator pos, size_type cnt,
const basic_json& val)
14631 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
14635 iterator result(
this);
14636 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
14640 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
14673 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
14678 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
14684 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
14690 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
14695 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container"));
14699 iterator result(
this);
14700 result.m_it.array_iterator = m_value.array->insert(
14701 pos.m_it.array_iterator,
14702 first.m_it.array_iterator,
14703 last.m_it.array_iterator);
14731 iterator insert(const_iterator pos, initializer_list_t ilist)
14736 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
14742 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
14746 iterator result(
this);
14747 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
14774 void insert(const_iterator first, const_iterator last)
14779 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
14785 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
14791 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
14794 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
14816 void update(const_reference j)
14821 m_type = value_t::object;
14822 m_value.object = create<object_t>();
14823 assert_invariant();
14828 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
14832 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(j.type_name())));
14835 for (
auto it = j.cbegin(); it != j.cend(); ++it)
14837 m_value.object->operator[](it.key()) = it.value();
14867 void update(const_iterator first, const_iterator last)
14872 m_type = value_t::object;
14873 m_value.object = create<object_t>();
14874 assert_invariant();
14879 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
14885 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
14890 or not last.m_object->is_object()))
14892 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
14895 for (
auto it = first; it != last; ++it)
14897 m_value.object->operator[](it.key()) = it.value();
14918 void swap(reference other)
noexcept (
14919 std::is_nothrow_move_constructible<value_t>::value
and 14920 std::is_nothrow_move_assignable<value_t>::value
and 14921 std::is_nothrow_move_constructible<json_value>::value
and 14922 std::is_nothrow_move_assignable<json_value>::value
14925 std::swap(m_type, other.m_type);
14926 std::swap(m_value, other.m_value);
14927 assert_invariant();
14950 void swap(array_t& other)
14955 std::swap(*(m_value.array), other);
14959 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
14983 void swap(object_t& other)
14988 std::swap(*(m_value.object), other);
14992 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
15016 void swap(string_t& other)
15021 std::swap(*(m_value.string), other);
15025 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
15078 friend bool operator==(const_reference lhs, const_reference rhs)
noexcept 15080 const auto lhs_type = lhs.type();
15081 const auto rhs_type = rhs.type();
15083 if (lhs_type == rhs_type)
15087 case value_t::array:
15088 return (*lhs.m_value.array == *rhs.m_value.array);
15090 case value_t::object:
15091 return (*lhs.m_value.object == *rhs.m_value.object);
15093 case value_t::null:
15096 case value_t::string:
15097 return (*lhs.m_value.string == *rhs.m_value.string);
15099 case value_t::boolean:
15100 return (lhs.m_value.boolean == rhs.m_value.boolean);
15102 case value_t::number_integer:
15103 return (lhs.m_value.number_integer == rhs.m_value.number_integer);
15105 case value_t::number_unsigned:
15106 return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
15108 case value_t::number_float:
15109 return (lhs.m_value.number_float == rhs.m_value.number_float);
15115 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_float)
15117 return (
static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
15119 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_integer)
15121 return (lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer));
15123 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_float)
15125 return (
static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
15127 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_unsigned)
15129 return (lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned));
15131 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_integer)
15133 return (
static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
15135 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_unsigned)
15137 return (lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned));
15147 template<
typename ScalarType,
typename std::enable_if<
15148 std::is_scalar<ScalarType>::value,
int>::type = 0>
15149 friend bool operator==(const_reference lhs,
const ScalarType rhs)
noexcept 15151 return (lhs == basic_json(rhs));
15158 template<
typename ScalarType,
typename std::enable_if<
15159 std::is_scalar<ScalarType>::value,
int>::type = 0>
15160 friend bool operator==(
const ScalarType lhs, const_reference rhs)
noexcept 15162 return (basic_json(lhs) == rhs);
15183 friend bool operator!=(const_reference lhs, const_reference rhs)
noexcept 15185 return not (lhs == rhs);
15192 template<
typename ScalarType,
typename std::enable_if<
15193 std::is_scalar<ScalarType>::value,
int>::type = 0>
15194 friend bool operator!=(const_reference lhs,
const ScalarType rhs)
noexcept 15196 return (lhs != basic_json(rhs));
15203 template<
typename ScalarType,
typename std::enable_if<
15204 std::is_scalar<ScalarType>::value,
int>::type = 0>
15205 friend bool operator!=(
const ScalarType lhs, const_reference rhs)
noexcept 15207 return (basic_json(lhs) != rhs);
15236 friend bool operator<(const_reference lhs, const_reference rhs)
noexcept 15238 const auto lhs_type = lhs.type();
15239 const auto rhs_type = rhs.type();
15241 if (lhs_type == rhs_type)
15245 case value_t::array:
15246 return (*lhs.m_value.array) < (*rhs.m_value.array);
15248 case value_t::object:
15249 return *lhs.m_value.object < *rhs.m_value.object;
15251 case value_t::null:
15254 case value_t::string:
15255 return *lhs.m_value.string < *rhs.m_value.string;
15257 case value_t::boolean:
15258 return lhs.m_value.boolean < rhs.m_value.boolean;
15260 case value_t::number_integer:
15261 return lhs.m_value.number_integer < rhs.m_value.number_integer;
15263 case value_t::number_unsigned:
15264 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
15266 case value_t::number_float:
15267 return lhs.m_value.number_float < rhs.m_value.number_float;
15273 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_float)
15275 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
15277 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_integer)
15279 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
15281 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_float)
15283 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
15285 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_unsigned)
15287 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
15289 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_unsigned)
15291 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
15293 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_integer)
15295 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
15301 return operator<(lhs_type, rhs_type);
15308 template<
typename ScalarType,
typename std::enable_if<
15309 std::is_scalar<ScalarType>::value,
int>::type = 0>
15310 friend bool operator<(const_reference lhs,
const ScalarType rhs)
noexcept 15312 return (lhs < basic_json(rhs));
15319 template<
typename ScalarType,
typename std::enable_if<
15320 std::is_scalar<ScalarType>::value,
int>::type = 0>
15321 friend bool operator<(
const ScalarType lhs, const_reference rhs)
noexcept 15323 return (basic_json(lhs) < rhs);
15345 friend bool operator<=(const_reference lhs, const_reference rhs)
noexcept 15347 return not (rhs < lhs);
15354 template<
typename ScalarType,
typename std::enable_if<
15355 std::is_scalar<ScalarType>::value,
int>::type = 0>
15356 friend bool operator<=(const_reference lhs,
const ScalarType rhs)
noexcept 15358 return (lhs <= basic_json(rhs));
15365 template<
typename ScalarType,
typename std::enable_if<
15366 std::is_scalar<ScalarType>::value,
int>::type = 0>
15367 friend bool operator<=(
const ScalarType lhs, const_reference rhs)
noexcept 15369 return (basic_json(lhs) <= rhs);
15391 friend bool operator>(const_reference lhs, const_reference rhs)
noexcept 15393 return not (lhs <= rhs);
15400 template<
typename ScalarType,
typename std::enable_if<
15401 std::is_scalar<ScalarType>::value,
int>::type = 0>
15402 friend bool operator>(const_reference lhs,
const ScalarType rhs)
noexcept 15404 return (lhs > basic_json(rhs));
15411 template<
typename ScalarType,
typename std::enable_if<
15412 std::is_scalar<ScalarType>::value,
int>::type = 0>
15413 friend bool operator>(
const ScalarType lhs, const_reference rhs)
noexcept 15415 return (basic_json(lhs) > rhs);
15437 friend bool operator>=(const_reference lhs, const_reference rhs)
noexcept 15439 return not (lhs < rhs);
15446 template<
typename ScalarType,
typename std::enable_if<
15447 std::is_scalar<ScalarType>::value,
int>::type = 0>
15448 friend bool operator>=(const_reference lhs,
const ScalarType rhs)
noexcept 15450 return (lhs >= basic_json(rhs));
15457 template<
typename ScalarType,
typename std::enable_if<
15458 std::is_scalar<ScalarType>::value,
int>::type = 0>
15459 friend bool operator>=(
const ScalarType lhs, const_reference rhs)
noexcept 15461 return (basic_json(lhs) >= rhs);
15504 friend std::ostream& operator<<(std::ostream& o,
const basic_json& j)
15507 const bool pretty_print = (o.width() > 0);
15508 const auto indentation = (pretty_print ? o.width() : 0);
15514 serializer s(detail::output_adapter<
char>(o), o.fill());
15515 s.dump(j, pretty_print,
false,
static_cast<
unsigned int>(indentation));
15528 friend std::ostream& operator>>(
const basic_json& j, std::ostream& o)
15605 static basic_json parse(detail::input_adapter i,
15606 const parser_callback_t cb =
nullptr,
15607 const bool allow_exceptions =
true)
15610 parser(i, cb, allow_exceptions).parse(
true, result);
15617 static basic_json parse(detail::input_adapter& i,
15618 const parser_callback_t cb =
nullptr,
15619 const bool allow_exceptions =
true)
15622 parser(i, cb, allow_exceptions).parse(
true, result);
15626 static bool accept(detail::input_adapter i)
15628 return parser(i).accept(
true);
15631 static bool accept(detail::input_adapter& i)
15633 return parser(i).accept(
true);
15683 template<
class IteratorType,
typename std::enable_if<
15685 std::random_access_iterator_tag,
15686 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
15687 static basic_json parse(IteratorType first, IteratorType last,
15688 const parser_callback_t cb =
nullptr,
15689 const bool allow_exceptions =
true)
15692 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(
true, result);
15696 template<
class IteratorType,
typename std::enable_if<
15698 std::random_access_iterator_tag,
15699 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
15700 static bool accept(IteratorType first, IteratorType last)
15702 return parser(detail::input_adapter(first, last)).accept(
true);
15714 friend std::istream& operator<<(basic_json& j, std::istream& i)
15716 return operator>>(i, j);
15744 friend std::istream& operator>>(std::istream& i, basic_json& j)
15746 parser(detail::input_adapter(i)).parse(
false, j);
15786 const char* type_name()
const noexcept 15791 case value_t::null:
15793 case value_t::object:
15795 case value_t::array:
15797 case value_t::string:
15799 case value_t::boolean:
15801 case value_t::discarded:
15802 return "discarded";
15816 value_t m_type = value_t::null;
15819 json_value m_value = {};
15917 static std::vector<uint8_t> to_cbor(
const basic_json& j)
15919 std::vector<uint8_t> result;
15920 to_cbor(j, result);
15924 static void to_cbor(
const basic_json& j, detail::output_adapter<uint8_t> o)
15926 binary_writer<uint8_t>(o).write_cbor(j);
15929 static void to_cbor(
const basic_json& j, detail::output_adapter<
char> o)
15931 binary_writer<
char>(o).write_cbor(j);
16014 static std::vector<uint8_t> to_msgpack(
const basic_json& j)
16016 std::vector<uint8_t> result;
16017 to_msgpack(j, result);
16021 static void to_msgpack(
const basic_json& j, detail::output_adapter<uint8_t> o)
16023 binary_writer<uint8_t>(o).write_msgpack(j);
16026 static void to_msgpack(
const basic_json& j, detail::output_adapter<
char> o)
16028 binary_writer<
char>(o).write_msgpack(j);
16111 static std::vector<uint8_t> to_ubjson(
const basic_json& j,
16112 const bool use_size =
false,
16113 const bool use_type =
false)
16115 std::vector<uint8_t> result;
16116 to_ubjson(j, result, use_size, use_type);
16120 static void to_ubjson(
const basic_json& j, detail::output_adapter<uint8_t> o,
16121 const bool use_size =
false,
const bool use_type =
false)
16123 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
16126 static void to_ubjson(
const basic_json& j, detail::output_adapter<
char> o,
16127 const bool use_size =
false,
const bool use_type =
false)
16129 binary_writer<
char>(o).write_ubjson(j, use_size, use_type);
16225 static basic_json from_cbor(detail::input_adapter i,
16226 const bool strict =
true)
16228 return binary_reader(i).parse_cbor(strict);
16234 template<
typename A1,
typename A2,
16235 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
16236 static basic_json from_cbor(A1 && a1, A2 && a2,
const bool strict =
true)
16238 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_cbor(strict);
16314 static basic_json from_msgpack(detail::input_adapter i,
16315 const bool strict =
true)
16317 return binary_reader(i).parse_msgpack(strict);
16323 template<
typename A1,
typename A2,
16324 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
16325 static basic_json from_msgpack(A1 && a1, A2 && a2,
const bool strict =
true)
16327 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_msgpack(strict);
16383 static basic_json from_ubjson(detail::input_adapter i,
16384 const bool strict =
true)
16386 return binary_reader(i).parse_ubjson(strict);
16389 template<
typename A1,
typename A2,
16390 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
16391 static basic_json from_ubjson(A1 && a1, A2 && a2,
const bool strict =
true)
16393 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_ubjson(strict);
16438 reference operator[](
const json_pointer& ptr)
16440 return ptr.get_unchecked(
this);
16466 const_reference operator[](
const json_pointer& ptr)
const 16468 return ptr.get_unchecked(
this);
16509 reference at(
const json_pointer& ptr)
16511 return ptr.get_checked(
this);
16552 const_reference at(
const json_pointer& ptr)
const 16554 return ptr.get_checked(
this);
16579 basic_json flatten()
const 16581 basic_json result(value_t::object);
16582 json_pointer::flatten(
"", *
this, result);
16616 basic_json unflatten()
const 16618 return json_pointer::unflatten(*
this);
16677 basic_json patch(
const basic_json& json_patch)
const 16680 basic_json result = *
this;
16683 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
16685 const auto get_op = [](
const std::string & op)
16689 return patch_operations::add;
16691 if (op ==
"remove")
16693 return patch_operations::remove;
16695 if (op ==
"replace")
16697 return patch_operations::replace;
16701 return patch_operations::move;
16705 return patch_operations::copy;
16709 return patch_operations::test;
16712 return patch_operations::invalid;
16716 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
16726 json_pointer top_pointer = ptr.top();
16727 if (top_pointer != ptr)
16729 result.at(top_pointer);
16733 const auto last_path = ptr.pop_back();
16734 basic_json& parent = result[ptr];
16736 switch (parent.m_type)
16738 case value_t::null:
16739 case value_t::object:
16742 parent[last_path] = val;
16746 case value_t::array:
16748 if (last_path ==
"-")
16751 parent.push_back(val);
16755 const auto idx = json_pointer::array_index(last_path);
16756 if (
JSON_UNLIKELY(
static_cast<size_type>(idx) > parent.size()))
16759 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
16764 parent.insert(parent.begin() +
static_cast<difference_type>(idx), val);
16780 const auto operation_remove = [&result](json_pointer & ptr)
16783 const auto last_path = ptr.pop_back();
16784 basic_json& parent = result.at(ptr);
16787 if (parent.is_object())
16790 auto it = parent.find(last_path);
16797 JSON_THROW(out_of_range::create(403,
"key '" + last_path +
"' not found"));
16800 else if (parent.is_array())
16803 parent.erase(
static_cast<size_type>(json_pointer::array_index(last_path)));
16810 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
16814 for (
const auto& val : json_patch)
16817 const auto get_value = [&val](
const std::string & op,
16818 const std::string & member,
16819 bool string_type) -> basic_json &
16822 auto it = val.m_value.object->find(member);
16825 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
16830 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have member '" + member +
"'"));
16834 if (
JSON_UNLIKELY(string_type
and not it->second.is_string()))
16836 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have string member '" + member +
"'"));
16846 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
16850 const std::string op = get_value(
"op",
"op",
true);
16851 const std::string path = get_value(op,
"path",
true);
16852 json_pointer ptr(path);
16854 switch (get_op(op))
16856 case patch_operations::add:
16858 operation_add(ptr, get_value(
"add",
"value",
false));
16862 case patch_operations::remove:
16864 operation_remove(ptr);
16868 case patch_operations::replace:
16871 result.at(ptr) = get_value(
"replace",
"value",
false);
16875 case patch_operations::move:
16877 const std::string from_path = get_value(
"move",
"from",
true);
16878 json_pointer from_ptr(from_path);
16881 basic_json v = result.at(from_ptr);
16887 operation_remove(from_ptr);
16888 operation_add(ptr, v);
16892 case patch_operations::copy:
16894 const std::string from_path = get_value(
"copy",
"from",
true);
16895 const json_pointer from_ptr(from_path);
16898 basic_json v = result.at(from_ptr);
16903 operation_add(ptr, v);
16907 case patch_operations::test:
16909 bool success =
false;
16914 success = (result.at(ptr) == get_value(
"test",
"value",
false));
16924 JSON_THROW(other_error::create(501,
"unsuccessful: " + val.dump()));
16930 case patch_operations::invalid:
16934 JSON_THROW(parse_error::create(105, 0,
"operation value '" + op +
"' is invalid"));
16975 static basic_json diff(
const basic_json& source,
const basic_json& target,
16976 const std::string& path =
"")
16979 basic_json result(value_t::array);
16982 if (source == target)
16987 if (source.type() != target.type())
16992 {
"op",
"replace"}, {
"path", path}, {
"value", target}
16997 switch (source.type())
16999 case value_t::array:
17003 while (i < source.size()
and i < target.size())
17006 auto temp_diff = diff(source[i], target[i], path +
"/" + std::to_string(i));
17007 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
17015 const auto end_index =
static_cast<difference_type>(result.size());
17016 while (i < source.size())
17020 result.insert(result.begin() + end_index, object(
17023 {
"path", path +
"/" + std::to_string(i)}
17029 while (i < target.size())
17034 {
"path", path +
"/" + std::to_string(i)},
17035 {
"value", target[i]}
17043 case value_t::object:
17046 for (
auto it = source.cbegin(); it != source.cend(); ++it)
17049 const auto key = json_pointer::escape(it.key());
17051 if (target.find(it.key()) != target.end())
17054 auto temp_diff = diff(it.value(), target[it.key()], path +
"/" + key);
17055 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
17060 result.push_back(object(
17062 {
"op",
"remove"}, {
"path", path +
"/" + key}
17068 for (
auto it = target.cbegin(); it != target.cend(); ++it)
17070 if (source.find(it.key()) == source.end())
17073 const auto key = json_pointer::escape(it.key());
17076 {
"op",
"add"}, {
"path", path +
"/" + key},
17077 {
"value", it.value()}
17090 {
"op",
"replace"}, {
"path", path}, {
"value", target}
17151 void merge_patch(
const basic_json& patch)
17153 if (patch.is_object())
17155 if (
not is_object())
17159 for (
auto it = patch.begin(); it != patch.end(); ++it)
17161 if (it.value().is_null())
17167 operator[](it.key()).merge_patch(it.value());
17194 inline void swap(nlohmann::json& j1,
17195 nlohmann::json& j2)
noexcept(
17196 is_nothrow_move_constructible<nlohmann::json>::value
and 17197 is_nothrow_move_assignable<nlohmann::json>::value
17205 struct hash<nlohmann::json>
17212 std::size_t operator()(
const nlohmann::json& j)
const 17215 const auto& h = hash<nlohmann::json::string_t>();
17216 return h(j.dump());
17224 struct less< ::nlohmann::detail::value_t>
17230 bool operator()(nlohmann::detail::value_t lhs,
17231 nlohmann::detail::value_t rhs)
const noexcept 17233 return nlohmann::detail::operator<(lhs, rhs);
17252 inline nlohmann::json operator
"" _json(
const char* s, std::size_t n)
17254 return nlohmann::json::parse(s, s + n);
17270 inline nlohmann::json::json_pointer operator
"" _json_pointer(
const char* s, std::size_t n)
17272 return nlohmann::json::json_pointer(std::string(s, n));
17279 #if defined(__clang__
) || defined(__GNUC__
) || defined(__GNUG__
) 17280 #pragma GCC diagnostic pop 17282 #if defined(__clang__
) 17283 #pragma GCC diagnostic pop 17291 #undef JSON_UNLIKELY 17292 #undef JSON_DEPRECATED 17293 #undef JSON_HAS_CPP_14 17294 #undef JSON_HAS_CPP_17 17295 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION 17296 #undef NLOHMANN_BASIC_JSON_TPL 17297 #undef NLOHMANN_JSON_HAS_HELPER #define NLOHMANN_BASIC_JSON_TPL_DECLARATION
#define NLOHMANN_JSON_HAS_HELPER(type)
Helper to determine whether there's a key_type for T.
#define NLOHMANN_JSON_VERSION_MAJOR
#define JSON_CATCH(exception)
#define NLOHMANN_BASIC_JSON_TPL
#define NLOHMANN_JSON_VERSION_PATCH
#define NLOHMANN_JSON_VERSION_MINOR
#define JSON_THROW(exception)