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 1 41 #include <initializer_list> 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> {};
302 template<
typename... Ts>
322 template<
class B1,
class... Bn>
323 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
325 template<
class B>
struct negation : std::integral_constant<bool, not B::value> {};
338 template<
typename T,
typename =
void>
344 NLOHMANN_JSON_HAS_HELPER(mapped_type);
345 NLOHMANN_JSON_HAS_HELPER(key_type);
346 NLOHMANN_JSON_HAS_HELPER(value_type);
347 NLOHMANN_JSON_HAS_HELPER(iterator);
349 template<
bool B,
class RealType,
class CompatibleObjectType>
352 template<
class RealType,
class CompatibleObjectType>
355 static constexpr
auto value =
356 std::is_constructible<typename RealType::key_type, typename CompatibleObjectType::key_type>::value and
357 std::is_constructible<
typename RealType::mapped_type,
358 typename CompatibleObjectType::mapped_type>::value;
361 template<
class BasicJsonType,
class CompatibleObjectType>
366 has_mapped_type<CompatibleObjectType>,
367 has_key_type<CompatibleObjectType>>::value,
368 typename BasicJsonType::object_t, CompatibleObjectType>::value;
371 template<
typename BasicJsonType,
typename T>
374 static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
375 std::is_same<T, typename BasicJsonType::const_iterator>::value or
376 std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
377 std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
380 template<
class BasicJsonType,
class CompatibleArrayType>
383 static auto constexpr value =
386 BasicJsonType, CompatibleArrayType>>,
387 negation<std::is_constructible<
typename BasicJsonType::string_t,
388 CompatibleArrayType>>,
390 has_value_type<CompatibleArrayType>,
391 has_iterator<CompatibleArrayType>>::value;
394 template<
bool,
typename,
typename>
397 template<
typename RealIntegerType,
typename CompatibleNumberIntegerType>
401 using RealLimits = std::numeric_limits<RealIntegerType>;
402 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
404 static constexpr
auto value =
405 std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
406 CompatibleLimits::is_integer and
407 RealLimits::is_signed == CompatibleLimits::is_signed;
410 template<
typename RealIntegerType,
typename CompatibleNumberIntegerType>
413 static constexpr
auto value =
415 std::is_integral<CompatibleNumberIntegerType>::value and
416 not std::is_same<bool, CompatibleNumberIntegerType>::value,
417 RealIntegerType, CompatibleNumberIntegerType>::value;
421 template<
typename BasicJsonType,
typename T>
426 template<typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
427 std::declval<BasicJsonType>(),
428 std::declval<T &>()))>::value>>
429 static int detect(U &&);
430 static void detect(...);
433 static constexpr
bool value = std::is_integral<decltype(
434 detect(std::declval<
typename BasicJsonType::template json_serializer<T,
441 template<
typename BasicJsonType,
typename T>
447 typename = enable_if_t<std::is_same<
449 decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value>>
450 static int detect(U &&);
451 static void detect(...);
454 static constexpr
bool value = std::is_integral<decltype(detect(
455 std::declval<
typename BasicJsonType::template json_serializer<T,
461 template<
typename BasicJsonType,
typename T>
465 template<typename U, typename = decltype(uncvref_t<U>::to_json(
466 std::declval<BasicJsonType &>(), std::declval<T>()))>
467 static int detect(U &&);
468 static void detect(...);
471 static constexpr
bool value = std::is_integral<decltype(detect(
472 std::declval<
typename BasicJsonType::template json_serializer<T,
477 template<
typename BasicJsonType,
typename CompatibleCompleteType>
480 static constexpr
bool value =
481 not std::is_base_of<std::istream, CompatibleCompleteType>::value and
482 not std::is_same<BasicJsonType, CompatibleCompleteType>::value and
487 template<
typename BasicJsonType,
typename CompatibleType>
490 is_compatible_complete_type<BasicJsonType, CompatibleType>>
498 static constexpr T value {};
553 const char *
what() const noexcept
override 562 exception(
int id_,
const char *what_arg) : id(id_), m(what_arg) {}
566 return "[json.exception." + ename +
"." + std::to_string(id_) +
"] ";
571 std::runtime_error m;
630 std::string w = exception::name(
"parse_error", id_) +
"parse error" +
631 (byte_ != 0 ? (
" at " + std::to_string(byte_)) :
"") +
648 parse_error(
int id_, std::size_t byte_,
const char *what_arg)
649 :
exception(id_, what_arg), byte(byte_) {}
694 std::string w = exception::name(
"invalid_iterator", id_) + what_arg;
746 std::string w = exception::name(
"type_error", id_) + what_arg;
791 std::string w = exception::name(
"out_of_range", id_) + what_arg;
829 std::string w = exception::name(
"other_error", id_) + what_arg;
905 static constexpr std::array<std::uint8_t, 8> order = { {
912 const auto l_index =
static_cast<std::size_t
>(lhs);
913 const auto r_index =
static_cast<std::size_t
>(rhs);
914 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
925 #include <forward_list> 929 #include <type_traits> 947 template<
typename BasicJsonType,
typename ArithmeticType,
948 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
949 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
951 void get_arithmetic_value(
const BasicJsonType &j, ArithmeticType &val)
953 switch (static_cast<value_t>(j)) {
957 static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t *>());
963 static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t *>());
969 static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t *>());
974 JSON_THROW(type_error::create(302,
"type must be number, but is " +
std::string(j.type_name())));
978 template<
typename BasicJsonType>
979 void from_json(
const BasicJsonType &j,
typename BasicJsonType::boolean_t &b)
981 if (JSON_UNLIKELY(not j.is_boolean())) {
982 JSON_THROW(type_error::create(302,
"type must be boolean, but is " +
std::string(j.type_name())));
985 b = *j.template get_ptr<const typename BasicJsonType::boolean_t *>();
988 template<
typename BasicJsonType>
989 void from_json(
const BasicJsonType &j,
typename BasicJsonType::string_t &s)
991 if (JSON_UNLIKELY(not j.is_string())) {
992 JSON_THROW(type_error::create(302,
"type must be string, but is " +
std::string(j.type_name())));
995 s = *j.template get_ptr<const typename BasicJsonType::string_t *>();
998 template<
typename BasicJsonType>
999 void from_json(
const BasicJsonType &j,
typename BasicJsonType::number_float_t &val)
1001 get_arithmetic_value(j, val);
1004 template<
typename BasicJsonType>
1005 void from_json(
const BasicJsonType &j,
typename BasicJsonType::number_unsigned_t &val)
1007 get_arithmetic_value(j, val);
1010 template<
typename BasicJsonType>
1011 void from_json(
const BasicJsonType &j,
typename BasicJsonType::number_integer_t &val)
1013 get_arithmetic_value(j, val);
1016 template<
typename BasicJsonType,
typename EnumType,
1017 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
1018 void from_json(
const BasicJsonType &j, EnumType &e)
1020 typename std::underlying_type<EnumType>::type val;
1021 get_arithmetic_value(j, val);
1022 e =
static_cast<EnumType
>(val);
1025 template<
typename BasicJsonType>
1026 void from_json(
const BasicJsonType &j,
typename BasicJsonType::array_t &arr)
1028 if (JSON_UNLIKELY(not j.is_array())) {
1029 JSON_THROW(type_error::create(302,
"type must be array, but is " +
std::string(j.type_name())));
1032 arr = *j.template get_ptr<const typename BasicJsonType::array_t *>();
1036 template<
typename BasicJsonType,
typename T,
typename Allocator,
1037 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1038 void from_json(
const BasicJsonType &j, std::forward_list<T, Allocator> &l)
1040 if (JSON_UNLIKELY(not j.is_array())) {
1041 JSON_THROW(type_error::create(302,
"type must be array, but is " +
std::string(j.type_name())));
1044 std::transform(j.rbegin(), j.rend(),
1045 std::front_inserter(l), [](
const BasicJsonType &i) {
1046 return i.template get<T>();
1051 template<
typename BasicJsonType,
typename T,
1052 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1053 void from_json(
const BasicJsonType &j, std::valarray<T> &l)
1055 if (JSON_UNLIKELY(not j.is_array())) {
1056 JSON_THROW(type_error::create(302,
"type must be array, but is " +
std::string(j.type_name())));
1060 std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1063 template<
typename BasicJsonType,
typename CompatibleArrayType>
1064 void from_json_array_impl(
const BasicJsonType &j, CompatibleArrayType &arr,
priority_tag<0> )
1068 std::transform(j.begin(), j.end(),
1069 std::inserter(arr, end(arr)), [](
const BasicJsonType &i) {
1072 return i.template get<typename CompatibleArrayType::value_type>();
1076 template<
typename BasicJsonType,
typename CompatibleArrayType>
1077 auto from_json_array_impl(
const BasicJsonType &j, CompatibleArrayType &arr,
priority_tag<1> )
1079 arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
1084 arr.reserve(j.size());
1085 std::transform(j.begin(), j.end(),
1086 std::inserter(arr, end(arr)), [](
const BasicJsonType &i) {
1089 return i.template get<typename CompatibleArrayType::value_type>();
1093 template<
typename BasicJsonType,
typename T, std::
size_t N>
1094 void from_json_array_impl(
const BasicJsonType &j, std::array<T, N> &arr,
priority_tag<2> )
1096 for (std::size_t i = 0; i < N; ++i) {
1097 arr[i] = j.at(i).template get<T>();
1102 typename BasicJsonType,
typename CompatibleArrayType,
1105 not std::is_same<
typename BasicJsonType::array_t,
1106 CompatibleArrayType>::value and
1107 std::is_constructible<
1108 BasicJsonType,
typename CompatibleArrayType::value_type>::value,
1110 void from_json(
const BasicJsonType &j, CompatibleArrayType &arr)
1112 if (JSON_UNLIKELY(not j.is_array())) {
1113 JSON_THROW(type_error::create(302,
"type must be array, but is " +
1120 template<
typename BasicJsonType,
typename CompatibleObjectType,
1121 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
int> = 0>
1122 void from_json(
const BasicJsonType &j, CompatibleObjectType &obj)
1124 if (JSON_UNLIKELY(not j.is_object())) {
1125 JSON_THROW(type_error::create(302,
"type must be object, but is " +
std::string(j.type_name())));
1128 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t *>();
1129 using value_type =
typename CompatibleObjectType::value_type;
1131 inner_object->begin(), inner_object->end(),
1132 std::inserter(obj, obj.begin()),
1133 [](
typename BasicJsonType::object_t::value_type
const &p) {
1134 return value_type(p.first,
1135 p.second.template get<typename CompatibleObjectType::mapped_type>());
1143 template<
typename BasicJsonType,
typename ArithmeticType,
1145 std::is_arithmetic<ArithmeticType>::value and
1146 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1147 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1148 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1149 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1151 void from_json(
const BasicJsonType &j, ArithmeticType &val)
1153 switch (static_cast<value_t>(j)) {
1157 static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t *>());
1163 static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t *>());
1169 static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t *>());
1174 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::boolean_t *>());
1179 JSON_THROW(type_error::create(302,
"type must be number, but is " +
std::string(j.type_name())));
1183 template<
typename BasicJsonType,
typename A1,
typename A2>
1184 void from_json(
const BasicJsonType &j, std::pair<A1, A2> &p)
1186 p = { j.at(0).template get<A1>(), j.at(1).template get<A2>() };
1189 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1192 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>() ...);
1195 template<
typename BasicJsonType,
typename... Args>
1196 void from_json(
const BasicJsonType &j, std::tuple<Args...> &t)
1204 template<
typename BasicJsonType,
typename T>
1206 noexcept (noexcept (from_json(j, val)))
1207 ->decltype(from_json(j, val),
void ())
1209 return from_json(j, val);
1212 template<
typename BasicJsonType,
typename T>
1213 void call(
const BasicJsonType & , T & ,
priority_tag<0> )
const noexcept
1215 static_assert(
sizeof(BasicJsonType) == 0,
1216 "could not find from_json() method in T's namespace");
1219 using decayed = uncvref_t<T>;
1220 static_assert(
sizeof(
typename decayed::force_msvc_stacktrace) == 0,
1221 "forcing MSVC stacktrace to show which T we're talking about.");
1226 template<
typename BasicJsonType,
typename T>
1227 void operator()(
const BasicJsonType &j, T &val)
const 1228 noexcept (noexcept (std::declval<from_json_fn>().call(j, val,
priority_tag<1> {})))
1251 #include <type_traits> 1274 template<
typename BasicJsonType>
1275 static void construct(BasicJsonType &j,
typename BasicJsonType::boolean_t b) noexcept
1279 j.assert_invariant();
1286 template<
typename BasicJsonType>
1287 static void construct(BasicJsonType &j,
const typename BasicJsonType::string_t &s)
1291 j.assert_invariant();
1294 template<
typename BasicJsonType>
1295 static void construct(BasicJsonType &j,
typename BasicJsonType::string_t &&s)
1298 j.m_value = std::move(s);
1299 j.assert_invariant();
1306 template<
typename BasicJsonType>
1307 static void construct(BasicJsonType &j,
typename BasicJsonType::number_float_t val) noexcept
1311 j.assert_invariant();
1318 template<
typename BasicJsonType>
1319 static void construct(BasicJsonType &j,
typename BasicJsonType::number_unsigned_t val) noexcept
1323 j.assert_invariant();
1330 template<
typename BasicJsonType>
1331 static void construct(BasicJsonType &j,
typename BasicJsonType::number_integer_t val) noexcept
1335 j.assert_invariant();
1342 template<
typename BasicJsonType>
1343 static void construct(BasicJsonType &j,
const typename BasicJsonType::array_t &arr)
1347 j.assert_invariant();
1350 template<
typename BasicJsonType>
1351 static void construct(BasicJsonType &j,
typename BasicJsonType::array_t &&arr)
1354 j.m_value = std::move(arr);
1355 j.assert_invariant();
1358 template<
typename BasicJsonType,
typename CompatibleArrayType,
1359 enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
1361 static void construct(BasicJsonType &j,
const CompatibleArrayType &arr)
1366 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
1367 j.assert_invariant();
1370 template<
typename BasicJsonType>
1371 static void construct(BasicJsonType &j,
const std::vector<bool> &arr)
1375 j.m_value.array->reserve(arr.size());
1376 for (
const bool x : arr) {
1377 j.m_value.array->push_back(x);
1380 j.assert_invariant();
1383 template<
typename BasicJsonType,
typename T,
1384 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
1385 static void construct(BasicJsonType &j,
const std::valarray<T> &arr)
1389 j.m_value.array->resize(arr.size());
1390 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
1391 j.assert_invariant();
1398 template<
typename BasicJsonType>
1399 static void construct(BasicJsonType &j,
const typename BasicJsonType::object_t &obj)
1403 j.assert_invariant();
1406 template<
typename BasicJsonType>
1407 static void construct(BasicJsonType &j,
typename BasicJsonType::object_t &&obj)
1410 j.m_value = std::move(obj);
1411 j.assert_invariant();
1414 template<
typename BasicJsonType,
typename CompatibleObjectType,
1415 enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value,
1417 static void construct(BasicJsonType &j,
const CompatibleObjectType &obj)
1423 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
1424 j.assert_invariant();
1432 template<
typename BasicJsonType,
typename T,
1433 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value,
int> = 0>
1434 void to_json(BasicJsonType &j, T b) noexcept
1439 template<
typename BasicJsonType,
typename CompatibleString,
1440 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value,
1442 void to_json(BasicJsonType &j,
const CompatibleString &s)
1447 template<
typename BasicJsonType>
1448 void to_json(BasicJsonType &j,
typename BasicJsonType::string_t &&s)
1453 template<
typename BasicJsonType,
typename FloatType,
1454 enable_if_t<std::is_floating_point<FloatType>::value,
int> = 0>
1455 void to_json(BasicJsonType &j, FloatType val) noexcept
1458 static_cast<typename BasicJsonType::number_float_t>(
1462 template<
typename BasicJsonType,
typename CompatibleNumberUnsignedType,
1464 CompatibleNumberUnsignedType>::value,
int> = 0>
1465 void to_json(BasicJsonType &j, CompatibleNumberUnsignedType val) noexcept
1468 static_cast<typename BasicJsonType::
1469 number_unsigned_t
>(val));
1472 template<
typename BasicJsonType,
typename CompatibleNumberIntegerType,
1474 CompatibleNumberIntegerType>::value,
int> = 0>
1475 void to_json(BasicJsonType &j, CompatibleNumberIntegerType val) noexcept
1478 static_cast<typename BasicJsonType::
1479 number_integer_t
>(val));
1482 template<
typename BasicJsonType,
typename EnumType,
1483 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
1484 void to_json(BasicJsonType &j, EnumType e) noexcept
1486 using underlying_type =
typename std::underlying_type<EnumType>::type;
1490 template<
typename BasicJsonType>
1491 void to_json(BasicJsonType &j,
const std::vector<bool> &e)
1496 template<
typename BasicJsonType,
typename CompatibleArrayType,
1497 enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value or
1498 std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
1500 void to_json(BasicJsonType &j,
const CompatibleArrayType &arr)
1505 template<
typename BasicJsonType,
typename T,
1506 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
1507 void to_json(BasicJsonType &j, std::valarray<T> arr)
1512 template<
typename BasicJsonType>
1513 void to_json(BasicJsonType &j,
typename BasicJsonType::array_t &&arr)
1518 template<
typename BasicJsonType,
typename CompatibleObjectType,
1519 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
int> = 0>
1520 void to_json(BasicJsonType &j,
const CompatibleObjectType &obj)
1525 template<
typename BasicJsonType>
1526 void to_json(BasicJsonType &j,
typename BasicJsonType::object_t &&obj)
1531 template<
typename BasicJsonType,
typename T, std::size_t N,
1532 enable_if_t<not std::is_constructible<typename BasicJsonType::string_t, T( &)[N]>::value,
int> = 0>
1533 void to_json(BasicJsonType &j, T(&arr)[N])
1538 template<
typename BasicJsonType,
typename... Args>
1539 void to_json(BasicJsonType &j,
const std::pair<Args...> &p)
1541 j = { p.first, p.second };
1544 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1547 j = { std::get<Idx>(t) ... };
1550 template<
typename BasicJsonType,
typename... Args>
1551 void to_json(BasicJsonType &j,
const std::tuple<Args...> &t)
1559 template<
typename BasicJsonType,
typename T>
1560 auto call(BasicJsonType &j, T &&val,
1561 priority_tag<1> )
const noexcept (noexcept (to_json(j, std::forward<T>(val))))
1562 ->decltype(to_json(j, std::forward<T>(val)),
void ())
1564 return to_json(j, std::forward<T>(val));
1567 template<
typename BasicJsonType,
typename T>
1570 static_assert(
sizeof(BasicJsonType) == 0,
1571 "could not find to_json() method in T's namespace");
1575 using decayed = uncvref_t<T>;
1576 static_assert(
sizeof(
typename decayed::force_msvc_stacktrace) == 0,
1577 "forcing MSVC stacktrace to show which T we're talking about.");
1582 template<
typename BasicJsonType,
typename T>
1583 void operator()(BasicJsonType &j, T &&val)
const 1584 noexcept (noexcept (std::declval<to_json_fn>().call(j, std::forward<T>(val),
priority_tag<1> {})))
1602 #include <algorithm> 1613 #include <type_traits> 1641 virtual std::char_traits<char>::int_type get_character() = 0;
1643 virtual void unget_character() = 0;
1670 : is(i), sb(*i.rdbuf())
1673 std::char_traits<char>::int_type c;
1674 if ((c = get_character()) == 0xEF) {
1675 if ((c = get_character()) == 0xBB) {
1676 if ((c = get_character()) == 0xBF) {
1678 }
else if (c != std::char_traits<char>::eof()) {
1683 }
else if (c != std::char_traits<char>::eof()) {
1688 }
else if (c != std::char_traits<char>::eof()) {
1721 : cursor(b), limit(b + l), start(b)
1724 if (l >= 3 and b[0] ==
'\xEF' and b[1] ==
'\xBB' and b[2] ==
'\xBF') {
1735 if (JSON_LIKELY(cursor < limit)) {
1736 return std::char_traits<char>::to_int_type(*(cursor++));
1739 return std::char_traits<char>::eof();
1744 if (JSON_LIKELY(cursor > start)) {
1772 template<
typename CharT,
1773 typename std::enable_if<
1774 std::is_pointer<CharT>::value and
1775 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
1776 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
1779 : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char *>(b), l)) {}
1784 template<
typename CharT,
1785 typename std::enable_if<
1786 std::is_pointer<CharT>::value and
1787 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
1788 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
1792 std::strlen(reinterpret_cast<const char *>(b))) {}
1795 template<
class IteratorType,
1796 typename std::enable_if<
1797 std::is_same<typename std::iterator_traits<IteratorType>::iterator_category,
1798 std::random_access_iterator_tag>::value,
1804 assert(std::accumulate(
1805 first, last, std::pair<bool, int>(
true, 0),
1806 [&first](std::pair<bool, int> res, decltype(*first) val) {
1807 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
1813 sizeof(
typename std::iterator_traits<IteratorType>::value_type) == 1,
1814 "each element in the iterator range must have the size of 1 byte");
1816 const auto len =
static_cast<size_t>(std::distance(first, last));
1817 if (JSON_LIKELY(len > 0)) {
1819 ia = std::make_shared<input_buffer_adapter>(
reinterpret_cast<const char *
>(&(*first)), len);
1822 ia = std::make_shared<input_buffer_adapter>(
nullptr, len);
1827 template<
class T, std::
size_t N>
1832 template<
class ContiguousContainer,
typename 1833 std::enable_if<not std::is_pointer<ContiguousContainer>::value and
1834 std::is_base_of<std::random_access_iterator_tag,
1835 typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
1859 #include <initializer_list> 1884 template<
typename BasicJsonType>
1888 using number_integer_t =
typename BasicJsonType::number_integer_t;
1889 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
1890 using number_float_t =
typename BasicJsonType::number_float_t;
1919 case token_type::uninitialized:
1920 return "<uninitialized>";
1921 case token_type::literal_true:
1922 return "true literal";
1923 case token_type::literal_false:
1924 return "false literal";
1925 case token_type::literal_null:
1926 return "null literal";
1927 case token_type::value_string:
1928 return "string literal";
1932 return "number literal";
1933 case token_type::begin_array:
1935 case token_type::begin_object:
1937 case token_type::end_array:
1939 case token_type::end_object:
1941 case token_type::name_separator:
1943 case token_type::value_separator:
1945 case token_type::parse_error:
1946 return "<parse error>";
1947 case token_type::end_of_input:
1948 return "end of input";
1949 case token_type::literal_or_value:
1950 return "'[', '{', or a literal";
1952 return "unknown token";
1957 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
1969 static char get_decimal_point() noexcept
1971 const auto loc = localeconv();
1972 assert(loc !=
nullptr);
1973 return (loc->decimal_point ==
nullptr) ?
'.' : *(loc->decimal_point);
1998 assert(current ==
'u');
2001 const auto factors = { 12, 8, 4, 0 };
2002 for (
const auto factor : factors) {
2005 if (current >=
'0' and current <=
'9') {
2006 codepoint += ((current - 0x30) << factor);
2007 }
else if (current >=
'A' and current <=
'F') {
2008 codepoint += ((current - 0x37) << factor);
2009 }
else if (current >=
'a' and current <=
'f') {
2010 codepoint += ((current - 0x57) << factor);
2016 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
2035 bool next_byte_in_range(std::initializer_list<int> ranges)
2037 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
2040 for (
auto range = ranges.begin(); range != ranges.end(); ++range) {
2042 if (JSON_LIKELY(*range <= current and current <= *(++range))) {
2045 error_message =
"invalid string: ill-formed UTF-8 byte";
2074 assert(current ==
'\"');
2080 case std::char_traits<char>::eof():
2082 error_message =
"invalid string: missing closing quote";
2083 return token_type::parse_error;
2089 return token_type::value_string;
2132 const int codepoint1 = get_codepoint();
2133 int codepoint = codepoint1;
2135 if (JSON_UNLIKELY(codepoint1 == -1)) {
2136 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
2137 return token_type::parse_error;
2141 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF) {
2143 if (JSON_LIKELY(
get() ==
'\\' and
get() ==
'u')) {
2144 const int codepoint2 = get_codepoint();
2146 if (JSON_UNLIKELY(codepoint2 == -1)) {
2147 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
2148 return token_type::parse_error;
2152 if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF)) {
2165 "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2166 return token_type::parse_error;
2170 "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2171 return token_type::parse_error;
2174 if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF)) {
2176 "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
2177 return token_type::parse_error;
2182 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
2185 if (codepoint < 0x80) {
2188 }
else if (codepoint <= 0x7FF) {
2190 add(0xC0 | (codepoint >> 6));
2191 add(0x80 | (codepoint & 0x3F));
2192 }
else if (codepoint <= 0xFFFF) {
2194 add(0xE0 | (codepoint >> 12));
2195 add(0x80 | ((codepoint >> 6) & 0x3F));
2196 add(0x80 | (codepoint & 0x3F));
2199 add(0xF0 | (codepoint >> 18));
2200 add(0x80 | ((codepoint >> 12) & 0x3F));
2201 add(0x80 | ((codepoint >> 6) & 0x3F));
2202 add(0x80 | (codepoint & 0x3F));
2210 error_message =
"invalid string: forbidden character after backslash";
2211 return token_type::parse_error;
2251 error_message =
"invalid string: control character must be escaped";
2252 return token_type::parse_error;
2387 if (JSON_UNLIKELY(not next_byte_in_range({ 0x80, 0xBF }))) {
2388 return token_type::parse_error;
2397 if (JSON_UNLIKELY(not (next_byte_in_range({ 0xA0, 0xBF, 0x80, 0xBF })))) {
2398 return token_type::parse_error;
2421 if (JSON_UNLIKELY(not (next_byte_in_range({ 0x80, 0xBF, 0x80, 0xBF })))) {
2422 return token_type::parse_error;
2431 if (JSON_UNLIKELY(not (next_byte_in_range({ 0x80, 0x9F, 0x80, 0xBF })))) {
2432 return token_type::parse_error;
2441 if (JSON_UNLIKELY(not (next_byte_in_range({ 0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF })))) {
2442 return token_type::parse_error;
2453 if (JSON_UNLIKELY(not (next_byte_in_range({ 0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF })))) {
2454 return token_type::parse_error;
2463 if (JSON_UNLIKELY(not (next_byte_in_range({ 0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF })))) {
2464 return token_type::parse_error;
2473 error_message =
"invalid string: ill-formed UTF-8 byte";
2474 return token_type::parse_error;
2480 static void strtof(
float &f,
const char *str,
char **endptr) noexcept
2482 f = std::strtof(str, endptr);
2485 static void strtof(
double &f,
const char *str,
char **endptr) noexcept
2487 f = std::strtod(str, endptr);
2490 static void strtof(
long double &f,
const char *str,
char **endptr) noexcept
2492 f = std::strtold(str, endptr);
2542 token_type number_type = token_type::value_unsigned;
2549 goto scan_number_minus;
2555 goto scan_number_zero;
2569 goto scan_number_any1;
2581 number_type = token_type::value_integer;
2586 goto scan_number_zero;
2600 goto scan_number_any1;
2605 error_message =
"invalid number; expected digit after '-'";
2606 return token_type::parse_error;
2615 add(decimal_point_char);
2616 goto scan_number_decimal1;
2623 goto scan_number_exponent;
2627 goto scan_number_done;
2645 goto scan_number_any1;
2650 add(decimal_point_char);
2651 goto scan_number_decimal1;
2658 goto scan_number_exponent;
2662 goto scan_number_done;
2665 scan_number_decimal1:
2667 number_type = token_type::value_float;
2681 goto scan_number_decimal2;
2686 error_message =
"invalid number; expected digit after '.'";
2687 return token_type::parse_error;
2691 scan_number_decimal2:
2706 goto scan_number_decimal2;
2713 goto scan_number_exponent;
2717 goto scan_number_done;
2720 scan_number_exponent:
2722 number_type = token_type::value_float;
2728 goto scan_number_sign;
2743 goto scan_number_any2;
2749 "invalid number; expected '+', '-', or digit after exponent";
2750 return token_type::parse_error;
2769 goto scan_number_any2;
2774 error_message =
"invalid number; expected digit after exponent sign";
2775 return token_type::parse_error;
2794 goto scan_number_any2;
2798 goto scan_number_done;
2806 char *endptr =
nullptr;
2810 if (number_type == token_type::value_unsigned) {
2811 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
2814 assert(endptr == token_buffer.data() + token_buffer.size());
2817 value_unsigned =
static_cast<number_unsigned_t
>(x);
2818 if (value_unsigned == x) {
2819 return token_type::value_unsigned;
2822 }
else if (number_type == token_type::value_integer) {
2823 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
2826 assert(endptr == token_buffer.data() + token_buffer.size());
2829 value_integer =
static_cast<number_integer_t
>(x);
2830 if (value_integer == x) {
2831 return token_type::value_integer;
2838 strtof(value_float, token_buffer.data(), &endptr);
2841 assert(endptr == token_buffer.data() + token_buffer.size());
2843 return token_type::value_float;
2851 token_type scan_literal(
const char *literal_text,
const std::size_t length,
2854 assert(current == literal_text[0]);
2855 for (std::size_t i = 1; i < length; ++i) {
2856 if (JSON_UNLIKELY(
get() != literal_text[i])) {
2857 error_message =
"invalid literal";
2858 return token_type::parse_error;
2870 void reset() noexcept
2872 token_buffer.clear();
2873 token_string.clear();
2874 token_string.push_back(std::char_traits<char>::to_char_type(current));
2887 std::char_traits<char>::int_type
get()
2890 current = ia->get_character();
2891 if (JSON_LIKELY(current != std::char_traits<char>::eof())) {
2892 token_string.push_back(std::char_traits<char>::to_char_type(current));
2902 if (JSON_LIKELY(current != std::char_traits<char>::eof())) {
2903 ia->unget_character();
2904 assert(token_string.size() != 0);
2905 token_string.pop_back();
2912 token_buffer.push_back(std::char_traits<char>::to_char_type(c));
2923 return value_integer;
2929 return value_unsigned;
2941 return std::move(token_buffer);
2961 for (
const auto c : token_string) {
2962 if (
'\x00' <= c and c <=
'\x1F') {
2964 std::stringstream ss;
2965 ss <<
"<U+" << std::setw(4) << std::uppercase << std::setfill(
'0')
2966 << std::hex << static_cast<int>(c) <<
">";
2970 result.push_back(c);
2980 return error_message;
2992 }
while (current ==
' ' or current ==
'\t' or current ==
'\n' or current ==
'\r');
2997 return token_type::begin_array;
2999 return token_type::end_array;
3001 return token_type::begin_object;
3003 return token_type::end_object;
3005 return token_type::name_separator;
3007 return token_type::value_separator;
3011 return scan_literal(
"true", 4, token_type::literal_true);
3013 return scan_literal(
"false", 5, token_type::literal_false);
3015 return scan_literal(
"null", 4, token_type::literal_null);
3019 return scan_string();
3033 return scan_number();
3038 case std::char_traits<char>::eof():
3039 return token_type::end_of_input;
3043 error_message =
"invalid literal";
3044 return token_type::parse_error;
3053 std::char_traits<char>::int_type current = std::char_traits<char>::eof();
3056 std::size_t chars_read = 0;
3059 std::vector<char> token_string {};
3065 const char *error_message =
"";
3068 number_integer_t value_integer = 0;
3069 number_unsigned_t value_unsigned = 0;
3070 number_float_t value_float = 0;
3073 const char decimal_point_char =
'.';
3085 #include <functional> 3113 template<
typename BasicJsonType>
3117 using number_integer_t =
typename BasicJsonType::number_integer_t;
3118 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
3119 using number_float_t =
typename BasicJsonType::number_float_t;
3140 using parser_callback_t =
3141 std::function<bool(int depth, parse_event_t event, BasicJsonType &parsed)>;
3145 const parser_callback_t cb =
nullptr,
3146 const bool allow_exceptions_ =
true)
3147 : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_)
3160 void parse(
const bool strict, BasicJsonType &result)
3165 parse_internal(
true, result);
3166 result.assert_invariant();
3171 expect(token_type::end_of_input);
3182 if (result.is_discarded()) {
3198 if (not accept_internal()) {
3203 return not strict or (get_token() == token_type::end_of_input);
3213 void parse_internal(
bool keep, BasicJsonType &result)
3216 assert(not errored);
3219 if (not result.is_discarded()) {
3220 result.m_value.destroy(result.m_type);
3224 switch (last_token) {
3225 case token_type::begin_object:
3229 keep = callback(depth++, parse_event_t::object_start, result);
3232 if (not callback or keep) {
3243 if (last_token == token_type::end_object) {
3244 if (keep and callback and not callback(--depth, parse_event_t::object_end, result)) {
3245 result.m_value.destroy(result.m_type);
3254 BasicJsonType value;
3257 if (not expect(token_type::value_string)) {
3261 key = m_lexer.move_string();
3263 bool keep_tag =
false;
3266 BasicJsonType k(key);
3267 keep_tag = callback(depth, parse_event_t::key, k);
3275 if (not expect(token_type::name_separator)) {
3281 value.m_value.destroy(value.m_type);
3283 parse_internal(keep, value);
3285 if (JSON_UNLIKELY(errored)) {
3289 if (keep and keep_tag and not value.is_discarded()) {
3290 result.m_value.object->emplace(std::move(key), std::move(value));
3295 if (last_token == token_type::value_separator) {
3301 if (not expect(token_type::end_object)) {
3308 if (keep and callback and not callback(--depth, parse_event_t::object_end, result)) {
3309 result.m_value.destroy(result.m_type);
3316 case token_type::begin_array:
3320 keep = callback(depth++, parse_event_t::array_start, result);
3323 if (not callback or keep) {
3334 if (last_token == token_type::end_array) {
3335 if (callback and not callback(--depth, parse_event_t::array_end, result)) {
3336 result.m_value.destroy(result.m_type);
3344 BasicJsonType value;
3347 value.m_value.destroy(value.m_type);
3349 parse_internal(keep, value);
3351 if (JSON_UNLIKELY(errored)) {
3355 if (keep and not value.is_discarded()) {
3356 result.m_value.array->push_back(std::move(value));
3361 if (last_token == token_type::value_separator) {
3367 if (not expect(token_type::end_array)) {
3374 if (keep and callback and not callback(--depth, parse_event_t::array_end, result)) {
3375 result.m_value.destroy(result.m_type);
3382 case token_type::literal_null:
3388 case token_type::value_string:
3391 result.m_value = m_lexer.move_string();
3395 case token_type::literal_true:
3398 result.m_value =
true;
3402 case token_type::literal_false:
3405 result.m_value =
false;
3409 case token_type::value_unsigned:
3412 result.m_value = m_lexer.get_number_unsigned();
3416 case token_type::value_integer:
3419 result.m_value = m_lexer.get_number_integer();
3423 case token_type::value_float:
3426 result.m_value = m_lexer.get_number_float();
3429 if (JSON_UNLIKELY(not std::isfinite(result.m_value.number_float))) {
3430 if (allow_exceptions) {
3431 JSON_THROW(out_of_range::create(406,
"number overflow parsing '" +
3432 m_lexer.get_token_string() +
"'"));
3435 expect(token_type::uninitialized);
3441 case token_type::parse_error:
3444 if (not expect(token_type::uninitialized)) {
3454 if (not expect(token_type::literal_or_value)) {
3462 if (keep and callback and not callback(depth, parse_event_t::value, result)) {
3477 bool accept_internal()
3479 switch (last_token) {
3480 case token_type::begin_object:
3486 if (last_token == token_type::end_object) {
3493 if (last_token != token_type::value_string) {
3499 if (last_token != token_type::name_separator) {
3505 if (not accept_internal()) {
3511 if (last_token == token_type::value_separator) {
3517 return (last_token == token_type::end_object);
3521 case token_type::begin_array:
3527 if (last_token == token_type::end_array) {
3534 if (not accept_internal()) {
3540 if (last_token == token_type::value_separator) {
3546 return (last_token == token_type::end_array);
3550 case token_type::value_float:
3553 return std::isfinite(m_lexer.get_number_float());
3556 case token_type::literal_false:
3557 case token_type::literal_null:
3558 case token_type::literal_true:
3559 case token_type::value_integer:
3560 case token_type::value_string:
3561 case token_type::value_unsigned:
3570 token_type get_token()
3572 return (last_token = m_lexer.scan());
3578 bool expect(token_type t)
3580 if (JSON_UNLIKELY(t != last_token)) {
3583 if (allow_exceptions) {
3593 [[noreturn]]
void throw_exception()
const 3596 if (last_token == token_type::parse_error) {
3597 error_msg +=
std::string(m_lexer.get_error_message()) +
"; last read: '" +
3598 m_lexer.get_token_string() +
"'";
3600 error_msg +=
"unexpected " +
std::string(lexer_t::token_type_name(last_token));
3603 if (expected != token_type::uninitialized) {
3604 error_msg +=
"; expected " +
std::string(lexer_t::token_type_name(expected));
3614 const parser_callback_t callback =
nullptr;
3616 token_type last_token = token_type::uninitialized;
3620 bool errored =
false;
3622 token_type expected = token_type::uninitialized;
3624 const bool allow_exceptions =
true;
3653 using difference_type = std::ptrdiff_t;
3654 static constexpr difference_type begin_value = 0;
3655 static constexpr difference_type end_value = begin_value + 1;
3658 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
3661 constexpr difference_type get_value()
const noexcept
3681 return m_it == begin_value;
3687 return m_it == end_value;
3692 return lhs.m_it == rhs.m_it;
3697 return lhs.m_it < rhs.m_it;
3702 auto result = *
this;
3709 return lhs.m_it - rhs.m_it;
3720 auto result = *
this;
3733 auto result = *
this;
3773 typename BasicJsonType::object_t::iterator object_iterator {};
3775 typename BasicJsonType::array_t::iterator array_iterator {};
3788 #include <type_traits> 3830 template<
typename BasicJsonType>
3836 typename std::remove_const<BasicJsonType>::type,
3837 const BasicJsonType>::type>;
3838 friend BasicJsonType;
3841 using object_t =
typename BasicJsonType::object_t;
3842 using array_t =
typename BasicJsonType::array_t;
3844 static_assert(
is_basic_json<
typename std::remove_const<BasicJsonType>::type>::value,
3845 "iter_impl only accepts (const) basic_json");
3861 using pointer =
typename std::conditional<std::is_const<BasicJsonType>::value,
3862 typename BasicJsonType::const_pointer,
3863 typename BasicJsonType::pointer>::type;
3866 typename std::conditional<std::is_const<BasicJsonType>::value,
3867 typename BasicJsonType::const_reference,
3868 typename BasicJsonType::reference>::type;
3881 assert(m_object !=
nullptr);
3883 switch (m_object->m_type) {
3886 m_it.object_iterator =
typename object_t::iterator();
3892 m_it.array_iterator =
typename array_t::iterator();
3919 : m_object(other.m_object), m_it(other.m_it) {}
3929 m_object = other.m_object;
3939 void set_begin() noexcept
3941 assert(m_object !=
nullptr);
3943 switch (m_object->m_type) {
3946 m_it.object_iterator = m_object->m_value.object->begin();
3952 m_it.array_iterator = m_object->m_value.array->begin();
3959 m_it.primitive_iterator.set_end();
3965 m_it.primitive_iterator.set_begin();
3975 void set_end() noexcept
3977 assert(m_object !=
nullptr);
3979 switch (m_object->m_type) {
3982 m_it.object_iterator = m_object->m_value.object->end();
3988 m_it.array_iterator = m_object->m_value.array->end();
3994 m_it.primitive_iterator.set_end();
4007 assert(m_object !=
nullptr);
4009 switch (m_object->m_type) {
4012 assert(m_it.object_iterator != m_object->m_value.object->end());
4013 return m_it.object_iterator->second;
4018 assert(m_it.array_iterator != m_object->m_value.array->end());
4019 return *m_it.array_iterator;
4023 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4027 if (JSON_LIKELY(m_it.primitive_iterator.is_begin())) {
4031 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4042 assert(m_object !=
nullptr);
4044 switch (m_object->m_type) {
4047 assert(m_it.object_iterator != m_object->m_value.object->end());
4048 return &(m_it.object_iterator->second);
4053 assert(m_it.array_iterator != m_object->m_value.array->end());
4054 return &*m_it.array_iterator;
4059 if (JSON_LIKELY(m_it.primitive_iterator.is_begin())) {
4063 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4074 auto result = *
this;
4085 assert(m_object !=
nullptr);
4087 switch (m_object->m_type) {
4090 std::advance(m_it.object_iterator, 1);
4096 std::advance(m_it.array_iterator, 1);
4102 ++m_it.primitive_iterator;
4116 auto result = *
this;
4127 assert(m_object !=
nullptr);
4129 switch (m_object->m_type) {
4132 std::advance(m_it.object_iterator, -1);
4138 std::advance(m_it.array_iterator, -1);
4144 --m_it.primitive_iterator;
4159 if (JSON_UNLIKELY(m_object != other.m_object)) {
4160 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
4163 assert(m_object !=
nullptr);
4165 switch (m_object->m_type) {
4183 return not operator==(other);
4193 if (JSON_UNLIKELY(m_object != other.m_object)) {
4194 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
4197 assert(m_object !=
nullptr);
4199 switch (m_object->m_type) {
4201 JSON_THROW(invalid_iterator::create(213,
"cannot compare order of object iterators"));
4217 return not other.operator<(*this);
4226 return not operator<=(other);
4244 assert(m_object !=
nullptr);
4246 switch (m_object->m_type) {
4248 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
4252 std::advance(m_it.array_iterator, i);
4258 m_it.primitive_iterator += i;
4272 return operator+=(-i);
4281 auto result = *
this;
4303 auto result = *
this;
4314 assert(m_object !=
nullptr);
4316 switch (m_object->m_type) {
4318 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
4334 assert(m_object !=
nullptr);
4336 switch (m_object->m_type) {
4338 JSON_THROW(invalid_iterator::create(208,
"cannot use operator[] for object iterators"));
4341 return *std::next(m_it.array_iterator, n);
4344 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4348 if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n)) {
4352 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4361 typename object_t::key_type
key()
const 4363 assert(m_object !=
nullptr);
4365 if (JSON_LIKELY(m_object->is_object())) {
4366 return m_it.object_iterator->first;
4369 JSON_THROW(invalid_iterator::create(207,
"cannot use key() for non-object iterators"));
4409 class iteration_proxy_internal
4413 IteratorType anchor;
4415 std::size_t array_index = 0;
4418 explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
4421 iteration_proxy_internal &operator*()
4427 iteration_proxy_internal &operator++()
4436 bool operator!=(
const iteration_proxy_internal &o)
const noexcept
4438 return anchor != o.anchor;
4444 assert(anchor.m_object !=
nullptr);
4446 switch (anchor.m_object->type()) {
4449 return std::to_string(array_index);
4453 return anchor.key();
4462 typename IteratorType::reference value()
const 4464 return anchor.value();
4469 typename IteratorType::reference container;
4474 : container(cont) {}
4477 iteration_proxy_internal
begin() noexcept
4479 return iteration_proxy_internal(container.begin());
4483 iteration_proxy_internal
end() noexcept
4485 return iteration_proxy_internal(container.end());
4525 template<
typename Base>
4530 using difference_type = std::ptrdiff_t;
4594 return *(this->operator+(n));
4598 auto key() const->decltype(
std::declval<Base>().key())
4600 auto it = --this->base();
4607 auto it = --this->base();
4608 return it.operator*();
4618 #include <algorithm> 4634 virtual void write_character(CharType c) = 0;
4635 virtual void write_characters(
const CharType *s, std::size_t length) = 0;
4640 template<
typename CharType>
4644 template<
typename CharType>
4650 void write_character(CharType c)
override 4655 void write_characters(
const CharType *s, std::size_t length)
override 4657 std::copy(s, s + length, std::back_inserter(v));
4661 std::vector<CharType> &v;
4665 template<
typename CharType>
4671 void write_character(CharType c)
override 4676 void write_characters(
const CharType *s, std::size_t length)
override 4678 stream.write(s, static_cast<std::streamsize>(length));
4682 std::basic_ostream<CharType> &stream;
4686 template<
typename CharType>
4692 void write_character(CharType c)
override 4697 void write_characters(
const CharType *s, std::size_t length)
override 4699 str.append(s, length);
4703 std::basic_string<CharType> &str;
4706 template<
typename CharType>
4735 #include <algorithm> 4770 template<
typename BasicJsonType>
4774 using number_integer_t =
typename BasicJsonType::number_integer_t;
4775 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
4776 using string_t =
typename BasicJsonType::string_t;
4801 const auto res = parse_cbor_internal();
4822 const auto res = parse_msgpack_internal();
4843 const auto res = parse_ubjson_internal();
4861 return (*reinterpret_cast<char *>(&num) == 1);
4870 BasicJsonType parse_cbor_internal(
const bool get_char =
true)
4872 switch (get_char ?
get() : current) {
4874 case std::char_traits<char>::eof():
4902 return static_cast<number_unsigned_t
>(current);
4905 return get_number<uint8_t>();
4908 return get_number<uint16_t>();
4911 return get_number<uint32_t>();
4914 return get_number<uint64_t>();
4941 return static_cast<int8_t
>(0x20 - 1 - current);
4945 return static_cast<number_integer_t
>(-1) - get_number<uint8_t>();
4950 return static_cast<number_integer_t
>(-1) - get_number<uint16_t>();
4955 return static_cast<number_integer_t
>(-1) - get_number<uint32_t>();
4960 return static_cast<number_integer_t
>(-1) -
4961 static_cast<number_integer_t>(get_number<uint64_t>());
4995 return get_cbor_string();
5024 return get_cbor_array(current & 0x1F);
5029 return get_cbor_array(get_number<uint8_t>());
5034 return get_cbor_array(get_number<uint16_t>());
5039 return get_cbor_array(get_number<uint32_t>());
5044 return get_cbor_array(get_number<uint64_t>());
5050 while (
get() != 0xFF) {
5051 result.push_back(parse_cbor_internal(
false));
5083 return get_cbor_object(current & 0x1F);
5088 return get_cbor_object(get_number<uint8_t>());
5093 return get_cbor_object(get_number<uint16_t>());
5098 return get_cbor_object(get_number<uint32_t>());
5103 return get_cbor_object(get_number<uint64_t>());
5109 while (
get() != 0xFF) {
5110 auto key = get_cbor_string();
5111 result[key] = parse_cbor_internal();
5134 const int byte1 =
get();
5136 const int byte2 =
get();
5147 const int half = (byte1 << 8) + byte2;
5148 const int exp = (half >> 10) & 0x1F;
5149 const int mant = half & 0x3FF;
5152 val = std::ldexp(mant, -24);
5153 }
else if (exp != 31) {
5154 val = std::ldexp(mant + 1024, exp - 25);
5156 val = (mant == 0) ? std::numeric_limits<double>::infinity()
5157 : std::numeric_limits<double>::quiet_NaN();
5160 return (half & 0x8000) != 0 ? -val : val;
5165 return get_number<float>();
5170 return get_number<double>();
5175 std::stringstream ss;
5176 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5177 JSON_THROW(
parse_error::create(112, chars_read,
"error reading CBOR; last byte: 0x" + ss.str()));
5182 BasicJsonType parse_msgpack_internal()
5186 case std::char_traits<char>::eof():
5318 return static_cast<number_unsigned_t
>(current);
5338 return get_msgpack_object(current & 0x0F);
5359 return get_msgpack_array(current & 0x0F);
5395 return get_msgpack_string();
5407 return get_number<float>();
5410 return get_number<double>();
5413 return get_number<uint8_t>();
5416 return get_number<uint16_t>();
5419 return get_number<uint32_t>();
5422 return get_number<uint64_t>();
5425 return get_number<int8_t>();
5428 return get_number<int16_t>();
5431 return get_number<int32_t>();
5434 return get_number<int64_t>();
5439 return get_msgpack_string();
5443 return get_msgpack_array(get_number<uint16_t>());
5448 return get_msgpack_array(get_number<uint32_t>());
5453 return get_msgpack_object(get_number<uint16_t>());
5458 return get_msgpack_object(get_number<uint32_t>());
5494 return static_cast<int8_t
>(current);
5498 std::stringstream ss;
5499 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5501 "error reading MessagePack; last byte: 0x" + ss.str()));
5511 BasicJsonType parse_ubjson_internal(
const bool get_char =
true)
5513 return get_ubjson_value(get_char ? get_ignore_noop() : current);
5528 return (current = ia->get_character());
5534 int get_ignore_noop()
5538 }
while (current ==
'N');
5556 template<
typename NumberType> NumberType get_number()
5559 std::array<uint8_t, sizeof(NumberType)> vec;
5560 for (std::size_t i = 0; i <
sizeof(NumberType); ++i) {
5565 if (is_little_endian) {
5566 vec[
sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
5568 vec[i] =
static_cast<uint8_t
>(current);
5574 std::memcpy(&result, vec.data(),
sizeof(NumberType));
5591 template<
typename NumberType>
5592 string_t get_string(
const NumberType len)
5595 std::generate_n(std::back_inserter(result), len, [
this]() {
5598 return static_cast<char>(current);
5615 string_t get_cbor_string()
5646 return get_string(current & 0x1F);
5651 return get_string(get_number<uint8_t>());
5656 return get_string(get_number<uint16_t>());
5661 return get_string(get_number<uint32_t>());
5666 return get_string(get_number<uint64_t>());
5672 while (
get() != 0xFF) {
5673 result.append(get_cbor_string());
5681 std::stringstream ss;
5682 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5684 "expected a CBOR string; last byte: 0x" + ss.str()));
5689 template<
typename NumberType>
5690 BasicJsonType get_cbor_array(
const NumberType len)
5693 std::generate_n(std::back_inserter(*result.m_value.array), len, [
this]() {
5694 return parse_cbor_internal();
5699 template<
typename NumberType>
5700 BasicJsonType get_cbor_object(
const NumberType len)
5703 std::generate_n(std::inserter(*result.m_value.object,
5704 result.m_value.object->end()),
5707 auto key = get_cbor_string();
5708 auto val = parse_cbor_internal();
5709 return std::make_pair(std::move(key), std::move(val));
5725 string_t get_msgpack_string()
5764 return get_string(current & 0x1F);
5769 return get_string(get_number<uint8_t>());
5774 return get_string(get_number<uint16_t>());
5779 return get_string(get_number<uint32_t>());
5784 std::stringstream ss;
5785 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5787 "expected a MessagePack string; last byte: 0x" + ss.str()));
5792 template<
typename NumberType>
5793 BasicJsonType get_msgpack_array(
const NumberType len)
5796 std::generate_n(std::back_inserter(*result.m_value.array), len, [
this]() {
5797 return parse_msgpack_internal();
5802 template<
typename NumberType>
5803 BasicJsonType get_msgpack_object(
const NumberType len)
5806 std::generate_n(std::inserter(*result.m_value.object,
5807 result.m_value.object->end()),
5810 auto key = get_msgpack_string();
5811 auto val = parse_msgpack_internal();
5812 return std::make_pair(std::move(key), std::move(val));
5833 string_t get_ubjson_string(
const bool get_char =
true)
5843 return get_string(get_number<uint8_t>());
5845 return get_string(get_number<int8_t>());
5847 return get_string(get_number<int16_t>());
5849 return get_string(get_number<int32_t>());
5851 return get_string(get_number<int64_t>());
5853 std::stringstream ss;
5854 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5856 "expected a UBJSON string; last byte: 0x" + ss.str()));
5868 std::pair<std::size_t, int> get_ubjson_size_type()
5870 std::size_t sz = string_t::npos;
5875 if (current ==
'$') {
5880 if (current !=
'#') {
5881 std::stringstream ss;
5882 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5884 "expected '#' after UBJSON type information; last byte: 0x" +
5888 sz = parse_ubjson_internal();
5889 }
else if (current ==
'#') {
5890 sz = parse_ubjson_internal();
5893 return std::make_pair(sz, tc);
5896 BasicJsonType get_ubjson_value(
const int prefix)
5899 case std::char_traits<char>::eof():
5911 return get_number<uint8_t>();
5913 return get_number<int8_t>();
5915 return get_number<int16_t>();
5917 return get_number<int32_t>();
5919 return get_number<int64_t>();
5921 return get_number<float>();
5923 return get_number<double>();
5929 if (JSON_UNLIKELY(current > 127)) {
5930 std::stringstream ss;
5931 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5933 "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" +
5937 return string_t(1, static_cast<char>(current));
5941 return get_ubjson_string();
5944 return get_ubjson_array();
5947 return get_ubjson_object();
5950 std::stringstream ss;
5951 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5953 "error reading UBJSON; last byte: 0x" + ss.str()));
5957 BasicJsonType get_ubjson_array()
5960 const auto size_and_type = get_ubjson_size_type();
5962 if (size_and_type.first != string_t::npos) {
5963 if (JSON_UNLIKELY(size_and_type.first > result.max_size())) {
5964 JSON_THROW(out_of_range::create(408,
5965 "excessive array size: " + std::to_string(
5966 size_and_type.first)));
5969 if (size_and_type.second != 0) {
5970 if (size_and_type.second !=
'N') {
5971 std::generate_n(std::back_inserter(*result.m_value.array),
5972 size_and_type.first, [
this, size_and_type]() {
5973 return get_ubjson_value(size_and_type.second);
5977 std::generate_n(std::back_inserter(*result.m_value.array),
5978 size_and_type.first, [
this]() {
5979 return parse_ubjson_internal();
5983 while (current !=
']') {
5984 result.push_back(parse_ubjson_internal(
false));
5992 BasicJsonType get_ubjson_object()
5995 const auto size_and_type = get_ubjson_size_type();
5997 if (size_and_type.first != string_t::npos) {
5998 if (JSON_UNLIKELY(size_and_type.first > result.max_size())) {
5999 JSON_THROW(out_of_range::create(408,
6000 "excessive object size: " +
6001 std::to_string(size_and_type.first)));
6004 if (size_and_type.second != 0) {
6005 std::generate_n(std::inserter(*result.m_value.object,
6006 result.m_value.object->end()),
6007 size_and_type.first, [
this, size_and_type]() {
6008 auto key = get_ubjson_string();
6009 auto val = get_ubjson_value(size_and_type.second);
6010 return std::make_pair(std::move(key), std::move(val));
6013 std::generate_n(std::inserter(*result.m_value.object,
6014 result.m_value.object->end()),
6015 size_and_type.first, [
this]() {
6016 auto key = get_ubjson_string();
6017 auto val = parse_ubjson_internal();
6018 return std::make_pair(std::move(key), std::move(val));
6022 while (current !=
'}') {
6023 auto key = get_ubjson_string(
false);
6024 result[std::move(key)] = parse_ubjson_internal();
6036 void expect_eof()
const 6038 if (JSON_UNLIKELY(current != std::char_traits<char>::eof())) {
6047 void unexpect_eof()
const 6049 if (JSON_UNLIKELY(current == std::char_traits<char>::eof())) {
6059 int current = std::char_traits<char>::eof();
6062 std::size_t chars_read = 0;
6065 const bool is_little_endian = little_endianess();
6074 #include <algorithm> 6096 template<
typename BasicJsonType,
typename CharType>
6119 oa->write_character(static_cast<CharType>(0xF6));
6125 oa->write_character(j.m_value.boolean
6126 ? static_cast<CharType>(0xF5)
6127 : static_cast<CharType>(0xF4));
6133 if (j.m_value.number_integer >= 0) {
6137 if (j.m_value.number_integer <= 0x17) {
6138 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6139 }
else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)()) {
6140 oa->write_character(static_cast<CharType>(0x18));
6141 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6142 }
else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)()) {
6143 oa->write_character(static_cast<CharType>(0x19));
6144 write_number(static_cast<uint16_t>(j.m_value.number_integer));
6145 }
else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)()) {
6146 oa->write_character(static_cast<CharType>(0x1A));
6147 write_number(static_cast<uint32_t>(j.m_value.number_integer));
6149 oa->write_character(static_cast<CharType>(0x1B));
6150 write_number(static_cast<uint64_t>(j.m_value.number_integer));
6155 const auto positive_number = -1 - j.m_value.number_integer;
6156 if (j.m_value.number_integer >= -24) {
6157 write_number(static_cast<uint8_t>(0x20 + positive_number));
6158 }
else if (positive_number <= (std::numeric_limits<uint8_t>::max)()) {
6159 oa->write_character(static_cast<CharType>(0x38));
6160 write_number(static_cast<uint8_t>(positive_number));
6161 }
else if (positive_number <= (std::numeric_limits<uint16_t>::max)()) {
6162 oa->write_character(static_cast<CharType>(0x39));
6163 write_number(static_cast<uint16_t>(positive_number));
6164 }
else if (positive_number <= (std::numeric_limits<uint32_t>::max)()) {
6165 oa->write_character(static_cast<CharType>(0x3A));
6166 write_number(static_cast<uint32_t>(positive_number));
6168 oa->write_character(static_cast<CharType>(0x3B));
6169 write_number(static_cast<uint64_t>(positive_number));
6178 if (j.m_value.number_unsigned <= 0x17) {
6179 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
6180 }
else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)()) {
6181 oa->write_character(static_cast<CharType>(0x18));
6182 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
6183 }
else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)()) {
6184 oa->write_character(static_cast<CharType>(0x19));
6185 write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
6186 }
else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)()) {
6187 oa->write_character(static_cast<CharType>(0x1A));
6188 write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
6190 oa->write_character(static_cast<CharType>(0x1B));
6191 write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
6199 oa->write_character(static_cast<CharType>(0xFB));
6200 write_number(j.m_value.number_float);
6207 const auto N = j.m_value.string->size();
6209 write_number(static_cast<uint8_t>(0x60 + N));
6210 }
else if (N <= (std::numeric_limits<uint8_t>::max)()) {
6211 oa->write_character(static_cast<CharType>(0x78));
6212 write_number(static_cast<uint8_t>(N));
6213 }
else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6214 oa->write_character(static_cast<CharType>(0x79));
6215 write_number(static_cast<uint16_t>(N));
6216 }
else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6217 oa->write_character(static_cast<CharType>(0x7A));
6218 write_number(static_cast<uint32_t>(N));
6221 else if (N <= (std::numeric_limits<uint64_t>::max)()) {
6222 oa->write_character(static_cast<CharType>(0x7B));
6223 write_number(static_cast<uint64_t>(N));
6229 oa->write_characters(
6230 reinterpret_cast<const CharType *>(j.m_value.string->c_str()),
6231 j.m_value.string->size());
6238 const auto N = j.m_value.array->size();
6240 write_number(static_cast<uint8_t>(0x80 + N));
6241 }
else if (N <= (std::numeric_limits<uint8_t>::max)()) {
6242 oa->write_character(static_cast<CharType>(0x98));
6243 write_number(static_cast<uint8_t>(N));
6244 }
else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6245 oa->write_character(static_cast<CharType>(0x99));
6246 write_number(static_cast<uint16_t>(N));
6247 }
else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6248 oa->write_character(static_cast<CharType>(0x9A));
6249 write_number(static_cast<uint32_t>(N));
6252 else if (N <= (std::numeric_limits<uint64_t>::max)()) {
6253 oa->write_character(static_cast<CharType>(0x9B));
6254 write_number(static_cast<uint64_t>(N));
6260 for (
const auto &el : *j.m_value.array) {
6270 const auto N = j.m_value.object->size();
6272 write_number(static_cast<uint8_t>(0xA0 + N));
6273 }
else if (N <= (std::numeric_limits<uint8_t>::max)()) {
6274 oa->write_character(static_cast<CharType>(0xB8));
6275 write_number(static_cast<uint8_t>(N));
6276 }
else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6277 oa->write_character(static_cast<CharType>(0xB9));
6278 write_number(static_cast<uint16_t>(N));
6279 }
else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6280 oa->write_character(static_cast<CharType>(0xBA));
6281 write_number(static_cast<uint32_t>(N));
6284 else if (N <= (std::numeric_limits<uint64_t>::max)()) {
6285 oa->write_character(static_cast<CharType>(0xBB));
6286 write_number(static_cast<uint64_t>(N));
6292 for (
const auto &el : *j.m_value.object) {
6293 write_cbor(el.first);
6294 write_cbor(el.second);
6313 oa->write_character(static_cast<CharType>(0xC0));
6319 oa->write_character(j.m_value.boolean
6320 ? static_cast<CharType>(0xC3)
6321 : static_cast<CharType>(0xC2));
6327 if (j.m_value.number_integer >= 0) {
6331 if (j.m_value.number_unsigned < 128) {
6333 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6334 }
else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)()) {
6336 oa->write_character(static_cast<CharType>(0xCC));
6337 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6338 }
else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)()) {
6340 oa->write_character(static_cast<CharType>(0xCD));
6341 write_number(static_cast<uint16_t>(j.m_value.number_integer));
6342 }
else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)()) {
6344 oa->write_character(static_cast<CharType>(0xCE));
6345 write_number(static_cast<uint32_t>(j.m_value.number_integer));
6346 }
else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)()) {
6348 oa->write_character(static_cast<CharType>(0xCF));
6349 write_number(static_cast<uint64_t>(j.m_value.number_integer));
6352 if (j.m_value.number_integer >= -32) {
6354 write_number(static_cast<int8_t>(j.m_value.number_integer));
6355 }
else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and
6356 j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)()) {
6358 oa->write_character(static_cast<CharType>(0xD0));
6359 write_number(static_cast<int8_t>(j.m_value.number_integer));
6360 }
else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and
6361 j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)()) {
6363 oa->write_character(static_cast<CharType>(0xD1));
6364 write_number(static_cast<int16_t>(j.m_value.number_integer));
6365 }
else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and
6366 j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)()) {
6368 oa->write_character(static_cast<CharType>(0xD2));
6369 write_number(static_cast<int32_t>(j.m_value.number_integer));
6370 }
else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and
6371 j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)()) {
6373 oa->write_character(static_cast<CharType>(0xD3));
6374 write_number(static_cast<int64_t>(j.m_value.number_integer));
6383 if (j.m_value.number_unsigned < 128) {
6385 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6386 }
else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)()) {
6388 oa->write_character(static_cast<CharType>(0xCC));
6389 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6390 }
else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)()) {
6392 oa->write_character(static_cast<CharType>(0xCD));
6393 write_number(static_cast<uint16_t>(j.m_value.number_integer));
6394 }
else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)()) {
6396 oa->write_character(static_cast<CharType>(0xCE));
6397 write_number(static_cast<uint32_t>(j.m_value.number_integer));
6398 }
else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)()) {
6400 oa->write_character(static_cast<CharType>(0xCF));
6401 write_number(static_cast<uint64_t>(j.m_value.number_integer));
6409 oa->write_character(static_cast<CharType>(0xCB));
6410 write_number(j.m_value.number_float);
6417 const auto N = j.m_value.string->size();
6420 write_number(static_cast<uint8_t>(0xA0 | N));
6421 }
else if (N <= (std::numeric_limits<uint8_t>::max)()) {
6423 oa->write_character(static_cast<CharType>(0xD9));
6424 write_number(static_cast<uint8_t>(N));
6425 }
else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6427 oa->write_character(static_cast<CharType>(0xDA));
6428 write_number(static_cast<uint16_t>(N));
6429 }
else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6431 oa->write_character(static_cast<CharType>(0xDB));
6432 write_number(static_cast<uint32_t>(N));
6436 oa->write_characters(
6437 reinterpret_cast<const CharType *>(j.m_value.string->c_str()),
6438 j.m_value.string->size());
6445 const auto N = j.m_value.array->size();
6448 write_number(static_cast<uint8_t>(0x90 | N));
6449 }
else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6451 oa->write_character(static_cast<CharType>(0xDC));
6452 write_number(static_cast<uint16_t>(N));
6453 }
else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6455 oa->write_character(static_cast<CharType>(0xDD));
6456 write_number(static_cast<uint32_t>(N));
6460 for (
const auto &el : *j.m_value.array) {
6470 const auto N = j.m_value.object->size();
6473 write_number(static_cast<uint8_t>(0x80 | (N & 0xF)));
6474 }
else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6476 oa->write_character(static_cast<CharType>(0xDE));
6477 write_number(static_cast<uint16_t>(N));
6478 }
else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6480 oa->write_character(static_cast<CharType>(0xDF));
6481 write_number(static_cast<uint32_t>(N));
6485 for (
const auto &el : *j.m_value.object) {
6486 write_msgpack(el.first);
6487 write_msgpack(el.second);
6505 const bool use_type,
const bool add_prefix =
true)
6511 oa->write_character(static_cast<CharType>(
'Z'));
6520 oa->write_character(j.m_value.boolean
6521 ? static_cast<CharType>(
'T')
6522 : static_cast<CharType>(
'F'));
6529 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
6535 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
6541 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
6548 oa->write_character(static_cast<CharType>(
'S'));
6551 write_number_with_ubjson_prefix(j.m_value.string->size(),
true);
6552 oa->write_characters(
6553 reinterpret_cast<const CharType *>(j.m_value.string->c_str()),
6554 j.m_value.string->size());
6561 oa->write_character(static_cast<CharType>(
'['));
6564 bool prefix_required =
true;
6565 if (use_type and not j.m_value.array->empty()) {
6567 const char first_prefix = ubjson_prefix(j.front());
6568 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
6569 [
this, first_prefix](
const BasicJsonType &v) {
6570 return ubjson_prefix(v) == first_prefix;
6574 prefix_required =
false;
6575 oa->write_character(static_cast<CharType>(
'$'));
6576 oa->write_character(static_cast<CharType>(first_prefix));
6581 oa->write_character(static_cast<CharType>(
'#'));
6582 write_number_with_ubjson_prefix(j.m_value.array->size(),
true);
6585 for (
const auto &el : *j.m_value.array) {
6586 write_ubjson(el, use_count, use_type, prefix_required);
6589 if (not use_count) {
6590 oa->write_character(static_cast<CharType>(
']'));
6599 oa->write_character(static_cast<CharType>(
'{'));
6602 bool prefix_required =
true;
6603 if (use_type and not j.m_value.object->empty()) {
6605 const char first_prefix = ubjson_prefix(j.front());
6606 const bool same_prefix = std::all_of(j.begin(), j.end(),
6607 [
this, first_prefix](
const BasicJsonType &v) {
6608 return ubjson_prefix(v) == first_prefix;
6612 prefix_required =
false;
6613 oa->write_character(static_cast<CharType>(
'$'));
6614 oa->write_character(static_cast<CharType>(first_prefix));
6619 oa->write_character(static_cast<CharType>(
'#'));
6620 write_number_with_ubjson_prefix(j.m_value.object->size(),
true);
6623 for (
const auto &el : *j.m_value.object) {
6624 write_number_with_ubjson_prefix(el.first.size(),
true);
6625 oa->write_characters(
6626 reinterpret_cast<const CharType *>(el.first.c_str()),
6628 write_ubjson(el.second, use_count, use_type, prefix_required);
6631 if (not use_count) {
6632 oa->write_character(static_cast<CharType>(
'}'));
6654 template<
typename NumberType>
6655 void write_number(
const NumberType n)
6658 std::array<CharType, sizeof(NumberType)> vec;
6659 std::memcpy(vec.data(), &n,
sizeof(NumberType));
6662 if (is_little_endian) {
6664 std::reverse(vec.begin(), vec.end());
6667 oa->write_characters(vec.data(),
sizeof(NumberType));
6670 template<
typename NumberType>
6671 void write_number_with_ubjson_prefix(
const NumberType n,
6672 const bool add_prefix)
6674 if (std::is_floating_point<NumberType>::value) {
6676 oa->write_character(static_cast<CharType>(
'D'));
6680 }
else if (std::is_unsigned<NumberType>::value) {
6681 if (n <= (std::numeric_limits<int8_t>::max)()) {
6683 oa->write_character(static_cast<CharType>(
'i'));
6686 write_number(static_cast<uint8_t>(n));
6687 }
else if (n <= (std::numeric_limits<uint8_t>::max)()) {
6689 oa->write_character(static_cast<CharType>(
'U'));
6692 write_number(static_cast<uint8_t>(n));
6693 }
else if (n <= (std::numeric_limits<int16_t>::max)()) {
6695 oa->write_character(static_cast<CharType>(
'I'));
6698 write_number(static_cast<int16_t>(n));
6699 }
else if (n <= (std::numeric_limits<int32_t>::max)()) {
6701 oa->write_character(static_cast<CharType>(
'l'));
6704 write_number(static_cast<int32_t>(n));
6705 }
else if (n <= (std::numeric_limits<int64_t>::max)()) {
6707 oa->write_character(static_cast<CharType>(
'L'));
6710 write_number(static_cast<int64_t>(n));
6712 JSON_THROW(out_of_range::create(407,
"number overflow serializing " + std::to_string(n)));
6715 if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)()) {
6717 oa->write_character(static_cast<CharType>(
'i'));
6720 write_number(static_cast<int8_t>(n));
6721 }
else if ((std::numeric_limits<uint8_t>::min)() <= n and n <=
6722 (std::numeric_limits<uint8_t>::max)()) {
6724 oa->write_character(static_cast<CharType>(
'U'));
6727 write_number(static_cast<uint8_t>(n));
6728 }
else if ((std::numeric_limits<int16_t>::min)() <= n and n <=
6729 (std::numeric_limits<int16_t>::max)()) {
6731 oa->write_character(static_cast<CharType>(
'I'));
6734 write_number(static_cast<int16_t>(n));
6735 }
else if ((std::numeric_limits<int32_t>::min)() <= n and n <=
6736 (std::numeric_limits<int32_t>::max)()) {
6738 oa->write_character(static_cast<CharType>(
'l'));
6741 write_number(static_cast<int32_t>(n));
6742 }
else if ((std::numeric_limits<int64_t>::min)() <= n and n <=
6743 (std::numeric_limits<int64_t>::max)()) {
6745 oa->write_character(static_cast<CharType>(
'L'));
6748 write_number(static_cast<int64_t>(n));
6752 JSON_THROW(out_of_range::create(407,
"number overflow serializing " + std::to_string(n)));
6768 char ubjson_prefix(
const BasicJsonType &j)
const noexcept
6775 return j.m_value.boolean ?
'T' :
'F';
6779 if ((std::numeric_limits<int8_t>::min)() <=
6780 j.m_value.number_integer and j.m_value.number_integer <=
6781 (std::numeric_limits<int8_t>::max)()) {
6783 }
else if ((std::numeric_limits<uint8_t>::min)() <=
6784 j.m_value.number_integer and j.m_value.number_integer <=
6785 (std::numeric_limits<uint8_t>::max)()) {
6787 }
else if ((std::numeric_limits<int16_t>::min)() <=
6788 j.m_value.number_integer and j.m_value.number_integer <=
6789 (std::numeric_limits<int16_t>::max)()) {
6791 }
else if ((std::numeric_limits<int32_t>::min)() <=
6792 j.m_value.number_integer and j.m_value.number_integer <=
6793 (std::numeric_limits<int32_t>::max)()) {
6802 if (j.m_value.number_unsigned <= (std::numeric_limits<int8_t>::max)()) {
6804 }
else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)()) {
6806 }
else if (j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max)()) {
6808 }
else if (j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max)()) {
6846 #include <algorithm> 6860 #include <type_traits> 6900 template<
typename Target,
typename Source>
6901 Target reinterpret_bits(
const Source source)
6903 static_assert(
sizeof(Target) ==
sizeof(Source),
"size mismatch");
6906 std::memcpy(&target, &source,
sizeof(Source));
6912 static constexpr
int kPrecision = 64;
6917 constexpr
diyfp() noexcept : f(0), e(0) {}
6918 constexpr
diyfp(uint64_t f_,
int e_) noexcept : f(f_), e(e_) {}
6929 return diyfp(x.f - y.f, x.e);
6938 static_assert(kPrecision == 64,
"internal error");
6963 const uint64_t u_lo = x.f & 0xFFFFFFFF;
6964 const uint64_t u_hi = x.f >> 32;
6965 const uint64_t v_lo = y.f & 0xFFFFFFFF;
6966 const uint64_t v_hi = y.f >> 32;
6968 const uint64_t p0 = u_lo * v_lo;
6969 const uint64_t p1 = u_lo * v_hi;
6970 const uint64_t p2 = u_hi * v_lo;
6971 const uint64_t p3 = u_hi * v_hi;
6973 const uint64_t p0_hi = p0 >> 32;
6974 const uint64_t p1_lo = p1 & 0xFFFFFFFF;
6975 const uint64_t p1_hi = p1 >> 32;
6976 const uint64_t p2_lo = p2 & 0xFFFFFFFF;
6977 const uint64_t p2_hi = p2 >> 32;
6979 uint64_t Q = p0_hi + p1_lo + p2_lo;
6990 Q += uint64_t { 1 } << (64 - 32 - 1);
6992 const uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32);
6994 return diyfp(h, x.e + y.e + 64);
7005 while ((x.f >> 63) == 0) {
7019 const int delta = x.e - target_exponent;
7022 assert(((x.f << delta) >> delta) == x.f);
7024 return diyfp(x.f << delta, target_exponent);
7041 template<
typename FloatType>
7044 assert(std::isfinite(value));
7054 static_assert(std::numeric_limits<FloatType>::is_iec559,
7055 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
7057 constexpr
int kPrecision = std::numeric_limits<FloatType>::digits;
7058 constexpr
int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
7059 constexpr
int kMinExp = 1 - kBias;
7060 constexpr uint64_t kHiddenBit = uint64_t { 1 } << (kPrecision - 1);
7062 using bits_type =
typename std::conditional<kPrecision == 24, uint32_t, uint64_t>::type;
7064 const uint64_t bits = reinterpret_bits<bits_type>(value);
7065 const uint64_t E = bits >> (kPrecision - 1);
7066 const uint64_t F = bits & (kHiddenBit - 1);
7068 const bool is_denormal = (E == 0);
7069 const diyfp v = is_denormal
7071 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
7094 const bool lower_boundary_is_closer = (F == 0 and E > 1);
7095 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
7096 const diyfp m_minus = lower_boundary_is_closer
7097 ? diyfp(4 * v.f - 1, v.e - 2)
7098 : diyfp(2 * v.f - 1, v.e - 1);
7101 const diyfp w_plus = diyfp::normalize(m_plus);
7104 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
7106 return { diyfp::normalize(v), w_minus, w_plus };
7164 constexpr
int kAlpha = -60;
7165 constexpr
int kGamma = -32;
7233 constexpr
int kCachedPowersSize = 79;
7234 constexpr
int kCachedPowersMinDecExp = -300;
7235 constexpr
int kCachedPowersDecStep = 8;
7239 { 0xAB70FE17C79AC6CA, -1060, -300 },
7240 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
7241 { 0xBE5691EF416BD60C, -1007, -284 },
7242 { 0x8DD01FAD907FFC3C, -980, -276 },
7243 { 0xD3515C2831559A83, -954, -268 },
7244 { 0x9D71AC8FADA6C9B5, -927, -260 },
7245 { 0xEA9C227723EE8BCB, -901, -252 },
7246 { 0xAECC49914078536D, -874, -244 },
7247 { 0x823C12795DB6CE57, -847, -236 },
7248 { 0xC21094364DFB5637, -821, -228 },
7249 { 0x9096EA6F3848984F, -794, -220 },
7250 { 0xD77485CB25823AC7, -768, -212 },
7251 { 0xA086CFCD97BF97F4, -741, -204 },
7252 { 0xEF340A98172AACE5, -715, -196 },
7253 { 0xB23867FB2A35B28E, -688, -188 },
7254 { 0x84C8D4DFD2C63F3B, -661, -180 },
7255 { 0xC5DD44271AD3CDBA, -635, -172 },
7256 { 0x936B9FCEBB25C996, -608, -164 },
7257 { 0xDBAC6C247D62A584, -582, -156 },
7258 { 0xA3AB66580D5FDAF6, -555, -148 },
7259 { 0xF3E2F893DEC3F126, -529, -140 },
7260 { 0xB5B5ADA8AAFF80B8, -502, -132 },
7261 { 0x87625F056C7C4A8B, -475, -124 },
7262 { 0xC9BCFF6034C13053, -449, -116 },
7263 { 0x964E858C91BA2655, -422, -108 },
7264 { 0xDFF9772470297EBD, -396, -100 },
7265 { 0xA6DFBD9FB8E5B88F, -369, -92 },
7266 { 0xF8A95FCF88747D94, -343, -84 },
7267 { 0xB94470938FA89BCF, -316, -76 },
7268 { 0x8A08F0F8BF0F156B, -289, -68 },
7269 { 0xCDB02555653131B6, -263, -60 },
7270 { 0x993FE2C6D07B7FAC, -236, -52 },
7271 { 0xE45C10C42A2B3B06, -210, -44 },
7272 { 0xAA242499697392D3, -183, -36 },
7273 { 0xFD87B5F28300CA0E, -157, -28 },
7274 { 0xBCE5086492111AEB, -130, -20 },
7275 { 0x8CBCCC096F5088CC, -103, -12 },
7276 { 0xD1B71758E219652C, -77, -4 },
7277 { 0x9C40000000000000, -50, 4 },
7278 { 0xE8D4A51000000000, -24, 12 },
7279 { 0xAD78EBC5AC620000, 3, 20 },
7280 { 0x813F3978F8940984, 30, 28 },
7281 { 0xC097CE7BC90715B3, 56, 36 },
7282 { 0x8F7E32CE7BEA5C70, 83, 44 },
7283 { 0xD5D238A4ABE98068, 109, 52 },
7284 { 0x9F4F2726179A2245, 136, 60 },
7285 { 0xED63A231D4C4FB27, 162, 68 },
7286 { 0xB0DE65388CC8ADA8, 189, 76 },
7287 { 0x83C7088E1AAB65DB, 216, 84 },
7288 { 0xC45D1DF942711D9A, 242, 92 },
7289 { 0x924D692CA61BE758, 269, 100 },
7290 { 0xDA01EE641A708DEA, 295, 108 },
7291 { 0xA26DA3999AEF774A, 322, 116 },
7292 { 0xF209787BB47D6B85, 348, 124 },
7293 { 0xB454E4A179DD1877, 375, 132 },
7294 { 0x865B86925B9BC5C2, 402, 140 },
7295 { 0xC83553C5C8965D3D, 428, 148 },
7296 { 0x952AB45CFA97A0B3, 455, 156 },
7297 { 0xDE469FBD99A05FE3, 481, 164 },
7298 { 0xA59BC234DB398C25, 508, 172 },
7299 { 0xF6C69A72A3989F5C, 534, 180 },
7300 { 0xB7DCBF5354E9BECE, 561, 188 },
7301 { 0x88FCF317F22241E2, 588, 196 },
7302 { 0xCC20CE9BD35C78A5, 614, 204 },
7303 { 0x98165AF37B2153DF, 641, 212 },
7304 { 0xE2A0B5DC971F303A, 667, 220 },
7305 { 0xA8D9D1535CE3B396, 694, 228 },
7306 { 0xFB9B7CD9A4A7443C, 720, 236 },
7307 { 0xBB764C4CA7A44410, 747, 244 },
7308 { 0x8BAB8EEFB6409C1A, 774, 252 },
7309 { 0xD01FEF10A657842C, 800, 260 },
7310 { 0x9B10A4E5E9913129, 827, 268 },
7311 { 0xE7109BFBA19C0C9D, 853, 276 },
7312 { 0xAC2820D9623BF429, 880, 284 },
7313 { 0x80444B5E7AA7CF85, 907, 292 },
7314 { 0xBF21E44003ACDD2D, 933, 300 },
7315 { 0x8E679C2F5E44FF8F, 960, 308 },
7316 { 0xD433179D9C8CB841, 986, 316 },
7317 { 0x9E19DB92B4E31BA9, 1013, 324 },
7326 const int f = kAlpha - e - 1;
7327 const int k = (f * 78913) / (1 << 18) + (f > 0);
7329 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
7331 assert(index < kCachedPowersSize);
7332 static_cast<void>(kCachedPowersSize);
7335 assert(kAlpha <= cached.e + e + 64);
7336 assert(kGamma >= cached.e + e + 64);
7348 if (n >= 1000000000) {
7353 else if (n >= 100000000) {
7356 }
else if (n >= 10000000) {
7359 }
else if (n >= 1000000) {
7362 }
else if (n >= 100000) {
7365 }
else if (n >= 10000) {
7368 }
else if (n >= 1000) {
7371 }
else if (n >= 100) {
7374 }
else if (n >= 10) {
7383 inline void grisu2_round(
char *buf,
int len, uint64_t dist, uint64_t delta,
7384 uint64_t rest, uint64_t ten_k)
7387 assert(dist <= delta);
7388 assert(rest <= delta);
7411 and delta - rest >= ten_k
7412 and (rest + ten_k<dist or dist - rest> rest + ten_k - dist)) {
7413 assert(buf[len - 1] !=
'0');
7426 static_assert(kAlpha >= -60,
"internal error");
7427 static_assert(kGamma <= -32,
"internal error");
7441 assert(M_plus.e >= kAlpha);
7442 assert(M_plus.e <= kGamma);
7444 uint64_t delta = diyfp::sub(M_plus, M_minus).f;
7445 uint64_t dist = diyfp::sub(M_plus, w).f;
7454 const diyfp one(uint64_t { 1 } << -M_plus.e, M_plus.e);
7456 uint32_t p1 =
static_cast<uint32_t
>(M_plus.f >> -one.e);
7457 uint64_t p2 = M_plus.f & (one.f - 1);
7492 const uint32_t d = p1 / pow10;
7493 const uint32_t r = p1 % pow10;
7499 buffer[length++] =
static_cast<char>(
'0' + d);
7518 const uint64_t rest = (uint64_t { p1 } << -one.e) + p2;
7519 if (rest <= delta) {
7522 decimal_exponent += n;
7533 const uint64_t ten_n = uint64_t { pow10 } << -one.e;
7534 grisu2_round(buffer, length, dist, delta, rest, ten_n);
7594 assert(p2 <= UINT64_MAX / 10);
7596 const uint64_t d = p2 >> -one.e;
7597 const uint64_t r = p2 & (one.f - 1);
7604 buffer[length++] =
static_cast<char>(
'0' + d);
7628 decimal_exponent -= m;
7636 const uint64_t ten_m = one.f;
7637 grisu2_round(buffer, length, dist, delta, p2, ten_m);
7659 inline void grisu2(
char *buf,
int &len,
int &decimal_exponent,
7662 assert(m_plus.e == m_minus.e);
7663 assert(m_plus.e == v.e);
7676 const diyfp c_minus_k(cached.f, cached.e);
7679 const diyfp w = diyfp::mul(v, c_minus_k);
7680 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
7681 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
7704 const diyfp M_minus(w_minus.f + 1, w_minus.e);
7705 const diyfp M_plus(w_plus.f - 1, w_plus.e);
7707 decimal_exponent = -cached.k;
7717 template<
typename FloatType>
7718 void grisu2(
char *buf,
int &len,
int &decimal_exponent, FloatType value)
7720 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
7721 "internal error: not enough precision");
7723 assert(std::isfinite(value));
7748 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
7768 uint32_t k =
static_cast<uint32_t
>(e);
7773 *buf++ =
static_cast<char>(
'0' + k);
7774 }
else if (k < 100) {
7775 *buf++ =
static_cast<char>(
'0' + k / 10);
7777 *buf++ =
static_cast<char>(
'0' + k);
7779 *buf++ =
static_cast<char>(
'0' + k / 100);
7781 *buf++ =
static_cast<char>(
'0' + k / 10);
7783 *buf++ =
static_cast<char>(
'0' + k);
7799 int min_exp,
int max_exp)
7801 assert(min_exp < 0);
7802 assert(max_exp > 0);
7805 const int n = len + decimal_exponent;
7811 if (k <= n and n <= max_exp) {
7815 std::memset(buf + k,
'0', static_cast<size_t>(n - k));
7819 return buf + (n + 2);
7822 if (0 < n and n <= max_exp) {
7828 std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
7830 return buf + (k + 1);
7833 if (min_exp < n and n <= 0) {
7837 std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
7840 std::memset(buf + 2,
'0', static_cast<size_t>(-n));
7841 return buf + (2 + (-n) + k);
7853 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
7874 template<
typename FloatType>
7875 char *
to_chars(
char *first,
char *last, FloatType value)
7877 static_cast<void>(last);
7878 assert(std::isfinite(value));
7881 if (std::signbit(value)) {
7894 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
7901 int decimal_exponent = 0;
7904 assert(len <= std::numeric_limits<FloatType>::max_digits10);
7907 constexpr
int kMinExp = -4;
7909 constexpr
int kMaxExp = std::numeric_limits<FloatType>::digits10;
7911 assert(last - first >= kMaxExp + 2);
7912 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
7913 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
7938 template<
typename BasicJsonType>
7942 using string_t =
typename BasicJsonType::string_t;
7943 using number_float_t =
typename BasicJsonType::number_float_t;
7944 using number_integer_t =
typename BasicJsonType::number_integer_t;
7945 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
7946 static constexpr uint8_t UTF8_ACCEPT = 0;
7947 static constexpr uint8_t UTF8_REJECT = 1;
7955 : o(
std::move(s)), loc(
std::localeconv()),
7956 thousands_sep(loc->thousands_sep == nullptr ?
'\0' : *(loc->thousands_sep)), decimal_point(
7957 loc->decimal_point == nullptr ?
'\0' : *(loc->decimal_point)), indent_char(ichar), indent_string(
7982 void dump(
const BasicJsonType &val,
const bool pretty_print,
7983 const bool ensure_ascii,
7984 const unsigned int indent_step,
7985 const unsigned int current_indent = 0)
7987 switch (val.m_type) {
7990 if (val.m_value.object->empty()) {
7991 o->write_characters(
"{}", 2);
7996 o->write_characters(
"{\n", 2);
7999 const auto new_indent = current_indent + indent_step;
8000 if (JSON_UNLIKELY(indent_string.size() < new_indent)) {
8001 indent_string.resize(indent_string.size() * 2,
' ');
8005 auto i = val.m_value.object->cbegin();
8006 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) {
8007 o->write_characters(indent_string.c_str(), new_indent);
8008 o->write_character(
'\"');
8009 dump_escaped(i->first, ensure_ascii);
8010 o->write_characters(
"\": ", 3);
8011 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
8012 o->write_characters(
",\n", 2);
8016 assert(i != val.m_value.object->cend());
8017 assert(std::next(i) == val.m_value.object->cend());
8018 o->write_characters(indent_string.c_str(), new_indent);
8019 o->write_character(
'\"');
8020 dump_escaped(i->first, ensure_ascii);
8021 o->write_characters(
"\": ", 3);
8022 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
8024 o->write_character(
'\n');
8025 o->write_characters(indent_string.c_str(), current_indent);
8026 o->write_character(
'}');
8028 o->write_character(
'{');
8031 auto i = val.m_value.object->cbegin();
8032 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) {
8033 o->write_character(
'\"');
8034 dump_escaped(i->first, ensure_ascii);
8035 o->write_characters(
"\":", 2);
8036 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
8037 o->write_character(
',');
8041 assert(i != val.m_value.object->cend());
8042 assert(std::next(i) == val.m_value.object->cend());
8043 o->write_character(
'\"');
8044 dump_escaped(i->first, ensure_ascii);
8045 o->write_characters(
"\":", 2);
8046 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
8048 o->write_character(
'}');
8056 if (val.m_value.array->empty()) {
8057 o->write_characters(
"[]", 2);
8062 o->write_characters(
"[\n", 2);
8065 const auto new_indent = current_indent + indent_step;
8066 if (JSON_UNLIKELY(indent_string.size() < new_indent)) {
8067 indent_string.resize(indent_string.size() * 2,
' ');
8071 for (
auto i = val.m_value.array->cbegin();
8072 i != val.m_value.array->cend() - 1; ++i) {
8073 o->write_characters(indent_string.c_str(), new_indent);
8074 dump(*i,
true, ensure_ascii, indent_step, new_indent);
8075 o->write_characters(
",\n", 2);
8079 assert(not val.m_value.array->empty());
8080 o->write_characters(indent_string.c_str(), new_indent);
8081 dump(val.m_value.array->back(),
true, ensure_ascii, indent_step, new_indent);
8083 o->write_character(
'\n');
8084 o->write_characters(indent_string.c_str(), current_indent);
8085 o->write_character(
']');
8087 o->write_character(
'[');
8090 for (
auto i = val.m_value.array->cbegin();
8091 i != val.m_value.array->cend() - 1; ++i) {
8092 dump(*i,
false, ensure_ascii, indent_step, current_indent);
8093 o->write_character(
',');
8097 assert(not val.m_value.array->empty());
8098 dump(val.m_value.array->back(),
false, ensure_ascii, indent_step, current_indent);
8100 o->write_character(
']');
8108 o->write_character(
'\"');
8109 dump_escaped(*val.m_value.string, ensure_ascii);
8110 o->write_character(
'\"');
8116 if (val.m_value.boolean) {
8117 o->write_characters(
"true", 4);
8119 o->write_characters(
"false", 5);
8127 dump_integer(val.m_value.number_integer);
8133 dump_integer(val.m_value.number_unsigned);
8139 dump_float(val.m_value.number_float);
8145 o->write_characters(
"<discarded>", 11);
8151 o->write_characters(
"null", 4);
8172 void dump_escaped(
const string_t &s,
const bool ensure_ascii)
8175 uint8_t state = UTF8_ACCEPT;
8176 std::size_t bytes = 0;
8178 for (std::size_t i = 0; i < s.size(); ++i) {
8179 const auto byte =
static_cast<uint8_t
>(s[i]);
8181 switch (decode(state, codepoint, byte)) {
8184 switch (codepoint) {
8187 string_buffer[bytes++] =
'\\';
8188 string_buffer[bytes++] =
'b';
8194 string_buffer[bytes++] =
'\\';
8195 string_buffer[bytes++] =
't';
8201 string_buffer[bytes++] =
'\\';
8202 string_buffer[bytes++] =
'n';
8208 string_buffer[bytes++] =
'\\';
8209 string_buffer[bytes++] =
'f';
8215 string_buffer[bytes++] =
'\\';
8216 string_buffer[bytes++] =
'r';
8222 string_buffer[bytes++] =
'\\';
8223 string_buffer[bytes++] =
'\"';
8229 string_buffer[bytes++] =
'\\';
8230 string_buffer[bytes++] =
'\\';
8238 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F))) {
8239 if (codepoint <= 0xFFFF) {
8240 std::snprintf(string_buffer.data() + bytes, 7,
"\\u%04x",
8241 static_cast<uint16_t
>(codepoint));
8244 std::snprintf(string_buffer.data() + bytes, 13,
"\\u%04x\\u%04x",
8245 static_cast<uint16_t
>(0xD7C0 + (codepoint >> 10)),
8246 static_cast<uint16_t
>(0xDC00 + (codepoint & 0x3FF)));
8252 string_buffer[bytes++] = s[i];
8262 if (string_buffer.size() - bytes < 13) {
8263 o->write_characters(string_buffer.data(), bytes);
8272 std::stringstream ss;
8273 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex <<
8274 static_cast<int>(byte);
8275 JSON_THROW(type_error::create(316,
8276 "invalid UTF-8 byte at index " + std::to_string(i) +
": 0x" +
8282 if (not ensure_ascii) {
8284 string_buffer[bytes++] = s[i];
8292 if (JSON_LIKELY(state == UTF8_ACCEPT)) {
8295 o->write_characters(string_buffer.data(), bytes);
8299 std::stringstream ss;
8300 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex <<
8301 static_cast<int>(
static_cast<uint8_t
>(s.back()));
8302 JSON_THROW(type_error::create(316,
"incomplete UTF-8 string; last byte: 0x" + ss.str()));
8315 template<
typename NumberType, detail::enable_if_t<
8316 std::is_same<NumberType, number_unsigned_t>::value or
8317 std::is_same<NumberType, number_integer_t>::value,
8319 void dump_integer(NumberType x)
8323 o->write_character(
'0');
8327 const bool is_negative = (x <= 0) and (x != 0);
8332 assert(i < number_buffer.size() - 1);
8334 const auto digit = std::labs(static_cast<long>(x % 10));
8335 number_buffer[i++] =
static_cast<char>(
'0' + digit);
8341 assert(i < number_buffer.size() - 2);
8342 number_buffer[i++] =
'-';
8345 std::reverse(number_buffer.begin(), number_buffer.begin() + i);
8346 o->write_characters(number_buffer.data(), i);
8357 void dump_float(number_float_t x)
8360 if (not std::isfinite(x)) {
8361 o->write_characters(
"null", 4);
8370 static constexpr
bool is_ieee_single_or_double
8371 = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits
8372 == 24 and std::numeric_limits<number_float_t>::max_exponent == 128) or
8373 (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::
8374 digits == 53 and std::numeric_limits<number_float_t>::max_exponent == 1024);
8376 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
8379 void dump_float(number_float_t x, std::true_type )
8381 char *begin = number_buffer.data();
8382 char *end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
8384 o->write_characters(begin, static_cast<size_t>(end - begin));
8387 void dump_float(number_float_t x, std::false_type )
8390 static constexpr
auto d = std::numeric_limits<number_float_t>::max_digits10;
8393 std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(),
"%.*g", d, x);
8398 assert(static_cast<std::size_t>(len) < number_buffer.size());
8401 if (thousands_sep !=
'\0') {
8402 const auto end = std::remove(number_buffer.begin(),
8403 number_buffer.begin() + len, thousands_sep);
8404 std::fill(end, number_buffer.end(),
'\0');
8405 assert((end - number_buffer.begin()) <= len);
8406 len = (end - number_buffer.begin());
8410 if (decimal_point !=
'\0' and decimal_point !=
'.') {
8411 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
8412 if (dec_pos != number_buffer.end()) {
8417 o->write_characters(number_buffer.data(),
static_cast<std::size_t
>(len));
8420 const bool value_is_int_like =
8421 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
8423 return (c ==
'.' or c ==
'e');
8426 if (value_is_int_like) {
8427 o->write_characters(
".0", 2);
8452 static uint8_t decode(uint8_t &state, uint32_t &codep,
const uint8_t byte) noexcept
8454 static const std::array<uint8_t, 400> utf8d =
8457 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,
8459 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,
8461 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,
8463 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,
8465 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,
8467 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,
8469 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,
8471 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
8472 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
8473 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
8474 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,
8476 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,
8478 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,
8480 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
8484 const uint8_t type = utf8d[byte];
8486 codep = (state != UTF8_ACCEPT)
8487 ? (byte & 0x3fu) | (codep << 6)
8488 : static_cast<uint32_t>(0xff >> type) & (byte);
8490 state = utf8d[256u + state * 16u + type];
8499 std::array<char, 64> number_buffer { {} };
8502 const std::lconv *loc =
nullptr;
8504 const char thousands_sep =
'\0';
8506 const char decimal_point =
'\0';
8509 std::array<char, 512> string_buffer { {} };
8512 const char indent_char;
8514 string_t indent_string;
8523 #include <initializer_list> 8530 template<
typename BasicJsonType>
8535 using value_type = BasicJsonType;
8538 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(
true)
8542 : value_ref(const_cast<value_type *>(&value)), is_rvalue(
false)
8545 json_ref(std::initializer_list<json_ref> init)
8546 : owned_value(init), value_ref(&owned_value), is_rvalue(
true)
8549 template<
class... Args>
8551 : owned_value(std::forward<Args>(args) ...), value_ref(&owned_value), is_rvalue(
true)
8555 json_ref(json_ref &&) =
default;
8556 json_ref(
const json_ref &) =
delete;
8557 json_ref &operator=(
const json_ref &) =
delete;
8559 value_type moved_or_copied()
const 8562 return std::move(*value_ref);
8568 value_type
const &operator*()
const 8570 return *
static_cast<value_type
const *
>(value_ref);
8573 value_type
const *operator->()
const 8575 return static_cast<value_type
const *
>(value_ref);
8579 mutable value_type owned_value =
nullptr;
8580 value_type *value_ref =
nullptr;
8581 const bool is_rvalue;
8604 template<
typename BasicJsonType>
8609 NLOHMANN_BASIC_JSON_TPL_DECLARATION
8635 : reference_tokens(split(s))
8655 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
8658 return a +
"/" + escape(b);
8677 std::size_t processed_chars = 0;
8678 const int res = std::stoi(s, &processed_chars);
8681 if (JSON_UNLIKELY(processed_chars != s.size())) {
8682 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + s +
"'"));
8695 if (JSON_UNLIKELY(is_root())) {
8696 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
8699 auto last = reference_tokens.back();
8700 reference_tokens.pop_back();
8705 bool is_root()
const 8707 return reference_tokens.empty();
8712 if (JSON_UNLIKELY(is_root())) {
8713 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
8717 result.reference_tokens = { reference_tokens[0] };
8729 BasicJsonType &get_and_create(BasicJsonType &j)
const 8731 using size_type =
typename BasicJsonType::size_type;
8736 for (
const auto &reference_token : reference_tokens) {
8737 switch (result->m_type) {
8740 if (reference_token ==
"0") {
8742 result = &result->operator[](0);
8745 result = &result->operator[](reference_token);
8754 result = &result->operator[](reference_token);
8763 result = &result->operator[](
static_cast<size_type
>(array_index(reference_token)));
8765 JSON_CATCH(std::invalid_argument &)
8768 "array index '" + reference_token +
8769 "' is not a number"));
8780 JSON_THROW(detail::type_error::create(313,
"invalid value to unflatten"));
8806 BasicJsonType &get_unchecked(BasicJsonType *ptr)
const 8808 using size_type =
typename BasicJsonType::size_type;
8809 for (
const auto &reference_token : reference_tokens) {
8814 std::all_of(reference_token.begin(), reference_token.end(),
8816 return (x >=
'0' and x <=
'9');
8820 *ptr = (nums or reference_token ==
"-")
8825 switch (ptr->m_type) {
8829 ptr = &ptr->operator[](reference_token);
8836 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0')) {
8838 "array index '" + reference_token +
8839 "' must not begin with '0'"));
8842 if (reference_token ==
"-") {
8844 ptr = &ptr->operator[](ptr->m_value.array->size());
8849 ptr = &ptr->operator[](
8850 static_cast<size_type
>(array_index(reference_token)));
8852 JSON_CATCH(std::invalid_argument &)
8855 "array index '" + reference_token +
8856 "' is not a number"));
8864 JSON_THROW(detail::out_of_range::create(404,
8865 "unresolved reference token '" + reference_token +
8879 BasicJsonType &get_checked(BasicJsonType *ptr)
const 8881 using size_type =
typename BasicJsonType::size_type;
8882 for (
const auto &reference_token : reference_tokens) {
8883 switch (ptr->m_type) {
8887 ptr = &ptr->at(reference_token);
8893 if (JSON_UNLIKELY(reference_token ==
"-")) {
8895 JSON_THROW(detail::out_of_range::create(402,
8896 "array index '-' (" +
8897 std::to_string(ptr->m_value.array->size()) +
8898 ") is out of range"));
8902 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0')) {
8904 "array index '" + reference_token +
8905 "' must not begin with '0'"));
8911 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
8913 JSON_CATCH(std::invalid_argument &)
8916 "array index '" + reference_token +
8917 "' is not a number"));
8923 JSON_THROW(detail::out_of_range::create(404,
8924 "unresolved reference token '" + reference_token +
8945 const BasicJsonType &get_unchecked(
const BasicJsonType *ptr)
const 8947 using size_type =
typename BasicJsonType::size_type;
8948 for (
const auto &reference_token : reference_tokens) {
8949 switch (ptr->m_type) {
8953 ptr = &ptr->operator[](reference_token);
8959 if (JSON_UNLIKELY(reference_token ==
"-")) {
8961 JSON_THROW(detail::out_of_range::create(402,
8962 "array index '-' (" +
8963 std::to_string(ptr->m_value.array->size()) +
8964 ") is out of range"));
8968 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0')) {
8970 "array index '" + reference_token +
8971 "' must not begin with '0'"));
8977 ptr = &ptr->operator[](
8978 static_cast<size_type
>(array_index(reference_token)));
8980 JSON_CATCH(std::invalid_argument &)
8983 "array index '" + reference_token +
8984 "' is not a number"));
8990 JSON_THROW(detail::out_of_range::create(404,
8991 "unresolved reference token '" + reference_token +
9005 const BasicJsonType &get_checked(
const BasicJsonType *ptr)
const 9007 using size_type =
typename BasicJsonType::size_type;
9008 for (
const auto &reference_token : reference_tokens) {
9009 switch (ptr->m_type) {
9013 ptr = &ptr->at(reference_token);
9019 if (JSON_UNLIKELY(reference_token ==
"-")) {
9021 JSON_THROW(detail::out_of_range::create(402,
9022 "array index '-' (" +
9023 std::to_string(ptr->m_value.array->size()) +
9024 ") is out of range"));
9028 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0')) {
9030 "array index '" + reference_token +
9031 "' must not begin with '0'"));
9037 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
9039 JSON_CATCH(std::invalid_argument &)
9042 "array index '" + reference_token +
9043 "' is not a number"));
9049 JSON_THROW(detail::out_of_range::create(404,
9050 "unresolved reference token '" + reference_token +
9067 static std::vector<std::string> split(
const std::string &reference_string)
9069 std::vector<std::string> result;
9072 if (reference_string.empty()) {
9077 if (JSON_UNLIKELY(reference_string[0] !=
'/')) {
9079 "JSON pointer must be empty or begin with '/' - was: '" +
9080 reference_string +
"'"));
9088 std::size_t slash = reference_string.find_first_of(
'/', 1),
9097 slash = reference_string.find_first_of(
'/', start)) {
9100 auto reference_token = reference_string.substr(start, slash - start);
9103 for (std::size_t pos = reference_token.find_first_of(
'~');
9104 pos != std::string::npos;
9105 pos = reference_token.find_first_of(
'~', pos + 1)) {
9106 assert(reference_token[pos] ==
'~');
9109 if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
9110 (reference_token[pos + 1] !=
'0' and
9111 reference_token[pos + 1] !=
'1'))) {
9113 "escape character '~' must be followed with '0' or '1'"));
9118 unescape(reference_token);
9119 result.push_back(reference_token);
9141 assert(not f.empty());
9142 for (
auto pos = s.find(f);
9143 pos != std::string::npos;
9144 s.replace(pos, f.size(), t),
9145 pos = s.find(f, pos + t.size()))
9152 replace_substring(s,
"~",
"~0");
9153 replace_substring(s,
"/",
"~1");
9160 replace_substring(s,
"~1",
"/");
9161 replace_substring(s,
"~0",
"~");
9171 static void flatten(
const std::string &reference_string,
9172 const BasicJsonType &value,
9173 BasicJsonType &result)
9175 switch (value.m_type) {
9178 if (value.m_value.array->empty()) {
9180 result[reference_string] =
nullptr;
9183 for (std::size_t i = 0; i < value.m_value.array->size(); ++i) {
9184 flatten(reference_string +
"/" + std::to_string(i),
9185 value.m_value.array->operator[](i), result);
9194 if (value.m_value.object->empty()) {
9196 result[reference_string] =
nullptr;
9199 for (
const auto &element : *value.m_value.object) {
9200 flatten(reference_string +
"/" + escape(element.first), element.second, result);
9210 result[reference_string] = value;
9226 static BasicJsonType
9227 unflatten(
const BasicJsonType &value)
9229 if (JSON_UNLIKELY(not value.is_object())) {
9230 JSON_THROW(detail::type_error::create(314,
"only objects can be unflattened"));
9233 BasicJsonType result;
9236 for (
const auto &element : *value.m_value.object) {
9237 if (JSON_UNLIKELY(not element.second.is_primitive())) {
9238 JSON_THROW(detail::type_error::create(315,
"values in object must be primitive"));
9245 json_pointer(element.first).get_and_create(result) = element.second;
9254 return (lhs.reference_tokens == rhs.reference_tokens);
9260 return not (lhs == rhs);
9264 std::vector<std::string> reference_tokens;
9281 template<
typename,
typename>
9293 template<
typename BasicJsonType,
typename ValueType>
9294 static void from_json(BasicJsonType &&j, ValueType &val) noexcept (
9295 noexcept (::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
9297 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
9309 template<
typename BasicJsonType,
typename ValueType>
9310 static void to_json(BasicJsonType &j, ValueType &&val) noexcept (
9311 noexcept (::nlohmann::to_json(j, std::forward<ValueType>(val))))
9313 ::nlohmann::to_json(j, std::forward<ValueType>(val));
9409 NLOHMANN_BASIC_JSON_TPL_DECLARATION
9415 friend ::nlohmann::json_pointer<basic_json>;
9416 friend ::nlohmann::detail::parser<basic_json>;
9417 friend ::nlohmann::detail::serializer<basic_json>;
9418 template<
typename BasicJsonType>
9419 friend class ::nlohmann::detail::iter_impl;
9420 template<
typename BasicJsonType,
typename CharType>
9421 friend class ::nlohmann::detail::binary_writer;
9422 template<
typename BasicJsonType>
9423 friend class ::nlohmann::detail::binary_reader;
9426 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
9433 template<
typename BasicJsonType>
9435 template<
typename BasicJsonType>
9437 template<
typename Iterator>
9441 template<
typename CharType>
9453 template<
typename T,
typename SFINAE>
9508 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
9510 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
9562 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
9563 result[
"name"] =
"JSON for Modern C++";
9564 result[
"url"] =
"https://github.com/nlohmann/json";
9565 result[
"version"][
"string"] =
9566 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) +
"." +
9567 std::to_string(NLOHMANN_JSON_VERSION_MINOR) +
"." +
9568 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
9569 result[
"version"][
"major"] = NLOHMANN_JSON_VERSION_MAJOR;
9570 result[
"version"][
"minor"] = NLOHMANN_JSON_VERSION_MINOR;
9571 result[
"version"][
"patch"] = NLOHMANN_JSON_VERSION_PATCH;
9574 result[
"platform"] =
"win32";
9575 #elif defined __linux__ 9576 result[
"platform"] =
"linux";
9577 #elif defined __APPLE__ 9578 result[
"platform"] =
"apple";
9579 #elif defined __unix__ 9580 result[
"platform"] =
"unix";
9582 result[
"platform"] =
"unknown";
9585 #if defined(__ICC) || defined(__INTEL_COMPILER) 9586 result[
"compiler"] = { {
"family",
"icc" }, {
"version", __INTEL_COMPILER } };
9587 #elif defined(__clang__) 9588 result[
"compiler"] = { {
"family",
"clang" }, {
"version", __clang_version__ } };
9589 #elif defined(__GNUC__) || defined(__GNUG__) 9590 result[
"compiler"] =
9591 { {
"family",
"gcc" },
9593 std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(
9594 __GNUC_PATCHLEVEL__) } };
9595 #elif defined(__HP_cc) || defined(__HP_aCC) 9596 result[
"compiler"] =
"hp" 9597 #elif defined(__IBMCPP__) 9598 result[
"compiler"] = { {
"family",
"ilecpp" }, {
"version", __IBMCPP__ } };
9599 #elif defined(_MSC_VER) 9600 result[
"compiler"] = { {
"family",
"msvc" }, {
"version", _MSC_VER } };
9601 #elif defined(__PGI) 9602 result[
"compiler"] = { {
"family",
"pgcpp" }, {
"version", __PGI } };
9603 #elif defined(__SUNPRO_CC) 9604 result[
"compiler"] = { {
"family",
"sunpro" }, {
"version", __SUNPRO_CC } };
9606 result[
"compiler"] = { {
"family",
"unknown" }, {
"version",
"unknown" } };
9610 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
9612 result[
"compiler"][
"c++"] =
"unknown";
9627 #if defined(JSON_HAS_CPP_14) 9630 using object_comparator_t = std::less<>;
9632 using object_comparator_t = std::less<StringType>;
9718 using object_t = ObjectType<StringType,
9720 object_comparator_t,
9721 AllocatorType<std::pair<
const StringType,
9768 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
10065 template<
typename T,
typename... Args>
10066 static T *create(Args && ... args)
10068 AllocatorType<T> alloc;
10069 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
10071 auto deleter = [&](T *
object) {
10072 AllocatorTraits::deallocate(alloc,
object, 1);
10074 std::unique_ptr<T, decltype(deleter)>
object(AllocatorTraits::allocate(alloc, 1), deleter);
10075 AllocatorTraits::construct(alloc,
object.
get(), std::forward<Args>(args) ...);
10076 assert(
object !=
nullptr);
10077 return object.release();
10126 json_value() =
default;
10141 object = create<object_t>();
10147 array = create<array_t>();
10153 string = create<string_t>(
"");
10191 JSON_THROW(other_error::create(500,
"961c151d2e87f2686a955a9be24d316f1362bf21 3.1.1"));
10202 string = create<string_t>(value);
10208 string = create<string_t>(std::move(value));
10214 object = create<object_t>(value);
10220 object = create<object_t>(std::move(value));
10224 json_value(
const array_t &value)
10226 array = create<array_t>(value);
10232 array = create<array_t>(std::move(value));
10235 void destroy(
value_t t) noexcept
10240 AllocatorType<object_t> alloc;
10241 std::allocator_traits<decltype(alloc)>::destroy(alloc,
object);
10242 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
object, 1);
10248 AllocatorType<array_t> alloc;
10249 std::allocator_traits<decltype(alloc)>::destroy(alloc,
array);
10250 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
array, 1);
10256 AllocatorType<string_t> alloc;
10257 std::allocator_traits<decltype(alloc)>::destroy(alloc,
string);
10258 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
string, 1);
10279 void assert_invariant()
const noexcept
10399 : m_type(v), m_value(v)
10401 assert_invariant();
10425 assert_invariant();
10484 template<
typename CompatibleType,
10485 typename U = detail::uncvref_t<CompatibleType>,
10486 detail::enable_if_t<
10489 JSONSerializer<U>::to_json(std::declval<basic_json_t &>(),
10490 std::forward<CompatibleType>(val))))
10492 JSONSerializer<U>::to_json(*
this, std::forward<CompatibleType>(val));
10493 assert_invariant();
10571 bool type_deduction =
true,
10576 bool is_an_object = std::all_of(init.begin(), init.end(),
10578 return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
10582 if (not type_deduction) {
10585 is_an_object =
false;
10589 if (JSON_UNLIKELY(manual_type ==
value_t::object and not is_an_object)) {
10590 JSON_THROW(type_error::create(301,
"cannot create object from initializer list"));
10594 if (is_an_object) {
10600 auto element = element_ref.moved_or_copied();
10601 m_value.object->emplace(
10602 std::move(*((*element.m_value.array)[0].m_value.string)),
10603 std::move((*element.m_value.array)[1]));
10608 m_value.array = create<array_t>(init.begin(), init.end());
10611 assert_invariant();
10724 m_value.array = create<array_t>(cnt, val);
10725 assert_invariant();
10783 template<
class InputIT,
typename std::enable_if<
10784 std::is_same<InputIT, typename basic_json_t::iterator>::value or
10785 std::is_same<InputIT, typename basic_json_t::const_iterator>::value,
int>::type = 0>
10788 assert(first.m_object !=
nullptr);
10789 assert(last.m_object !=
nullptr);
10792 if (JSON_UNLIKELY(first.m_object != last.m_object)) {
10793 JSON_THROW(invalid_iterator::create(201,
"iterators are not compatible"));
10797 m_type = first.m_object->m_type;
10807 if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
10808 or not last.m_it.primitive_iterator.is_end())) {
10809 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
10822 m_value.number_integer = first.m_object->m_value.number_integer;
10828 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
10834 m_value.number_float = first.m_object->m_value.number_float;
10840 m_value.boolean = first.m_object->m_value.boolean;
10846 m_value = *first.m_object->m_value.string;
10852 m_value.object = create<object_t>(first.m_it.object_iterator,
10853 last.m_it.object_iterator);
10859 m_value.array = create<array_t>(first.m_it.array_iterator,
10860 last.m_it.array_iterator);
10865 JSON_THROW(invalid_iterator::create(206,
"cannot construct with iterators from " +
10869 assert_invariant();
10879 : basic_json(ref.moved_or_copied())
10908 : m_type(other.m_type)
10911 other.assert_invariant();
10916 m_value = *other.m_value.object;
10922 m_value = *other.m_value.array;
10928 m_value = *other.m_value.string;
10934 m_value = other.m_value.boolean;
10940 m_value = other.m_value.number_integer;
10946 m_value = other.m_value.number_unsigned;
10952 m_value = other.m_value.number_float;
10960 assert_invariant();
10990 : m_type(std::move(other.m_type)), m_value(std::move(other.m_value))
10993 other.assert_invariant();
10997 other.m_value = {};
10999 assert_invariant();
11026 std::is_nothrow_move_constructible<value_t>::value and
11027 std::is_nothrow_move_assignable<value_t>::value and
11028 std::is_nothrow_move_constructible<json_value>::value and
11029 std::is_nothrow_move_assignable<json_value>::value
11033 other.assert_invariant();
11036 swap(m_type, other.m_type);
11037 swap(m_value, other.m_value);
11039 assert_invariant();
11060 assert_invariant();
11061 m_value.destroy(m_type);
11112 const bool ensure_ascii =
false)
const 11118 s.
dump(*
this,
true, ensure_ascii, static_cast<unsigned int>(indent));
11120 s.
dump(*
this,
false, ensure_ascii, 0);
11190 return is_null() or is_string() or is_boolean() or is_number();
11217 return is_array() or is_object();
11291 return is_number_integer() or is_number_float();
11508 if (JSON_LIKELY(is_boolean())) {
11509 return m_value.boolean;
11512 JSON_THROW(type_error::create(302,
"type must be boolean, but is " +
std::string(type_name())));
11518 return is_object() ? m_value.object :
nullptr;
11524 return is_object() ? m_value.object :
nullptr;
11530 return is_array() ? m_value.array :
nullptr;
11534 constexpr
const array_t *get_impl_ptr(
const array_t * )
const noexcept
11536 return is_array() ? m_value.array :
nullptr;
11542 return is_string() ? m_value.string :
nullptr;
11548 return is_string() ? m_value.string :
nullptr;
11554 return is_boolean() ? &m_value.boolean :
nullptr;
11560 return is_boolean() ? &m_value.boolean :
nullptr;
11566 return is_number_integer() ? &m_value.number_integer :
nullptr;
11572 return is_number_integer() ? &m_value.number_integer :
nullptr;
11578 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
11584 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
11590 return is_number_float() ? &m_value.number_float :
nullptr;
11596 return is_number_float() ? &m_value.number_float :
nullptr;
11610 template<
typename ReferenceType,
typename ThisType>
11611 static ReferenceType get_ref_impl(ThisType &obj)
11614 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
11616 if (JSON_LIKELY(ptr !=
nullptr)) {
11620 JSON_THROW(type_error::create(303,
11621 "incompatible ReferenceType for get_ref, actual type is " +
11644 template<
typename BasicJsonType, detail::enable_if_t<
11645 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
11647 basic_json
get()
const 11691 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
11692 detail::enable_if_t<
11693 not std::is_same<basic_json_t, ValueType>::value and
11694 detail::has_from_json<basic_json_t, ValueType>::value and
11695 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
11697 ValueType
get()
const noexcept (noexcept (
11698 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t &>(),
11699 std::declval<ValueType &>())))
11704 static_assert(not std::is_reference<ValueTypeCV>::value,
11705 "get() cannot be used with reference types, you might want to use get_ref()");
11706 static_assert(std::is_default_constructible<ValueType>::value,
11707 "types must be DefaultConstructible when used with get()");
11710 JSONSerializer<ValueType>::from_json(*
this, ret);
11745 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
11746 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
11747 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
11749 ValueType
get()
const noexcept (noexcept (
11750 JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t &>())))
11752 static_assert(not std::is_reference<ValueTypeCV>::value,
11753 "get() cannot be used with reference types, you might want to use get_ref()");
11754 return JSONSerializer<ValueTypeCV>::from_json(*
this);
11784 template<
typename PointerType,
typename std::enable_if<
11785 std::is_pointer<PointerType>::value,
int>::type = 0>
11786 PointerType
get() noexcept
11789 return get_ptr<PointerType>();
11796 template<
typename PointerType,
typename std::enable_if<
11797 std::is_pointer<PointerType>::value,
int>::type = 0>
11798 constexpr
const PointerType
get()
const noexcept
11801 return get_ptr<PointerType>();
11830 template<
typename PointerType,
typename std::enable_if<
11831 std::is_pointer<PointerType>::value,
int>::type = 0>
11835 using pointee_t =
typename std::remove_const<
typename 11836 std::remove_pointer<
typename 11837 std::remove_const<PointerType>::type>::type>
11841 std::is_same<object_t, pointee_t>::value
11842 or std::is_same<array_t, pointee_t>::value
11843 or std::is_same<string_t, pointee_t>::value
11844 or std::is_same<boolean_t, pointee_t>::value
11845 or std::is_same<number_integer_t, pointee_t>::value
11846 or std::is_same<number_unsigned_t, pointee_t>::value
11847 or std::is_same<number_float_t, pointee_t>::value
11848 ,
"incompatible pointer type");
11851 return get_impl_ptr(static_cast<PointerType>(
nullptr));
11858 template<
typename PointerType,
typename std::enable_if<
11859 std::is_pointer<PointerType>::value and
11860 std::is_const<typename std::remove_pointer<PointerType>::type>::value,
int>::type = 0>
11864 using pointee_t =
typename std::remove_const<
typename 11865 std::remove_pointer<
typename 11866 std::remove_const<PointerType>::type>::type>
11870 std::is_same<object_t, pointee_t>::value
11871 or std::is_same<array_t, pointee_t>::value
11872 or std::is_same<string_t, pointee_t>::value
11873 or std::is_same<boolean_t, pointee_t>::value
11874 or std::is_same<number_integer_t, pointee_t>::value
11875 or std::is_same<number_unsigned_t, pointee_t>::value
11876 or std::is_same<number_float_t, pointee_t>::value
11877 ,
"incompatible pointer type");
11880 return get_impl_ptr(static_cast<PointerType>(
nullptr));
11909 template<
typename ReferenceType,
typename std::enable_if<
11910 std::is_reference<ReferenceType>::value,
int>::type = 0>
11914 return get_ref_impl<ReferenceType>(*this);
11921 template<
typename ReferenceType,
typename std::enable_if<
11922 std::is_reference<ReferenceType>::value and
11923 std::is_const<typename std::remove_reference<ReferenceType>::type>::value,
int>::type = 0>
11927 return get_ref_impl<ReferenceType>(*this);
11959 template<
typename ValueType,
typename std::enable_if<
11960 not std::is_pointer<ValueType>::value and
11961 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
11962 not std::is_same<ValueType, typename string_t::value_type>::value
11963 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015 11964 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
11966 #if defined(JSON_HAS_CPP_17) 11967 and not std::is_same<ValueType, typename std::string_view>::value
11970 operator ValueType()
const 11973 return get<ValueType>();
12016 if (JSON_LIKELY(is_array())) {
12019 return m_value.array->at(idx);
12021 JSON_CATCH(std::out_of_range &)
12024 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(
12025 idx) +
" is out of range"));
12028 JSON_THROW(type_error::create(304,
"cannot use at() with " +
std::string(type_name())));
12061 if (JSON_LIKELY(is_array())) {
12064 return m_value.array->at(idx);
12066 JSON_CATCH(std::out_of_range &)
12069 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(
12070 idx) +
" is out of range"));
12073 JSON_THROW(type_error::create(304,
"cannot use at() with " +
std::string(type_name())));
12110 if (JSON_LIKELY(is_object())) {
12113 return m_value.object->at(key);
12115 JSON_CATCH(std::out_of_range &)
12118 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
12121 JSON_THROW(type_error::create(304,
"cannot use at() with " +
std::string(type_name())));
12158 if (JSON_LIKELY(is_object())) {
12161 return m_value.object->at(key);
12163 JSON_CATCH(std::out_of_range &)
12166 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
12169 JSON_THROW(type_error::create(304,
"cannot use at() with " +
std::string(type_name())));
12203 m_value.array = create<array_t>();
12204 assert_invariant();
12208 if (JSON_LIKELY(is_array())) {
12210 if (idx >= m_value.array->size()) {
12211 m_value.array->insert(m_value.array->end(),
12212 idx - m_value.array->size() + 1,
12216 return m_value.array->operator[](idx);
12219 JSON_THROW(type_error::create(305,
"cannot use operator[] with " +
std::string(type_name())));
12244 if (JSON_LIKELY(is_array())) {
12245 return m_value.
array->operator[](idx);
12248 JSON_THROW(type_error::create(305,
"cannot use operator[] with " +
std::string(type_name())));
12283 m_value.object = create<object_t>();
12284 assert_invariant();
12288 if (JSON_LIKELY(is_object())) {
12289 return m_value.object->operator[](key);
12292 JSON_THROW(type_error::create(305,
"cannot use operator[] with " +
std::string(type_name())));
12328 if (JSON_LIKELY(is_object())) {
12329 assert(m_value.object->find(key) != m_value.object->end());
12333 JSON_THROW(type_error::create(305,
"cannot use operator[] with " +
std::string(type_name())));
12363 template<
typename T>
12370 assert_invariant();
12374 if (JSON_LIKELY(is_object())) {
12375 return m_value.object->operator[](key);
12378 JSON_THROW(type_error::create(305,
"cannot use operator[] with " +
std::string(type_name())));
12411 template<
typename T>
12415 if (JSON_LIKELY(is_object())) {
12416 assert(m_value.object->find(key) != m_value.object->end());
12420 JSON_THROW(type_error::create(305,
"cannot use operator[] with " +
std::string(type_name())));
12471 template<
class ValueType,
typename std::enable_if<
12472 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
12473 ValueType
value(
const typename object_t::key_type &key,
const ValueType &default_value)
const 12476 if (JSON_LIKELY(is_object())) {
12478 const auto it = find(key);
12483 return default_value;
12486 JSON_THROW(type_error::create(306,
"cannot use value() with " +
std::string(type_name())));
12493 string_t value(
const typename object_t::key_type &key,
const char *default_value)
const 12495 return value(key,
string_t(default_value));
12539 template<
class ValueType,
typename std::enable_if<
12540 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
12544 if (JSON_LIKELY(is_object())) {
12548 return ptr.get_checked(
this);
12552 return default_value;
12556 JSON_THROW(type_error::create(306,
"cannot use value() with " +
std::string(type_name())));
12565 return value(ptr,
string_t(default_value));
12700 template<
class IteratorType,
typename std::enable_if<
12701 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
12702 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>::type
12707 if (JSON_UNLIKELY(
this != pos.m_object)) {
12708 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
12711 IteratorType result = end();
12720 if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin())) {
12721 JSON_THROW(invalid_iterator::create(205,
"iterator out of range"));
12725 AllocatorType<string_t> alloc;
12726 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
12727 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
12728 m_value.string =
nullptr;
12732 assert_invariant();
12738 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
12744 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
12749 JSON_THROW(type_error::create(307,
"cannot use erase() with " +
std::string(type_name())));
12801 template<
class IteratorType,
typename std::enable_if<
12802 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
12803 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>::type
12805 IteratorType
erase(IteratorType first, IteratorType last)
12808 if (JSON_UNLIKELY(
this != first.m_object or
this != last.m_object)) {
12809 JSON_THROW(invalid_iterator::create(203,
"iterators do not fit current value"));
12812 IteratorType result = end();
12821 if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
12822 or not last.m_it.primitive_iterator.is_end())) {
12823 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
12827 AllocatorType<string_t> alloc;
12828 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
12829 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
12830 m_value.string =
nullptr;
12834 assert_invariant();
12840 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
12841 last.m_it.object_iterator);
12847 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
12848 last.m_it.array_iterator);
12853 JSON_THROW(type_error::create(307,
"cannot use erase() with " +
std::string(type_name())));
12891 if (JSON_LIKELY(is_object())) {
12892 return m_value.object->erase(key);
12895 JSON_THROW(type_error::create(307,
"cannot use erase() with " +
std::string(type_name())));
12925 if (JSON_LIKELY(is_array())) {
12926 if (JSON_UNLIKELY(idx >= size())) {
12927 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(
12928 idx) +
" is out of range"));
12931 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
12933 JSON_THROW(type_error::create(307,
"cannot use erase() with " +
std::string(type_name())));
12969 template<
typename KeyT>
12972 auto result = end();
12975 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
12985 template<
typename KeyT>
12988 auto result = cend();
12991 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
13018 template<
typename KeyT>
13022 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
13062 result.set_begin();
13102 result.set_begin();
13369 return ref.items();
13378 return ref.items();
13509 return m_value.array->empty();
13515 return m_value.object->empty();
13580 return m_value.array->size();
13586 return m_value.object->size();
13643 return m_value.array->max_size();
13649 return m_value.object->max_size();
13711 m_value.number_integer = 0;
13717 m_value.number_unsigned = 0;
13723 m_value.number_float = 0.0;
13729 m_value.boolean =
false;
13735 m_value.string->clear();
13741 m_value.array->clear();
13747 m_value.object->clear();
13779 if (JSON_UNLIKELY(not (is_null() or is_array()))) {
13780 JSON_THROW(type_error::create(308,
"cannot use push_back() with " +
std::string(type_name())));
13787 assert_invariant();
13791 m_value.array->push_back(std::move(val));
13802 push_back(std::move(val));
13813 if (JSON_UNLIKELY(not (is_null() or is_array()))) {
13814 JSON_THROW(type_error::create(308,
"cannot use push_back() with " +
std::string(type_name())));
13821 assert_invariant();
13825 m_value.array->push_back(val);
13861 if (JSON_UNLIKELY(not (is_null() or is_object()))) {
13862 JSON_THROW(type_error::create(308,
"cannot use push_back() with " +
std::string(type_name())));
13869 assert_invariant();
13873 m_value.object->insert(val);
13913 if (is_object() and init.size() == 2 and (*init.begin())->is_string()) {
13914 basic_json &&key = init.begin()->moved_or_copied();
13915 push_back(
typename object_t::value_type(
13916 std::move(key.
get_ref<
string_t &>()), (init.begin() + 1)->moved_or_copied()));
13918 push_back(basic_json(init));
13953 template<
class... Args>
13957 if (JSON_UNLIKELY(not (is_null() or is_array()))) {
13958 JSON_THROW(type_error::create(311,
"cannot use emplace_back() with " +
std::string(type_name())));
13965 assert_invariant();
13969 m_value.array->emplace_back(std::forward<Args>(args) ...);
13999 template<
class... Args>
14003 if (JSON_UNLIKELY(not (is_null() or is_object()))) {
14004 JSON_THROW(type_error::create(311,
"cannot use emplace() with " +
std::string(type_name())));
14011 assert_invariant();
14015 auto res = m_value.object->emplace(std::forward<Args>(args) ...);
14018 it.m_it.object_iterator = res.first;
14021 return { it, res.second };
14049 if (JSON_LIKELY(is_array())) {
14051 if (JSON_UNLIKELY(pos.m_object !=
this)) {
14052 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
14061 JSON_THROW(type_error::create(309,
"cannot use insert() with " +
std::string(type_name())));
14070 return insert(pos, val);
14100 if (JSON_LIKELY(is_array())) {
14102 if (JSON_UNLIKELY(pos.m_object !=
this)) {
14103 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
14112 JSON_THROW(type_error::create(309,
"cannot use insert() with " +
std::string(type_name())));
14148 if (JSON_UNLIKELY(not is_array())) {
14149 JSON_THROW(type_error::create(309,
"cannot use insert() with " +
std::string(type_name())));
14153 if (JSON_UNLIKELY(pos.m_object !=
this)) {
14154 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
14158 if (JSON_UNLIKELY(first.m_object != last.m_object)) {
14159 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
14162 if (JSON_UNLIKELY(first.m_object ==
this)) {
14163 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container"));
14202 if (JSON_UNLIKELY(not is_array())) {
14203 JSON_THROW(type_error::create(309,
"cannot use insert() with " +
std::string(type_name())));
14207 if (JSON_UNLIKELY(pos.m_object !=
this)) {
14208 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
14214 m_value.array->insert(pos.m_it.
array_iterator, ilist.begin(), ilist.end());
14244 if (JSON_UNLIKELY(not is_object())) {
14245 JSON_THROW(type_error::create(309,
"cannot use insert() with " +
std::string(type_name())));
14249 if (JSON_UNLIKELY(first.m_object != last.m_object)) {
14250 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
14254 if (JSON_UNLIKELY(not first.m_object->is_object())) {
14255 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
14285 m_value.object = create<object_t>();
14286 assert_invariant();
14289 if (JSON_UNLIKELY(not is_object())) {
14290 JSON_THROW(type_error::create(312,
"cannot use update() with " +
std::string(type_name())));
14293 if (JSON_UNLIKELY(not j.
is_object())) {
14294 JSON_THROW(type_error::create(312,
"cannot use update() with " +
std::string(j.
type_name())));
14297 for (
auto it = j.
cbegin(); it != j.
cend(); ++it) {
14298 m_value.object->operator[](it.key()) = it.value();
14333 m_value.object = create<object_t>();
14334 assert_invariant();
14337 if (JSON_UNLIKELY(not is_object())) {
14338 JSON_THROW(type_error::create(312,
"cannot use update() with " +
std::string(type_name())));
14342 if (JSON_UNLIKELY(first.m_object != last.m_object)) {
14343 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
14347 if (JSON_UNLIKELY(not first.m_object->is_object()
14348 or not first.m_object->is_object())) {
14349 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
14352 for (
auto it = first; it != last; ++it) {
14353 m_value.object->operator[](it.key()) = it.value();
14375 std::is_nothrow_move_constructible<value_t>::value and
14376 std::is_nothrow_move_assignable<value_t>::value and
14377 std::is_nothrow_move_constructible<json_value>::value and
14378 std::is_nothrow_move_assignable<json_value>::value
14381 std::swap(m_type, other.m_type);
14382 std::swap(m_value, other.m_value);
14383 assert_invariant();
14409 if (JSON_LIKELY(is_array())) {
14410 std::swap(*(m_value.array), other);
14412 JSON_THROW(type_error::create(310,
"cannot use swap() with " +
std::string(type_name())));
14439 if (JSON_LIKELY(is_object())) {
14440 std::swap(*(m_value.object), other);
14442 JSON_THROW(type_error::create(310,
"cannot use swap() with " +
std::string(type_name())));
14469 if (JSON_LIKELY(is_string())) {
14470 std::swap(*(m_value.string), other);
14472 JSON_THROW(type_error::create(310,
"cannot use swap() with " +
std::string(type_name())));
14527 const auto lhs_type = lhs.type();
14528 const auto rhs_type = rhs.type();
14530 if (lhs_type == rhs_type) {
14531 switch (lhs_type) {
14533 return (*lhs.m_value.array == *rhs.m_value.array);
14536 return (*lhs.m_value.object == *rhs.m_value.object);
14542 return (*lhs.m_value.string == *rhs.m_value.string);
14545 return (lhs.m_value.boolean == rhs.m_value.boolean);
14548 return (lhs.m_value.number_integer == rhs.m_value.number_integer);
14551 return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
14554 return (lhs.m_value.number_float == rhs.m_value.number_float);
14560 return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
14562 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
14564 return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
14566 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
14568 return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
14570 return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
14580 template<
typename ScalarType,
typename std::enable_if<
14581 std::is_scalar<ScalarType>::value,
int>::type = 0>
14584 return (lhs == basic_json(rhs));
14591 template<
typename ScalarType,
typename std::enable_if<
14592 std::is_scalar<ScalarType>::value,
int>::type = 0>
14595 return (basic_json(lhs) == rhs);
14618 return not (lhs == rhs);
14625 template<
typename ScalarType,
typename std::enable_if<
14626 std::is_scalar<ScalarType>::value,
int>::type = 0>
14629 return (lhs != basic_json(rhs));
14636 template<
typename ScalarType,
typename std::enable_if<
14637 std::is_scalar<ScalarType>::value,
int>::type = 0>
14640 return (basic_json(lhs) != rhs);
14671 const auto lhs_type = lhs.type();
14672 const auto rhs_type = rhs.type();
14674 if (lhs_type == rhs_type) {
14675 switch (lhs_type) {
14677 return (*lhs.m_value.array) < (*rhs.m_value.array);
14680 return *lhs.m_value.object < *rhs.m_value.object;
14686 return *lhs.m_value.string < *rhs.m_value.string;
14689 return lhs.m_value.boolean < rhs.m_value.boolean;
14692 return lhs.m_value.number_integer < rhs.m_value.number_integer;
14695 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
14698 return lhs.m_value.number_float < rhs.m_value.number_float;
14704 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
14706 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
14708 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
14710 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
14712 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
14714 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
14727 template<
typename ScalarType,
typename std::enable_if<
14728 std::is_scalar<ScalarType>::value,
int>::type = 0>
14731 return (lhs < basic_json(rhs));
14738 template<
typename ScalarType,
typename std::enable_if<
14739 std::is_scalar<ScalarType>::value,
int>::type = 0>
14742 return (basic_json(lhs) < rhs);
14766 return not (rhs < lhs);
14773 template<
typename ScalarType,
typename std::enable_if<
14774 std::is_scalar<ScalarType>::value,
int>::type = 0>
14777 return (lhs <= basic_json(rhs));
14784 template<
typename ScalarType,
typename std::enable_if<
14785 std::is_scalar<ScalarType>::value,
int>::type = 0>
14788 return (basic_json(lhs) <= rhs);
14812 return not (lhs <= rhs);
14819 template<
typename ScalarType,
typename std::enable_if<
14820 std::is_scalar<ScalarType>::value,
int>::type = 0>
14823 return (lhs > basic_json(rhs));
14830 template<
typename ScalarType,
typename std::enable_if<
14831 std::is_scalar<ScalarType>::value,
int>::type = 0>
14834 return (basic_json(lhs) > rhs);
14858 return not (lhs < rhs);
14865 template<
typename ScalarType,
typename std::enable_if<
14866 std::is_scalar<ScalarType>::value,
int>::type = 0>
14869 return (lhs >= basic_json(rhs));
14876 template<
typename ScalarType,
typename std::enable_if<
14877 std::is_scalar<ScalarType>::value,
int>::type = 0>
14880 return (basic_json(lhs) >= rhs);
14923 friend std ::ostream &
operator<<(std::ostream &o,
const basic_json &j)
14926 const bool pretty_print = (o.width() > 0);
14927 const auto indentation = (pretty_print ? o.width() : 0);
14934 s.
dump(j, pretty_print,
false, static_cast<unsigned int>(indentation));
14947 friend std ::ostream &
operator>>(
const basic_json &j, std::ostream &o)
15026 const bool allow_exceptions =
true)
15029 parser(i, cb, allow_exceptions).
parse(
true, result);
15038 const bool allow_exceptions =
true)
15041 parser(i, cb, allow_exceptions).
parse(
true, result);
15102 template<
class IteratorType,
typename std::enable_if<
15104 std::random_access_iterator_tag,
15105 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
15106 static basic_json
parse(IteratorType first, IteratorType last,
15108 const bool allow_exceptions =
true)
15115 template<
class IteratorType,
typename std::enable_if<
15117 std::random_access_iterator_tag,
15118 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
15119 static bool accept(IteratorType first, IteratorType last)
15135 return operator>>(i, j);
15220 return "discarded";
15236 json_value m_value = {};
15334 static std::vector<uint8_t>
to_cbor(
const basic_json &j)
15336 std::vector<uint8_t> result;
15337 to_cbor(j, result);
15433 std::vector<uint8_t> result;
15434 to_msgpack(j, result);
15529 const bool use_size =
false,
15530 const bool use_type =
false)
15532 std::vector<uint8_t> result;
15533 to_ubjson(j, result, use_size, use_type);
15538 const bool use_size =
false,
const bool use_type =
false)
15544 const bool use_size =
false,
const bool use_type =
false)
15643 const bool strict =
true)
15651 template<
typename A1,
typename A2,
15652 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
15653 static basic_json
from_cbor(A1 &&a1, A2 &&a2,
const bool strict =
true)
15733 const bool strict =
true)
15741 template<
typename A1,
typename A2,
15742 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
15803 const bool strict =
true)
15808 template<
typename A1,
typename A2,
15809 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
15810 static basic_json from_ubjson(A1 &&a1, A2 &&a2,
const bool strict =
true)
15860 return ptr.get_unchecked(
this);
15888 return ptr.get_unchecked(
this);
15931 return ptr.get_checked(
this);
15974 return ptr.get_checked(
this);
16002 json_pointer::flatten(
"", *
this, result);
16038 return json_pointer::unflatten(*
this);
16097 basic_json
patch(
const basic_json &json_patch)
const 16100 basic_json result = *
this;
16103 enum class patch_operations { add,
remove, replace, move, copy, test, invalid };
16107 return patch_operations::add;
16110 if (op ==
"remove") {
16111 return patch_operations::remove;
16114 if (op ==
"replace") {
16115 return patch_operations::replace;
16118 if (op ==
"move") {
16119 return patch_operations::move;
16122 if (op ==
"copy") {
16123 return patch_operations::copy;
16126 if (op ==
"test") {
16127 return patch_operations::test;
16130 return patch_operations::invalid;
16134 const auto operation_add = [&result](
json_pointer &ptr, basic_json val) {
16136 if (ptr.is_root()) {
16141 if (top_pointer != ptr) {
16142 result.
at(top_pointer);
16146 const auto last_path = ptr.pop_back();
16147 basic_json &parent = result[ptr];
16149 switch (parent.m_type) {
16154 parent[last_path] = val;
16160 if (last_path ==
"-") {
16165 if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.
size())) {
16167 JSON_THROW(out_of_range::create(401,
16168 "array index " + std::to_string(idx) +
16169 " is out of range"));
16189 const auto operation_remove = [&result](
json_pointer &ptr) {
16191 const auto last_path = ptr.pop_back();
16192 basic_json &parent = result.
at(ptr);
16197 auto it = parent.
find(last_path);
16198 if (JSON_LIKELY(it != parent.
end())) {
16201 JSON_THROW(out_of_range::create(403,
"key '" + last_path +
"' not found"));
16210 if (JSON_UNLIKELY(not json_patch.
is_array())) {
16215 for (
const auto &val : json_patch) {
16217 const auto get_value = [&val](
const std::string &op,
16219 bool string_type) -> basic_json & {
16221 auto it = val.m_value.object->find(member);
16224 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
16227 if (JSON_UNLIKELY(it == val.m_value.object->end())) {
16229 error_msg +
" must have member '" + member +
"'"));
16233 if (JSON_UNLIKELY(string_type and not it->second.is_string())) {
16235 error_msg +
" must have string member '" + member +
16244 if (JSON_UNLIKELY(not val.is_object())) {
16249 const std::string op = get_value(
"op",
"op",
true);
16250 const std::string path = get_value(op,
"path",
true);
16253 switch (get_op(op)) {
16254 case patch_operations::add:
16256 operation_add(ptr, get_value(
"add",
"value",
false));
16260 case patch_operations::remove:
16262 operation_remove(ptr);
16266 case patch_operations::replace:
16269 result.
at(ptr) = get_value(
"replace",
"value",
false);
16273 case patch_operations::move:
16275 const std::string from_path = get_value(
"move",
"from",
true);
16279 basic_json v = result.
at(from_ptr);
16285 operation_remove(from_ptr);
16286 operation_add(ptr, v);
16290 case patch_operations::copy:
16292 const std::string from_path = get_value(
"copy",
"from",
true);
16296 basic_json v = result.
at(from_ptr);
16301 operation_add(ptr, v);
16305 case patch_operations::test:
16307 bool success =
false;
16312 success = (result.
at(ptr) == get_value(
"test",
"value",
false));
16320 if (JSON_UNLIKELY(not success)) {
16321 JSON_THROW(other_error::create(501,
"unsuccessful: " + val.dump()));
16327 case patch_operations::invalid:
16372 static basic_json
diff(
const basic_json &source,
const basic_json &target,
16379 if (source == target) {
16383 if (source.
type() != target.
type()) {
16387 {
"op",
"replace" }, {
"path", path }, {
"value", target }
16390 switch (source.
type()) {
16395 while (i < source.
size() and i < target.
size()) {
16397 auto temp_diff = diff(source[i], target[i], path +
"/" + std::to_string(i));
16398 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
16407 while (i < source.
size()) {
16412 {
"op",
"remove" },
16413 {
"path", path +
"/" + std::to_string(i) }
16419 while (i < target.
size()) {
16423 {
"path", path +
"/" + std::to_string(i) },
16424 {
"value", target[i] }
16435 for (
auto it = source.
cbegin(); it != source.
cend(); ++it) {
16437 const auto key = json_pointer::escape(it.key());
16439 if (target.
find(it.key()) != target.
end()) {
16441 auto temp_diff = diff(it.value(), target[it.key()], path +
"/" + key);
16442 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
16447 {
"op",
"remove" }, {
"path", path +
"/" + key }
16453 for (
auto it = target.
cbegin(); it != target.
cend(); ++it) {
16454 if (source.
find(it.key()) == source.
end()) {
16456 const auto key = json_pointer::escape(it.key());
16459 {
"op",
"add" }, {
"path", path +
"/" + key },
16460 {
"value", it.value() }
16473 {
"op",
"replace" }, {
"path", path }, {
"value", target }
16537 if (not is_object()) {
16541 for (
auto it = patch.
begin(); it != patch.
end(); ++it) {
16542 if (it.value().is_null()) {
16545 operator[](it.key()).merge_patch(it.value());
16573 is_nothrow_move_constructible<nlohmann::json>::value and
16574 is_nothrow_move_assignable<nlohmann::json>::value
16592 const auto &h = hash<nlohmann::json::string_t>();
16593 return h(j.
dump());
16629 inline nlohmann::json operator"" _json(
const char *s, std::size_t n)
16656 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 16657 #pragma GCC diagnostic pop 16659 #if defined(__clang__) 16660 #pragma GCC diagnostic pop 16668 #undef JSON_UNLIKELY 16669 #undef JSON_DEPRECATED 16670 #undef JSON_HAS_CPP_14 16671 #undef JSON_HAS_CPP_17 16672 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION 16673 #undef NLOHMANN_BASIC_JSON_TPL 16674 #undef NLOHMANN_JSON_HAS_HELPER std::vector< basic_json, std::allocator< basic_json > > array_t
a type for an array
Definition: json.hpp:9768
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:13832
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:10786
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
Definition: json.hpp:12325
Definition: json.hpp:6910
void update(const_iterator first, const_iterator last)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:14328
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:2927
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:13376
typename parser::parser_callback_t parser_callback_t
per-element parser callback type
Definition: json.hpp:10357
token_type
token types for the parser
Definition: json.hpp:1894
const int id
the id of the exception
Definition: json.hpp:559
void emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:13954
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:4279
std::shared_ptr< input_adapter_protocol > input_adapter_t
a type to simplify interfaces
Definition: json.hpp:1648
Definition: json.hpp:1201
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:13637
Definition: json.hpp:3650
static JSON_DEPRECATED iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:13367
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:14669
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:13433
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:10989
double number_float_t
a type for a number (floating-point)
Definition: json.hpp:10058
JSON_DEPRECATED friend std ::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
Definition: json.hpp:15133
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:4592
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:6924
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:4242
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:4224
value_t
the JSON type enumeration
Definition: json.hpp:880
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:4301
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:7423
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:4598
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:13441
iter_impl(pointer object) noexcept
constructor for a given JSON instance
Definition: json.hpp:3879
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:12704
json_reverse_iterator const operator--(int)
post-decrement (it–)
Definition: json.hpp:4556
~basic_json() noexcept
destructor
Definition: json.hpp:11058
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:15886
Definition: json.hpp:7940
Definition: json.hpp:4708
reference value() const
return the value of an iterator
Definition: json.hpp:4605
const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:553
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:4532
a signed integer – use get_number_integer() for actual value
Definition: json.hpp:1269
array (ordered collection of values)
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:8634
std::uint64_t number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:9990
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:11158
friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than or equal
Definition: json.hpp:14775
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:4083
std::int64_t number_integer_t
a type for a number (integer)
Definition: json.hpp:9919
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition: json.hpp:12278
a template for a reverse iterator class
Definition: json.hpp:4527
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:3918
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:11188
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:9508
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:15929
iterator insert(const_iterator pos, basic_json &&val)
inserts element
Definition: json.hpp:14068
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:4233
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:10398
default JSONSerializer template argument
Definition: json.hpp:73
void insert(const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:14241
iter_impl const operator--(int)
post-decrement (it–)
Definition: json.hpp:4114
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:11215
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:9527
std::string string_t
a type for a string
Definition: json.hpp:9821
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:4190
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:3160
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:7017
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:13130
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:10721
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:15999
Definition: json.hpp:16563
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:13059
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:4568
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:9500
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:13880
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:14145
friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:14638
friend std ::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:14923
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:7982
friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than
Definition: json.hpp:14821
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:4473
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:4270
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:13208
a template for a bidirectional iterator for the basic_json class
Definition: json.hpp:3832
friend std ::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:15163
friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:14593
std::bidirectional_iterator_tag iterator_category
Definition: json.hpp:3854
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:11396
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:7181
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:14000
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:4537
BasicJsonType parse_ubjson(const bool strict)
create a JSON value from UBJSON input
Definition: json.hpp:4841
lexical analysis
Definition: json.hpp:1886
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:3673
binary_reader(input_adapter_t adapter)
create a binary reader
Definition: json.hpp:4784
friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:14832
syntax analysis
Definition: json.hpp:3115
serialization to CBOR and MessagePack values
Definition: json.hpp:6098
serializer(output_adapter_t< char > s, const char ichar)
Definition: json.hpp:7954
output adapter for byte vectors
Definition: json.hpp:4645
pointer operator->() const
dereference the iterator
Definition: json.hpp:4040
const std::size_t byte
byte index of the parse error
Definition: json.hpp:645
friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:14867
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.hpp:3773
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:9310
const_reference operator[](T *key) const
read-only access specified object element
Definition: json.hpp:12412
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:11025
std::string move_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:2939
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:10694
exception indicating access out of the defined range
Definition: json.hpp:786
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:11237
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:11374
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.hpp:12970
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:3667
void write_msgpack(const BasicJsonType &j)
[in] j JSON value to serialize
Definition: json.hpp:6308
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:7001
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:12013
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:10422
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:12155
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:12888
friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than
Definition: json.hpp:14729
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false) const
serialization
Definition: json.hpp:11111
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:10907
iter_impl const operator++(int)
post-increment (it++)
Definition: json.hpp:4072
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:4580
void clear() noexcept
clears the contents
Definition: json.hpp:13706
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
Definition: json.hpp:14097
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:13926
parse_event_t
Definition: json.hpp:3124
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:2921
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:11289
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:16372
exception indicating a parse error
Definition: json.hpp:617
reference operator[](T *key)
access specified object element
Definition: json.hpp:12364
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:4312
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:2933
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:4541
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:15732
const_iterator find(KeyT &&key) const
find an element in a JSON object
Definition: json.hpp:12986
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:15858
json_reverse_iterator const operator++(int)
post-increment (it++)
Definition: json.hpp:4544
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:12107
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:4534
an unsigned integer – use get_number_unsigned() for actual value
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:3777
abstract output adapter interface
Definition: json.hpp:4632
general exception of the basic_json class
Definition: json.hpp:549
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:13568
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:15528
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:7042
constexpr const PointerType get_ptr() const noexcept
get a pointer value (implicit)
Definition: json.hpp:11861
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:15334
char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:7756
reference back()
access the last element
Definition: json.hpp:12637
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:3775
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:3868
friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
comparison: equal
Definition: json.hpp:14582
const char * type_name() const noexcept
return the type as string
Definition: json.hpp:15205
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:15743
bool operator!=(const iter_impl &other) const
comparison: not equal
Definition: json.hpp:4181
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:13069
exception indicating errors with iterators
Definition: json.hpp:689
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:13237
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:11259
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:903
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition: json.hpp:7659
namespace for Niels Lohmann
Definition: json.hpp:63
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:12805
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:11440
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:4574
object (unordered set of name/value pairs)
Definition: json.hpp:1556
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:11911
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:4005
Definition: json.hpp:7167
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:9456
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:3863
exception indicating executing a member function with a wrong type
Definition: json.hpp:741
friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:14786
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:3679
PointerType get_ptr() noexcept
get a pointer value (implicit)
Definition: json.hpp:11832
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:14525
std::map< std::string, basic_json, object_comparator_t, std::allocator< std::pair< const std::string, basic_json > >> object_t
a type for an object
Definition: json.hpp:9722
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer.
Definition: json.hpp:9452
typename parser::parse_event_t parse_event_t
parser event types
Definition: json.hpp:10306
string_t value(const json_pointer &ptr, const char *default_value) const
overload for a default value of type const char*
Definition: json.hpp:12563
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:13810
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:13911
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:3144
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:15106
void merge_patch(const basic_json &patch)
applies a JSON Merge Patch
Definition: json.hpp:16534
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:15653
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:4361
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
Definition: json.hpp:16589
static int array_index(const std::string &s)
Definition: json.hpp:8675
Definition: json.hpp:7028
const_reference back() const
access the last element
Definition: json.hpp:12647
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:11467
output adapter for basic_string
Definition: json.hpp:4687
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:14280
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:12473
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:4641
bool boolean_t
a type for a boolean
Definition: json.hpp:9847
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:14810
constexpr const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:2978
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:6106
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:3193
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:7798
output adapter for output streams
Definition: json.hpp:4666
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:15024
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:13800
JSON_DEPRECATED friend std ::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:14947
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:11318
exception indicating other library errors
Definition: json.hpp:824
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:3685
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:13099
friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:14878
void swap(array_t &other)
exchanges the values
Definition: json.hpp:14406
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:12058
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:9510
deserialization of CBOR and MessagePack values
Definition: json.hpp:4772
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:3857
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:16607
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:11346
iteration_proxy_internal begin() noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:4477
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:4215
void swap(string_t &other)
exchanges the values
Definition: json.hpp:14466
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:3927
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:4125
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:14046
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:11418
an iterator value
Definition: json.hpp:3770
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:13140
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:13274
Definition: json.hpp:8532
bool operator==(const iter_impl &other) const
comparison: equal
Definition: json.hpp:4156
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements
Definition: json.hpp:14199
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:1916
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:3859
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:15642
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:10488
std::string to_string() const noexcept
return a string representation of the JSON pointer
Definition: json.hpp:8653
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:12198
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:12493
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:13776
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
Definition: json.hpp:6504
friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:14740
reference front()
access the first element
Definition: json.hpp:12593
JSON Pointer.
Definition: json.hpp:99
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:13200
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:4332
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:11924
BasicJsonType parse_msgpack(const bool strict)
create a JSON value from MessagePack input
Definition: json.hpp:4820
number value (unsigned integer)
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:9502
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:13303
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:16097
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:12241
basic_json<> json
default JSON class
Definition: json.hpp:109
friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
comparison: not equal
Definition: json.hpp:14627
BasicJsonType parse_cbor(const bool strict)
create a JSON value from CBOR input
Definition: json.hpp:4799
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:13019
void swap(object_t &other)
exchanges the values
Definition: json.hpp:14436
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:15431
constexpr std::size_t get_position() const noexcept
return position of last read token
Definition: json.hpp:2949
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:12541
reference value() const
return the value of an iterator
Definition: json.hpp:4376
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:13170
proxy class for the items() function
Definition: json.hpp:3808
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:4562
std::string get_token_string() const
Definition: json.hpp:2957
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:13858
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:10570
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:16036
static basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:10651
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:14764
number value (floating-point)
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:12922
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:14856
iteration_proxy_internal end() noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:4483
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:14616
void write_cbor(const BasicJsonType &j)
[in] j JSON value to serialize
Definition: json.hpp:6114
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg)
create a parse error exception
Definition: json.hpp:628
std::allocator< basic_json > allocator_type
the allocator type
Definition: json.hpp:9505
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:14374
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:4550
const_reference front() const
access the first element
Definition: json.hpp:12601
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:15802
static constexpr bool little_endianess(int num=1) noexcept
determine system byte order
Definition: json.hpp:4859
int find_largest_pow10(const uint32_t n, uint32_t &pow10)
Definition: json.hpp:7345
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:15036
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:4290
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:15972
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:7875
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:13245
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:4586
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:13497
static basic_json meta()
returns version information on the library
Definition: json.hpp:9558
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:6936
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:9294