29 #ifndef NLOHMANN_JSON_HPP 30 #define NLOHMANN_JSON_HPP 32 #define NLOHMANN_JSON_VERSION_MAJOR 3 33 #define NLOHMANN_JSON_VERSION_MINOR 1 34 #define NLOHMANN_JSON_VERSION_PATCH 2 41 #include <initializer_list> 49 #ifndef NLOHMANN_JSON_FWD_HPP 50 #define NLOHMANN_JSON_FWD_HPP 72 template<
typename =
void,
typename =
void>
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,
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> 267 template<
bool B,
typename T =
void>
271 using uncvref_t =
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
275 template<std::size_t... Ints>
280 static constexpr std::size_t
size() noexcept
282 return sizeof...(Ints);
286 template<
class Sequence1,
class Sequence2>
289 template<std::size_t... I1, std::size_t... I2>
293 template<std::
size_t N>
296 typename make_index_sequence < N - N / 2 >::type > {};
301 template<
typename... Ts>
319 template<
class B1,
class... Bn>
320 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
322 template<
class B>
struct negation : std::integral_constant<bool, not B::value> {};
334 template <
typename T,
typename =
void>
337 template <
typename T>
345 template<
bool B,
class RealType,
class CompatibleObjectType>
348 template<
class RealType,
class CompatibleObjectType>
351 static constexpr
auto value =
352 std::is_constructible<typename RealType::key_type, typename CompatibleObjectType::key_type>::value and
353 std::is_constructible<typename RealType::mapped_type, typename CompatibleObjectType::mapped_type>::value;
356 template<
class BasicJsonType,
class CompatibleObjectType>
361 has_mapped_type<CompatibleObjectType>,
362 has_key_type<CompatibleObjectType>>::value,
363 typename BasicJsonType::object_t, CompatibleObjectType >::value;
366 template<
typename BasicJsonType,
typename T>
369 static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
370 std::is_same<T, typename BasicJsonType::const_iterator>::value or
371 std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
372 std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
375 template<
class BasicJsonType,
class CompatibleArrayType>
378 static auto constexpr value =
381 BasicJsonType, CompatibleArrayType>>,
382 negation<std::is_constructible<
typename BasicJsonType::string_t,
383 CompatibleArrayType>>,
385 has_value_type<CompatibleArrayType>,
386 has_iterator<CompatibleArrayType>>::value;
389 template<
bool,
typename,
typename>
392 template<
typename RealIntegerType,
typename CompatibleNumberIntegerType>
399 static constexpr
auto value =
400 std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
401 CompatibleLimits::is_integer and
402 RealLimits::is_signed == CompatibleLimits::is_signed;
405 template<
typename RealIntegerType,
typename CompatibleNumberIntegerType>
408 static constexpr
auto value =
410 std::is_integral<CompatibleNumberIntegerType>::value and
411 not std::is_same<bool, CompatibleNumberIntegerType>::value,
412 RealIntegerType, CompatibleNumberIntegerType > ::value;
416 template<
typename BasicJsonType,
typename T>
422 std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
423 static int detect(U&&);
424 static void detect(...);
427 static constexpr
bool value = std::is_integral<decltype(
428 detect(std::declval<
typename BasicJsonType::template json_serializer<T, void>>()))>::value;
433 template<
typename BasicJsonType,
typename T>
441 static int detect(U&&);
442 static void detect(...);
445 static constexpr
bool value = std::is_integral<decltype(detect(
446 std::declval<
typename BasicJsonType::template json_serializer<T, void>>()))>::value;
450 template<
typename BasicJsonType,
typename T>
455 std::declval<BasicJsonType&>(), std::declval<T>()))>
456 static int detect(U&&);
457 static void detect(...);
460 static constexpr
bool value = std::is_integral<decltype(detect(
461 std::declval<
typename BasicJsonType::template json_serializer<T, void>>()))>::value;
464 template <
typename BasicJsonType,
typename CompatibleCompleteType>
467 static constexpr
bool value =
468 not std::is_base_of<std::istream, CompatibleCompleteType>::value and
474 template <
typename BasicJsonType,
typename CompatibleType>
477 is_compatible_complete_type<BasicJsonType, CompatibleType>>
485 static constexpr T value{};
540 const char*
what() const noexcept
override 549 exception(
int id_,
const char* what_arg) : id(id_), m(what_arg) {}
553 return "[json.exception." + ename +
"." + std::to_string(id_) +
"] ";
558 std::runtime_error
m;
618 (byte_ != 0 ? (
" at " + std::to_string(byte_)) :
"") +
636 :
exception(id_, what_arg), byte(byte_) {}
890 static constexpr std::array<std::uint8_t, 8> order = {{
896 const auto l_index =
static_cast<std::size_t
>(lhs);
897 const auto r_index =
static_cast<std::size_t
>(rhs);
898 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
909 #include <forward_list> 913 #include <type_traits> 931 template<
typename BasicJsonType,
typename ArithmeticType,
933 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
937 switch (static_cast<value_t>(j))
941 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
946 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
951 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
960 template<
typename BasicJsonType>
961 void from_json(
const BasicJsonType& j,
typename BasicJsonType::boolean_t& b)
967 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
970 template<
typename BasicJsonType>
971 void from_json(
const BasicJsonType& j,
typename BasicJsonType::string_t& s)
977 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
980 template<
typename BasicJsonType>
981 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_float_t& val)
986 template<
typename BasicJsonType>
987 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_unsigned_t& val)
992 template<
typename BasicJsonType>
993 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_integer_t& val)
998 template<
typename BasicJsonType,
typename EnumType,
1002 typename std::underlying_type<EnumType>::type val;
1004 e =
static_cast<EnumType
>(val);
1007 template<
typename BasicJsonType>
1008 void from_json(
const BasicJsonType& j,
typename BasicJsonType::array_t& arr)
1014 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
1018 template<
typename BasicJsonType,
typename T,
typename Allocator,
1020 void from_json(
const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1026 std::transform(j.rbegin(), j.rend(),
1027 std::front_inserter(l), [](
const BasicJsonType & i)
1029 return i.template get<T>();
1034 template<
typename BasicJsonType,
typename T,
1035 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1043 std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1046 template<
typename BasicJsonType,
typename CompatibleArrayType>
1051 std::transform(j.begin(), j.end(),
1052 std::inserter(arr, end(arr)), [](
const BasicJsonType & i)
1056 return i.template get<typename CompatibleArrayType::value_type>();
1060 template<
typename BasicJsonType,
typename CompatibleArrayType>
1063 arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
1068 arr.reserve(j.size());
1069 std::transform(j.begin(), j.end(),
1070 std::inserter(arr, end(arr)), [](
const BasicJsonType & i)
1074 return i.template get<typename CompatibleArrayType::value_type>();
1078 template<
typename BasicJsonType,
typename T, std::
size_t N>
1081 for (std::size_t i = 0; i < N; ++i)
1083 arr[i] = j.at(i).template get<T>();
1088 typename BasicJsonType,
typename CompatibleArrayType,
1091 not std::is_same<
typename BasicJsonType::array_t,
1092 CompatibleArrayType>::value and
1093 std::is_constructible <
1094 BasicJsonType,
typename CompatibleArrayType::value_type >::value,
1096 void from_json(
const BasicJsonType& j, CompatibleArrayType& arr)
1107 template<
typename BasicJsonType,
typename CompatibleObjectType,
1109 void from_json(
const BasicJsonType& j, CompatibleObjectType& obj)
1116 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1117 using value_type =
typename CompatibleObjectType::value_type;
1119 inner_object->begin(), inner_object->end(),
1120 std::inserter(obj, obj.begin()),
1121 [](
typename BasicJsonType::object_t::value_type
const & p)
1123 return value_type(p.first, p.second.template get<typename CompatibleObjectType::mapped_type>());
1131 template<
typename BasicJsonType,
typename ArithmeticType,
1133 std::is_arithmetic<ArithmeticType>::value and
1134 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1135 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1136 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1137 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1141 switch (static_cast<value_t>(j))
1145 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1150 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1155 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1160 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1169 template<
typename BasicJsonType,
typename A1,
typename A2>
1170 void from_json(
const BasicJsonType& j, std::pair<A1, A2>& p)
1172 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
1175 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1178 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
1181 template<
typename BasicJsonType,
typename... Args>
1182 void from_json(
const BasicJsonType& j, std::tuple<Args...>& t)
1190 template<
typename BasicJsonType,
typename T>
1198 template<
typename BasicJsonType,
typename T>
1201 static_assert(
sizeof(BasicJsonType) == 0,
1202 "could not find from_json() method in T's namespace");
1206 static_assert(
sizeof(
typename decayed::force_msvc_stacktrace) == 0,
1207 "forcing MSVC stacktrace to show which T we're talking about.");
1212 template<
typename BasicJsonType,
typename T>
1236 #include <type_traits> 1259 template<
typename BasicJsonType>
1260 static void construct(BasicJsonType& j,
typename BasicJsonType::boolean_t b) noexcept
1264 j.assert_invariant();
1271 template<
typename BasicJsonType>
1272 static void construct(BasicJsonType& j,
const typename BasicJsonType::string_t& s)
1276 j.assert_invariant();
1279 template<
typename BasicJsonType>
1280 static void construct(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
1283 j.m_value = std::move(
s);
1284 j.assert_invariant();
1291 template<
typename BasicJsonType>
1292 static void construct(BasicJsonType& j,
typename BasicJsonType::number_float_t val) noexcept
1296 j.assert_invariant();
1303 template<
typename BasicJsonType>
1304 static void construct(BasicJsonType& j,
typename BasicJsonType::number_unsigned_t val) noexcept
1308 j.assert_invariant();
1315 template<
typename BasicJsonType>
1316 static void construct(BasicJsonType& j,
typename BasicJsonType::number_integer_t val) noexcept
1320 j.assert_invariant();
1327 template<
typename BasicJsonType>
1328 static void construct(BasicJsonType& j,
const typename BasicJsonType::array_t& arr)
1332 j.assert_invariant();
1335 template<
typename BasicJsonType>
1336 static void construct(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
1339 j.m_value = std::move(arr);
1340 j.assert_invariant();
1343 template<
typename BasicJsonType,
typename CompatibleArrayType,
1346 static void construct(BasicJsonType& j,
const CompatibleArrayType& arr)
1351 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
1352 j.assert_invariant();
1355 template<
typename BasicJsonType>
1356 static void construct(BasicJsonType& j,
const std::vector<bool>& arr)
1360 j.m_value.array->reserve(arr.size());
1361 for (
const bool x : arr)
1363 j.m_value.array->push_back(x);
1365 j.assert_invariant();
1368 template<
typename BasicJsonType,
typename T,
1370 static void construct(BasicJsonType& j,
const std::valarray<T>& arr)
1374 j.m_value.array->resize(arr.size());
1375 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
1376 j.assert_invariant();
1383 template<
typename BasicJsonType>
1384 static void construct(BasicJsonType& j,
const typename BasicJsonType::object_t& obj)
1388 j.assert_invariant();
1391 template<
typename BasicJsonType>
1392 static void construct(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
1395 j.m_value = std::move(obj);
1396 j.assert_invariant();
1399 template<
typename BasicJsonType,
typename CompatibleObjectType,
1401 static void construct(BasicJsonType& j,
const CompatibleObjectType& obj)
1407 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
1408 j.assert_invariant();
1416 template<
typename BasicJsonType,
typename T,
1423 template<
typename BasicJsonType,
typename CompatibleString,
1425 void to_json(BasicJsonType& j,
const CompatibleString& s)
1430 template<
typename BasicJsonType>
1431 void to_json(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
1436 template<
typename BasicJsonType,
typename FloatType,
1438 void to_json(BasicJsonType& j, FloatType val) noexcept
1443 template<
typename BasicJsonType,
typename CompatibleNumberUnsignedType,
1445 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
1450 template<
typename BasicJsonType,
typename CompatibleNumberIntegerType,
1452 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
1457 template<
typename BasicJsonType,
typename EnumType,
1458 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
1459 void to_json(BasicJsonType& j, EnumType e) noexcept
1461 using underlying_type =
typename std::underlying_type<EnumType>::type;
1465 template<
typename BasicJsonType>
1466 void to_json(BasicJsonType& j,
const std::vector<bool>& e)
1471 template<
typename BasicJsonType,
typename CompatibleArrayType,
1473 std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
1475 void to_json(BasicJsonType& j,
const CompatibleArrayType& arr)
1480 template<
typename BasicJsonType,
typename T,
1482 void to_json(BasicJsonType& j, std::valarray<T> arr)
1487 template<
typename BasicJsonType>
1488 void to_json(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
1493 template<
typename BasicJsonType,
typename CompatibleObjectType,
1494 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
int> = 0>
1495 void to_json(BasicJsonType& j,
const CompatibleObjectType& obj)
1500 template<
typename BasicJsonType>
1501 void to_json(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
1506 template<
typename BasicJsonType,
typename T, std::size_t N,
1513 template<
typename BasicJsonType,
typename... Args>
1514 void to_json(BasicJsonType& j,
const std::pair<Args...>& p)
1516 j = {p.first, p.second};
1519 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1522 j = {std::get<Idx>(t)...};
1525 template<
typename BasicJsonType,
typename... Args>
1526 void to_json(BasicJsonType& j,
const std::tuple<Args...>& t)
1534 template<
typename BasicJsonType,
typename T>
1536 -> decltype(
to_json(j,
std::forward<T>(val)),
void())
1538 return to_json(j, std::forward<T>(val));
1541 template<
typename BasicJsonType,
typename T>
1544 static_assert(
sizeof(BasicJsonType) == 0,
1545 "could not find to_json() method in T's namespace");
1550 static_assert(
sizeof(
typename decayed::force_msvc_stacktrace) == 0,
1551 "forcing MSVC stacktrace to show which T we're talking about.");
1556 template<
typename BasicJsonType,
typename T>
1575 #include <algorithm> 1586 #include <type_traits> 1614 virtual std::char_traits<char>::int_type get_character() = 0;
1616 virtual void unget_character() = 0;
1643 : is(i), sb(*i.rdbuf())
1646 std::char_traits<char>::int_type c;
1647 if ((c = get_character()) == 0xEF)
1649 if ((c = get_character()) == 0xBB)
1651 if ((c = get_character()) == 0xBF)
1655 else if (c != std::char_traits<char>::eof())
1661 else if (c != std::char_traits<char>::eof())
1667 else if (c != std::char_traits<char>::eof())
1701 : cursor(b), limit(b + l),
start(b)
1704 if (l >= 3 and b[0] ==
'\xEF' and b[1] ==
'\xBB' and b[2] ==
'\xBF')
1718 return std::char_traits<char>::to_int_type(*(cursor++));
1721 return std::char_traits<char>::eof();
1755 template<
typename CharT,
1756 typename std::enable_if<
1757 std::is_pointer<CharT>::value and
1758 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
1759 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
1762 : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
1767 template<
typename CharT,
1768 typename std::enable_if<
1769 std::is_pointer<CharT>::value and
1770 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
1771 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
1775 std::strlen(reinterpret_cast<const char*>(b))) {}
1778 template<
class IteratorType,
1779 typename std::enable_if<
1780 std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
1786 assert(std::accumulate(
1787 first, last, std::pair<bool, int>(
true, 0),
1788 [&first](std::pair<bool, int> res, decltype(*first) val)
1790 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
1796 sizeof(
typename std::iterator_traits<IteratorType>::value_type) == 1,
1797 "each element in the iterator range must have the size of 1 byte");
1799 const auto len =
static_cast<size_t>(std::distance(first, last));
1803 ia = std::make_shared<input_buffer_adapter>(
reinterpret_cast<const char*
>(&(*first)), len);
1808 ia = std::make_shared<input_buffer_adapter>(
nullptr, len);
1813 template<
class T, std::
size_t N>
1818 template<
class ContiguousContainer,
typename 1819 std::enable_if<not std::is_pointer<ContiguousContainer>::value and
1820 std::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
1843 #include <initializer_list> 1868 template<
typename BasicJsonType>
1904 case token_type::uninitialized:
1905 return "<uninitialized>";
1906 case token_type::literal_true:
1907 return "true literal";
1908 case token_type::literal_false:
1909 return "false literal";
1910 case token_type::literal_null:
1911 return "null literal";
1912 case token_type::value_string:
1913 return "string literal";
1917 return "number literal";
1918 case token_type::begin_array:
1920 case token_type::begin_object:
1922 case token_type::end_array:
1924 case token_type::end_object:
1926 case token_type::name_separator:
1928 case token_type::value_separator:
1930 case token_type::parse_error:
1931 return "<parse error>";
1932 case token_type::end_of_input:
1933 return "end of input";
1934 case token_type::literal_or_value:
1935 return "'[', '{', or a literal";
1937 return "unknown token";
1942 : ia(
std::move(adapter)), decimal_point_char(get_decimal_point()) {}
1956 const auto loc = localeconv();
1957 assert(loc !=
nullptr);
1958 return (loc->decimal_point ==
nullptr) ?
'.' : *(loc->decimal_point);
1983 assert(current ==
'u');
1986 const auto factors = { 12, 8, 4, 0 };
1987 for (
const auto factor : factors)
1991 if (current >=
'0' and current <=
'9')
1993 codepoint += ((current - 0x30) << factor);
1995 else if (current >=
'A' and current <=
'F')
1997 codepoint += ((current - 0x37) << factor);
1999 else if (current >=
'a' and current <=
'f')
2001 codepoint += ((current - 0x57) << factor);
2009 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
2030 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
2033 for (
auto range = ranges.begin(); range != ranges.end(); ++range)
2036 if (
JSON_LIKELY(*range <= current and current <= *(++range)))
2042 error_message =
"invalid string: ill-formed UTF-8 byte";
2071 assert(current ==
'\"');
2079 case std::char_traits<char>::eof():
2081 error_message =
"invalid string: missing closing quote";
2082 return token_type::parse_error;
2088 return token_type::value_string;
2132 const int codepoint1 = get_codepoint();
2133 int codepoint = codepoint1;
2137 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
2138 return token_type::parse_error;
2142 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
2147 const int codepoint2 = get_codepoint();
2151 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
2152 return token_type::parse_error;
2156 if (
JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
2171 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2172 return token_type::parse_error;
2177 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2178 return token_type::parse_error;
2183 if (
JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
2185 error_message =
"invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
2186 return token_type::parse_error;
2191 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
2194 if (codepoint < 0x80)
2199 else if (codepoint <= 0x7FF)
2202 add(0xC0 | (codepoint >> 6));
2203 add(0x80 | (codepoint & 0x3F));
2205 else if (codepoint <= 0xFFFF)
2208 add(0xE0 | (codepoint >> 12));
2209 add(0x80 | ((codepoint >> 6) & 0x3F));
2210 add(0x80 | (codepoint & 0x3F));
2215 add(0xF0 | (codepoint >> 18));
2216 add(0x80 | ((codepoint >> 12) & 0x3F));
2217 add(0x80 | ((codepoint >> 6) & 0x3F));
2218 add(0x80 | (codepoint & 0x3F));
2226 error_message =
"invalid string: forbidden character after backslash";
2227 return token_type::parse_error;
2267 error_message =
"invalid string: control character must be escaped";
2268 return token_type::parse_error;
2405 return token_type::parse_error;
2413 if (
JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
2415 return token_type::parse_error;
2437 if (
JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
2439 return token_type::parse_error;
2447 if (
JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
2449 return token_type::parse_error;
2457 if (
JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2459 return token_type::parse_error;
2469 if (
JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2471 return token_type::parse_error;
2479 if (
JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
2481 return token_type::parse_error;
2489 error_message =
"invalid string: ill-formed UTF-8 byte";
2490 return token_type::parse_error;
2496 static void strtof(
float& f,
const char* str,
char** endptr) noexcept
2498 f = std::strtof(str, endptr);
2501 static void strtof(
double& f,
const char* str,
char** endptr) noexcept
2503 f = std::strtod(str, endptr);
2506 static void strtof(
long double& f,
const char* str,
char** endptr) noexcept
2508 f = std::strtold(str, endptr);
2558 token_type number_type = token_type::value_unsigned;
2566 goto scan_number_minus;
2572 goto scan_number_zero;
2586 goto scan_number_any1;
2598 number_type = token_type::value_integer;
2604 goto scan_number_zero;
2618 goto scan_number_any1;
2623 error_message =
"invalid number; expected digit after '-'";
2624 return token_type::parse_error;
2634 add(decimal_point_char);
2635 goto scan_number_decimal1;
2642 goto scan_number_exponent;
2646 goto scan_number_done;
2665 goto scan_number_any1;
2670 add(decimal_point_char);
2671 goto scan_number_decimal1;
2678 goto scan_number_exponent;
2682 goto scan_number_done;
2685 scan_number_decimal1:
2687 number_type = token_type::value_float;
2702 goto scan_number_decimal2;
2707 error_message =
"invalid number; expected digit after '.'";
2708 return token_type::parse_error;
2712 scan_number_decimal2:
2728 goto scan_number_decimal2;
2735 goto scan_number_exponent;
2739 goto scan_number_done;
2742 scan_number_exponent:
2744 number_type = token_type::value_float;
2751 goto scan_number_sign;
2766 goto scan_number_any2;
2772 "invalid number; expected '+', '-', or digit after exponent";
2773 return token_type::parse_error;
2793 goto scan_number_any2;
2798 error_message =
"invalid number; expected digit after exponent sign";
2799 return token_type::parse_error;
2819 goto scan_number_any2;
2823 goto scan_number_done;
2831 char* endptr =
nullptr;
2835 if (number_type == token_type::value_unsigned)
2837 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
2840 assert(endptr == token_buffer.data() + token_buffer.size());
2845 if (value_unsigned == x)
2847 return token_type::value_unsigned;
2851 else if (number_type == token_type::value_integer)
2853 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
2856 assert(endptr == token_buffer.data() + token_buffer.size());
2861 if (value_integer == x)
2863 return token_type::value_integer;
2870 strtof(value_float, token_buffer.data(), &endptr);
2873 assert(endptr == token_buffer.data() + token_buffer.size());
2875 return token_type::value_float;
2886 assert(current == literal_text[0]);
2887 for (std::size_t i = 1; i < length; ++i)
2891 error_message =
"invalid literal";
2892 return token_type::parse_error;
2905 token_buffer.clear();
2906 token_string.clear();
2907 token_string.push_back(std::char_traits<char>::to_char_type(current));
2920 std::char_traits<char>::int_type
get()
2923 current = ia->get_character();
2924 if (
JSON_LIKELY(current != std::char_traits<char>::eof()))
2926 token_string.push_back(std::char_traits<char>::to_char_type(current));
2935 if (
JSON_LIKELY(current != std::char_traits<char>::eof()))
2937 ia->unget_character();
2938 assert(token_string.size() != 0);
2939 token_string.pop_back();
2946 token_buffer.push_back(std::char_traits<char>::to_char_type(c));
2957 return value_integer;
2963 return value_unsigned;
2975 return std::move(token_buffer);
2995 for (
const auto c : token_string)
2997 if (
'\x00' <= c and c <=
'\x1F')
3000 std::stringstream ss;
3001 ss <<
"<U+" << std::setw(4) << std::uppercase << std::setfill(
'0')
3002 << std::hex << static_cast<int>(c) <<
">";
3008 result.push_back(c);
3018 return error_message;
3032 while (current ==
' ' or current ==
'\t' or current ==
'\n' or current ==
'\r');
3038 return token_type::begin_array;
3040 return token_type::end_array;
3042 return token_type::begin_object;
3044 return token_type::end_object;
3046 return token_type::name_separator;
3048 return token_type::value_separator;
3052 return scan_literal(
"true", 4, token_type::literal_true);
3054 return scan_literal(
"false", 5, token_type::literal_false);
3056 return scan_literal(
"null", 4, token_type::literal_null);
3060 return scan_string();
3074 return scan_number();
3079 case std::char_traits<char>::eof():
3080 return token_type::end_of_input;
3084 error_message =
"invalid literal";
3085 return token_type::parse_error;
3094 std::char_traits<char>::int_type current = std::char_traits<char>::eof();
3097 std::size_t chars_read = 0;
3100 std::vector<char> token_string {};
3106 const char* error_message =
"";
3114 const char decimal_point_char =
'.';
3125 #include <functional> 3153 template<
typename BasicJsonType>
3181 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
3186 const bool allow_exceptions_ =
true)
3187 : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_)
3200 void parse(
const bool strict, BasicJsonType& result)
3205 parse_internal(
true, result);
3206 result.assert_invariant();
3212 expect(token_type::end_of_input);
3224 if (result.is_discarded())
3241 if (not accept_internal())
3247 return not strict or (get_token() == token_type::end_of_input);
3260 assert(not errored);
3263 if (not result.is_discarded())
3265 result.m_value.destroy(result.m_type);
3271 case token_type::begin_object:
3277 keep = callback(depth++, parse_event_t::object_start, result);
3280 if (not callback or keep)
3292 if (last_token == token_type::end_object)
3294 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
3296 result.m_value.destroy(result.m_type);
3304 BasicJsonType value;
3308 if (not expect(token_type::value_string))
3312 key = m_lexer.move_string();
3314 bool keep_tag =
false;
3319 BasicJsonType k(key);
3320 keep_tag = callback(depth, parse_event_t::key, k);
3330 if (not expect(token_type::name_separator))
3337 value.m_value.destroy(value.m_type);
3339 parse_internal(keep, value);
3346 if (keep and keep_tag and not value.is_discarded())
3348 result.m_value.object->emplace(std::move(key), std::move(value));
3353 if (last_token == token_type::value_separator)
3360 if (not expect(token_type::end_object))
3367 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
3369 result.m_value.destroy(result.m_type);
3375 case token_type::begin_array:
3381 keep = callback(depth++, parse_event_t::array_start, result);
3384 if (not callback or keep)
3396 if (last_token == token_type::end_array)
3398 if (callback and not callback(--depth, parse_event_t::array_end, result))
3400 result.m_value.destroy(result.m_type);
3407 BasicJsonType value;
3411 value.m_value.destroy(value.m_type);
3413 parse_internal(keep, value);
3420 if (keep and not value.is_discarded())
3422 result.m_value.array->push_back(std::move(value));
3427 if (last_token == token_type::value_separator)
3434 if (not expect(token_type::end_array))
3441 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
3443 result.m_value.destroy(result.m_type);
3449 case token_type::literal_null:
3455 case token_type::value_string:
3458 result.m_value = m_lexer.move_string();
3462 case token_type::literal_true:
3465 result.m_value =
true;
3469 case token_type::literal_false:
3472 result.m_value =
false;
3476 case token_type::value_unsigned:
3479 result.m_value = m_lexer.get_number_unsigned();
3483 case token_type::value_integer:
3486 result.m_value = m_lexer.get_number_integer();
3490 case token_type::value_float:
3493 result.m_value = m_lexer.get_number_float();
3496 if (
JSON_UNLIKELY(not std::isfinite(result.m_value.number_float)))
3498 if (allow_exceptions)
3501 m_lexer.get_token_string() +
"'"));
3503 expect(token_type::uninitialized);
3508 case token_type::parse_error:
3511 if (not expect(token_type::uninitialized))
3521 if (not expect(token_type::literal_or_value))
3529 if (keep and callback and not callback(depth, parse_event_t::value, result))
3531 result.m_value.destroy(result.m_type);
3550 case token_type::begin_object:
3556 if (last_token == token_type::end_object)
3565 if (last_token != token_type::value_string)
3572 if (last_token != token_type::name_separator)
3579 if (not accept_internal())
3586 if (last_token == token_type::value_separator)
3593 return (last_token == token_type::end_object);
3597 case token_type::begin_array:
3603 if (last_token == token_type::end_array)
3612 if (not accept_internal())
3619 if (last_token == token_type::value_separator)
3626 return (last_token == token_type::end_array);
3630 case token_type::value_float:
3633 return std::isfinite(m_lexer.get_number_float());
3636 case token_type::literal_false:
3637 case token_type::literal_null:
3638 case token_type::literal_true:
3639 case token_type::value_integer:
3640 case token_type::value_string:
3641 case token_type::value_unsigned:
3652 return (last_token = m_lexer.scan());
3664 if (allow_exceptions)
3680 if (last_token == token_type::parse_error)
3682 error_msg +=
std::string(m_lexer.get_error_message()) +
"; last read: '" +
3683 m_lexer.get_token_string() +
"'";
3687 error_msg +=
"unexpected " +
std::string(lexer_t::token_type_name(last_token));
3690 if (expected != token_type::uninitialized)
3692 error_msg +=
"; expected " +
std::string(lexer_t::token_type_name(expected));
3708 bool errored =
false;
3712 const bool allow_exceptions =
true;
3767 return m_it == begin_value;
3773 return m_it == end_value;
3778 return lhs.m_it == rhs.m_it;
3783 return lhs.m_it < rhs.m_it;
3788 auto result = *
this;
3795 return lhs.m_it - rhs.m_it;
3806 auto result = *
this;
3819 auto result = *
this;
3858 typename BasicJsonType::object_t::iterator object_iterator {};
3860 typename BasicJsonType::array_t::iterator array_iterator {};
3872 #include <type_traits> 3914 template<
typename BasicJsonType>
3925 static_assert(
is_basic_json<
typename std::remove_const<BasicJsonType>::type>::value,
3926 "iter_impl only accepts (const) basic_json");
3942 using pointer =
typename std::conditional<std::is_const<BasicJsonType>::value,
3943 typename BasicJsonType::const_pointer,
3944 typename BasicJsonType::pointer>::type;
3947 typename std::conditional<std::is_const<BasicJsonType>::value,
3948 typename BasicJsonType::const_reference,
3949 typename BasicJsonType::reference>::type;
3962 assert(m_object !=
nullptr);
3964 switch (m_object->m_type)
3968 m_it.object_iterator =
typename object_t::iterator();
3974 m_it.array_iterator =
typename array_t::iterator();
4001 : m_object(other.m_object), m_it(other.m_it) {}
4023 assert(m_object !=
nullptr);
4025 switch (m_object->m_type)
4029 m_it.object_iterator = m_object->m_value.object->begin();
4035 m_it.array_iterator = m_object->m_value.array->begin();
4042 m_it.primitive_iterator.set_end();
4048 m_it.primitive_iterator.set_begin();
4060 assert(m_object !=
nullptr);
4062 switch (m_object->m_type)
4066 m_it.object_iterator = m_object->m_value.object->end();
4072 m_it.array_iterator = m_object->m_value.array->end();
4078 m_it.primitive_iterator.set_end();
4091 assert(m_object !=
nullptr);
4093 switch (m_object->m_type)
4097 assert(m_it.object_iterator != m_object->m_value.object->end());
4098 return m_it.object_iterator->second;
4103 assert(m_it.array_iterator != m_object->m_value.array->end());
4104 return *m_it.array_iterator;
4112 if (
JSON_LIKELY(m_it.primitive_iterator.is_begin()))
4128 assert(m_object !=
nullptr);
4130 switch (m_object->m_type)
4134 assert(m_it.object_iterator != m_object->m_value.object->end());
4135 return &(m_it.object_iterator->second);
4140 assert(m_it.array_iterator != m_object->m_value.array->end());
4141 return &*m_it.array_iterator;
4146 if (
JSON_LIKELY(m_it.primitive_iterator.is_begin()))
4162 auto result = *
this;
4173 assert(m_object !=
nullptr);
4175 switch (m_object->m_type)
4179 std::advance(m_it.object_iterator, 1);
4185 std::advance(m_it.array_iterator, 1);
4191 ++m_it.primitive_iterator;
4205 auto result = *
this;
4216 assert(m_object !=
nullptr);
4218 switch (m_object->m_type)
4222 std::advance(m_it.object_iterator, -1);
4228 std::advance(m_it.array_iterator, -1);
4234 --m_it.primitive_iterator;
4254 assert(m_object !=
nullptr);
4256 switch (m_object->m_type)
4290 assert(m_object !=
nullptr);
4292 switch (m_object->m_type)
4311 return not other.operator < (*this);
4320 return not operator<=(other);
4338 assert(m_object !=
nullptr);
4340 switch (m_object->m_type)
4347 std::advance(m_it.array_iterator, i);
4353 m_it.primitive_iterator += i;
4367 return operator+=(-i);
4376 auto result = *
this;
4398 auto result = *
this;
4409 assert(m_object !=
nullptr);
4411 switch (m_object->m_type)
4430 assert(m_object !=
nullptr);
4432 switch (m_object->m_type)
4438 return *std::next(m_it.array_iterator, n);
4445 if (
JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
4459 typename object_t::key_type
key()
const 4461 assert(m_object !=
nullptr);
4465 return m_it.object_iterator->first;
4513 std::size_t array_index = 0;
4536 return anchor != o.anchor;
4542 assert(anchor.m_object !=
nullptr);
4544 switch (anchor.m_object->type())
4548 return std::to_string(array_index);
4552 return anchor.key();
4561 typename IteratorType::reference
value()
const 4563 return anchor.value();
4573 : container(cont) {}
4623 template<
typename Base>
4691 return *(this->operator+(n));
4695 auto key() const -> decltype(
std::declval<Base>().key())
4697 auto it = --this->base();
4704 auto it = --this->base();
4705 return it.operator * ();
4714 #include <algorithm> 4730 virtual void write_character(CharType c) = 0;
4731 virtual void write_characters(
const CharType*
s, std::size_t length) = 0;
4736 template<
typename CharType>
4740 template<
typename CharType>
4753 std::copy(s, s + length, std::back_inserter(v));
4757 std::vector<CharType>&
v;
4761 template<
typename CharType>
4774 stream.write(s, static_cast<std::streamsize>(length));
4782 template<
typename CharType,
typename StringType = std::basic_
string<CharType>>
4795 str.append(s, length);
4802 template<
typename CharType,
typename StringType = std::basic_
string<CharType>>
4829 #include <algorithm> 4864 template<
typename BasicJsonType>
4894 const auto res = parse_cbor_internal();
4915 const auto res = parse_msgpack_internal();
4936 const auto res = parse_ubjson_internal();
4954 return (*reinterpret_cast<char*>(&num) == 1);
4965 switch (get_char ?
get() : current)
4968 case std::char_traits<char>::eof():
4999 return get_number<uint8_t>();
5002 return get_number<uint16_t>();
5005 return get_number<uint32_t>();
5008 return get_number<uint64_t>();
5035 return static_cast<int8_t
>(0x20 - 1 - current);
5055 static_cast<number_integer_t>(get_number<uint64_t>());
5089 return get_cbor_string();
5118 return get_cbor_array(current & 0x1F);
5123 return get_cbor_array(get_number<uint8_t>());
5128 return get_cbor_array(get_number<uint16_t>());
5133 return get_cbor_array(get_number<uint32_t>());
5138 return get_cbor_array(get_number<uint64_t>());
5144 while (
get() != 0xFF)
5146 result.push_back(parse_cbor_internal(
false));
5177 return get_cbor_object(current & 0x1F);
5182 return get_cbor_object(get_number<uint8_t>());
5187 return get_cbor_object(get_number<uint16_t>());
5192 return get_cbor_object(get_number<uint32_t>());
5197 return get_cbor_object(get_number<uint64_t>());
5203 while (
get() != 0xFF)
5205 auto key = get_cbor_string();
5206 result[key] = parse_cbor_internal();
5228 const int byte1 =
get();
5230 const int byte2 =
get();
5241 const int half = (byte1 << 8) + byte2;
5242 const int exp = (half >> 10) & 0x1F;
5243 const int mant = half & 0x3FF;
5247 val = std::ldexp(mant, -24);
5251 val = std::ldexp(mant + 1024, exp - 25);
5255 val = (mant == 0) ? std::numeric_limits<double>::infinity()
5256 : std::numeric_limits<double>::quiet_NaN();
5258 return (half & 0x8000) != 0 ? -val : val;
5263 return get_number<float>();
5268 return get_number<double>();
5273 std::stringstream ss;
5274 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5285 case std::char_traits<char>::eof():
5437 return get_msgpack_object(current & 0x0F);
5458 return get_msgpack_array(current & 0x0F);
5494 return get_msgpack_string();
5506 return get_number<float>();
5509 return get_number<double>();
5512 return get_number<uint8_t>();
5515 return get_number<uint16_t>();
5518 return get_number<uint32_t>();
5521 return get_number<uint64_t>();
5524 return get_number<int8_t>();
5527 return get_number<int16_t>();
5530 return get_number<int32_t>();
5533 return get_number<int64_t>();
5538 return get_msgpack_string();
5542 return get_msgpack_array(get_number<uint16_t>());
5547 return get_msgpack_array(get_number<uint32_t>());
5552 return get_msgpack_object(get_number<uint16_t>());
5557 return get_msgpack_object(get_number<uint32_t>());
5593 return static_cast<int8_t
>(current);
5597 std::stringstream ss;
5598 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5600 "error reading MessagePack; last byte: 0x" + ss.str()));
5612 return get_ubjson_value(get_char ? get_ignore_noop() : current);
5627 return (current = ia->get_character());
5639 while (current ==
'N');
5660 std::array<uint8_t, sizeof(NumberType)> vec;
5661 for (std::size_t i = 0; i <
sizeof(NumberType); ++i)
5667 if (is_little_endian)
5669 vec[
sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
5673 vec[i] =
static_cast<uint8_t
>(current);
5679 std::memcpy(&result, vec.data(),
sizeof(NumberType));
5696 template<
typename NumberType>
5700 std::generate_n(std::back_inserter(result), len, [
this]()
5704 return static_cast<char>(current);
5753 return get_string(current & 0x1F);
5758 return get_string(get_number<uint8_t>());
5763 return get_string(get_number<uint16_t>());
5768 return get_string(get_number<uint32_t>());
5773 return get_string(get_number<uint64_t>());
5779 while (
get() != 0xFF)
5781 result.append(get_cbor_string());
5788 std::stringstream ss;
5789 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5795 template<
typename NumberType>
5799 std::generate_n(std::back_inserter(*result.m_value.array), len, [
this]()
5801 return parse_cbor_internal();
5806 template<
typename NumberType>
5810 std::generate_n(std::inserter(*result.m_value.object,
5811 result.m_value.object->end()),
5815 auto key = get_cbor_string();
5816 auto val = parse_cbor_internal();
5817 return std::make_pair(std::move(key), std::move(val));
5873 return get_string(current & 0x1F);
5878 return get_string(get_number<uint8_t>());
5883 return get_string(get_number<uint16_t>());
5888 return get_string(get_number<uint32_t>());
5893 std::stringstream ss;
5894 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5896 "expected a MessagePack string; last byte: 0x" + ss.str()));
5901 template<
typename NumberType>
5905 std::generate_n(std::back_inserter(*result.m_value.array), len, [
this]()
5907 return parse_msgpack_internal();
5912 template<
typename NumberType>
5916 std::generate_n(std::inserter(*result.m_value.object,
5917 result.m_value.object->end()),
5921 auto key = get_msgpack_string();
5922 auto val = parse_msgpack_internal();
5923 return std::make_pair(std::move(key), std::move(val));
5956 return get_string(get_number<uint8_t>());
5958 return get_string(get_number<int8_t>());
5960 return get_string(get_number<int16_t>());
5962 return get_string(get_number<int32_t>());
5964 return get_string(get_number<int64_t>());
5966 std::stringstream ss;
5967 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5969 "expected a UBJSON string; last byte: 0x" + ss.str()));
5983 std::size_t sz = string_t::npos;
5996 std::stringstream ss;
5997 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5999 "expected '#' after UBJSON type information; last byte: 0x" + ss.str()));
6001 sz = parse_ubjson_internal();
6003 else if (current ==
'#')
6005 sz = parse_ubjson_internal();
6008 return std::make_pair(sz, tc);
6015 case std::char_traits<char>::eof():
6027 return get_number<uint8_t>();
6029 return get_number<int8_t>();
6031 return get_number<int16_t>();
6033 return get_number<int32_t>();
6035 return get_number<int64_t>();
6037 return get_number<float>();
6039 return get_number<double>();
6047 std::stringstream ss;
6048 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
6050 "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + ss.str()));
6052 return string_t(1, static_cast<char>(current));
6056 return get_ubjson_string();
6059 return get_ubjson_array();
6062 return get_ubjson_object();
6065 std::stringstream ss;
6066 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
6068 "error reading UBJSON; last byte: 0x" + ss.str()));
6075 const auto size_and_type = get_ubjson_size_type();
6077 if (size_and_type.first != string_t::npos)
6082 "excessive array size: " + std::to_string(size_and_type.first)));
6085 if (size_and_type.second != 0)
6087 if (size_and_type.second !=
'N')
6089 std::generate_n(std::back_inserter(*result.m_value.array),
6090 size_and_type.first, [
this, size_and_type]()
6092 return get_ubjson_value(size_and_type.second);
6098 std::generate_n(std::back_inserter(*result.m_value.array),
6099 size_and_type.first, [
this]()
6101 return parse_ubjson_internal();
6107 while (current !=
']')
6109 result.push_back(parse_ubjson_internal(
false));
6120 const auto size_and_type = get_ubjson_size_type();
6122 if (size_and_type.first != string_t::npos)
6127 "excessive object size: " + std::to_string(size_and_type.first)));
6130 if (size_and_type.second != 0)
6132 std::generate_n(std::inserter(*result.m_value.object,
6133 result.m_value.object->end()),
6134 size_and_type.first, [
this, size_and_type]()
6136 auto key = get_ubjson_string();
6137 auto val = get_ubjson_value(size_and_type.second);
6138 return std::make_pair(std::move(key), std::move(val));
6143 std::generate_n(std::inserter(*result.m_value.object,
6144 result.m_value.object->end()),
6145 size_and_type.first, [
this]()
6147 auto key = get_ubjson_string();
6148 auto val = parse_ubjson_internal();
6149 return std::make_pair(std::move(key), std::move(val));
6155 while (current !=
'}')
6157 auto key = get_ubjson_string(
false);
6158 result[std::move(key)] = parse_ubjson_internal();
6172 if (
JSON_UNLIKELY(current != std::char_traits<char>::eof()))
6184 if (
JSON_UNLIKELY(current == std::char_traits<char>::eof()))
6195 int current = std::char_traits<char>::eof();
6198 std::size_t chars_read = 0;
6201 const bool is_little_endian = little_endianess();
6209 #include <algorithm> 6231 template<
typename BasicJsonType,
typename CharType>
6254 oa->write_character(static_cast<CharType>(0xF6));
6260 oa->write_character(j.m_value.boolean
6261 ? static_cast<CharType>(0xF5)
6262 : static_cast<CharType>(0xF4));
6268 if (j.m_value.number_integer >= 0)
6273 if (j.m_value.number_integer <= 0x17)
6275 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6277 else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
6279 oa->write_character(static_cast<CharType>(0x18));
6280 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6282 else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
6284 oa->write_character(static_cast<CharType>(0x19));
6285 write_number(static_cast<uint16_t>(j.m_value.number_integer));
6287 else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
6289 oa->write_character(static_cast<CharType>(0x1A));
6290 write_number(static_cast<uint32_t>(j.m_value.number_integer));
6294 oa->write_character(static_cast<CharType>(0x1B));
6295 write_number(static_cast<uint64_t>(j.m_value.number_integer));
6302 const auto positive_number = -1 - j.m_value.number_integer;
6303 if (j.m_value.number_integer >= -24)
6305 write_number(static_cast<uint8_t>(0x20 + positive_number));
6307 else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
6309 oa->write_character(static_cast<CharType>(0x38));
6310 write_number(static_cast<uint8_t>(positive_number));
6312 else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
6314 oa->write_character(static_cast<CharType>(0x39));
6315 write_number(static_cast<uint16_t>(positive_number));
6317 else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
6319 oa->write_character(static_cast<CharType>(0x3A));
6320 write_number(static_cast<uint32_t>(positive_number));
6324 oa->write_character(static_cast<CharType>(0x3B));
6325 write_number(static_cast<uint64_t>(positive_number));
6333 if (j.m_value.number_unsigned <= 0x17)
6335 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
6337 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
6339 oa->write_character(static_cast<CharType>(0x18));
6340 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
6342 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
6344 oa->write_character(static_cast<CharType>(0x19));
6345 write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
6347 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
6349 oa->write_character(static_cast<CharType>(0x1A));
6350 write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
6354 oa->write_character(static_cast<CharType>(0x1B));
6355 write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
6362 oa->write_character(static_cast<CharType>(0xFB));
6363 write_number(j.m_value.number_float);
6370 const auto N = j.m_value.string->size();
6373 write_number(static_cast<uint8_t>(0x60 + N));
6375 else if (N <= (std::numeric_limits<uint8_t>::max)())
6377 oa->write_character(static_cast<CharType>(0x78));
6378 write_number(static_cast<uint8_t>(N));
6380 else if (N <= (std::numeric_limits<uint16_t>::max)())
6382 oa->write_character(static_cast<CharType>(0x79));
6383 write_number(static_cast<uint16_t>(N));
6385 else if (N <= (std::numeric_limits<uint32_t>::max)())
6387 oa->write_character(static_cast<CharType>(0x7A));
6388 write_number(static_cast<uint32_t>(N));
6391 else if (N <= (std::numeric_limits<uint64_t>::max)())
6393 oa->write_character(static_cast<CharType>(0x7B));
6394 write_number(static_cast<uint64_t>(N));
6399 oa->write_characters(
6400 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
6401 j.m_value.string->size());
6408 const auto N = j.m_value.array->size();
6411 write_number(static_cast<uint8_t>(0x80 + N));
6413 else if (N <= (std::numeric_limits<uint8_t>::max)())
6415 oa->write_character(static_cast<CharType>(0x98));
6416 write_number(static_cast<uint8_t>(N));
6418 else if (N <= (std::numeric_limits<uint16_t>::max)())
6420 oa->write_character(static_cast<CharType>(0x99));
6421 write_number(static_cast<uint16_t>(N));
6423 else if (N <= (std::numeric_limits<uint32_t>::max)())
6425 oa->write_character(static_cast<CharType>(0x9A));
6426 write_number(static_cast<uint32_t>(N));
6429 else if (N <= (std::numeric_limits<uint64_t>::max)())
6431 oa->write_character(static_cast<CharType>(0x9B));
6432 write_number(static_cast<uint64_t>(N));
6437 for (
const auto& el : *j.m_value.array)
6447 const auto N = j.m_value.object->size();
6450 write_number(static_cast<uint8_t>(0xA0 + N));
6452 else if (N <= (std::numeric_limits<uint8_t>::max)())
6454 oa->write_character(static_cast<CharType>(0xB8));
6455 write_number(static_cast<uint8_t>(N));
6457 else if (N <= (std::numeric_limits<uint16_t>::max)())
6459 oa->write_character(static_cast<CharType>(0xB9));
6460 write_number(static_cast<uint16_t>(N));
6462 else if (N <= (std::numeric_limits<uint32_t>::max)())
6464 oa->write_character(static_cast<CharType>(0xBA));
6465 write_number(static_cast<uint32_t>(N));
6468 else if (N <= (std::numeric_limits<uint64_t>::max)())
6470 oa->write_character(static_cast<CharType>(0xBB));
6471 write_number(static_cast<uint64_t>(N));
6476 for (
const auto& el : *j.m_value.object)
6478 write_cbor(el.first);
6479 write_cbor(el.second);
6498 oa->write_character(static_cast<CharType>(0xC0));
6504 oa->write_character(j.m_value.boolean
6505 ? static_cast<CharType>(0xC3)
6506 : static_cast<CharType>(0xC2));
6512 if (j.m_value.number_integer >= 0)
6517 if (j.m_value.number_unsigned < 128)
6520 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6522 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
6525 oa->write_character(static_cast<CharType>(0xCC));
6526 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6528 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
6531 oa->write_character(static_cast<CharType>(0xCD));
6532 write_number(static_cast<uint16_t>(j.m_value.number_integer));
6534 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
6537 oa->write_character(static_cast<CharType>(0xCE));
6538 write_number(static_cast<uint32_t>(j.m_value.number_integer));
6540 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
6543 oa->write_character(static_cast<CharType>(0xCF));
6544 write_number(static_cast<uint64_t>(j.m_value.number_integer));
6549 if (j.m_value.number_integer >= -32)
6552 write_number(static_cast<int8_t>(j.m_value.number_integer));
6554 else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and
6555 j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
6558 oa->write_character(static_cast<CharType>(0xD0));
6559 write_number(static_cast<int8_t>(j.m_value.number_integer));
6561 else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and
6562 j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
6565 oa->write_character(static_cast<CharType>(0xD1));
6566 write_number(static_cast<int16_t>(j.m_value.number_integer));
6568 else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and
6569 j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
6572 oa->write_character(static_cast<CharType>(0xD2));
6573 write_number(static_cast<int32_t>(j.m_value.number_integer));
6575 else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and
6576 j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
6579 oa->write_character(static_cast<CharType>(0xD3));
6580 write_number(static_cast<int64_t>(j.m_value.number_integer));
6588 if (j.m_value.number_unsigned < 128)
6591 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6593 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
6596 oa->write_character(static_cast<CharType>(0xCC));
6597 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6599 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
6602 oa->write_character(static_cast<CharType>(0xCD));
6603 write_number(static_cast<uint16_t>(j.m_value.number_integer));
6605 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
6608 oa->write_character(static_cast<CharType>(0xCE));
6609 write_number(static_cast<uint32_t>(j.m_value.number_integer));
6611 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
6614 oa->write_character(static_cast<CharType>(0xCF));
6615 write_number(static_cast<uint64_t>(j.m_value.number_integer));
6622 oa->write_character(static_cast<CharType>(0xCB));
6623 write_number(j.m_value.number_float);
6630 const auto N = j.m_value.string->size();
6634 write_number(static_cast<uint8_t>(0xA0 | N));
6636 else if (N <= (std::numeric_limits<uint8_t>::max)())
6639 oa->write_character(static_cast<CharType>(0xD9));
6640 write_number(static_cast<uint8_t>(N));
6642 else if (N <= (std::numeric_limits<uint16_t>::max)())
6645 oa->write_character(static_cast<CharType>(0xDA));
6646 write_number(static_cast<uint16_t>(N));
6648 else if (N <= (std::numeric_limits<uint32_t>::max)())
6651 oa->write_character(static_cast<CharType>(0xDB));
6652 write_number(static_cast<uint32_t>(N));
6656 oa->write_characters(
6657 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
6658 j.m_value.string->size());
6665 const auto N = j.m_value.array->size();
6669 write_number(static_cast<uint8_t>(0x90 | N));
6671 else if (N <= (std::numeric_limits<uint16_t>::max)())
6674 oa->write_character(static_cast<CharType>(0xDC));
6675 write_number(static_cast<uint16_t>(N));
6677 else if (N <= (std::numeric_limits<uint32_t>::max)())
6680 oa->write_character(static_cast<CharType>(0xDD));
6681 write_number(static_cast<uint32_t>(N));
6685 for (
const auto& el : *j.m_value.array)
6695 const auto N = j.m_value.object->size();
6699 write_number(static_cast<uint8_t>(0x80 | (N & 0xF)));
6701 else if (N <= (std::numeric_limits<uint16_t>::max)())
6704 oa->write_character(static_cast<CharType>(0xDE));
6705 write_number(static_cast<uint16_t>(N));
6707 else if (N <= (std::numeric_limits<uint32_t>::max)())
6710 oa->write_character(static_cast<CharType>(0xDF));
6711 write_number(static_cast<uint32_t>(N));
6715 for (
const auto& el : *j.m_value.object)
6717 write_msgpack(el.first);
6718 write_msgpack(el.second);
6735 const bool use_type,
const bool add_prefix =
true)
6743 oa->write_character(static_cast<CharType>(
'Z'));
6751 oa->write_character(j.m_value.boolean
6752 ? static_cast<CharType>(
'T')
6753 : static_cast<CharType>(
'F'));
6759 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
6765 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
6771 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
6779 oa->write_character(static_cast<CharType>(
'S'));
6781 write_number_with_ubjson_prefix(j.m_value.string->size(),
true);
6782 oa->write_characters(
6783 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
6784 j.m_value.string->size());
6792 oa->write_character(static_cast<CharType>(
'['));
6795 bool prefix_required =
true;
6796 if (use_type and not j.m_value.array->empty())
6799 const char first_prefix = ubjson_prefix(j.front());
6800 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
6801 [
this, first_prefix](
const BasicJsonType & v)
6803 return ubjson_prefix(v) == first_prefix;
6808 prefix_required =
false;
6809 oa->write_character(static_cast<CharType>(
'$'));
6810 oa->write_character(static_cast<CharType>(first_prefix));
6816 oa->write_character(static_cast<CharType>(
'#'));
6817 write_number_with_ubjson_prefix(j.m_value.array->size(),
true);
6820 for (
const auto& el : *j.m_value.array)
6822 write_ubjson(el, use_count, use_type, prefix_required);
6827 oa->write_character(static_cast<CharType>(
']'));
6837 oa->write_character(static_cast<CharType>(
'{'));
6840 bool prefix_required =
true;
6841 if (use_type and not j.m_value.object->empty())
6844 const char first_prefix = ubjson_prefix(j.front());
6845 const bool same_prefix = std::all_of(j.begin(), j.end(),
6846 [
this, first_prefix](
const BasicJsonType & v)
6848 return ubjson_prefix(v) == first_prefix;
6853 prefix_required =
false;
6854 oa->write_character(static_cast<CharType>(
'$'));
6855 oa->write_character(static_cast<CharType>(first_prefix));
6861 oa->write_character(static_cast<CharType>(
'#'));
6862 write_number_with_ubjson_prefix(j.m_value.object->size(),
true);
6865 for (
const auto& el : *j.m_value.object)
6867 write_number_with_ubjson_prefix(el.first.size(),
true);
6868 oa->write_characters(
6869 reinterpret_cast<const CharType*>(el.first.c_str()),
6871 write_ubjson(el.second, use_count, use_type, prefix_required);
6876 oa->write_character(static_cast<CharType>(
'}'));
6898 template<
typename NumberType>
6902 std::array<CharType, sizeof(NumberType)> vec;
6903 std::memcpy(vec.data(), &n,
sizeof(NumberType));
6906 if (is_little_endian)
6909 std::reverse(vec.begin(), vec.end());
6912 oa->write_characters(vec.data(),
sizeof(NumberType));
6916 template<
typename NumberType,
typename std::enable_if<
6917 std::is_floating_point<NumberType>::value,
int>::type = 0>
6919 const bool add_prefix)
6923 oa->write_character(static_cast<CharType>(
'D'));
6929 template<
typename NumberType,
typename std::enable_if<
6930 std::is_unsigned<NumberType>::value,
int>::type = 0>
6932 const bool add_prefix)
6934 if (n <= static_cast<uint64_t>((std::numeric_limits<int8_t>::max)()))
6938 oa->write_character(static_cast<CharType>(
'i'));
6940 write_number(static_cast<uint8_t>(n));
6942 else if (n <= (std::numeric_limits<uint8_t>::max)())
6946 oa->write_character(static_cast<CharType>(
'U'));
6948 write_number(static_cast<uint8_t>(n));
6950 else if (n <= static_cast<uint64_t>((std::numeric_limits<int16_t>::max)()))
6954 oa->write_character(static_cast<CharType>(
'I'));
6956 write_number(static_cast<int16_t>(n));
6958 else if (n <= static_cast<uint64_t>((std::numeric_limits<int32_t>::max)()))
6962 oa->write_character(static_cast<CharType>(
'l'));
6964 write_number(static_cast<int32_t>(n));
6966 else if (n <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)()))
6970 oa->write_character(static_cast<CharType>(
'L'));
6972 write_number(static_cast<int64_t>(n));
6981 template<
typename NumberType,
typename std::enable_if<
6982 std::is_signed<NumberType>::value and
6983 not std::is_floating_point<NumberType>::value,
int>::type = 0>
6985 const bool add_prefix)
6987 if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)())
6991 oa->write_character(static_cast<CharType>(
'i'));
6993 write_number(static_cast<int8_t>(n));
6995 else if (static_cast<int64_t>((std::numeric_limits<uint8_t>::min)()) <= n and n <= static_cast<int64_t>((std::numeric_limits<uint8_t>::max)()))
6999 oa->write_character(static_cast<CharType>(
'U'));
7001 write_number(static_cast<uint8_t>(n));
7003 else if ((std::numeric_limits<int16_t>::min)() <= n and n <= (std::numeric_limits<int16_t>::max)())
7007 oa->write_character(static_cast<CharType>(
'I'));
7009 write_number(static_cast<int16_t>(n));
7011 else if ((std::numeric_limits<int32_t>::min)() <= n and n <= (std::numeric_limits<int32_t>::max)())
7015 oa->write_character(static_cast<CharType>(
'l'));
7017 write_number(static_cast<int32_t>(n));
7019 else if ((std::numeric_limits<int64_t>::min)() <= n and n <= (std::numeric_limits<int64_t>::max)())
7023 oa->write_character(static_cast<CharType>(
'L'));
7025 write_number(static_cast<int64_t>(n));
7052 return j.m_value.boolean ?
'T' :
'F';
7056 if ((std::numeric_limits<int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
7060 else if ((std::numeric_limits<uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
7064 else if ((std::numeric_limits<int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
7068 else if ((std::numeric_limits<int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
7080 if (j.m_value.number_unsigned <= (std::numeric_limits<int8_t>::max)())
7084 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
7088 else if (j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max)())
7092 else if (j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max)())
7132 #include <algorithm> 7146 #include <type_traits> 7186 template <
typename Target,
typename Source>
7189 static_assert(
sizeof(Target) ==
sizeof(Source),
"size mismatch");
7192 std::memcpy(&target, &source,
sizeof(Source));
7198 static constexpr
int kPrecision = 64;
7203 constexpr
diyfp() noexcept : f(0), e(0) {}
7204 constexpr
diyfp(uint64_t f_,
int e_) noexcept : f(f_), e(e_) {}
7215 return diyfp(x.f - y.f, x.e);
7224 static_assert(kPrecision == 64,
"internal error");
7249 const uint64_t u_lo = x.f & 0xFFFFFFFF;
7250 const uint64_t u_hi = x.f >> 32;
7251 const uint64_t v_lo = y.f & 0xFFFFFFFF;
7252 const uint64_t v_hi = y.f >> 32;
7254 const uint64_t p0 = u_lo * v_lo;
7255 const uint64_t p1 = u_lo * v_hi;
7256 const uint64_t p2 = u_hi * v_lo;
7257 const uint64_t p3 = u_hi * v_hi;
7259 const uint64_t p0_hi = p0 >> 32;
7260 const uint64_t p1_lo = p1 & 0xFFFFFFFF;
7261 const uint64_t p1_hi = p1 >> 32;
7262 const uint64_t p2_lo = p2 & 0xFFFFFFFF;
7263 const uint64_t p2_hi = p2 >> 32;
7265 uint64_t Q = p0_hi + p1_lo + p2_lo;
7276 Q += uint64_t{1} << (64 - 32 - 1);
7278 const uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32);
7280 return diyfp(h, x.e + y.e + 64);
7291 while ((x.f >> 63) == 0)
7306 const int delta = x.
e - target_exponent;
7309 assert(((x.f << delta) >> delta) == x.f);
7311 return diyfp(x.f << delta, target_exponent);
7328 template <
typename FloatType>
7331 assert(std::isfinite(value));
7341 static_assert(std::numeric_limits<FloatType>::is_iec559,
7342 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
7344 constexpr
int kPrecision = std::numeric_limits<FloatType>::digits;
7345 constexpr
int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
7346 constexpr
int kMinExp = 1 - kBias;
7347 constexpr uint64_t kHiddenBit = uint64_t{1} << (kPrecision - 1);
7349 using bits_type =
typename std::conditional< kPrecision == 24, uint32_t, uint64_t >::type;
7351 const uint64_t bits = reinterpret_bits<bits_type>(value);
7352 const uint64_t E = bits >> (kPrecision - 1);
7353 const uint64_t F = bits & (kHiddenBit - 1);
7355 const bool is_denormal = (E == 0);
7356 const diyfp v = is_denormal
7358 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
7381 const bool lower_boundary_is_closer = (F == 0 and E > 1);
7382 const diyfp m_plus = diyfp(2 * v.
f + 1, v.
e - 1);
7383 const diyfp m_minus = lower_boundary_is_closer
7384 ? diyfp(4 * v.
f - 1, v.
e - 2)
7385 : diyfp(2 * v.
f - 1, v.
e - 1);
7388 const diyfp w_plus = diyfp::normalize(m_plus);
7391 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.
e);
7393 return {diyfp::normalize(v), w_minus, w_plus};
7520 constexpr
int kCachedPowersSize = 79;
7521 constexpr
int kCachedPowersMinDecExp = -300;
7522 constexpr
int kCachedPowersDecStep = 8;
7526 { 0xAB70FE17C79AC6CA, -1060, -300 },
7527 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
7528 { 0xBE5691EF416BD60C, -1007, -284 },
7529 { 0x8DD01FAD907FFC3C, -980, -276 },
7530 { 0xD3515C2831559A83, -954, -268 },
7531 { 0x9D71AC8FADA6C9B5, -927, -260 },
7532 { 0xEA9C227723EE8BCB, -901, -252 },
7533 { 0xAECC49914078536D, -874, -244 },
7534 { 0x823C12795DB6CE57, -847, -236 },
7535 { 0xC21094364DFB5637, -821, -228 },
7536 { 0x9096EA6F3848984F, -794, -220 },
7537 { 0xD77485CB25823AC7, -768, -212 },
7538 { 0xA086CFCD97BF97F4, -741, -204 },
7539 { 0xEF340A98172AACE5, -715, -196 },
7540 { 0xB23867FB2A35B28E, -688, -188 },
7541 { 0x84C8D4DFD2C63F3B, -661, -180 },
7542 { 0xC5DD44271AD3CDBA, -635, -172 },
7543 { 0x936B9FCEBB25C996, -608, -164 },
7544 { 0xDBAC6C247D62A584, -582, -156 },
7545 { 0xA3AB66580D5FDAF6, -555, -148 },
7546 { 0xF3E2F893DEC3F126, -529, -140 },
7547 { 0xB5B5ADA8AAFF80B8, -502, -132 },
7548 { 0x87625F056C7C4A8B, -475, -124 },
7549 { 0xC9BCFF6034C13053, -449, -116 },
7550 { 0x964E858C91BA2655, -422, -108 },
7551 { 0xDFF9772470297EBD, -396, -100 },
7552 { 0xA6DFBD9FB8E5B88F, -369, -92 },
7553 { 0xF8A95FCF88747D94, -343, -84 },
7554 { 0xB94470938FA89BCF, -316, -76 },
7555 { 0x8A08F0F8BF0F156B, -289, -68 },
7556 { 0xCDB02555653131B6, -263, -60 },
7557 { 0x993FE2C6D07B7FAC, -236, -52 },
7558 { 0xE45C10C42A2B3B06, -210, -44 },
7559 { 0xAA242499697392D3, -183, -36 },
7560 { 0xFD87B5F28300CA0E, -157, -28 },
7561 { 0xBCE5086492111AEB, -130, -20 },
7562 { 0x8CBCCC096F5088CC, -103, -12 },
7563 { 0xD1B71758E219652C, -77, -4 },
7564 { 0x9C40000000000000, -50, 4 },
7565 { 0xE8D4A51000000000, -24, 12 },
7566 { 0xAD78EBC5AC620000, 3, 20 },
7567 { 0x813F3978F8940984, 30, 28 },
7568 { 0xC097CE7BC90715B3, 56, 36 },
7569 { 0x8F7E32CE7BEA5C70, 83, 44 },
7570 { 0xD5D238A4ABE98068, 109, 52 },
7571 { 0x9F4F2726179A2245, 136, 60 },
7572 { 0xED63A231D4C4FB27, 162, 68 },
7573 { 0xB0DE65388CC8ADA8, 189, 76 },
7574 { 0x83C7088E1AAB65DB, 216, 84 },
7575 { 0xC45D1DF942711D9A, 242, 92 },
7576 { 0x924D692CA61BE758, 269, 100 },
7577 { 0xDA01EE641A708DEA, 295, 108 },
7578 { 0xA26DA3999AEF774A, 322, 116 },
7579 { 0xF209787BB47D6B85, 348, 124 },
7580 { 0xB454E4A179DD1877, 375, 132 },
7581 { 0x865B86925B9BC5C2, 402, 140 },
7582 { 0xC83553C5C8965D3D, 428, 148 },
7583 { 0x952AB45CFA97A0B3, 455, 156 },
7584 { 0xDE469FBD99A05FE3, 481, 164 },
7585 { 0xA59BC234DB398C25, 508, 172 },
7586 { 0xF6C69A72A3989F5C, 534, 180 },
7587 { 0xB7DCBF5354E9BECE, 561, 188 },
7588 { 0x88FCF317F22241E2, 588, 196 },
7589 { 0xCC20CE9BD35C78A5, 614, 204 },
7590 { 0x98165AF37B2153DF, 641, 212 },
7591 { 0xE2A0B5DC971F303A, 667, 220 },
7592 { 0xA8D9D1535CE3B396, 694, 228 },
7593 { 0xFB9B7CD9A4A7443C, 720, 236 },
7594 { 0xBB764C4CA7A44410, 747, 244 },
7595 { 0x8BAB8EEFB6409C1A, 774, 252 },
7596 { 0xD01FEF10A657842C, 800, 260 },
7597 { 0x9B10A4E5E9913129, 827, 268 },
7598 { 0xE7109BFBA19C0C9D, 853, 276 },
7599 { 0xAC2820D9623BF429, 880, 284 },
7600 { 0x80444B5E7AA7CF85, 907, 292 },
7601 { 0xBF21E44003ACDD2D, 933, 300 },
7602 { 0x8E679C2F5E44FF8F, 960, 308 },
7603 { 0xD433179D9C8CB841, 986, 316 },
7604 { 0x9E19DB92B4E31BA9, 1013, 324 },
7613 const int f = kAlpha - e - 1;
7614 const int k = (f * 78913) / (1 << 18) + (f > 0);
7616 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
7618 assert(index < kCachedPowersSize);
7619 static_cast<void>(kCachedPowersSize);
7622 assert(kAlpha <= cached.
e + e + 64);
7623 assert(kGamma >= cached.
e + e + 64);
7635 if (n >= 1000000000)
7641 else if (n >= 100000000)
7646 else if (n >= 10000000)
7651 else if (n >= 1000000)
7656 else if (n >= 100000)
7661 else if (n >= 10000)
7688 inline void grisu2_round(
char* buf,
int len, uint64_t dist, uint64_t delta,
7689 uint64_t rest, uint64_t ten_k)
7692 assert(dist <= delta);
7693 assert(rest <= delta);
7716 and delta - rest >= ten_k
7717 and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
7719 assert(buf[len - 1] !=
'0');
7732 static_assert(kAlpha >= -60,
"internal error");
7733 static_assert(kGamma <= -32,
"internal error");
7747 assert(M_plus.
e >= kAlpha);
7748 assert(M_plus.
e <= kGamma);
7750 uint64_t delta = diyfp::sub(M_plus, M_minus).f;
7751 uint64_t dist = diyfp::sub(M_plus, w ).f;
7760 const diyfp one(uint64_t{1} << -M_plus.
e, M_plus.
e);
7762 uint32_t p1 =
static_cast<uint32_t
>(M_plus.
f >> -one.e);
7763 uint64_t p2 = M_plus.
f & (one.f - 1);
7799 const uint32_t
d = p1 / pow10;
7800 const uint32_t r = p1 % pow10;
7806 buffer[length++] =
static_cast<char>(
'0' +
d);
7825 const uint64_t rest = (uint64_t{p1} << -one.e) + p2;
7830 decimal_exponent += n;
7841 const uint64_t ten_n = uint64_t{pow10} << -one.e;
7842 grisu2_round(buffer, length, dist, delta, rest, ten_n);
7903 assert(p2 <= UINT64_MAX / 10);
7905 const uint64_t
d = p2 >> -one.e;
7906 const uint64_t r = p2 & (one.f - 1);
7913 buffer[length++] =
static_cast<char>(
'0' +
d);
7938 decimal_exponent -= m;
7946 const uint64_t ten_m = one.f;
7969 inline void grisu2(
char* buf,
int& len,
int& decimal_exponent,
7972 assert(m_plus.
e == m_minus.
e);
7973 assert(m_plus.
e == v.
e);
7986 const diyfp c_minus_k(cached.
f, cached.
e);
7989 const diyfp w = diyfp::mul(v, c_minus_k);
7990 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
7991 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
8014 const diyfp M_minus(w_minus.
f + 1, w_minus.
e);
8015 const diyfp M_plus (w_plus.
f - 1, w_plus.
e );
8017 decimal_exponent = -cached.
k;
8027 template <
typename FloatType>
8028 void grisu2(
char* buf,
int& len,
int& decimal_exponent, FloatType value)
8030 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
8031 "internal error: not enough precision");
8033 assert(std::isfinite(value));
8081 uint32_t k =
static_cast<uint32_t
>(e);
8087 *buf++ =
static_cast<char>(
'0' + k);
8091 *buf++ =
static_cast<char>(
'0' + k / 10);
8093 *buf++ =
static_cast<char>(
'0' + k);
8097 *buf++ =
static_cast<char>(
'0' + k / 100);
8099 *buf++ =
static_cast<char>(
'0' + k / 10);
8101 *buf++ =
static_cast<char>(
'0' + k);
8117 int min_exp,
int max_exp)
8119 assert(min_exp < 0);
8120 assert(max_exp > 0);
8123 const int n = len + decimal_exponent;
8129 if (k <= n and n <= max_exp)
8134 std::memset(buf + k,
'0', static_cast<size_t>(n - k));
8138 return buf + (n + 2);
8141 if (0 < n and n <= max_exp)
8148 std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
8150 return buf + (k + 1);
8153 if (min_exp < n and n <= 0)
8158 std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
8161 std::memset(buf + 2,
'0', static_cast<size_t>(-n));
8162 return buf + (2 + (-n) + k);
8177 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
8198 template <
typename FloatType>
8199 char*
to_chars(
char* first,
char* last, FloatType value)
8201 static_cast<void>(last);
8202 assert(std::isfinite(value));
8205 if (std::signbit(value))
8220 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
8227 int decimal_exponent = 0;
8230 assert(len <= std::numeric_limits<FloatType>::max_digits10);
8233 constexpr
int kMinExp = -4;
8235 constexpr
int kMaxExp = std::numeric_limits<FloatType>::digits10;
8237 assert(last - first >= kMaxExp + 2);
8238 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
8239 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
8264 template<
typename BasicJsonType>
8271 static constexpr uint8_t UTF8_ACCEPT = 0;
8272 static constexpr uint8_t UTF8_REJECT = 1;
8280 : o(
std::move(s)), loc(
std::localeconv()),
8281 thousands_sep(loc->thousands_sep == nullptr ?
'\0' : * (loc->thousands_sep)),
8282 decimal_point(loc->decimal_point == nullptr ?
'\0' : * (loc->decimal_point)),
8283 indent_char(ichar), indent_string(512, indent_char)
8307 void dump(
const BasicJsonType& val,
const bool pretty_print,
8308 const bool ensure_ascii,
8309 const unsigned int indent_step,
8310 const unsigned int current_indent = 0)
8316 if (val.m_value.object->empty())
8318 o->write_characters(
"{}", 2);
8324 o->write_characters(
"{\n", 2);
8327 const auto new_indent = current_indent + indent_step;
8330 indent_string.resize(indent_string.size() * 2,
' ');
8334 auto i = val.m_value.object->cbegin();
8335 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
8337 o->write_characters(indent_string.c_str(), new_indent);
8338 o->write_character(
'\"');
8339 dump_escaped(i->first, ensure_ascii);
8340 o->write_characters(
"\": ", 3);
8341 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
8342 o->write_characters(
",\n", 2);
8346 assert(i != val.m_value.object->cend());
8347 assert(std::next(i) == val.m_value.object->cend());
8348 o->write_characters(indent_string.c_str(), new_indent);
8349 o->write_character(
'\"');
8350 dump_escaped(i->first, ensure_ascii);
8351 o->write_characters(
"\": ", 3);
8352 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
8354 o->write_character(
'\n');
8355 o->write_characters(indent_string.c_str(), current_indent);
8356 o->write_character(
'}');
8360 o->write_character(
'{');
8363 auto i = val.m_value.object->cbegin();
8364 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
8366 o->write_character(
'\"');
8367 dump_escaped(i->first, ensure_ascii);
8368 o->write_characters(
"\":", 2);
8369 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
8370 o->write_character(
',');
8374 assert(i != val.m_value.object->cend());
8375 assert(std::next(i) == val.m_value.object->cend());
8376 o->write_character(
'\"');
8377 dump_escaped(i->first, ensure_ascii);
8378 o->write_characters(
"\":", 2);
8379 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
8381 o->write_character(
'}');
8389 if (val.m_value.array->empty())
8391 o->write_characters(
"[]", 2);
8397 o->write_characters(
"[\n", 2);
8400 const auto new_indent = current_indent + indent_step;
8403 indent_string.resize(indent_string.size() * 2,
' ');
8407 for (
auto i = val.m_value.array->cbegin();
8408 i != val.m_value.array->cend() - 1; ++i)
8410 o->write_characters(indent_string.c_str(), new_indent);
8411 dump(*i,
true, ensure_ascii, indent_step, new_indent);
8412 o->write_characters(
",\n", 2);
8416 assert(not val.m_value.array->empty());
8417 o->write_characters(indent_string.c_str(), new_indent);
8418 dump(val.m_value.array->back(),
true, ensure_ascii, indent_step, new_indent);
8420 o->write_character(
'\n');
8421 o->write_characters(indent_string.c_str(), current_indent);
8422 o->write_character(
']');
8426 o->write_character(
'[');
8429 for (
auto i = val.m_value.array->cbegin();
8430 i != val.m_value.array->cend() - 1; ++i)
8432 dump(*i,
false, ensure_ascii, indent_step, current_indent);
8433 o->write_character(
',');
8437 assert(not val.m_value.array->empty());
8438 dump(val.m_value.array->back(),
false, ensure_ascii, indent_step, current_indent);
8440 o->write_character(
']');
8448 o->write_character(
'\"');
8449 dump_escaped(*val.m_value.string, ensure_ascii);
8450 o->write_character(
'\"');
8456 if (val.m_value.boolean)
8458 o->write_characters(
"true", 4);
8462 o->write_characters(
"false", 5);
8469 dump_integer(val.m_value.number_integer);
8475 dump_integer(val.m_value.number_unsigned);
8481 dump_float(val.m_value.number_float);
8487 o->write_characters(
"<discarded>", 11);
8493 o->write_characters(
"null", 4);
8517 uint8_t state = UTF8_ACCEPT;
8518 std::size_t bytes = 0;
8520 for (std::size_t i = 0; i < s.size(); ++i)
8522 const auto byte =
static_cast<uint8_t
>(s[i]);
8524 switch (decode(state, codepoint, byte))
8532 string_buffer[bytes++] =
'\\';
8533 string_buffer[bytes++] =
'b';
8539 string_buffer[bytes++] =
'\\';
8540 string_buffer[bytes++] =
't';
8546 string_buffer[bytes++] =
'\\';
8547 string_buffer[bytes++] =
'n';
8553 string_buffer[bytes++] =
'\\';
8554 string_buffer[bytes++] =
'f';
8560 string_buffer[bytes++] =
'\\';
8561 string_buffer[bytes++] =
'r';
8567 string_buffer[bytes++] =
'\\';
8568 string_buffer[bytes++] =
'\"';
8574 string_buffer[bytes++] =
'\\';
8575 string_buffer[bytes++] =
'\\';
8583 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
8585 if (codepoint <= 0xFFFF)
8587 std::snprintf(string_buffer.data() + bytes, 7,
"\\u%04x",
8588 static_cast<uint16_t
>(codepoint));
8593 std::snprintf(string_buffer.data() + bytes, 13,
"\\u%04x\\u%04x",
8594 static_cast<uint16_t
>(0xD7C0 + (codepoint >> 10)),
8595 static_cast<uint16_t
>(0xDC00 + (codepoint & 0x3FF)));
8603 string_buffer[bytes++] = s[i];
8612 if (string_buffer.size() - bytes < 13)
8614 o->write_characters(string_buffer.data(), bytes);
8622 std::stringstream ss;
8623 ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << static_cast<int>(byte);
8629 if (not ensure_ascii)
8632 string_buffer[bytes++] = s[i];
8644 o->write_characters(string_buffer.data(), bytes);
8650 std::stringstream ss;
8651 ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << static_cast<int>(
static_cast<uint8_t
>(s.back()));
8666 std::is_same<NumberType, number_unsigned_t>::value or
8667 std::is_same<NumberType, number_integer_t>::value,
8674 o->write_character(
'0');
8678 const bool is_negative = (x <= 0) and (x != 0);
8684 assert(i < number_buffer.size() - 1);
8686 const auto digit = std::labs(static_cast<long>(x % 10));
8687 number_buffer[i++] =
static_cast<char>(
'0' + digit);
8694 assert(i < number_buffer.size() - 2);
8695 number_buffer[i++] =
'-';
8698 std::reverse(number_buffer.begin(), number_buffer.begin() + i);
8699 o->write_characters(number_buffer.data(), i);
8713 if (not std::isfinite(x))
8715 o->write_characters(
"null", 4);
8724 static constexpr
bool is_ieee_single_or_double
8725 = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and std::numeric_limits<number_float_t>::max_exponent == 128) or
8726 (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and std::numeric_limits<number_float_t>::max_exponent == 1024);
8728 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
8733 char* begin = number_buffer.data();
8736 o->write_characters(begin, static_cast<size_t>(end - begin));
8742 static constexpr
auto d = std::numeric_limits<number_float_t>::max_digits10;
8745 std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(),
"%.*g",
d, x);
8750 assert(static_cast<std::size_t>(len) < number_buffer.size());
8753 if (thousands_sep !=
'\0')
8755 const auto end = std::remove(number_buffer.begin(),
8756 number_buffer.begin() + len, thousands_sep);
8757 std::fill(end, number_buffer.end(),
'\0');
8758 assert((end - number_buffer.begin()) <= len);
8759 len = (end - number_buffer.begin());
8763 if (decimal_point !=
'\0' and decimal_point !=
'.')
8765 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
8766 if (dec_pos != number_buffer.end())
8772 o->write_characters(number_buffer.data(),
static_cast<std::size_t
>(len));
8775 const bool value_is_int_like =
8776 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
8779 return (c ==
'.' or c ==
'e');
8782 if (value_is_int_like)
8784 o->write_characters(
".0", 2);
8809 static uint8_t
decode(uint8_t& state, uint32_t& codep,
const uint8_t byte) noexcept
8811 static const std::array<uint8_t, 400> utf8d =
8814 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8815 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8816 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8817 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8818 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
8819 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
8820 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
8821 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
8822 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
8823 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
8824 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1,
8825 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
8826 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1,
8827 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
8831 const uint8_t type = utf8d[byte];
8833 codep = (state != UTF8_ACCEPT)
8834 ? (byte & 0x3fu) | (codep << 6)
8835 : static_cast<uint32_t>(0xff >> type) & (byte);
8837 state = utf8d[256u + state * 16u + type];
8846 std::array<char, 64> number_buffer{{}};
8849 const std::lconv* loc =
nullptr;
8851 const char thousands_sep =
'\0';
8853 const char decimal_point =
'\0';
8856 std::array<char, 512> string_buffer{{}};
8869 #include <initializer_list> 8876 template<
typename BasicJsonType>
8883 : owned_value(
std::move(value)), value_ref(&owned_value), is_rvalue(true)
8887 : value_ref(const_cast<
value_type*>(&value)), is_rvalue(false)
8891 : owned_value(init), value_ref(&owned_value), is_rvalue(true)
8894 template<
class... Args>
8896 : owned_value(
std::forward<Args>(args)...), value_ref(&owned_value), is_rvalue(true)
8908 return std::move(*value_ref);
8915 return *
static_cast<value_type const*
>(value_ref);
8920 return static_cast<value_type const*
>(value_ref);
8948 template<
typename BasicJsonType>
8978 : reference_tokens(split(
s))
8998 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
9002 return a +
"/" + escape(b);
9021 std::size_t processed_chars = 0;
9022 const int res = std::stoi(s, &processed_chars);
9045 auto last = reference_tokens.back();
9046 reference_tokens.pop_back();
9053 return reference_tokens.empty();
9078 using size_type =
typename BasicJsonType::size_type;
9083 for (
const auto& reference_token : reference_tokens)
9085 switch (result->m_type)
9089 if (reference_token ==
"0")
9092 result = &result->operator[](0);
9097 result = &result->operator[](reference_token);
9105 result = &result->operator[](reference_token);
9114 result = &result->operator[](
static_cast<size_type
>(array_index(reference_token)));
9158 using size_type =
typename BasicJsonType::size_type;
9159 for (
const auto& reference_token : reference_tokens)
9166 std::all_of(reference_token.begin(), reference_token.end(),
9169 return (x >=
'0' and x <=
'9');
9173 *ptr = (nums or reference_token ==
"-")
9178 switch (ptr->m_type)
9183 ptr = &ptr->operator[](reference_token);
9190 if (
JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0'))
9193 "array index '" + reference_token +
9194 "' must not begin with '0'"));
9197 if (reference_token ==
"-")
9200 ptr = &ptr->operator[](ptr->m_value.array->size());
9207 ptr = &ptr->operator[](
9208 static_cast<size_type
>(array_index(reference_token)));
9234 using size_type =
typename BasicJsonType::size_type;
9235 for (
const auto& reference_token : reference_tokens)
9237 switch (ptr->m_type)
9242 ptr = &ptr->at(reference_token);
9252 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
9253 ") is out of range"));
9257 if (
JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0'))
9260 "array index '" + reference_token +
9261 "' must not begin with '0'"));
9267 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
9299 using size_type =
typename BasicJsonType::size_type;
9300 for (
const auto& reference_token : reference_tokens)
9302 switch (ptr->m_type)
9307 ptr = &ptr->operator[](reference_token);
9317 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
9318 ") is out of range"));
9322 if (
JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0'))
9325 "array index '" + reference_token +
9326 "' must not begin with '0'"));
9332 ptr = &ptr->operator[](
9333 static_cast<size_type
>(array_index(reference_token)));
9358 using size_type =
typename BasicJsonType::size_type;
9359 for (
const auto& reference_token : reference_tokens)
9361 switch (ptr->m_type)
9366 ptr = &ptr->at(reference_token);
9376 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
9377 ") is out of range"));
9381 if (
JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0'))
9384 "array index '" + reference_token +
9385 "' must not begin with '0'"));
9391 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
9419 std::vector<std::string> result;
9422 if (reference_string.empty())
9431 "JSON pointer must be empty or begin with '/' - was: '" +
9432 reference_string +
"'"));
9440 std::size_t slash = reference_string.find_first_of(
'/', 1),
9449 slash = reference_string.find_first_of(
'/',
start))
9453 auto reference_token = reference_string.substr(
start, slash -
start);
9456 for (std::size_t pos = reference_token.find_first_of(
'~');
9457 pos != std::string::npos;
9458 pos = reference_token.find_first_of(
'~', pos + 1))
9460 assert(reference_token[pos] ==
'~');
9464 (reference_token[pos + 1] !=
'0' and
9465 reference_token[pos + 1] !=
'1')))
9472 unescape(reference_token);
9473 result.push_back(reference_token);
9495 assert(not f.empty());
9496 for (
auto pos = s.find(f);
9497 pos != std::string::npos;
9498 s.replace(pos, f.size(), t),
9499 pos = s.find(f, pos + t.size()))
9506 replace_substring(s,
"~",
"~0");
9507 replace_substring(s,
"/",
"~1");
9514 replace_substring(s,
"~1",
"/");
9515 replace_substring(s,
"~0",
"~");
9526 const BasicJsonType& value,
9527 BasicJsonType& result)
9529 switch (value.m_type)
9533 if (value.m_value.array->empty())
9536 result[reference_string] =
nullptr;
9541 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
9543 flatten(reference_string +
"/" + std::to_string(i),
9544 value.m_value.array->operator[](i), result);
9552 if (value.m_value.object->empty())
9555 result[reference_string] =
nullptr;
9560 for (
const auto& element : *value.m_value.object)
9562 flatten(reference_string +
"/" + escape(element.first), element.second, result);
9571 result[reference_string] = value;
9587 static BasicJsonType
9595 BasicJsonType result;
9598 for (
const auto& element : *value.m_value.object)
9618 return (lhs.reference_tokens == rhs.reference_tokens);
9624 return not (lhs == rhs);
9644 template<
typename,
typename>
9656 template<
typename BasicJsonType,
typename ValueType>
9657 static void from_json(BasicJsonType&& j, ValueType& val) noexcept(
9672 template<
typename BasicJsonType,
typename ValueType>
9673 static void to_json(BasicJsonType& j, ValueType&& val) noexcept(
9776 friend ::nlohmann::json_pointer<basic_json>;
9777 friend ::nlohmann::detail::parser<basic_json>;
9778 friend ::nlohmann::detail::serializer<basic_json>;
9779 template<
typename BasicJsonType>
9780 friend class ::nlohmann::detail::iter_impl;
9781 template<
typename BasicJsonType,
typename CharType>
9782 friend class ::nlohmann::detail::binary_writer;
9783 template<
typename BasicJsonType>
9784 friend class ::nlohmann::detail::binary_reader;
9794 template<
typename BasicJsonType>
9796 template<
typename BasicJsonType>
9798 template<
typename Iterator>
9802 template<
typename CharType>
9814 template<
typename T,
typename SFINAE>
9869 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
9871 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
9923 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
9924 result[
"name"] =
"JSON for Modern C++";
9925 result[
"url"] =
"https://github.com/nlohmann/json";
9926 result[
"version"][
"string"] =
9935 result[
"platform"] =
"win32";
9936 #elif defined __linux__ 9937 result[
"platform"] =
"linux";
9938 #elif defined __APPLE__ 9939 result[
"platform"] =
"apple";
9940 #elif defined __unix__ 9941 result[
"platform"] =
"unix";
9943 result[
"platform"] =
"unknown";
9946 #if defined(__ICC) || defined(__INTEL_COMPILER) 9947 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
9948 #elif defined(__clang__) 9949 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
9950 #elif defined(__GNUC__) || defined(__GNUG__) 9951 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(__GNUC_PATCHLEVEL__)}};
9952 #elif defined(__HP_cc) || defined(__HP_aCC) 9953 result[
"compiler"] =
"hp" 9954 #elif defined(__IBMCPP__) 9955 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
9956 #elif defined(_MSC_VER) 9957 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
9958 #elif defined(__PGI) 9959 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
9960 #elif defined(__SUNPRO_CC) 9961 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
9963 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
9967 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
9969 result[
"compiler"][
"c++"] =
"unknown";
9984 #if defined(JSON_HAS_CPP_14) 10075 using object_t = ObjectType<StringType,
10078 AllocatorType<std::pair<
const StringType,
10125 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
10422 template<
typename T,
typename... Args>
10425 AllocatorType<T> alloc;
10426 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
10428 auto deleter = [&](T *
object)
10430 AllocatorTraits::deallocate(alloc,
object, 1);
10432 std::unique_ptr<T, decltype(deleter)>
object(AllocatorTraits::allocate(alloc, 1), deleter);
10433 AllocatorTraits::construct(alloc,
object.
get(), std::forward<Args>(args)...);
10434 assert(
object !=
nullptr);
10435 return object.release();
10500 object = create<object_t>();
10506 array = create<array_t>();
10512 string = create<string_t>(
"");
10561 string = create<string_t>(value);
10567 string = create<string_t>(std::move(value));
10573 object = create<object_t>(value);
10579 object = create<object_t>(std::move(value));
10585 array = create<array_t>(value);
10591 array = create<array_t>(std::move(value));
10600 AllocatorType<object_t> alloc;
10601 std::allocator_traits<decltype(alloc)>::destroy(alloc,
object);
10602 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
object, 1);
10608 AllocatorType<array_t> alloc;
10609 std::allocator_traits<decltype(alloc)>::destroy(alloc,
array);
10610 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
array, 1);
10616 AllocatorType<string_t> alloc;
10617 std::allocator_traits<decltype(alloc)>::destroy(alloc,
string);
10618 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
string, 1);
10759 : m_type(v), m_value(v)
10761 assert_invariant();
10785 assert_invariant();
10845 template <
typename CompatibleType,
10851 std::forward<CompatibleType>(val))))
10854 assert_invariant();
10883 template <
typename BasicJsonType,
10888 using other_boolean_t =
typename BasicJsonType::boolean_t;
10889 using other_number_float_t =
typename BasicJsonType::number_float_t;
10890 using other_number_integer_t =
typename BasicJsonType::number_integer_t;
10891 using other_number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
10892 using other_string_t =
typename BasicJsonType::string_t;
10893 using other_object_t =
typename BasicJsonType::object_t;
10894 using other_array_t =
typename BasicJsonType::array_t;
10896 switch (val.type())
10926 assert_invariant();
11004 bool type_deduction =
true,
11009 bool is_an_object = std::all_of(init.begin(), init.end(),
11012 return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
11016 if (not type_deduction)
11021 is_an_object =
false;
11039 auto element = element_ref.moved_or_copied();
11040 m_value.object->emplace(
11041 std::move(*((*element.m_value.array)[0].m_value.string)),
11042 std::move((*element.m_value.array)[1]));
11049 m_value.array = create<array_t>(init.begin(), init.end());
11052 assert_invariant();
11165 m_value.array = create<array_t>(cnt, val);
11166 assert_invariant();
11224 template<
class InputIT,
typename std::enable_if<
11225 std::is_same<InputIT, typename basic_json_t::iterator>::value or
11226 std::is_same<InputIT, typename basic_json_t::const_iterator>::value,
int>::type = 0>
11229 assert(first.m_object !=
nullptr);
11230 assert(last.m_object !=
nullptr);
11239 m_type = first.m_object->m_type;
11250 if (
JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
11251 or not last.m_it.primitive_iterator.is_end()))
11266 m_value.number_integer = first.m_object->m_value.number_integer;
11272 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
11278 m_value.number_float = first.m_object->m_value.number_float;
11284 m_value.boolean = first.m_object->m_value.boolean;
11290 m_value = *first.m_object->m_value.string;
11296 m_value.object = create<object_t>(first.m_it.object_iterator,
11297 last.m_it.object_iterator);
11303 m_value.array = create<array_t>(first.m_it.array_iterator,
11304 last.m_it.array_iterator);
11313 assert_invariant();
11323 : basic_json(ref.moved_or_copied())
11352 : m_type(other.m_type)
11405 assert_invariant();
11435 : m_type(
std::move(other.m_type)),
11436 m_value(
std::move(other.m_value))
11439 other.assert_invariant();
11443 other.m_value = {};
11445 assert_invariant();
11472 std::is_nothrow_move_constructible<value_t>::value and
11473 std::is_nothrow_move_assignable<value_t>::value and
11474 std::is_nothrow_move_constructible<json_value>::value and
11475 std::is_nothrow_move_assignable<json_value>::value
11482 swap(m_type, other.m_type);
11483 swap(m_value, other.m_value);
11485 assert_invariant();
11506 assert_invariant();
11507 m_value.destroy(m_type);
11558 const bool ensure_ascii =
false)
const 11565 s.
dump(*
this,
true, ensure_ascii, static_cast<unsigned int>(indent));
11569 s.
dump(*
this,
false, ensure_ascii, 0);
11639 return is_null() or
is_string() or is_boolean() or is_number();
11666 return is_array() or is_object();
11740 return is_number_integer() or is_number_float();
11959 return m_value.boolean;
11968 return is_object() ? m_value.object :
nullptr;
11974 return is_object() ? m_value.object :
nullptr;
11980 return is_array() ? m_value.array :
nullptr;
11986 return is_array() ? m_value.array :
nullptr;
11992 return is_string() ? m_value.string :
nullptr;
11998 return is_string() ? m_value.string :
nullptr;
12004 return is_boolean() ? &m_value.boolean :
nullptr;
12010 return is_boolean() ? &m_value.boolean :
nullptr;
12016 return is_number_integer() ? &m_value.number_integer :
nullptr;
12022 return is_number_integer() ? &m_value.number_integer :
nullptr;
12028 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
12034 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
12040 return is_number_float() ? &m_value.number_float :
nullptr;
12046 return is_number_float() ? &m_value.number_float :
nullptr;
12060 template<
typename ReferenceType,
typename ThisType>
12064 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
12094 std::is_same<typename std::remove_const<BasicJsonType>::type,
basic_json_t>::value,
12096 basic_json
get()
const 12117 not std::is_same<BasicJsonType, basic_json>::value and
12119 BasicJsonType
get()
const 12163 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
12164 detail::enable_if_t <
12165 not detail::is_basic_json<ValueType>::value and
12166 detail::has_from_json<basic_json_t, ValueType>::value and
12167 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
12169 ValueType
get()
const noexcept(noexcept(
12175 static_assert(not std::is_reference<ValueTypeCV>::value,
12176 "get() cannot be used with reference types, you might want to use get_ref()");
12177 static_assert(std::is_default_constructible<ValueType>::value,
12178 "types must be DefaultConstructible when used with get()");
12216 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
12217 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
12218 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
12220 ValueType
get()
const noexcept(noexcept(
12223 static_assert(not std::is_reference<ValueTypeCV>::value,
12224 "get() cannot be used with reference types, you might want to use get_ref()");
12255 template<
typename PointerType,
typename std::enable_if<
12256 std::is_pointer<PointerType>::value,
int>::type = 0>
12257 PointerType
get() noexcept
12260 return get_ptr<PointerType>();
12267 template<
typename PointerType,
typename std::enable_if<
12268 std::is_pointer<PointerType>::value,
int>::type = 0>
12269 constexpr
const PointerType
get()
const noexcept
12272 return get_ptr<PointerType>();
12301 template<
typename PointerType,
typename std::enable_if<
12302 std::is_pointer<PointerType>::value,
int>::type = 0>
12306 using pointee_t =
typename std::remove_const<
typename 12307 std::remove_pointer<
typename 12308 std::remove_const<PointerType>::type>::type>::type;
12311 std::is_same<object_t, pointee_t>::value
12312 or std::is_same<array_t, pointee_t>::value
12313 or std::is_same<string_t, pointee_t>::value
12314 or std::is_same<boolean_t, pointee_t>::value
12315 or std::is_same<number_integer_t, pointee_t>::value
12316 or std::is_same<number_unsigned_t, pointee_t>::value
12317 or std::is_same<number_float_t, pointee_t>::value
12318 ,
"incompatible pointer type");
12321 return get_impl_ptr(static_cast<PointerType>(
nullptr));
12328 template<
typename PointerType,
typename std::enable_if<
12329 std::is_pointer<PointerType>::value and
12330 std::is_const<typename std::remove_pointer<PointerType>::type>::value,
int>::type = 0>
12334 using pointee_t =
typename std::remove_const<
typename 12335 std::remove_pointer<
typename 12336 std::remove_const<PointerType>::type>::type>::type;
12339 std::is_same<object_t, pointee_t>::value
12340 or std::is_same<array_t, pointee_t>::value
12341 or std::is_same<string_t, pointee_t>::value
12342 or std::is_same<boolean_t, pointee_t>::value
12343 or std::is_same<number_integer_t, pointee_t>::value
12344 or std::is_same<number_unsigned_t, pointee_t>::value
12345 or std::is_same<number_float_t, pointee_t>::value
12346 ,
"incompatible pointer type");
12349 return get_impl_ptr(static_cast<PointerType>(
nullptr));
12378 template<
typename ReferenceType,
typename std::enable_if<
12379 std::is_reference<ReferenceType>::value,
int>::type = 0>
12383 return get_ref_impl<ReferenceType>(*this);
12390 template<
typename ReferenceType,
typename std::enable_if<
12391 std::is_reference<ReferenceType>::value and
12392 std::is_const<typename std::remove_reference<ReferenceType>::type>::value,
int>::type = 0>
12396 return get_ref_impl<ReferenceType>(*this);
12428 template <
typename ValueType,
typename std::enable_if <
12429 not std::is_pointer<ValueType>::value and
12430 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
12431 not std::is_same<ValueType, typename string_t::value_type>::value and
12433 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015 12434 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
12436 #if defined(JSON_HAS_CPP_17) 12437 and not std::is_same<ValueType, typename std::string_view>::value
12439 ,
int >::type = 0 >
12440 operator ValueType()
const 12443 return get<ValueType>();
12490 return m_value.array->at(idx);
12537 return m_value.array->at(idx);
12588 return m_value.object->at(key);
12639 return m_value.object->at(key);
12684 m_value.array = create<array_t>();
12685 assert_invariant();
12692 if (idx >= m_value.array->size())
12694 m_value.array->insert(m_value.array->end(),
12695 idx - m_value.array->size() + 1,
12699 return m_value.array->operator[](idx);
12729 return m_value.
array->operator[](idx);
12768 m_value.object = create<object_t>();
12769 assert_invariant();
12775 return m_value.object->operator[](key);
12816 assert(m_value.object->find(key) != m_value.object->end());
12850 template<
typename T>
12858 assert_invariant();
12864 return m_value.object->operator[](key);
12900 template<
typename T>
12906 assert(m_value.object->find(key) != m_value.object->end());
12961 template<
class ValueType,
typename std::enable_if<
12962 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
12963 ValueType
value(
const typename object_t::key_type& key,
const ValueType& default_value)
const 12969 const auto it = find(key);
12975 return default_value;
12985 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 12987 return value(key,
string_t(default_value));
13031 template<
class ValueType,
typename std::enable_if<
13032 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
13045 return default_value;
13058 return value(ptr,
string_t(default_value));
13193 template<
class IteratorType,
typename std::enable_if<
13194 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
13195 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>::type
13205 IteratorType result = end();
13215 if (
JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
13222 AllocatorType<string_t> alloc;
13223 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
13224 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
13225 m_value.string =
nullptr;
13229 assert_invariant();
13235 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
13241 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
13298 template<
class IteratorType,
typename std::enable_if<
13299 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
13300 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>::type
13302 IteratorType
erase(IteratorType first, IteratorType last)
13305 if (
JSON_UNLIKELY(
this != first.m_object or
this != last.m_object))
13310 IteratorType result = end();
13320 if (
JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
13321 or not last.m_it.primitive_iterator.is_end()))
13328 AllocatorType<string_t> alloc;
13329 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
13330 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
13331 m_value.string =
nullptr;
13335 assert_invariant();
13341 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
13342 last.m_it.object_iterator);
13348 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
13349 last.m_it.array_iterator);
13394 return m_value.object->erase(key);
13434 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
13474 template<
typename KeyT>
13477 auto result = end();
13481 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
13491 template<
typename KeyT>
13494 auto result = cend();
13498 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
13525 template<
typename KeyT>
13529 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
13876 return ref.items();
13885 return ref.items();
14017 return m_value.array->empty();
14023 return m_value.object->empty();
14089 return m_value.array->size();
14095 return m_value.object->size();
14153 return m_value.array->max_size();
14159 return m_value.object->max_size();
14222 m_value.number_integer = 0;
14228 m_value.number_unsigned = 0;
14234 m_value.number_float = 0.0;
14240 m_value.boolean =
false;
14246 m_value.string->clear();
14252 m_value.array->clear();
14258 m_value.object->clear();
14300 assert_invariant();
14304 m_value.array->push_back(std::move(val));
14315 push_back(std::move(val));
14336 assert_invariant();
14340 m_value.array->push_back(val);
14386 assert_invariant();
14390 m_value.object->insert(val);
14430 if (is_object() and init.size() == 2 and (*init.begin())->
is_string())
14432 basic_json&& key = init.begin()->moved_or_copied();
14433 push_back(
typename object_t::value_type(
14434 std::move(key.
get_ref<
string_t&>()), (init.begin() + 1)->moved_or_copied()));
14438 push_back(basic_json(init));
14473 template<
class... Args>
14487 assert_invariant();
14491 m_value.array->emplace_back(std::forward<Args>(args)...);
14521 template<
class... Args>
14535 assert_invariant();
14539 auto res = m_value.object->emplace(std::forward<Args>(args)...);
14542 it.m_it.object_iterator = res.first;
14545 return {it, res.second};
14596 return insert(pos, val);
14822 m_value.object = create<object_t>();
14823 assert_invariant();
14835 for (
auto it = j.
cbegin(); it != j.
cend(); ++it)
14837 m_value.object->operator[](it.key()) = it.value();
14873 m_value.object = create<object_t>();
14874 assert_invariant();
14890 or not last.
m_object->is_object()))
14895 for (
auto it = first; it != last; ++it)
14897 m_value.object->operator[](it.key()) = it.value();
14919 std::is_nothrow_move_constructible<value_t>::value and
14920 std::is_nothrow_move_assignable<value_t>::value and
14921 std::is_nothrow_move_constructible<json_value>::value and
14922 std::is_nothrow_move_assignable<json_value>::value
14927 assert_invariant();
15080 const auto lhs_type = lhs.type();
15081 const auto rhs_type = rhs.type();
15083 if (lhs_type == rhs_type)
15088 return (*lhs.m_value.array == *rhs.m_value.array);
15091 return (*lhs.m_value.object == *rhs.m_value.object);
15097 return (*lhs.m_value.string == *rhs.m_value.string);
15100 return (lhs.m_value.boolean == rhs.m_value.boolean);
15103 return (lhs.m_value.number_integer == rhs.m_value.number_integer);
15106 return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
15109 return (lhs.m_value.number_float == rhs.m_value.number_float);
15117 return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
15121 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
15125 return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
15129 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
15133 return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
15137 return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
15147 template<
typename ScalarType,
typename std::enable_if<
15148 std::is_scalar<ScalarType>::value,
int>::type = 0>
15151 return (lhs == basic_json(rhs));
15158 template<
typename ScalarType,
typename std::enable_if<
15159 std::is_scalar<ScalarType>::value,
int>::type = 0>
15162 return (basic_json(lhs) == rhs);
15185 return not (lhs == rhs);
15192 template<
typename ScalarType,
typename std::enable_if<
15193 std::is_scalar<ScalarType>::value,
int>::type = 0>
15196 return (lhs != basic_json(rhs));
15203 template<
typename ScalarType,
typename std::enable_if<
15204 std::is_scalar<ScalarType>::value,
int>::type = 0>
15207 return (basic_json(lhs) != rhs);
15238 const auto lhs_type = lhs.type();
15239 const auto rhs_type = rhs.type();
15241 if (lhs_type == rhs_type)
15246 return (*lhs.m_value.array) < (*rhs.m_value.array);
15249 return *lhs.m_value.object < *rhs.m_value.object;
15255 return *lhs.m_value.string < *rhs.m_value.string;
15258 return lhs.m_value.boolean < rhs.m_value.boolean;
15261 return lhs.m_value.number_integer < rhs.m_value.number_integer;
15264 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
15267 return lhs.m_value.number_float < rhs.m_value.number_float;
15275 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
15279 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
15283 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
15287 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
15291 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
15295 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
15308 template<
typename ScalarType,
typename std::enable_if<
15309 std::is_scalar<ScalarType>::value,
int>::type = 0>
15312 return (lhs < basic_json(rhs));
15319 template<
typename ScalarType,
typename std::enable_if<
15320 std::is_scalar<ScalarType>::value,
int>::type = 0>
15323 return (basic_json(lhs) < rhs);
15347 return not (rhs < lhs);
15354 template<
typename ScalarType,
typename std::enable_if<
15355 std::is_scalar<ScalarType>::value,
int>::type = 0>
15358 return (lhs <= basic_json(rhs));
15365 template<
typename ScalarType,
typename std::enable_if<
15366 std::is_scalar<ScalarType>::value,
int>::type = 0>
15369 return (basic_json(lhs) <= rhs);
15393 return not (lhs <= rhs);
15400 template<
typename ScalarType,
typename std::enable_if<
15401 std::is_scalar<ScalarType>::value,
int>::type = 0>
15404 return (lhs > basic_json(rhs));
15411 template<
typename ScalarType,
typename std::enable_if<
15412 std::is_scalar<ScalarType>::value,
int>::type = 0>
15415 return (basic_json(lhs) > rhs);
15439 return not (lhs < rhs);
15446 template<
typename ScalarType,
typename std::enable_if<
15447 std::is_scalar<ScalarType>::value,
int>::type = 0>
15450 return (lhs >= basic_json(rhs));
15457 template<
typename ScalarType,
typename std::enable_if<
15458 std::is_scalar<ScalarType>::value,
int>::type = 0>
15461 return (basic_json(lhs) >= rhs);
15504 friend std::ostream&
operator<<(std::ostream& o,
const basic_json& j)
15507 const bool pretty_print = (o.width() > 0);
15508 const auto indentation = (pretty_print ? o.width() : 0);
15515 s.dump(j, pretty_print,
false, static_cast<unsigned int>(indentation));
15528 friend std::ostream&
operator>>(
const basic_json& j, std::ostream& o)
15607 const bool allow_exceptions =
true)
15610 parser(i, cb, allow_exceptions).
parse(
true, result);
15619 const bool allow_exceptions =
true)
15622 parser(i, cb, allow_exceptions).
parse(
true, result);
15683 template<
class IteratorType,
typename std::enable_if<
15685 std::random_access_iterator_tag,
15686 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
15687 static basic_json
parse(IteratorType first, IteratorType last,
15689 const bool allow_exceptions =
true)
15696 template<
class IteratorType,
typename std::enable_if<
15698 std::random_access_iterator_tag,
15699 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
15700 static bool accept(IteratorType first, IteratorType last)
15716 return operator>>(i, j);
15802 return "discarded";
15917 static std::vector<uint8_t>
to_cbor(
const basic_json& j)
15919 std::vector<uint8_t> result;
15920 to_cbor(j, result);
16016 std::vector<uint8_t> result;
16017 to_msgpack(j, result);
16112 const bool use_size =
false,
16113 const bool use_type =
false)
16115 std::vector<uint8_t> result;
16116 to_ubjson(j, result, use_size, use_type);
16121 const bool use_size =
false,
const bool use_type =
false)
16127 const bool use_size =
false,
const bool use_type =
false)
16226 const bool strict =
true)
16234 template<
typename A1,
typename A2,
16236 static basic_json
from_cbor(A1 && a1, A2 && a2,
const bool strict =
true)
16315 const bool strict =
true)
16323 template<
typename A1,
typename A2,
16324 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
16384 const bool strict =
true)
16389 template<
typename A1,
typename A2,
16390 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
16391 static basic_json
from_ubjson(A1 && a1, A2 && a2,
const bool strict =
true)
16677 basic_json
patch(
const basic_json& json_patch)
const 16680 basic_json result = *
this;
16683 enum class patch_operations {add,
remove, replace, move, copy, test, invalid};
16689 return patch_operations::add;
16691 if (op ==
"remove")
16693 return patch_operations::remove;
16695 if (op ==
"replace")
16697 return patch_operations::replace;
16701 return patch_operations::move;
16705 return patch_operations::copy;
16709 return patch_operations::test;
16712 return patch_operations::invalid;
16716 const auto operation_add = [&result](
json_pointer & ptr, basic_json val)
16727 if (top_pointer != ptr)
16729 result.
at(top_pointer);
16733 const auto last_path = ptr.
pop_back();
16734 basic_json& parent = result[ptr];
16742 parent[last_path] = val;
16748 if (last_path ==
"-")
16780 const auto operation_remove = [&result](
json_pointer & ptr)
16783 const auto last_path = ptr.
pop_back();
16784 basic_json& parent = result.
at(ptr);
16790 auto it = parent.
find(last_path);
16814 for (
const auto& val : json_patch)
16817 const auto get_value = [&val](
const std::string & op,
16819 bool string_type) -> basic_json &
16822 auto it = val.m_value.object->find(member);
16825 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
16834 if (
JSON_UNLIKELY(string_type and not it->second.is_string()))
16850 const std::string op = get_value(
"op",
"op",
true);
16851 const std::string path = get_value(op,
"path",
true);
16854 switch (get_op(op))
16856 case patch_operations::add:
16858 operation_add(ptr, get_value(
"add",
"value",
false));
16862 case patch_operations::remove:
16864 operation_remove(ptr);
16868 case patch_operations::replace:
16871 result.
at(ptr) = get_value(
"replace",
"value",
false);
16875 case patch_operations::move:
16877 const std::string from_path = get_value(
"move",
"from",
true);
16881 basic_json v = result.
at(from_ptr);
16887 operation_remove(from_ptr);
16888 operation_add(ptr, v);
16892 case patch_operations::copy:
16894 const std::string from_path = get_value(
"copy",
"from",
true);
16898 basic_json v = result.
at(from_ptr);
16903 operation_add(ptr, v);
16907 case patch_operations::test:
16909 bool success =
false;
16914 success = (result.
at(ptr) == get_value(
"test",
"value",
false));
16930 case patch_operations::invalid:
16975 static basic_json
diff(
const basic_json& source,
const basic_json& target,
16982 if (source == target)
16987 if (source.
type() != target.
type())
16992 {
"op",
"replace"}, {
"path", path}, {
"value", target}
16997 switch (source.
type())
17003 while (i < source.
size() and i < target.
size())
17006 auto temp_diff = diff(source[i], target[i], path +
"/" + std::to_string(i));
17007 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
17016 while (i < source.
size())
17023 {
"path", path +
"/" + std::to_string(i)}
17029 while (i < target.
size())
17034 {
"path", path +
"/" + std::to_string(i)},
17035 {
"value", target[i]}
17046 for (
auto it = source.
cbegin(); it != source.
cend(); ++it)
17051 if (target.
find(it.key()) != target.
end())
17054 auto temp_diff = diff(it.value(), target[it.key()], path +
"/" + key);
17055 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
17062 {
"op",
"remove"}, {
"path", path +
"/" + key}
17068 for (
auto it = target.
cbegin(); it != target.
cend(); ++it)
17070 if (source.
find(it.key()) == source.
end())
17076 {
"op",
"add"}, {
"path", path +
"/" + key},
17077 {
"value", it.value()}
17090 {
"op",
"replace"}, {
"path", path}, {
"value", target}
17155 if (not is_object())
17159 for (
auto it = patch.
begin(); it != patch.
end(); ++it)
17161 if (it.value().is_null())
17167 operator[](it.key()).merge_patch(it.value());
17196 is_nothrow_move_constructible<nlohmann::json>::value and
17197 is_nothrow_move_assignable<nlohmann::json>::value
17215 const auto& h = hash<nlohmann::json::string_t>();
17216 return h(j.
dump());
17279 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 17280 #pragma GCC diagnostic pop 17282 #if defined(__clang__) 17283 #pragma GCC diagnostic pop 17291 #undef JSON_UNLIKELY 17292 #undef JSON_DEPRECATED 17293 #undef JSON_HAS_CPP_14 17294 #undef JSON_HAS_CPP_17 17295 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION 17296 #undef NLOHMANN_BASIC_JSON_TPL 17297 #undef NLOHMANN_JSON_HAS_HELPER json_value(string_t &&value)
constructor for rvalue strings
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix)
object_t * object
object (stored with pointer to save storage)
reference operator+=(const basic_json &val)
add an object to an array
value_type const & operator*() const
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
json_value(array_t &&value)
constructor for rvalue arrays
const_iterator find(KeyT &&key) const
find an element in a JSON object
reference value() const
return the value of an iterator
void update(const_iterator first, const_iterator last)
updates a JSON object from another object, overwriting existing keys
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
static JSON_DEPRECATED iteration_proxy< const_iterator > iterator_wrapper(const_reference ref) noexcept
wrapper to access iterator member functions in range-based for
typename parser::parser_callback_t parser_callback_t
per-element parser callback type
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
iter_impl operator-(difference_type i) const
subtract from iterator
token_type
token types for the parser
const int id
the id of the exception
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
parse_error(int id_, std::size_t byte_, const char *what_arg)
std::shared_ptr< input_adapter_protocol > input_adapter_t
a type to simplify interfaces
NLOHMANN_BASIC_JSON_TPL basic_json_t
workaround type for MSVC
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
size_type max_size() const noexcept
returns the maximum possible number of elements
BasicJsonType get_msgpack_object(const NumberType len)
static JSON_DEPRECATED iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
std::numeric_limits< RealIntegerType > RealLimits
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
std::initializer_list< detail::json_ref< basic_json >> initializer_list_t
helper type for initializer lists of basic_json values
typename BasicJsonType::number_float_t number_float_t
basic_json(basic_json &&other) noexcept
move constructor
#define JSON_CATCH(exception)
NumberFloatType number_float_t
a type for a number (floating-point)
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
iter_impl & operator+=(difference_type i)
add to iterator
value_t
the JSON type enumeration
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
primitive_iterator_t & operator+=(difference_type n) noexcept
iter_impl operator+(difference_type i) const
add to iterator
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
iter_impl(pointer object) noexcept
constructor for a given JSON instance
IteratorType erase(IteratorType pos)
remove element given an iterator
json_reverse_iterator const operator--(int)
post-decrement (it–)
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
~basic_json() noexcept
destructor
array_t * array
array (stored with pointer to save storage)
basic_json(CompatibleType &&val) noexcept(noexcept(JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value
string_t * string
string (stored with pointer to save storage)
static bool accept(detail::input_adapter i)
static void strtof(long double &f, const char *str, char **endptr) noexcept
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
void unexpect_eof() const
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
ReferenceType get_ref() const
get a reference value (implicit)
void destroy(value_t t) noexcept
primitive_iterator_t & operator++() noexcept
json_value(const string_t &value)
constructor for strings
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
a signed integer – use get_number_integer() for actual value
array (ordered collection of values)
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
json_pointer(const std::string &s="")
create JSON pointer
primitive_iterator_t operator+(difference_type n) noexcept
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than or equal
static other_error create(int id_, const std::string &what_arg)
iter_impl & operator++()
pre-increment (++it)
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
json_value(value_t t)
constructor for empty values of a given type
bool expect(token_type t)
static void replace_substring(std::string &s, const std::string &f, const std::string &t)
replace all occurrences of a substring by another string
NumberIntegerType number_integer_t
a type for a number (integer)
reference operator[](const typename object_t::key_type &key)
access specified object element
a template for a reverse iterator class
const char indent_char
the indentation character
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
constexpr bool is_primitive() const noexcept
return whether type is primitive
std::runtime_error m
an exception object as storage for error messages
a class to store JSON values
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
constexpr diyfp(uint64_t f_, int e_) noexcept
static void to_msgpack(const basic_json &j, detail::output_adapter< uint8_t > o)
void init(const M_string &remappings)
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
void from_json_array_impl(const BasicJsonType &j, CompatibleArrayType &arr, priority_tag< 0 >)
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
iterator insert(const_iterator pos, basic_json &&val)
inserts element
typename BasicJsonType::number_unsigned_t number_unsigned_t
bool is_root() const
return whether pointer points to the root document
std::numeric_limits< CompatibleNumberIntegerType > CompatibleLimits
value_type moved_or_copied() const
basic_json(const value_t v)
create an empty value with a given type
default JSONSerializer template argument
bool call(const std::string &service_name, MReq &req, MRes &res)
std::shared_ptr< output_adapter_protocol< CharType >> output_adapter_t
a type to simplify interfaces
void insert(const_iterator first, const_iterator last)
inserts elements
iter_impl const operator--(int)
post-decrement (it–)
std::ptrdiff_t difference_type
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
typename lexer_t::token_type token_type
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
constexpr bool is_structured() const noexcept
return whether type is structured
static std::string escape(std::string s)
escape "~"" to "~0" and "/" to "~1"
string_t get_msgpack_string()
reads a MessagePack string
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
type_error(int id_, const char *what_arg)
static allocator_type get_allocator()
returns the allocator associated with the container
StringType string_t
a type for a string
JSON_DEPRECATED friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
void parse(const bool strict, BasicJsonType &result)
public parser interface
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
iterator end() noexcept
returns an iterator to one past the last element
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json >>> object_t
a type for an object
number value (signed integer)
typename BasicJsonType::number_integer_t number_integer_t
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Target reinterpret_bits(const Source source)
std::pair< std::size_t, int > get_ubjson_size_type()
determine the type and size for a container
bool operator!=(const iteration_proxy_internal &o) const noexcept
inequality operator (needed for range-based for)
difference_type operator-(const iter_impl &other) const
return difference
BasicJsonType parse_msgpack_internal()
void dump_integer(NumberType x)
dump an integer
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value andstd::is_nothrow_move_assignable< value_t >::value andstd::is_nothrow_move_constructible< json_value >::value andstd::is_nothrow_move_assignable< json_value >::value)
exchanges the values
iterator begin() noexcept
returns an iterator to the first element
output_adapter(StringType &s)
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
json_reverse_iterator & operator+=(difference_type i)
add to iterator
bool operator==(const in6_addr a, const in6_addr b)
difference_type operator-(const json_reverse_iterator &other) const
return difference
std::ptrdiff_t difference_type
a type to represent differences between iterators
static void unescape(std::string &s)
unescape "~1" to tilde and "~0" to slash (order is important!)
reference operator+=(const typename object_t::value_type &val)
add an object to an object
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
BasicJsonType & get_and_create(BasicJsonType &j) const
create and return a reference to the pointed to value
pointer m_object
associated JSON instance
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
friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
iter_impl & operator-=(difference_type i)
subtract from iterator
void from_json(const BasicJsonType &j, std::tuple< Args... > &t)
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
number_unsigned_t number_unsigned
number (unsigned integer)
void set_end() noexcept
set the iterator past the last value
number_float_t number_float
number (floating-point)
BasicJsonType parse_cbor_internal(const bool get_char=true)
pointer operator->() const
dereference the iterator
a template for a bidirectional iterator for the basic_json class
void expect_eof() const
throw if end of input is not reached
token_type get_token()
get next token from lexer
friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
comparison: equal
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
::nlohmann::detail::output_adapter_t< CharType > output_adapter_t
std::bidirectional_iterator_tag iterator_category
constexpr bool is_object() const noexcept
return whether value is an object
output_adapter(std::basic_ostream< CharType > &s)
void write_character(CharType c) override
cached_power get_cached_power_for_binary_exponent(int e)
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
BasicJsonType parse_ubjson(const bool strict)
create a JSON value from UBJSON input
static std::vector< std::string > split(const std::string &reference_string)
split the string input to reference tokens
json_reverse_iterator operator+(difference_type i) const
add to iterator
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
reference operator[](difference_type n) const
access to successor
void set_end() noexcept
set iterator to a defined past the end
binary_reader(input_adapter_t adapter)
create a binary reader
BasicJsonType get_cbor_object(const NumberType len)
int get_codepoint()
get codepoint from 4 hex characters following \u
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
void emplace_back(Args &&...args)
add an object to an array
serialization to CBOR and MessagePack values
serializer(output_adapter_t< char > s, const char ichar)
output adapter for byte vectors
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
const std::size_t byte
byte index of the parse error
reference operator[](difference_type n) const
access to successor
void write_characters(const CharType *s, std::size_t length) override
void unget()
unget current character (return it again on next get)
string_t && move_string()
return current string value (implicitly resets the token; useful only once)
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than or equal
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
void to_json(BasicJsonType &j, T b) noexcept
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
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
static void strtof(double &f, const char *str, char **endptr) noexcept
NLOHMANN_JSON_HAS_HELPER(mapped_type)
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
exception indicating access out of the defined range
bool next_byte_in_range(std::initializer_list< int > ranges)
check if the next byte(s) are inside a given range
constexpr bool is_null() const noexcept
return whether value is null
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
std::function< bool(int depth, parse_event_t event, BasicJsonType &parsed)> parser_callback_t
primitive_iterator_t & operator--() noexcept
JSONSerializer< T, SFINAE > json_serializer
iterator find(KeyT &&key)
find an element in a JSON object
const_reference operator[](size_type idx) const
access specified array element
void set_begin() noexcept
set iterator to a defined beginning
void write_msgpack(const BasicJsonType &j)
[in] j JSON value to serialize
void parse_internal(bool keep, BasicJsonType &result)
the actual parser
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
reference at(size_type idx)
access specified array element with bounds checking
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
primitive_iterator_t const operator++(int) noexcept
typename BasicJsonType::number_integer_t number_integer_t
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
void add(int c)
add a character to token_buffer
friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than
basic_json(const basic_json &other)
copy constructor
bool operator>(const iter_impl &other) const
comparison: greater than
iter_impl const operator++(int)
post-increment (it++)
const_reference back() const
access the last element
const_reference front() const
access the first element
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
void clear() noexcept
clears the contents
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
void throw_exception() const
static T * create(Args &&...args)
helper for exception-safe object creation
reference operator+=(initializer_list_t init)
add an object to an object
BasicJsonType get_ubjson_array()
constexpr number_integer_t get_number_integer() const noexcept
return integer value
constexpr bool is_number() const noexcept
return whether value is a number
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
static basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
exception indicating a parse error
reference operator[](T *key)
access specified object element
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
#define JSON_THROW(exception)
constexpr number_float_t get_number_float() const noexcept
return floating-point value
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
static basic_json from_msgpack(detail::input_adapter i, const bool strict=true)
create a JSON value from an input in MessagePack format
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
const char * what() const noexceptoverride
returns the explanatory string
void operator()(const BasicJsonType &j, T &val) const noexcept(noexcept(std::declval< from_json_fn >().call(j, val, priority_tag< 1 >{})))
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
basic_json unflatten() const
unflatten a previously flattened JSON value
json_reverse_iterator const operator++(int)
post-increment (it++)
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
std::vector< CharType > & v
typename Base::reference reference
the reference type for the pointed-to element
an unsigned integer – use get_number_unsigned() for actual value
void reset() noexcept
reset token_buffer; current character is beginning of token
primitive_iterator_t primitive_iterator
generic iterator for all other types
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
abstract output adapter interface
void write_character(CharType c) override
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
general exception of the basic_json class
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
IteratorType anchor
the iterator
basic_json(const detail::json_ref< basic_json > &ref)
IteratorType::reference container
the container to iterate
size_type size() const noexcept
returns the number of elements
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
boundaries compute_boundaries(FloatType value)
out_of_range(int id_, const char *what_arg)
constexpr const PointerType get_ptr() const noexcept
get a pointer value (implicit)
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
value_type const * operator->() const
char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
std::string pop_back()
remove and return last reference pointer
typename BasicJsonType::number_float_t number_float_t
auto call(const BasicJsonType &j, T &val, priority_tag< 1 >) const noexcept(noexcept(from_json(j, val))) -> decltype(from_json(j, val), void())
reference back()
access the last element
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
void to_json(BasicJsonType &j, const std::tuple< Args... > &t)
string_t get_ubjson_string(const bool get_char=true)
reads a UBJSON string
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)
friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
comparison: equal
string_t get_string(const NumberType len)
create a string by reading characters from the input
output_adapter(std::vector< CharType > &vec)
const char * type_name() const noexcept
return the type as string
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
void write_number(const NumberType n)
static basic_json from_msgpack(A1 &&a1, A2 &&a2, const bool strict=true)
create a JSON value from an input in MessagePack format
BasicJsonType & get_checked(BasicJsonType *ptr) const
void dump_float(number_float_t x, std::false_type)
const_iterator begin() const noexcept
returns a const iterator to the first element
exception indicating errors with iterators
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
constexpr bool is_boolean() const noexcept
return whether value is a boolean
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
void from_json_tuple_impl(const BasicJsonType &j, Tuple &t, index_sequence< Idx... >)
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
namespace for Niels Lohmann
json_ref(std::initializer_list< json_ref > init)
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
constexpr bool is_string() const noexcept
return whether value is a string
constexpr difference_type get_value() const noexcept
an floating point number – use get_number_float() for actual value
typename BasicJsonType::number_integer_t number_integer_t
object (unordered set of name/value pairs)
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
iteration_proxy_internal & operator++()
increment operator (needed for range-based for)
void dump_float(number_float_t x, std::true_type)
ReferenceType get_ref()
get a reference value (implicit)
typename BasicJsonType::number_integer_t number_integer_t
std::string key() const
return key of the iterator
typename std::enable_if< B, T >::type enable_if_t
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)
#define NLOHMANN_BASIC_JSON_TPL
string_t get_cbor_string()
reads a CBOR string
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
exception indicating executing a member function with a wrong type
value_t m_type
the type of the current element
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
#define NLOHMANN_JSON_VERSION_PATCH
static void flatten(const std::string &reference_string, const BasicJsonType &value, BasicJsonType &result)
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
PointerType get_ptr() noexcept
get a pointer value (implicit)
void assert_invariant() const noexcept
checks the class invariants
static void strtof(float &f, const char *str, char **endptr) noexcept
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
basic_json flatten() const
return flattened JSON value
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer.
typename parser::parse_event_t parse_event_t
parser event types
void push_back(const basic_json &val)
add an object to an array
void push_back(initializer_list_t init)
add an object to an object
void write_characters(const CharType *s, std::size_t length) override
parser(detail::input_adapter_t adapter, const parser_callback_t cb=nullptr, const bool allow_exceptions_=true)
a parser reading from an input adapter
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
std::ptrdiff_t difference_type
void merge_patch(const basic_json &patch)
applies a JSON Merge Patch
static basic_json from_cbor(A1 &&a1, A2 &&a2, const bool strict=true)
create a JSON value from an input in CBOR format
constexpr diyfp() noexcept
static invalid_iterator create(int id_, const std::string &what_arg)
output_string_adapter(StringType &s)
void swap(nlohmann::json &j1, nlohmann::json &j2) noexcept(is_nothrow_move_constructible< nlohmann::json >::value andis_nothrow_move_assignable< nlohmann::json >::value)
exchanges the values of two JSON objects
ArrayType< basic_json, AllocatorType< basic_json >> array_t
a type for an array
static int array_index(const std::string &s)
typename BasicJsonType::string_t string_t
object_t::key_type key() const
return the key of an object iterator
constexpr bool is_discarded() const noexcept
return whether value is discarded
output adapter for basic_string
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
BasicJsonType get_ubjson_object()
BooleanType boolean_t
a type for a boolean
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
constexpr const char * get_error_message() const noexcept
return syntax error message
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
bool accept(const bool strict=true)
public accept interface
static BasicJsonType unflatten(const BasicJsonType &value)
char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
output adapter for output streams
reference operator*() const
return a reference to the value pointed to by the iterator
static basic_json parse(detail::input_adapter i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true)
deserialize from a compatible input
typename BasicJsonType::number_unsigned_t number_unsigned_t
#define NLOHMANN_JSON_VERSION_MINOR
reference operator+=(basic_json &&val)
add an object to an array
void operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(std::declval< to_json_fn >().call(j, std::forward< T >(val), priority_tag< 1 >{})))
typename BasicJsonType::object_t object_t
void dump_float(number_float_t x)
dump a floating-point number
bool operator<(const iter_impl &other) const
comparison: smaller
output_vector_adapter(std::vector< CharType > &vec)
json_ref(value_type &&value)
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
exception indicating other library errors
invalid_iterator(int id_, const char *what_arg)
static std::string name(const std::string &ename, int id_)
constexpr bool is_end() const noexcept
return whether the iterator is at end
typename BasicJsonType::string_t string_t
const_iterator cbegin() const noexcept
returns a const iterator to the first element
friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
void swap(array_t &other)
exchanges the values
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
deserialization of CBOR and MessagePack values
const BasicJsonType & get_checked(const BasicJsonType *ptr) const
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
static uint8_t decode(uint8_t &state, uint32_t &codep, const uint8_t byte) noexcept
check whether a string is UTF-8 encoded
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
std::basic_ostream< CharType > & stream
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
static void to_ubjson(const basic_json &j, detail::output_adapter< uint8_t > o, const bool use_size=false, const bool use_type=false)
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
iteration_proxy_internal begin() noexcept
return iterator begin (needed for range-based for)
static constexpr std::size_t size() noexcept
json_value(object_t &&value)
constructor for rvalue objects
void write_character(CharType c) override
number_integer_t number_integer
number (integer)
void swap(string_t &other)
exchanges the values
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
typename BasicJsonType::number_unsigned_t number_unsigned_t
exception(int id_, const char *what_arg)
json_value(const array_t &value)
constructor for arrays
IteratorType::reference value() const
return value of the iterator
string_t value(const json_pointer &ptr, const char *default_value) const
overload for a default value of type const char*
iter_impl & operator--()
pre-decrement (–it)
iterator insert(const_iterator pos, const basic_json &val)
inserts element
constexpr bool is_array() const noexcept
return whether value is an array
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
const_iterator end() const noexcept
returns a const iterator to one past the last element
std::less< StringType > object_comparator_t
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
typename BasicJsonType::string_t string_t
iteration_proxy_internal & operator*()
dereference operator (needed for range-based for)
BasicJsonType get_msgpack_array(const NumberType len)
BasicJsonType parse_ubjson_internal(const bool get_char=true)
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
static out_of_range create(int id_, const std::string &what_arg)
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements
typename BasicJsonType::number_unsigned_t number_unsigned_t
static const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
json_value(boolean_t v) noexcept
constructor for booleans
void dump_escaped(const string_t &s, const bool ensure_ascii)
dump escaped string
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
static basic_json from_cbor(detail::input_adapter i, const bool strict=true)
create a JSON value from an input in CBOR format
std::string to_string() const noexcept
return a string representation of the JSON pointer
token_type scan_literal(const char *literal_text, const std::size_t length, token_type return_type)
primitive_iterator_t const operator--(int) noexcept
reference operator[](size_type idx)
access specified array element
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
const_reference at(size_type idx) const
access specified array element with bounds checking
void push_back(basic_json &&val)
add an object to an array
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than
reference front()
access the first element
typename BasicJsonType::string_t string_t
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
token_type scan_number()
scan a number literal
bool operator<=(const iter_impl &other) const
comparison: less than or equal
BasicJsonType parse_msgpack(const bool strict)
create a JSON value from MessagePack input
number value (unsigned integer)
char ubjson_prefix(const BasicJsonType &j) const noexcept
determine the type prefix of container values
std::size_t size_type
a type to represent container sizes
typename BasicJsonType::array_t array_t
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
void call(BasicJsonType &, T &&, priority_tag< 0 >) const noexcept
static bool accept(IteratorType first, IteratorType last)
static basic_json from_ubjson(A1 &&a1, A2 &&a2, const bool strict=true)
basic_json<> json
default JSON class
const BasicJsonType & get_unchecked(const BasicJsonType *ptr) const
return a const reference to the pointed to value
friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
comparison: not equal
BasicJsonType parse_cbor(const bool strict)
create a JSON value from CBOR input
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
bool operator!=(const iter_impl &other) const
comparison: not equal
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
void swap(object_t &other)
exchanges the values
json_value(const object_t &value)
constructor for objects
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
static char get_decimal_point() noexcept
return the locale-dependent decimal point
constexpr std::size_t get_position() const noexcept
return position of last read token
void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value)
string_t dump(const int indent=-1, const char indent_char= ' ', const bool ensure_ascii=false) const
serialization
void call(const BasicJsonType &, T &, priority_tag< 0 >) const noexcept
void from_json(const BasicJsonType &j, typename BasicJsonType::boolean_t &b)
const_iterator cend() const noexcept
returns a const iterator to one past the last element
proxy class for the items() function
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
json_reverse_iterator & operator--()
pre-decrement (–it)
reference value() const
return the value of an iterator
bool operator==(const iter_impl &other) const
comparison: equal
output_stream_adapter(std::basic_ostream< CharType > &s)
reference & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value andstd::is_nothrow_move_assignable< value_t >::value andstd::is_nothrow_move_constructible< json_value >::value andstd::is_nothrow_move_assignable< json_value >::value)
copy assignment
void push_back(const typename object_t::value_type &val)
add an object to an object
void write_characters(const CharType *s, std::size_t length) override
string_t indent_string
the indentation string
other_error(int id_, const char *what_arg)
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
BasicJsonType get_ubjson_value(const int prefix)
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
JSON_DEPRECATED friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
iteration_proxy_internal(IteratorType it) noexcept
bool accept_internal()
the actual acceptor
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
static basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
auto call(BasicJsonType &j, T &&val, priority_tag< 1 >) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
number value (floating-point)
void erase(const size_type idx)
remove element from a JSON array given an index
token_type scan_string()
scan a string literal
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
iteration_proxy_internal end() noexcept
return iterator end (needed for range-based for)
std::vector< std::string > reference_tokens
the reference tokens
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
void write_cbor(const BasicJsonType &j)
[in] j JSON value to serialize
typename BasicJsonType::number_float_t number_float_t
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg)
create a parse error exception
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
std::pair< iterator, bool > emplace(Args &&...args)
add an object to an object if key does not exist
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
static bool accept(detail::input_adapter &i)
static type_error create(int id_, const std::string &what_arg)
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
void grisu2_round(char *buf, int len, uint64_t dist, uint64_t delta, uint64_t rest, uint64_t ten_k)
std::string get_token_string() const
AllocatorType< basic_json > allocator_type
the allocator type
json_ref(const value_type &value)
helper class for iteration
json_reverse_iterator & operator++()
pre-increment (++it)
primitive_iterator_t & operator-=(difference_type n) noexcept
static basic_json from_ubjson(detail::input_adapter i, const bool strict=true)
create a JSON value from an input in UBJSON format
static void to_cbor(const basic_json &j, detail::output_adapter< uint8_t > o)
static constexpr bool little_endianess(int num=1) noexcept
determine system byte order
int find_largest_pow10(const uint32_t n, uint32_t &pow10)
json_value m_value
the value of the current element
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) ...
const_reference operator[](T *key) const
read-only access specified object element
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
char * to_chars(char *first, char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
discarded by the the parser callback function
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
#define NLOHMANN_JSON_VERSION_MAJOR
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
bool empty() const noexcept
checks whether the container is empty.
BasicJsonType get_cbor_array(const NumberType len)
void set_begin() noexcept
set the iterator to the first value
static basic_json meta()
returns version information on the library
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
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
lexer(detail::input_adapter_t adapter)