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> 48 #include <json_fwd.hpp> 49 #ifndef NLOHMANN_JSON_FWD_HPP 50 #define NLOHMANN_JSON_FWD_HPP 72 template<
typename =
void,
typename =
void>
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>
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) // fix for issue #464 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> 263 NLOHMANN_BASIC_JSON_TPL_DECLARATION
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>
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>
289 template<std::size_t... I1, std::size_t... I2>
293 template<std::
size_t N>
296 typename make_index_sequence < N - N / 2 >::type > {};
301 template<
typename... Ts>
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> {};
334 template <
typename T,
typename =
void>
337 template <
typename T>
340 NLOHMANN_JSON_HAS_HELPER(mapped_type);
341 NLOHMANN_JSON_HAS_HELPER(key_type);
342 NLOHMANN_JSON_HAS_HELPER(value_type);
343 NLOHMANN_JSON_HAS_HELPER(iterator);
345 template<
bool B,
class RealType,
class CompatibleObjectType>
348 template<
class RealType,
class 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>
361 has_mapped_type<CompatibleObjectType>,
362 has_key_type<CompatibleObjectType>>::value,
363 typename BasicJsonType::object_t, CompatibleObjectType >::value;
366 template<
typename BasicJsonType,
typename T>
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>
378 static auto constexpr value =
381 BasicJsonType, CompatibleArrayType>>,
382 negation<std::is_constructible<
typename BasicJsonType::string_t,
383 CompatibleArrayType>>,
385 has_value_type<CompatibleArrayType>,
386 has_iterator<CompatibleArrayType>>::value;
389 template<
bool,
typename,
typename>
392 template<
typename RealIntegerType,
typename 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>
408 static constexpr
auto value =
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>
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>
467 static constexpr
bool value =
468 not std::is_base_of<std::istream, CompatibleCompleteType>::value and
474 template <
typename BasicJsonType,
typename CompatibleType>
477 is_compatible_complete_type<BasicJsonType, CompatibleType>>
485 static constexpr T value{};
540 const char*
what() const noexcept
override 549 exception(
int id_,
const char* what_arg) : id(id_), m(what_arg) {}
553 return "[json.exception." + ename +
"." + std::to_string(id_) +
"] ";
558 std::runtime_error m;
617 std::string w = exception::name(
"parse_error", id_) +
"parse error" +
618 (byte_ != 0 ? (
" at " + std::to_string(byte_)) :
"") +
635 parse_error(
int id_, std::size_t byte_,
const char* what_arg)
636 :
exception(id_, what_arg), byte(byte_) {}
681 std::string w = exception::name(
"invalid_iterator", id_) + what_arg;
733 std::string w = exception::name(
"type_error", id_) + what_arg;
778 std::string w = exception::name(
"out_of_range", id_) + what_arg;
815 std::string w = exception::name(
"other_error", id_) + what_arg;
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))
941 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
946 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
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)
963 if (JSON_UNLIKELY(not j.is_boolean()))
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)
973 if (JSON_UNLIKELY(not j.is_string()))
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)
1010 if (JSON_UNLIKELY(not j.is_array()))
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)
1022 if (JSON_UNLIKELY(not j.is_array()))
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)
1038 if (JSON_UNLIKELY(not j.is_array()))
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,
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)
1098 if (JSON_UNLIKELY(not j.is_array()))
1100 JSON_THROW(type_error::create(302,
"type must be array, but is " +
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)
1111 if (JSON_UNLIKELY(not j.is_object()))
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))
1145 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1150 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1155 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
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>
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)
1190 template<
typename BasicJsonType,
typename T>
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> {})))
1236 #include <type_traits> 1259 template<
typename BasicJsonType>
1260 static void construct(BasicJsonType& j,
typename BasicJsonType::boolean_t b) noexcept
1264 j.assert_invariant();
1271 template<
typename BasicJsonType>
1272 static void construct(BasicJsonType& j,
const typename BasicJsonType::string_t& s)
1276 j.assert_invariant();
1279 template<
typename BasicJsonType>
1280 static void construct(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
1283 j.m_value = std::move(s);
1284 j.assert_invariant();
1291 template<
typename BasicJsonType>
1292 static void construct(BasicJsonType& j,
typename BasicJsonType::number_float_t val) noexcept
1296 j.assert_invariant();
1303 template<
typename BasicJsonType>
1304 static void construct(BasicJsonType& j,
typename BasicJsonType::number_unsigned_t val) noexcept
1308 j.assert_invariant();
1315 template<
typename BasicJsonType>
1316 static void construct(BasicJsonType& j,
typename BasicJsonType::number_integer_t val) noexcept
1320 j.assert_invariant();
1327 template<
typename BasicJsonType>
1328 static void construct(BasicJsonType& j,
const typename BasicJsonType::array_t& arr)
1332 j.assert_invariant();
1335 template<
typename BasicJsonType>
1336 static void construct(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
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)
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)
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)
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();
1383 template<
typename BasicJsonType>
1384 static void construct(BasicJsonType& j,
const typename BasicJsonType::object_t& obj)
1388 j.assert_invariant();
1391 template<
typename BasicJsonType>
1392 static void construct(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
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)
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
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)
1430 template<
typename BasicJsonType>
1431 void to_json(BasicJsonType& j,
typename BasicJsonType::string_t&& 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
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
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
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;
1465 template<
typename BasicJsonType>
1466 void to_json(BasicJsonType& j,
const std::vector<bool>& 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)
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)
1487 template<
typename BasicJsonType>
1488 void to_json(BasicJsonType& j,
typename BasicJsonType::array_t&& 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)
1500 template<
typename BasicJsonType>
1501 void to_json(BasicJsonType& j,
typename BasicJsonType::object_t&& 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])
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>
1522 j = {std::get<Idx>(t)...};
1525 template<
typename BasicJsonType,
typename... Args>
1526 void to_json(BasicJsonType& j,
const std::tuple<Args...>& t)
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>
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> {})))
1575 #include <algorithm> 1586 #include <type_traits> 1614 virtual std::char_traits<char>::int_type get_character() = 0;
1616 virtual void unget_character() = 0;
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())
1701 : cursor(b), limit(b + l), start(b)
1704 if (l >= 3 and b[0] ==
'\xEF' and b[1] ==
'\xBB' and b[2] ==
'\xBF')
1716 if (JSON_LIKELY(cursor < limit))
1718 return std::char_traits<char>::to_int_type(*(cursor++));
1721 return std::char_traits<char>::eof();
1726 if (JSON_LIKELY(cursor > start))
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,
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,
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,
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));
1800 if (JSON_LIKELY(len > 0))
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>
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,
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;
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";
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";
1942 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
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";
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;
2135 if (JSON_UNLIKELY(codepoint1 == -1))
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)
2145 if (JSON_LIKELY(
get() ==
'\\' and
get() ==
'u'))
2147 const int codepoint2 = get_codepoint();
2149 if (JSON_UNLIKELY(codepoint2 == -1))
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;
2403 if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
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);
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,
2886 assert(current == literal_text[0]);
2887 for (std::size_t i = 1; i < length; ++i)
2889 if (JSON_UNLIKELY(
get() != literal_text[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));
2957 return value_integer;
2963 return value_unsigned;
2975 return std::move(token_buffer);
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);
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;
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;
3180 using parser_callback_t =
3181 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
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);
3224 if (result.is_discarded())
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);
3271 case token_type::begin_object:
3277 keep = callback(depth++, parse_event_t::object_start, result);
3280 if (not callback or keep)
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);
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);
3339 parse_internal(keep, value);
3341 if (JSON_UNLIKELY(errored))
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);
3375 case token_type::begin_array:
3381 keep = callback(depth++, parse_event_t::array_start, result);
3384 if (not callback or keep)
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);
3407 BasicJsonType value;
3411 value.m_value.destroy(value.m_type);
3413 parse_internal(keep, value);
3415 if (JSON_UNLIKELY(errored))
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);
3449 case token_type::literal_null:
3455 case token_type::value_string:
3458 result.m_value = m_lexer.move_string();
3462 case token_type::literal_true:
3465 result.m_value =
true;
3469 case token_type::literal_false:
3472 result.m_value =
false;
3476 case token_type::value_unsigned:
3479 result.m_value = m_lexer.get_number_unsigned();
3483 case token_type::value_integer:
3486 result.m_value = m_lexer.get_number_integer();
3490 case token_type::value_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);
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)
3660 if (JSON_UNLIKELY(t != last_token))
3664 if (allow_exceptions)
3677 [[noreturn]]
void throw_exception()
const 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));
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;
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
3767 return m_it == begin_value;
3773 return m_it == end_value;
3778 return lhs.m_it == rhs.m_it;
3783 return lhs.m_it < rhs.m_it;
3788 auto result = *
this;
3795 return lhs.m_it - rhs.m_it;
3806 auto result = *
this;
3819 auto result = *
this;
3858 typename BasicJsonType::object_t::iterator object_iterator {};
3860 typename BasicJsonType::array_t::iterator array_iterator {};
3872 #include <type_traits> 3914 template<
typename BasicJsonType>
3919 friend BasicJsonType;
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");
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;
3962 assert(m_object !=
nullptr);
3964 switch (m_object->m_type)
3968 m_it.object_iterator =
typename object_t::iterator();
3974 m_it.array_iterator =
typename array_t::iterator();
4001 : m_object(other.m_object), m_it(other.m_it) {}
4011 m_object = other.m_object;
4021 void set_begin() noexcept
4023 assert(m_object !=
nullptr);
4025 switch (m_object->m_type)
4029 m_it.object_iterator = m_object->m_value.object->begin();
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)
4066 m_it.object_iterator = m_object->m_value.object->end();
4072 m_it.array_iterator = m_object->m_value.array->end();
4078 m_it.primitive_iterator.set_end();
4091 assert(m_object !=
nullptr);
4093 switch (m_object->m_type)
4097 assert(m_it.object_iterator != m_object->m_value.object->end());
4098 return m_it.object_iterator->second;
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"));
4128 assert(m_object !=
nullptr);
4130 switch (m_object->m_type)
4134 assert(m_it.object_iterator != m_object->m_value.object->end());
4135 return &(m_it.object_iterator->second);
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"));
4162 auto result = *
this;
4173 assert(m_object !=
nullptr);
4175 switch (m_object->m_type)
4179 std::advance(m_it.object_iterator, 1);
4185 std::advance(m_it.array_iterator, 1);
4191 ++m_it.primitive_iterator;
4205 auto result = *
this;
4216 assert(m_object !=
nullptr);
4218 switch (m_object->m_type)
4222 std::advance(m_it.object_iterator, -1);
4228 std::advance(m_it.array_iterator, -1);
4234 --m_it.primitive_iterator;
4249 if (JSON_UNLIKELY(m_object != other.m_object))
4251 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
4254 assert(m_object !=
nullptr);
4256 switch (m_object->m_type)
4275 return not operator==(other);
4285 if (JSON_UNLIKELY(m_object != other.m_object))
4287 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
4290 assert(m_object !=
nullptr);
4292 switch (m_object->m_type)
4295 JSON_THROW(invalid_iterator::create(213,
"cannot compare order of object iterators"));
4311 return not other.operator < (*this);
4320 return not operator<=(other);
4338 assert(m_object !=
nullptr);
4340 switch (m_object->m_type)
4343 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
4347 std::advance(m_it.array_iterator, i);
4353 m_it.primitive_iterator += i;
4367 return operator+=(-i);
4376 auto result = *
this;
4398 auto result = *
this;
4409 assert(m_object !=
nullptr);
4411 switch (m_object->m_type)
4414 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
4430 assert(m_object !=
nullptr);
4432 switch (m_object->m_type)
4435 JSON_THROW(invalid_iterator::create(208,
"cannot use operator[] for object iterators"));
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);
4463 if (JSON_LIKELY(m_object->is_object()))
4465 return m_it.object_iterator->first;
4468 JSON_THROW(invalid_iterator::create(207,
"cannot use key() for non-object iterators"));
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;
4542 assert(anchor.m_object !=
nullptr);
4544 switch (anchor.m_object->type())
4548 return std::to_string(array_index);
4552 return anchor.key();
4561 typename IteratorType::reference value()
const 4563 return anchor.value();
4568 typename IteratorType::reference container;
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>
4627 using difference_type = std::ptrdiff_t;
4691 return *(this->operator+(n));
4695 auto key() const -> decltype(
std::declval<Base>().key())
4697 auto it = --this->base();
4704 auto it = --this->base();
4705 return it.operator * ();
4714 #include <algorithm> 4730 virtual void write_character(CharType c) = 0;
4731 virtual void write_characters(
const CharType* s, std::size_t length) = 0;
4736 template<
typename CharType>
4740 template<
typename CharType>
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>
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>>
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>>
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;
4894 const auto res = parse_cbor_internal();
4915 const auto res = parse_msgpack_internal();
4936 const auto res = parse_ubjson_internal();
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():
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>());
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>());
5203 while (
get() != 0xFF)
5205 auto key = get_cbor_string();
5206 result[key] = parse_cbor_internal();
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():
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();
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;
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)
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)
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;
5896 "expected a MessagePack string; last byte: 0x" + ss.str()));
5901 template<
typename NumberType>
5902 BasicJsonType get_msgpack_array(
const NumberType len)
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)
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;
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;
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():
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>();
6045 if (JSON_UNLIKELY(current > 127))
6047 std::stringstream ss;
6048 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
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;
6068 "error reading UBJSON; last byte: 0x" + ss.str()));
6072 BasicJsonType get_ubjson_array()
6075 const auto size_and_type = get_ubjson_size_type();
6077 if (size_and_type.first != string_t::npos)
6079 if (JSON_UNLIKELY(size_and_type.first > result.max_size()))
6081 JSON_THROW(out_of_range::create(408,
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()
6120 const auto size_and_type = get_ubjson_size_type();
6122 if (size_and_type.first != string_t::npos)
6124 if (JSON_UNLIKELY(size_and_type.first > result.max_size()))
6126 JSON_THROW(out_of_range::create(408,
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()))
6182 void unexpect_eof()
const 6184 if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
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>
6254 oa->write_character(static_cast<CharType>(0xF6));
6260 oa->write_character(j.m_value.boolean
6261 ? static_cast<CharType>(0xF5)
6262 : static_cast<CharType>(0xF4));
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));
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));
6362 oa->write_character(static_cast<CharType>(0xFB));
6363 write_number(j.m_value.number_float);
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());
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)
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);
6498 oa->write_character(static_cast<CharType>(0xC0));
6504 oa->write_character(j.m_value.boolean
6505 ? static_cast<CharType>(0xC3)
6506 : static_cast<CharType>(0xC2));
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));
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));
6622 oa->write_character(static_cast<CharType>(0xCB));
6623 write_number(j.m_value.number_float);
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());
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)
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);
6735 const bool use_type,
const bool add_prefix =
true)
6743 oa->write_character(static_cast<CharType>(
'Z'));
6751 oa->write_character(j.m_value.boolean
6752 ? static_cast<CharType>(
'T')
6753 : static_cast<CharType>(
'F'));
6759 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
6765 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
6771 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
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());
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>(
']'));
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
7052 return j.m_value.boolean ?
'T' :
'F';
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)())
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)())
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_) {}
7215 return diyfp(x.f - y.f, x.e);
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);
7291 while ((x.f >> 63) == 0)
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>
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;
7520 constexpr
int kCachedPowersSize = 79;
7521 constexpr
int kCachedPowersMinDecExp = -300;
7522 constexpr
int kCachedPowersDecStep = 8;
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);
7622 assert(kAlpha <= cached.e + e + 64);
7623 assert(kGamma >= cached.e + e + 64);
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');
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);
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,
7972 assert(m_plus.e == m_minus.e);
7973 assert(m_plus.e == v.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;
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));
8058 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
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);
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));
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;
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);
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;
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)
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)
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;
8328 if (JSON_UNLIKELY(indent_string.size() < new_indent))
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(
'}');
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;
8401 if (JSON_UNLIKELY(indent_string.size() < new_indent))
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(
']');
8448 o->write_character(
'\"');
8449 dump_escaped(*val.m_value.string, ensure_ascii);
8450 o->write_character(
'\"');
8456 if (val.m_value.boolean)
8458 o->write_characters(
"true", 4);
8462 o->write_characters(
"false", 5);
8469 dump_integer(val.m_value.number_integer);
8475 dump_integer(val.m_value.number_unsigned);
8481 dump_float(val.m_value.number_float);
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];
8639 if (JSON_LIKELY(state == UTF8_ACCEPT))
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];
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;
8883 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(
true)
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>
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>
8952 NLOHMANN_BASIC_JSON_TPL_DECLARATION
8978 : reference_tokens(split(s))
8998 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
9002 return a +
"/" + escape(b);
9021 std::size_t processed_chars = 0;
9022 const int res = std::stoi(s, &processed_chars);
9025 if (JSON_UNLIKELY(processed_chars != s.size()))
9027 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + s +
"'"));
9040 if (JSON_UNLIKELY(is_root()))
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();
9058 if (JSON_UNLIKELY(is_root()))
9060 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
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)
9089 if (reference_token ==
"0")
9092 result = &result->operator[](0);
9097 result = &result->operator[](reference_token);
9105 result = &result->operator[](reference_token);
9114 result = &result->operator[](
static_cast<size_type
>(array_index(reference_token)));
9116 JSON_CATCH(std::invalid_argument&)
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)
9166 std::all_of(reference_token.begin(), reference_token.end(),
9169 return (x >=
'0' and x <=
'9');
9173 *ptr = (nums or reference_token ==
"-")
9178 switch (ptr->m_type)
9183 ptr = &ptr->operator[](reference_token);
9190 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'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)));
9210 JSON_CATCH(std::invalid_argument&)
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)
9242 ptr = &ptr->at(reference_token);
9248 if (JSON_UNLIKELY(reference_token ==
"-"))
9251 JSON_THROW(detail::out_of_range::create(402,
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'))
9260 "array index '" + reference_token +
9261 "' must not begin with '0'"));
9267 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
9269 JSON_CATCH(std::invalid_argument&)
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)
9307 ptr = &ptr->operator[](reference_token);
9313 if (JSON_UNLIKELY(reference_token ==
"-"))
9316 JSON_THROW(detail::out_of_range::create(402,
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'))
9325 "array index '" + reference_token +
9326 "' must not begin with '0'"));
9332 ptr = &ptr->operator[](
9333 static_cast<size_type
>(array_index(reference_token)));
9335 JSON_CATCH(std::invalid_argument&)
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)
9366 ptr = &ptr->at(reference_token);
9372 if (JSON_UNLIKELY(reference_token ==
"-"))
9375 JSON_THROW(detail::out_of_range::create(402,
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'))
9384 "array index '" + reference_token +
9385 "' must not begin with '0'"));
9391 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
9393 JSON_CATCH(std::invalid_argument&)
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())
9428 if (JSON_UNLIKELY(reference_string[0] !=
'/'))
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] ==
'~');
9463 if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
9464 (reference_token[pos + 1] !=
'0' and
9465 reference_token[pos + 1] !=
'1')))
9472 unescape(reference_token);
9473 result.push_back(reference_token);
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()))
9506 replace_substring(s,
"~",
"~0");
9507 replace_substring(s,
"/",
"~1");
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)
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);
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)
9590 if (JSON_UNLIKELY(not value.is_object()))
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)
9600 if (JSON_UNLIKELY(not element.second.is_primitive()))
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;
9618 return (lhs.reference_tokens == rhs.reference_tokens);
9624 return not (lhs == rhs);
9628 std::vector<std::string> reference_tokens;
9644 template<
typename,
typename>
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));
9771 NLOHMANN_BASIC_JSON_TPL_DECLARATION
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;
9787 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
9794 template<
typename BasicJsonType>
9796 template<
typename BasicJsonType>
9798 template<
typename Iterator>
9802 template<
typename CharType>
9814 template<
typename T,
typename SFINAE>
9815 using json_serializer = JSONSerializer<T, SFINAE>;
9869 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
9871 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
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"] =
9927 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) +
"." +
9928 std::to_string(NLOHMANN_JSON_VERSION_MINOR) +
"." +
9929 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
9930 result[
"version"][
"major"] = NLOHMANN_JSON_VERSION_MAJOR;
9931 result[
"version"][
"minor"] = NLOHMANN_JSON_VERSION_MINOR;
9932 result[
"version"][
"patch"] = NLOHMANN_JSON_VERSION_PATCH;
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>>;
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();
10484 json_value() =
default;
10500 object = create<object_t>();
10506 array = create<array_t>();
10512 string = create<string_t>(
"");
10551 JSON_THROW(other_error::create(500,
"961c151d2e87f2686a955a9be24d316f1362bf21 3.1.2"));
10561 string = create<string_t>(value);
10567 string = create<string_t>(std::move(value));
10573 object = create<object_t>(value);
10579 object = create<object_t>(std::move(value));
10583 json_value(
const array_t& value)
10585 array = create<array_t>(value);
10591 array = create<array_t>(std::move(value));
10594 void destroy(
value_t t) noexcept
10600 AllocatorType<object_t> alloc;
10601 std::allocator_traits<decltype(alloc)>::destroy(alloc,
object);
10602 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
object, 1);
10608 AllocatorType<array_t> alloc;
10609 std::allocator_traits<decltype(alloc)>::destroy(alloc,
array);
10610 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
array, 1);
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
10759 : m_type(v), m_value(v)
10761 assert_invariant();
10785 assert_invariant();
10845 template <
typename CompatibleType,
10846 typename U = detail::uncvref_t<CompatibleType>,
10847 detail::enable_if_t<
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<
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())
10899 JSONSerializer<other_boolean_t>::to_json(*
this, val.template get<other_boolean_t>());
10902 JSONSerializer<other_number_float_t>::to_json(*
this, val.template get<other_number_float_t>());
10905 JSONSerializer<other_number_integer_t>::to_json(*
this, val.template get<other_number_integer_t>());
10908 JSONSerializer<other_number_unsigned_t>::to_json(*
this, val.template get<other_number_unsigned_t>());
10911 JSONSerializer<other_string_t>::to_json(*
this, val.template get_ref<const other_string_t&>());
10914 JSONSerializer<other_object_t>::to_json(*
this, val.template get_ref<const other_object_t&>());
10917 JSONSerializer<other_array_t>::to_json(*
this, val.template get_ref<const other_array_t&>());
10926 assert_invariant();
11004 bool type_deduction =
true,
11009 bool is_an_object = std::all_of(init.begin(), init.end(),
11012 return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
11016 if (not type_deduction)
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"));
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]));
11049 m_value.array = create<array_t>(init.begin(), init.end());
11052 assert_invariant();
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>
11229 assert(first.m_object !=
nullptr);
11230 assert(last.m_object !=
nullptr);
11233 if (JSON_UNLIKELY(first.m_object != last.m_object))
11235 JSON_THROW(invalid_iterator::create(201,
"iterators are not compatible"));
11239 m_type = first.m_object->m_type;
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"));
11266 m_value.number_integer = first.m_object->m_value.number_integer;
11272 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
11278 m_value.number_float = first.m_object->m_value.number_float;
11284 m_value.boolean = first.m_object->m_value.boolean;
11290 m_value = *first.m_object->m_value.string;
11296 m_value.object = create<object_t>(first.m_it.object_iterator,
11297 last.m_it.object_iterator);
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 " +
11313 assert_invariant();
11323 : basic_json(ref.moved_or_copied())
11352 : m_type(other.m_type)
11355 other.assert_invariant();
11361 m_value = *other.m_value.object;
11367 m_value = *other.m_value.array;
11373 m_value = *other.m_value.string;
11379 m_value = other.m_value.boolean;
11385 m_value = other.m_value.number_integer;
11391 m_value = other.m_value.number_unsigned;
11397 m_value = other.m_value.number_float;
11405 assert_invariant();
11435 : m_type(std::move(other.m_type)),
11436 m_value(std::move(other.m_value))
11439 other.assert_invariant();
11443 other.m_value = {};
11445 assert_invariant();
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();
11506 assert_invariant();
11507 m_value.destroy(m_type);
11558 const bool ensure_ascii =
false)
const 11565 s.
dump(*
this,
true, ensure_ascii, static_cast<unsigned int>(indent));
11569 s.
dump(*
this,
false, ensure_ascii, 0);
11639 return is_null() or is_string() or is_boolean() or is_number();
11666 return is_array() or is_object();
11740 return is_number_integer() or is_number_float();
11957 if (JSON_LIKELY(is_boolean()))
11959 return m_value.boolean;
11962 JSON_THROW(type_error::create(302,
"type must be boolean, but is " +
std::string(type_name())));
11968 return is_object() ? m_value.object :
nullptr;
11974 return is_object() ? m_value.object :
nullptr;
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;
11992 return is_string() ? m_value.string :
nullptr;
11998 return is_string() ? m_value.string :
nullptr;
12004 return is_boolean() ? &m_value.boolean :
nullptr;
12010 return is_boolean() ? &m_value.boolean :
nullptr;
12016 return is_number_integer() ? &m_value.number_integer :
nullptr;
12022 return is_number_integer() ? &m_value.number_integer :
nullptr;
12028 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
12034 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
12040 return is_number_float() ? &m_value.number_float :
nullptr;
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>();
12066 if (JSON_LIKELY(ptr !=
nullptr))
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
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>
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>
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>
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>
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
12433 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015 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>();
12486 if (JSON_LIKELY(is_array()))
12490 return m_value.array->at(idx);
12492 JSON_CATCH (std::out_of_range&)
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())));
12533 if (JSON_LIKELY(is_array()))
12537 return m_value.array->at(idx);
12539 JSON_CATCH (std::out_of_range&)
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())));
12584 if (JSON_LIKELY(is_object()))
12588 return m_value.object->at(key);
12590 JSON_CATCH (std::out_of_range&)
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())));
12635 if (JSON_LIKELY(is_object()))
12639 return m_value.object->at(key);
12641 JSON_CATCH (std::out_of_range&)
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())));
12684 m_value.array = create<array_t>();
12685 assert_invariant();
12689 if (JSON_LIKELY(is_array()))
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())));
12727 if (JSON_LIKELY(is_array()))
12729 return m_value.
array->operator[](idx);
12732 JSON_THROW(type_error::create(305,
"cannot use operator[] with " +
std::string(type_name())));
12768 m_value.object = create<object_t>();
12769 assert_invariant();
12773 if (JSON_LIKELY(is_object()))
12775 return m_value.object->operator[](key);
12778 JSON_THROW(type_error::create(305,
"cannot use operator[] with " +
std::string(type_name())));
12814 if (JSON_LIKELY(is_object()))
12816 assert(m_value.object->find(key) != m_value.object->end());
12820 JSON_THROW(type_error::create(305,
"cannot use operator[] with " +
std::string(type_name())));
12850 template<
typename T>
12858 assert_invariant();
12862 if (JSON_LIKELY(is_object()))
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>
12904 if (JSON_LIKELY(is_object()))
12906 assert(m_value.object->find(key) != m_value.object->end());
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 12966 if (JSON_LIKELY(is_object()))
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>
13036 if (JSON_LIKELY(is_object()))
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())));
13058 return value(ptr,
string_t(default_value));
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
13200 if (JSON_UNLIKELY(
this != pos.m_object))
13202 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
13205 IteratorType result = end();
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;
13229 assert_invariant();
13235 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
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();
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;
13335 assert_invariant();
13341 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
13342 last.m_it.object_iterator);
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())));
13392 if (JSON_LIKELY(is_object()))
13394 return m_value.object->erase(key);
13397 JSON_THROW(type_error::create(307,
"cannot use erase() with " +
std::string(type_name())));
13427 if (JSON_LIKELY(is_array()))
13429 if (JSON_UNLIKELY(idx >= size()))
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>
13477 auto result = end();
13481 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
13491 template<
typename KeyT>
13494 auto result = cend();
13498 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
13525 template<
typename KeyT>
13529 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
13569 result.set_begin();
13609 result.set_begin();
13876 return ref.items();
13885 return ref.items();
14017 return m_value.array->empty();
14023 return m_value.object->empty();
14089 return m_value.array->size();
14095 return m_value.object->size();
14153 return m_value.array->max_size();
14159 return m_value.object->max_size();
14222 m_value.number_integer = 0;
14228 m_value.number_unsigned = 0;
14234 m_value.number_float = 0.0;
14240 m_value.boolean =
false;
14246 m_value.string->clear();
14252 m_value.array->clear();
14258 m_value.object->clear();
14290 if (JSON_UNLIKELY(not(is_null() or is_array())))
14292 JSON_THROW(type_error::create(308,
"cannot use push_back() with " +
std::string(type_name())));
14300 assert_invariant();
14304 m_value.array->push_back(std::move(val));
14315 push_back(std::move(val));
14326 if (JSON_UNLIKELY(not(is_null() or is_array())))
14328 JSON_THROW(type_error::create(308,
"cannot use push_back() with " +
std::string(type_name())));
14336 assert_invariant();
14340 m_value.array->push_back(val);
14376 if (JSON_UNLIKELY(not(is_null() or is_object())))
14378 JSON_THROW(type_error::create(308,
"cannot use push_back() with " +
std::string(type_name())));
14386 assert_invariant();
14390 m_value.object->insert(val);
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));
14473 template<
class... Args>
14477 if (JSON_UNLIKELY(not(is_null() or is_array())))
14479 JSON_THROW(type_error::create(311,
"cannot use emplace_back() with " +
std::string(type_name())));
14487 assert_invariant();
14491 m_value.array->emplace_back(std::forward<Args>(args)...);
14521 template<
class... Args>
14525 if (JSON_UNLIKELY(not(is_null() or is_object())))
14527 JSON_THROW(type_error::create(311,
"cannot use emplace() with " +
std::string(type_name())));
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};
14573 if (JSON_LIKELY(is_array()))
14576 if (JSON_UNLIKELY(pos.m_object !=
this))
14578 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
14587 JSON_THROW(type_error::create(309,
"cannot use insert() with " +
std::string(type_name())));
14596 return insert(pos, val);
14626 if (JSON_LIKELY(is_array()))
14629 if (JSON_UNLIKELY(pos.m_object !=
this))
14631 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
14640 JSON_THROW(type_error::create(309,
"cannot use insert() with " +
std::string(type_name())));
14676 if (JSON_UNLIKELY(not is_array()))
14678 JSON_THROW(type_error::create(309,
"cannot use insert() with " +
std::string(type_name())));
14682 if (JSON_UNLIKELY(pos.m_object !=
this))
14684 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
14688 if (JSON_UNLIKELY(first.m_object != last.m_object))
14690 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
14693 if (JSON_UNLIKELY(first.m_object ==
this))
14695 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container"));
14734 if (JSON_UNLIKELY(not is_array()))
14736 JSON_THROW(type_error::create(309,
"cannot use insert() with " +
std::string(type_name())));
14740 if (JSON_UNLIKELY(pos.m_object !=
this))
14742 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
14777 if (JSON_UNLIKELY(not is_object()))
14779 JSON_THROW(type_error::create(309,
"cannot use insert() with " +
std::string(type_name())));
14783 if (JSON_UNLIKELY(first.m_object != last.m_object))
14785 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
14789 if (JSON_UNLIKELY(not first.m_object->is_object()))
14791 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
14822 m_value.object = create<object_t>();
14823 assert_invariant();
14826 if (JSON_UNLIKELY(not is_object()))
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();
14873 m_value.object = create<object_t>();
14874 assert_invariant();
14877 if (JSON_UNLIKELY(not is_object()))
14879 JSON_THROW(type_error::create(312,
"cannot use update() with " +
std::string(type_name())));
14883 if (JSON_UNLIKELY(first.m_object != last.m_object))
14885 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
14889 if (JSON_UNLIKELY(not first.m_object->is_object()
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();
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();
14953 if (JSON_LIKELY(is_array()))
14955 std::swap(*(m_value.array), other);
14959 JSON_THROW(type_error::create(310,
"cannot use swap() with " +
std::string(type_name())));
14986 if (JSON_LIKELY(is_object()))
14988 std::swap(*(m_value.object), other);
14992 JSON_THROW(type_error::create(310,
"cannot use swap() with " +
std::string(type_name())));
15019 if (JSON_LIKELY(is_string()))
15021 std::swap(*(m_value.string), other);
15025 JSON_THROW(type_error::create(310,
"cannot use swap() with " +
std::string(type_name())));
15080 const auto lhs_type = lhs.type();
15081 const auto rhs_type = rhs.type();
15083 if (lhs_type == rhs_type)
15088 return (*lhs.m_value.array == *rhs.m_value.array);
15091 return (*lhs.m_value.object == *rhs.m_value.object);
15097 return (*lhs.m_value.string == *rhs.m_value.string);
15100 return (lhs.m_value.boolean == rhs.m_value.boolean);
15103 return (lhs.m_value.number_integer == rhs.m_value.number_integer);
15106 return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
15109 return (lhs.m_value.number_float == rhs.m_value.number_float);
15117 return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
15121 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
15125 return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
15129 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
15133 return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
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>
15151 return (lhs == basic_json(rhs));
15158 template<
typename ScalarType,
typename std::enable_if<
15159 std::is_scalar<ScalarType>::value,
int>::type = 0>
15162 return (basic_json(lhs) == rhs);
15185 return not (lhs == rhs);
15192 template<
typename ScalarType,
typename std::enable_if<
15193 std::is_scalar<ScalarType>::value,
int>::type = 0>
15196 return (lhs != basic_json(rhs));
15203 template<
typename ScalarType,
typename std::enable_if<
15204 std::is_scalar<ScalarType>::value,
int>::type = 0>
15207 return (basic_json(lhs) != rhs);
15238 const auto lhs_type = lhs.type();
15239 const auto rhs_type = rhs.type();
15241 if (lhs_type == rhs_type)
15246 return (*lhs.m_value.array) < (*rhs.m_value.array);
15249 return *lhs.m_value.object < *rhs.m_value.object;
15255 return *lhs.m_value.string < *rhs.m_value.string;
15258 return lhs.m_value.boolean < rhs.m_value.boolean;
15261 return lhs.m_value.number_integer < rhs.m_value.number_integer;
15264 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
15267 return lhs.m_value.number_float < rhs.m_value.number_float;
15275 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
15279 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
15283 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
15287 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
15291 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
15295 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
15308 template<
typename ScalarType,
typename std::enable_if<
15309 std::is_scalar<ScalarType>::value,
int>::type = 0>
15312 return (lhs < basic_json(rhs));
15319 template<
typename ScalarType,
typename std::enable_if<
15320 std::is_scalar<ScalarType>::value,
int>::type = 0>
15323 return (basic_json(lhs) < rhs);
15347 return not (rhs < lhs);
15354 template<
typename ScalarType,
typename std::enable_if<
15355 std::is_scalar<ScalarType>::value,
int>::type = 0>
15358 return (lhs <= basic_json(rhs));
15365 template<
typename ScalarType,
typename std::enable_if<
15366 std::is_scalar<ScalarType>::value,
int>::type = 0>
15369 return (basic_json(lhs) <= rhs);
15393 return not (lhs <= rhs);
15400 template<
typename ScalarType,
typename std::enable_if<
15401 std::is_scalar<ScalarType>::value,
int>::type = 0>
15404 return (lhs > basic_json(rhs));
15411 template<
typename ScalarType,
typename std::enable_if<
15412 std::is_scalar<ScalarType>::value,
int>::type = 0>
15415 return (basic_json(lhs) > rhs);
15439 return not (lhs < rhs);
15446 template<
typename ScalarType,
typename std::enable_if<
15447 std::is_scalar<ScalarType>::value,
int>::type = 0>
15450 return (lhs >= basic_json(rhs));
15457 template<
typename ScalarType,
typename std::enable_if<
15458 std::is_scalar<ScalarType>::value,
int>::type = 0>
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);
15515 s.
dump(j, pretty_print,
false, static_cast<unsigned int>(indentation));
15528 friend std::ostream&
operator>>(
const basic_json& j, std::ostream& o)
15607 const bool allow_exceptions =
true)
15610 parser(i, cb, allow_exceptions).
parse(
true, result);
15619 const bool allow_exceptions =
true)
15622 parser(i, cb, allow_exceptions).
parse(
true, result);
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,
15689 const bool allow_exceptions =
true)
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)
15716 return operator>>(i, j);
15802 return "discarded";
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);
16016 std::vector<uint8_t> result;
16017 to_msgpack(j, result);
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);
16121 const bool use_size =
false,
const bool use_type =
false)
16127 const bool use_size =
false,
const bool use_type =
false)
16226 const bool strict =
true)
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)
16315 const bool strict =
true)
16323 template<
typename A1,
typename A2,
16324 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
16384 const bool strict =
true)
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)
16440 return ptr.get_unchecked(
this);
16468 return ptr.get_unchecked(
this);
16511 return ptr.get_checked(
this);
16554 return ptr.get_checked(
this);
16582 json_pointer::flatten(
"", *
this, result);
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};
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)
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)
16742 parent[last_path] = val;
16748 if (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"));
16780 const auto operation_remove = [&result](
json_pointer & ptr)
16783 const auto last_path = ptr.pop_back();
16784 basic_json& parent = result.
at(ptr);
16790 auto it = parent.
find(last_path);
16791 if (JSON_LIKELY(it != parent.
end()))
16797 JSON_THROW(out_of_range::create(403,
"key '" + last_path +
"' not found"));
16808 if (JSON_UNLIKELY(not json_patch.
is_array()))
16814 for (
const auto& val : json_patch)
16817 const auto get_value = [&val](
const std::string & op,
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 +
"'";
16828 if (JSON_UNLIKELY(it == val.m_value.object->end()))
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 +
"'"));
16844 if (JSON_UNLIKELY(not val.is_object()))
16850 const std::string op = get_value(
"op",
"op",
true);
16851 const std::string path = get_value(op,
"path",
true);
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);
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);
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));
16922 if (JSON_UNLIKELY(not success))
16924 JSON_THROW(other_error::create(501,
"unsuccessful: " + val.dump()));
16930 case patch_operations::invalid:
16975 static basic_json
diff(
const basic_json& source,
const basic_json& target,
16982 if (source == target)
16987 if (source.
type() != target.
type())
16992 {
"op",
"replace"}, {
"path", path}, {
"value", target}
16997 switch (source.
type())
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());
17016 while (i < source.
size())
17023 {
"path", path +
"/" + std::to_string(i)}
17029 while (i < target.
size())
17034 {
"path", path +
"/" + std::to_string(i)},
17035 {
"value", target[i]}
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());
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}
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());
17196 is_nothrow_move_constructible<nlohmann::json>::value and
17197 is_nothrow_move_assignable<nlohmann::json>::value
17215 const auto& h = hash<nlohmann::json::string_t>();
17216 return h(j.
dump());
17252 inline nlohmann::json operator "" _json(
const char* s, std::size_t 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 ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:10125
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:14347
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:11227
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
Definition: json.hpp:12811
Definition: json.hpp:7196
void update(const_iterator first, const_iterator last)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:14867
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:2961
static JSON_DEPRECATED iteration_proxy< const_iterator > iterator_wrapper(const_reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:13883
typename parser::parser_callback_t parser_callback_t
per-element parser callback type
Definition: json.hpp:10717
token_type
token types for the parser
Definition: json.hpp:1878
const int id
the id of the exception
Definition: json.hpp:546
void emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:14474
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:4374
std::shared_ptr< input_adapter_protocol > input_adapter_t
a type to simplify interfaces
Definition: json.hpp:1621
Definition: json.hpp:1187
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:14146
Definition: json.hpp:3736
static JSON_DEPRECATED iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:13874
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:15236
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:13940
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:11434
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:10415
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:4689
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:7210
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:4336
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:4318
value_t
the JSON type enumeration
Definition: json.hpp:865
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:10886
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:4396
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:7729
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:4695
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:13948
iter_impl(pointer object) noexcept
constructor for a given JSON instance
Definition: json.hpp:3960
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:13197
json_reverse_iterator const operator--(int)
post-decrement (it–)
Definition: json.hpp:4653
~basic_json() noexcept
destructor
Definition: json.hpp:11504
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:16466
Definition: json.hpp:8265
Definition: json.hpp:4803
reference value() const
return the value of an iterator
Definition: json.hpp:4702
const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:540
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:4629
a signed integer – use get_number_integer() for actual value
Definition: json.hpp:1254
array (ordered collection of values)
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:8977
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:10347
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:11607
friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than or equal
Definition: json.hpp:15356
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:4171
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:10276
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition: json.hpp:12762
a template for a reverse iterator class
Definition: json.hpp:4624
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:4000
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:11637
a class to store JSON values
Definition: json.hpp:85
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:9869
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:16509
iterator insert(const_iterator pos, basic_json &&val)
inserts element
Definition: json.hpp:14594
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:4327
A collection of functions for debugging.
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:10758
default JSONSerializer template argument
Definition: json.hpp:73
void insert(const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:14774
iter_impl const operator--(int)
post-decrement (it–)
Definition: json.hpp:4203
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:11664
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:15504
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:9888
StringType string_t
a type for a string
Definition: json.hpp:10178
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:4282
JSON_DEPRECATED friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
Definition: json.hpp:15714
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:3200
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition: json.hpp:7304
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:13637
number value (signed integer)
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:11162
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:16579
Definition: json.hpp:17186
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:13566
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:4665
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:9861
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:14397
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:14673
friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:15205
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition: json.hpp:8307
friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than
Definition: json.hpp:15402
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:4572
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:4365
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:13715
a template for a bidirectional iterator for the basic_json class
Definition: json.hpp:3915
friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:15160
std::bidirectional_iterator_tag iterator_category
Definition: json.hpp:3935
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:11845
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:7468
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:14522
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:4634
BasicJsonType parse_ubjson(const bool strict)
create a JSON value from UBJSON input
Definition: json.hpp:4934
lexical analysis
Definition: json.hpp:1869
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:3759
binary_reader(input_adapter_t adapter)
create a binary reader
Definition: json.hpp:4877
friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:15413
syntax analysis
Definition: json.hpp:3154
serialization to CBOR and MessagePack values
Definition: json.hpp:6232
serializer(output_adapter_t< char > s, const char ichar)
Definition: json.hpp:8279
output adapter for byte vectors
Definition: json.hpp:4741
pointer operator->() const
dereference the iterator
Definition: json.hpp:4126
const std::size_t byte
byte index of the parse error
Definition: json.hpp:632
string_t && move_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:2973
friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:15448
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.hpp:3858
static void to_json(BasicJsonType &j, ValueType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< ValueType >(val))))
convert any value type to a JSON value
Definition: json.hpp:9673
const_reference operator[](T *key) const
read-only access specified object element
Definition: json.hpp:12901
reference & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:11471
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:11135
exception indicating access out of the defined range
Definition: json.hpp:773
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:11686
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:11823
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.hpp:13475
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:3753
void write_msgpack(const BasicJsonType &j)
[in] j JSON value to serialize
Definition: json.hpp:6492
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:7287
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:12483
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:10782
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:12632
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:13389
friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than
Definition: json.hpp:15310
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false) const
serialization
Definition: json.hpp:11557
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:11351
iter_impl const operator++(int)
post-increment (it++)
Definition: json.hpp:4160
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:4677
void clear() noexcept
clears the contents
Definition: json.hpp:14216
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
Definition: json.hpp:14623
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:14446
parse_event_t
Definition: json.hpp:3164
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:2955
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:11738
static basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.hpp:16975
exception indicating a parse error
Definition: json.hpp:604
reference operator[](T *key)
access specified object element
Definition: json.hpp:12851
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:4407
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:2967
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:4638
static basic_json from_msgpack(detail::input_adapter i, const bool strict=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:16314
const_iterator find(KeyT &&key) const
find an element in a JSON object
Definition: json.hpp:13492
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:16438
json_reverse_iterator const operator++(int)
post-increment (it++)
Definition: json.hpp:4641
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:12581
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:4631
an unsigned integer – use get_number_unsigned() for actual value
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:3862
abstract output adapter interface
Definition: json.hpp:4728
general exception of the basic_json class
Definition: json.hpp:536
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:14076
static std::vector< uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:16111
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:7329
constexpr const PointerType get_ptr() const noexcept
get a pointer value (implicit)
Definition: json.hpp:12331
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:15917
char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:8066
reference back()
access the last element
Definition: json.hpp:13130
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:3860
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition: json.hpp:3949
friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
comparison: equal
Definition: json.hpp:15149
const char * type_name() const noexcept
return the type as string
Definition: json.hpp:15786
static basic_json from_msgpack(A1 &&a1, A2 &&a2, const bool strict=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:16325
bool operator!=(const iter_impl &other) const
comparison: not equal
Definition: json.hpp:4273
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:13576
exception indicating errors with iterators
Definition: json.hpp:676
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:13744
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:11708
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:888
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition: json.hpp:7969
namespace for Niels Lohmann
Definition: json.hpp:63
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:13302
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:11889
an floating point number – use get_number_float() for actual value
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:4671
object (unordered set of name/value pairs)
Definition: json.hpp:1531
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:12380
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:4089
Definition: json.hpp:7454
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:9817
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition: json.hpp:3944
exception indicating executing a member function with a wrong type
Definition: json.hpp:728
friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:15367
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:3765
PointerType get_ptr() noexcept
get a pointer value (implicit)
Definition: json.hpp:12303
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:15744
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:15078
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > >> object_t
a type for an object
Definition: json.hpp:10079
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer.
Definition: json.hpp:9813
typename parser::parse_event_t parse_event_t
parser event types
Definition: json.hpp:10666
string_t value(const json_pointer &ptr, const char *default_value) const
overload for a default value of type const char*
Definition: json.hpp:13056
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:14323
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:14428
parser(detail::input_adapter_t adapter, const parser_callback_t cb=nullptr, const bool allow_exceptions_=true)
a parser reading from an input adapter
Definition: json.hpp:3184
static basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr, const bool allow_exceptions=true)
deserialize from an iterator range with contiguous storage
Definition: json.hpp:15687
void merge_patch(const basic_json &patch)
applies a JSON Merge Patch
Definition: json.hpp:17151
static basic_json from_cbor(A1 &&a1, A2 &&a2, const bool strict=true)
create a JSON value from an input in CBOR format
Definition: json.hpp:16236
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:4459
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
Definition: json.hpp:17212
static int array_index(const std::string &s)
Definition: json.hpp:9019
Definition: json.hpp:7315
const_reference back() const
access the last element
Definition: json.hpp:13140
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:11916
output adapter for basic_string
Definition: json.hpp:4783
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:14816
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:12963
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:4737
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:10204
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:15391
constexpr const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:3016
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:6240
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:3236
char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
Definition: json.hpp:8116
output adapter for output streams
Definition: json.hpp:4762
static basic_json parse(detail::input_adapter i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true)
deserialize from a compatible input
Definition: json.hpp:15605
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:14313
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:11767
exception indicating other library errors
Definition: json.hpp:810
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:3771
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:13606
friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:15459
void swap(array_t &other)
exchanges the values
Definition: json.hpp:14950
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:12530
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:9871
deserialization of CBOR and MessagePack values
Definition: json.hpp:4865
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:3938
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:17230
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:11795
iteration_proxy_internal begin() noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:4576
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:4309
void swap(string_t &other)
exchanges the values
Definition: json.hpp:15016
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:4009
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:4214
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:14570
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:11867
an iterator value
Definition: json.hpp:3855
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:13647
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:13781
Definition: json.hpp:8877
bool operator==(const iter_impl &other) const
comparison: equal
Definition: json.hpp:4246
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements
Definition: json.hpp:14731
static const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition: json.hpp:1900
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:3940
static basic_json from_cbor(detail::input_adapter i, const bool strict=true)
create a JSON value from an input in CBOR format
Definition: json.hpp:16225
basic_json(CompatibleType &&val) noexcept(noexcept(JSONSerializer< U >::to_json(std::declval< basic_json_t &>(), std::forward< CompatibleType >(val))))
create a JSON value
Definition: json.hpp:10849
std::string to_string() const noexcept
return a string representation of the JSON pointer
Definition: json.hpp:8996
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:12678
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
Definition: json.hpp:12985
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:14287
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
Definition: json.hpp:6734
friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:15321
reference front()
access the first element
Definition: json.hpp:13086
JSON Pointer.
Definition: json.hpp:99
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:13707
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:4428
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:12393
BasicJsonType parse_msgpack(const bool strict)
create a JSON value from MessagePack input
Definition: json.hpp:4913
number value (unsigned integer)
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:9863
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:13810
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:16677
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:12724
friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
comparison: not equal
Definition: json.hpp:15194
BasicJsonType parse_cbor(const bool strict)
create a JSON value from CBOR input
Definition: json.hpp:4892
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:13526
void swap(object_t &other)
exchanges the values
Definition: json.hpp:14983
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:16014
constexpr std::size_t get_position() const noexcept
return position of last read token
Definition: json.hpp:2983
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:13033
reference value() const
return the value of an iterator
Definition: json.hpp:4475
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:13677
proxy class for the items() function
Definition: json.hpp:3892
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:4659
std::string get_token_string() const
Definition: json.hpp:2991
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:14373
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:11003
JSON_DEPRECATED friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:15528
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:16616
static basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:11092
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:15345
number value (floating-point)
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:13424
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:15437
iteration_proxy_internal end() noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:4582
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:15183
void write_cbor(const BasicJsonType &j)
[in] j JSON value to serialize
Definition: json.hpp:6248
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg)
create a parse error exception
Definition: json.hpp:615
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:9866
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:14918
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:4647
const_reference front() const
access the first element
Definition: json.hpp:13094
static basic_json from_ubjson(detail::input_adapter i, const bool strict=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:16383
static constexpr bool little_endianess(int num=1) noexcept
determine system byte order
Definition: json.hpp:4952
int find_largest_pow10(const uint32_t n, uint32_t &pow10)
Definition: json.hpp:7632
static basic_json parse(detail::input_adapter &i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true)
create an empty value with a given type parse(detail::input_adapter, const parser_callback_t) ...
Definition: json.hpp:15617
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:4385
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:16552
char * to_chars(char *first, char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition: json.hpp:8199
discarded by the the parser callback function
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:13752
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:4683
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:14004
static basic_json meta()
returns version information on the library
Definition: json.hpp:9919
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:7222
static void from_json(BasicJsonType &&j, ValueType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val)))
convert a JSON value to any value type
Definition: json.hpp:9657