29 #ifndef NLOHMANN_JSON_HPP 30 #define NLOHMANN_JSON_HPP 32 #define NLOHMANN_JSON_VERSION_MAJOR 3 33 #define NLOHMANN_JSON_VERSION_MINOR 1 34 #define NLOHMANN_JSON_VERSION_PATCH 2 41 #include <initializer_list> 48 #include <json_fwd.hpp> 49 #ifndef NLOHMANN_JSON_FWD_HPP 50 #define NLOHMANN_JSON_FWD_HPP 72 template<
typename =
void,
typename =
void>
75 template<
template<
typename U,
typename V,
typename... Args>
class ObjectType =
77 template<
typename U,
typename... Args>
class ArrayType = std::vector,
78 class StringType = std::string,
class BooleanType = bool,
79 class NumberIntegerType = std::int64_t,
80 class NumberUnsignedType = std::uint64_t,
81 class NumberFloatType = double,
82 template<
typename U>
class AllocatorType = std::allocator,
83 template<
typename T,
typename SFINAE =
void>
class JSONSerializer =
98 template<
typename BasicJsonType>
121 #if defined(__clang__) 122 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 123 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" 125 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) 126 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900 127 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" 132 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 133 #pragma GCC diagnostic push 134 #pragma GCC diagnostic ignored "-Wfloat-equal" 138 #if defined(__clang__) 139 #pragma GCC diagnostic push 140 #pragma GCC diagnostic ignored "-Wdocumentation" 144 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 145 #define JSON_DEPRECATED __attribute__((deprecated)) 146 #elif defined(_MSC_VER) 147 #define JSON_DEPRECATED __declspec(deprecated) 149 #define JSON_DEPRECATED 153 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) 154 #define JSON_THROW(exception) throw exception 156 #define JSON_CATCH(exception) catch(exception) 158 #define JSON_THROW(exception) std::abort() 159 #define JSON_TRY if(true) 160 #define JSON_CATCH(exception) if(false) 164 #if defined(JSON_THROW_USER) 166 #define JSON_THROW JSON_THROW_USER 168 #if defined(JSON_TRY_USER) 170 #define JSON_TRY JSON_TRY_USER 172 #if defined(JSON_CATCH_USER) 174 #define JSON_CATCH JSON_CATCH_USER 178 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 179 #define JSON_LIKELY(x) __builtin_expect(!!(x), 1) 180 #define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0) 182 #define JSON_LIKELY(x) x 183 #define JSON_UNLIKELY(x) x 187 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 188 #define JSON_HAS_CPP_17 189 #define JSON_HAS_CPP_14 190 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) 191 #define JSON_HAS_CPP_14 197 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ 198 template<template<typename, typename, typename...> class ObjectType, \ 199 template<typename, typename...> class ArrayType, \ 200 class StringType, class BooleanType, class NumberIntegerType, \ 201 class NumberUnsignedType, class NumberFloatType, \ 202 template<typename> class AllocatorType, \ 203 template<typename, typename = void> class JSONSerializer> 205 #define NLOHMANN_BASIC_JSON_TPL \ 206 basic_json<ObjectType, ArrayType, StringType, BooleanType, \ 207 NumberIntegerType, NumberUnsignedType, NumberFloatType, \ 208 AllocatorType, JSONSerializer> 220 #define NLOHMANN_JSON_HAS_HELPER(type) \ 221 template<typename T> struct has_##type { \ 223 template<typename U, typename = typename U::type> \ 224 static int detect(U &&); \ 225 static void detect(...); \ 227 static constexpr bool value = \ 228 std::is_integral<decltype(detect(std::declval<T>()))>::value; \ 237 #include <type_traits> 263 NLOHMANN_BASIC_JSON_TPL_DECLARATION
267 template<
bool B,
typename T =
void>
268 using enable_if_t =
typename std::enable_if<B, T>::type;
271 using uncvref_t =
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
275 template<std::size_t... Ints>
279 using value_type = std::size_t;
280 static constexpr std::size_t size() noexcept
282 return sizeof...(Ints);
286 template<
class Sequence1,
class Sequence2>
289 template<std::size_t... I1, std::size_t... I2>
293 template<std::
size_t N>
296 typename make_index_sequence < N - N / 2 >::type > {};
301 template<
typename... Ts>
319 template<
class B1,
class... Bn>
320 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
322 template<
class B>
struct negation : std::integral_constant<bool, not B::value> {};
334 template <
typename T,
typename =
void>
337 template <
typename T>
340 NLOHMANN_JSON_HAS_HELPER(mapped_type);
341 NLOHMANN_JSON_HAS_HELPER(key_type);
342 NLOHMANN_JSON_HAS_HELPER(value_type);
343 NLOHMANN_JSON_HAS_HELPER(iterator);
345 template<
bool B,
class RealType,
class CompatibleObjectType>
348 template<
class RealType,
class CompatibleObjectType>
351 static constexpr
auto value =
352 std::is_constructible<typename RealType::key_type, typename CompatibleObjectType::key_type>::value and
353 std::is_constructible<typename RealType::mapped_type, typename CompatibleObjectType::mapped_type>::value;
356 template<
class BasicJsonType,
class CompatibleObjectType>
361 has_mapped_type<CompatibleObjectType>,
362 has_key_type<CompatibleObjectType>>::value,
363 typename BasicJsonType::object_t, CompatibleObjectType >::value;
366 template<
typename BasicJsonType,
typename T>
369 static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
370 std::is_same<T, typename BasicJsonType::const_iterator>::value or
371 std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
372 std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
375 template<
class BasicJsonType,
class CompatibleArrayType>
378 static auto constexpr value =
381 BasicJsonType, CompatibleArrayType>>,
382 negation<std::is_constructible<
typename BasicJsonType::string_t,
383 CompatibleArrayType>>,
385 has_value_type<CompatibleArrayType>,
386 has_iterator<CompatibleArrayType>>::value;
389 template<
bool,
typename,
typename>
392 template<
typename RealIntegerType,
typename CompatibleNumberIntegerType>
396 using RealLimits = std::numeric_limits<RealIntegerType>;
397 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
399 static constexpr
auto value =
400 std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
401 CompatibleLimits::is_integer and
402 RealLimits::is_signed == CompatibleLimits::is_signed;
405 template<
typename RealIntegerType,
typename CompatibleNumberIntegerType>
408 static constexpr
auto value =
410 std::is_integral<CompatibleNumberIntegerType>::value and
411 not std::is_same<bool, CompatibleNumberIntegerType>::value,
412 RealIntegerType, CompatibleNumberIntegerType > ::value;
416 template<
typename BasicJsonType,
typename T>
421 template<typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
422 std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
423 static int detect(U&&);
424 static void detect(...);
427 static constexpr
bool value = std::is_integral<decltype(
428 detect(std::declval<
typename BasicJsonType::template json_serializer<T, void>>()))>::value;
433 template<
typename BasicJsonType,
typename T>
439 typename = enable_if_t<std::is_same<
440 T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
441 static int detect(U&&);
442 static void detect(...);
445 static constexpr
bool value = std::is_integral<decltype(detect(
446 std::declval<
typename BasicJsonType::template json_serializer<T, void>>()))>::value;
450 template<
typename BasicJsonType,
typename T>
454 template<typename U, typename = decltype(uncvref_t<U>::to_json(
455 std::declval<BasicJsonType&>(), std::declval<T>()))>
456 static int detect(U&&);
457 static void detect(...);
460 static constexpr
bool value = std::is_integral<decltype(detect(
461 std::declval<
typename BasicJsonType::template json_serializer<T, void>>()))>::value;
464 template <
typename BasicJsonType,
typename CompatibleCompleteType>
467 static constexpr
bool value =
468 not std::is_base_of<std::istream, CompatibleCompleteType>::value and
474 template <
typename BasicJsonType,
typename CompatibleType>
477 is_compatible_complete_type<BasicJsonType, CompatibleType>>
485 static constexpr T value{};
540 const char*
what() const noexcept
override 549 exception(
int id_,
const char* what_arg) : id(id_), m(what_arg) {}
553 return "[json.exception." + ename +
"." + std::to_string(id_) +
"] ";
558 std::runtime_error m;
617 std::string w = exception::name(
"parse_error", id_) +
"parse error" +
618 (byte_ != 0 ? (
" at " + std::to_string(byte_)) :
"") +
635 parse_error(
int id_, std::size_t byte_,
const char* what_arg)
636 :
exception(id_, what_arg), byte(byte_) {}
681 std::string w = exception::name(
"invalid_iterator", id_) + what_arg;
733 std::string w = exception::name(
"type_error", id_) + what_arg;
778 std::string w = exception::name(
"out_of_range", id_) + what_arg;
815 std::string w = exception::name(
"other_error", id_) + what_arg;
890 static constexpr std::array<std::uint8_t, 8> order = {{
896 const auto l_index =
static_cast<std::size_t
>(lhs);
897 const auto r_index =
static_cast<std::size_t
>(rhs);
898 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
909 #include <forward_list> 913 #include <type_traits> 931 template<
typename BasicJsonType,
typename ArithmeticType,
932 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
933 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
935 void get_arithmetic_value(
const BasicJsonType& j, ArithmeticType& val)
937 switch (static_cast<value_t>(j))
941 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
946 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
951 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
956 JSON_THROW(type_error::create(302,
"type must be number, but is " +
std::string(j.type_name())));
960 template<
typename BasicJsonType>
961 void from_json(
const BasicJsonType& j,
typename BasicJsonType::boolean_t& b)
963 if (JSON_UNLIKELY(not j.is_boolean()))
965 JSON_THROW(type_error::create(302,
"type must be boolean, but is " +
std::string(j.type_name())));
967 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
970 template<
typename BasicJsonType>
971 void from_json(
const BasicJsonType& j,
typename BasicJsonType::string_t& s)
973 if (JSON_UNLIKELY(not j.is_string()))
975 JSON_THROW(type_error::create(302,
"type must be string, but is " +
std::string(j.type_name())));
977 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
980 template<
typename BasicJsonType>
981 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_float_t& val)
983 get_arithmetic_value(j, val);
986 template<
typename BasicJsonType>
987 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_unsigned_t& val)
989 get_arithmetic_value(j, val);
992 template<
typename BasicJsonType>
993 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_integer_t& val)
995 get_arithmetic_value(j, val);
998 template<
typename BasicJsonType,
typename EnumType,
999 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
1000 void from_json(
const BasicJsonType& j, EnumType& e)
1002 typename std::underlying_type<EnumType>::type val;
1003 get_arithmetic_value(j, val);
1004 e =
static_cast<EnumType
>(val);
1007 template<
typename BasicJsonType>
1008 void from_json(
const BasicJsonType& j,
typename BasicJsonType::array_t& arr)
1010 if (JSON_UNLIKELY(not j.is_array()))
1012 JSON_THROW(type_error::create(302,
"type must be array, but is " +
std::string(j.type_name())));
1014 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
1018 template<
typename BasicJsonType,
typename T,
typename Allocator,
1019 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1020 void from_json(
const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1022 if (JSON_UNLIKELY(not j.is_array()))
1024 JSON_THROW(type_error::create(302,
"type must be array, but is " +
std::string(j.type_name())));
1026 std::transform(j.rbegin(), j.rend(),
1027 std::front_inserter(l), [](
const BasicJsonType & i)
1029 return i.template get<T>();
1034 template<
typename BasicJsonType,
typename T,
1035 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1036 void from_json(
const BasicJsonType& j, std::valarray<T>& l)
1038 if (JSON_UNLIKELY(not j.is_array()))
1040 JSON_THROW(type_error::create(302,
"type must be array, but is " +
std::string(j.type_name())));
1043 std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1046 template<
typename BasicJsonType,
typename CompatibleArrayType>
1047 void from_json_array_impl(
const BasicJsonType& j, CompatibleArrayType& arr,
priority_tag<0> )
1051 std::transform(j.begin(), j.end(),
1052 std::inserter(arr, end(arr)), [](
const BasicJsonType & i)
1056 return i.template get<typename CompatibleArrayType::value_type>();
1060 template<
typename BasicJsonType,
typename CompatibleArrayType>
1061 auto from_json_array_impl(
const BasicJsonType& j, CompatibleArrayType& arr,
priority_tag<1> )
1063 arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
1068 arr.reserve(j.size());
1069 std::transform(j.begin(), j.end(),
1070 std::inserter(arr, end(arr)), [](
const BasicJsonType & i)
1074 return i.template get<typename CompatibleArrayType::value_type>();
1078 template<
typename BasicJsonType,
typename T, std::
size_t N>
1079 void from_json_array_impl(
const BasicJsonType& j, std::array<T, N>& arr,
priority_tag<2> )
1081 for (std::size_t i = 0; i < N; ++i)
1083 arr[i] = j.at(i).template get<T>();
1088 typename BasicJsonType,
typename CompatibleArrayType,
1091 not std::is_same<
typename BasicJsonType::array_t,
1092 CompatibleArrayType>::value and
1093 std::is_constructible <
1094 BasicJsonType,
typename CompatibleArrayType::value_type >::value,
1096 void from_json(
const BasicJsonType& j, CompatibleArrayType& arr)
1098 if (JSON_UNLIKELY(not j.is_array()))
1100 JSON_THROW(type_error::create(302,
"type must be array, but is " +
1107 template<
typename BasicJsonType,
typename CompatibleObjectType,
1108 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
int> = 0>
1109 void from_json(
const BasicJsonType& j, CompatibleObjectType& obj)
1111 if (JSON_UNLIKELY(not j.is_object()))
1113 JSON_THROW(type_error::create(302,
"type must be object, but is " +
std::string(j.type_name())));
1116 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1117 using value_type =
typename CompatibleObjectType::value_type;
1119 inner_object->begin(), inner_object->end(),
1120 std::inserter(obj, obj.begin()),
1121 [](
typename BasicJsonType::object_t::value_type
const & p)
1123 return value_type(p.first, p.second.template get<typename CompatibleObjectType::mapped_type>());
1131 template<
typename BasicJsonType,
typename ArithmeticType,
1133 std::is_arithmetic<ArithmeticType>::value and
1134 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1135 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1136 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1137 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1139 void from_json(
const BasicJsonType& j, ArithmeticType& val)
1141 switch (static_cast<value_t>(j))
1145 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1150 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1155 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1160 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1165 JSON_THROW(type_error::create(302,
"type must be number, but is " +
std::string(j.type_name())));
1169 template<
typename BasicJsonType,
typename A1,
typename A2>
1170 void from_json(
const BasicJsonType& j, std::pair<A1, A2>& p)
1172 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
1175 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1178 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
1181 template<
typename BasicJsonType,
typename... Args>
1182 void from_json(
const BasicJsonType& j, std::tuple<Args...>& t)
1190 template<
typename BasicJsonType,
typename T>
1192 noexcept(noexcept(from_json(j, val)))
1193 -> decltype(from_json(j, val),
void())
1195 return from_json(j, val);
1198 template<
typename BasicJsonType,
typename T>
1199 void call(
const BasicJsonType& , T& ,
priority_tag<0> )
const noexcept
1201 static_assert(
sizeof(BasicJsonType) == 0,
1202 "could not find from_json() method in T's namespace");
1205 using decayed = uncvref_t<T>;
1206 static_assert(
sizeof(
typename decayed::force_msvc_stacktrace) == 0,
1207 "forcing MSVC stacktrace to show which T we're talking about.");
1212 template<
typename BasicJsonType,
typename T>
1213 void operator()(
const BasicJsonType& j, T& val)
const 1214 noexcept(noexcept(std::declval<from_json_fn>().call(j, val,
priority_tag<1> {})))
1236 #include <type_traits> 1259 template<
typename BasicJsonType>
1260 static void construct(BasicJsonType& j,
typename BasicJsonType::boolean_t b) noexcept
1264 j.assert_invariant();
1271 template<
typename BasicJsonType>
1272 static void construct(BasicJsonType& j,
const typename BasicJsonType::string_t& s)
1276 j.assert_invariant();
1279 template<
typename BasicJsonType>
1280 static void construct(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
1283 j.m_value = std::move(s);
1284 j.assert_invariant();
1291 template<
typename BasicJsonType>
1292 static void construct(BasicJsonType& j,
typename BasicJsonType::number_float_t val) noexcept
1296 j.assert_invariant();
1303 template<
typename BasicJsonType>
1304 static void construct(BasicJsonType& j,
typename BasicJsonType::number_unsigned_t val) noexcept
1308 j.assert_invariant();
1315 template<
typename BasicJsonType>
1316 static void construct(BasicJsonType& j,
typename BasicJsonType::number_integer_t val) noexcept
1320 j.assert_invariant();
1327 template<
typename BasicJsonType>
1328 static void construct(BasicJsonType& j,
const typename BasicJsonType::array_t& arr)
1332 j.assert_invariant();
1335 template<
typename BasicJsonType>
1336 static void construct(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
1339 j.m_value = std::move(arr);
1340 j.assert_invariant();
1343 template<
typename BasicJsonType,
typename CompatibleArrayType,
1344 enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
1346 static void construct(BasicJsonType& j,
const CompatibleArrayType& arr)
1351 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
1352 j.assert_invariant();
1355 template<
typename BasicJsonType>
1356 static void construct(BasicJsonType& j,
const std::vector<bool>& arr)
1360 j.m_value.array->reserve(arr.size());
1361 for (
const bool x : arr)
1363 j.m_value.array->push_back(x);
1365 j.assert_invariant();
1368 template<
typename BasicJsonType,
typename T,
1369 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
1370 static void construct(BasicJsonType& j,
const std::valarray<T>& arr)
1374 j.m_value.array->resize(arr.size());
1375 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
1376 j.assert_invariant();
1383 template<
typename BasicJsonType>
1384 static void construct(BasicJsonType& j,
const typename BasicJsonType::object_t& obj)
1388 j.assert_invariant();
1391 template<
typename BasicJsonType>
1392 static void construct(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
1395 j.m_value = std::move(obj);
1396 j.assert_invariant();
1399 template<
typename BasicJsonType,
typename CompatibleObjectType,
1400 enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value,
int> = 0>
1401 static void construct(BasicJsonType& j,
const CompatibleObjectType& obj)
1407 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
1408 j.assert_invariant();
1416 template<
typename BasicJsonType,
typename T,
1417 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value,
int> = 0>
1418 void to_json(BasicJsonType& j, T b) noexcept
1423 template<
typename BasicJsonType,
typename CompatibleString,
1424 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value,
int> = 0>
1425 void to_json(BasicJsonType& j,
const CompatibleString& s)
1430 template<
typename BasicJsonType>
1431 void to_json(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
1436 template<
typename BasicJsonType,
typename FloatType,
1437 enable_if_t<std::is_floating_point<FloatType>::value,
int> = 0>
1438 void to_json(BasicJsonType& j, FloatType val) noexcept
1443 template<
typename BasicJsonType,
typename CompatibleNumberUnsignedType,
1444 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value,
int> = 0>
1445 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
1450 template<
typename BasicJsonType,
typename CompatibleNumberIntegerType,
1451 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value,
int> = 0>
1452 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
1457 template<
typename BasicJsonType,
typename EnumType,
1458 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
1459 void to_json(BasicJsonType& j, EnumType e) noexcept
1461 using underlying_type =
typename std::underlying_type<EnumType>::type;
1465 template<
typename BasicJsonType>
1466 void to_json(BasicJsonType& j,
const std::vector<bool>& e)
1471 template<
typename BasicJsonType,
typename CompatibleArrayType,
1472 enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value or
1473 std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
1475 void to_json(BasicJsonType& j,
const CompatibleArrayType& arr)
1480 template<
typename BasicJsonType,
typename T,
1481 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
1482 void to_json(BasicJsonType& j, std::valarray<T> arr)
1487 template<
typename BasicJsonType>
1488 void to_json(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
1493 template<
typename BasicJsonType,
typename CompatibleObjectType,
1494 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
int> = 0>
1495 void to_json(BasicJsonType& j,
const CompatibleObjectType& obj)
1500 template<
typename BasicJsonType>
1501 void to_json(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
1506 template<
typename BasicJsonType,
typename T, std::size_t N,
1507 enable_if_t<not std::is_constructible<typename BasicJsonType::string_t, T (&)[N]>::value,
int> = 0>
1508 void to_json(BasicJsonType& j, T (&arr)[N])
1513 template<
typename BasicJsonType,
typename... Args>
1514 void to_json(BasicJsonType& j,
const std::pair<Args...>& p)
1516 j = {p.first, p.second};
1519 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1522 j = {std::get<Idx>(t)...};
1525 template<
typename BasicJsonType,
typename... Args>
1526 void to_json(BasicJsonType& j,
const std::tuple<Args...>& t)
1534 template<
typename BasicJsonType,
typename T>
1535 auto call(BasicJsonType& j, T&& val,
priority_tag<1> )
const noexcept(noexcept(to_json(j, std::forward<T>(val))))
1536 -> decltype(to_json(j, std::forward<T>(val)),
void())
1538 return to_json(j, std::forward<T>(val));
1541 template<
typename BasicJsonType,
typename T>
1544 static_assert(
sizeof(BasicJsonType) == 0,
1545 "could not find to_json() method in T's namespace");
1549 using decayed = uncvref_t<T>;
1550 static_assert(
sizeof(
typename decayed::force_msvc_stacktrace) == 0,
1551 "forcing MSVC stacktrace to show which T we're talking about.");
1556 template<
typename BasicJsonType,
typename T>
1557 void operator()(BasicJsonType& j, T&& val)
const 1558 noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val),
priority_tag<1> {})))
1575 #include <algorithm> 1586 #include <type_traits> 1614 virtual std::char_traits<char>::int_type get_character() = 0;
1616 virtual void unget_character() = 0;
1643 : is(i), sb(*i.rdbuf())
1646 std::char_traits<char>::int_type c;
1647 if ((c = get_character()) == 0xEF)
1649 if ((c = get_character()) == 0xBB)
1651 if ((c = get_character()) == 0xBF)
1655 else if (c != std::char_traits<char>::eof())
1661 else if (c != std::char_traits<char>::eof())
1667 else if (c != std::char_traits<char>::eof())
1701 : cursor(b), limit(b + l), start(b)
1704 if (l >= 3 and b[0] ==
'\xEF' and b[1] ==
'\xBB' and b[2] ==
'\xBF')
1716 if (JSON_LIKELY(cursor < limit))
1718 return std::char_traits<char>::to_int_type(*(cursor++));
1721 return std::char_traits<char>::eof();
1726 if (JSON_LIKELY(cursor > start))
1755 template<
typename CharT,
1756 typename std::enable_if<
1757 std::is_pointer<CharT>::value and
1758 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
1759 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
1762 : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
1767 template<
typename CharT,
1768 typename std::enable_if<
1769 std::is_pointer<CharT>::value and
1770 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
1771 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
1775 std::strlen(reinterpret_cast<const char*>(b))) {}
1778 template<
class IteratorType,
1779 typename std::enable_if<
1780 std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
1786 assert(std::accumulate(
1787 first, last, std::pair<bool, int>(
true, 0),
1788 [&first](std::pair<bool, int> res, decltype(*first) val)
1790 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
1796 sizeof(
typename std::iterator_traits<IteratorType>::value_type) == 1,
1797 "each element in the iterator range must have the size of 1 byte");
1799 const auto len =
static_cast<size_t>(std::distance(first, last));
1800 if (JSON_LIKELY(len > 0))
1803 ia = std::make_shared<input_buffer_adapter>(
reinterpret_cast<const char*
>(&(*first)), len);
1808 ia = std::make_shared<input_buffer_adapter>(
nullptr, len);
1813 template<
class T, std::
size_t N>
1818 template<
class ContiguousContainer,
typename 1819 std::enable_if<not std::is_pointer<ContiguousContainer>::value and
1820 std::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
1843 #include <initializer_list> 1868 template<
typename BasicJsonType>
1871 using number_integer_t =
typename BasicJsonType::number_integer_t;
1872 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
1873 using number_float_t =
typename BasicJsonType::number_float_t;
1874 using string_t =
typename BasicJsonType::string_t;
1904 case token_type::uninitialized:
1905 return "<uninitialized>";
1906 case token_type::literal_true:
1907 return "true literal";
1908 case token_type::literal_false:
1909 return "false literal";
1910 case token_type::literal_null:
1911 return "null literal";
1912 case token_type::value_string:
1913 return "string literal";
1917 return "number literal";
1918 case token_type::begin_array:
1920 case token_type::begin_object:
1922 case token_type::end_array:
1924 case token_type::end_object:
1926 case token_type::name_separator:
1928 case token_type::value_separator:
1930 case token_type::parse_error:
1931 return "<parse error>";
1932 case token_type::end_of_input:
1933 return "end of input";
1934 case token_type::literal_or_value:
1935 return "'[', '{', or a literal";
1937 return "unknown token";
1942 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
1954 static char get_decimal_point() noexcept
1956 const auto loc = localeconv();
1957 assert(loc !=
nullptr);
1958 return (loc->decimal_point ==
nullptr) ?
'.' : *(loc->decimal_point);
1983 assert(current ==
'u');
1986 const auto factors = { 12, 8, 4, 0 };
1987 for (
const auto factor : factors)
1991 if (current >=
'0' and current <=
'9')
1993 codepoint += ((current - 0x30) << factor);
1995 else if (current >=
'A' and current <=
'F')
1997 codepoint += ((current - 0x37) << factor);
1999 else if (current >=
'a' and current <=
'f')
2001 codepoint += ((current - 0x57) << factor);
2009 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
2028 bool next_byte_in_range(std::initializer_list<int> ranges)
2030 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
2033 for (
auto range = ranges.begin(); range != ranges.end(); ++range)
2036 if (JSON_LIKELY(*range <= current and current <= *(++range)))
2042 error_message =
"invalid string: ill-formed UTF-8 byte";
2071 assert(current ==
'\"');
2079 case std::char_traits<char>::eof():
2081 error_message =
"invalid string: missing closing quote";
2082 return token_type::parse_error;
2088 return token_type::value_string;
2132 const int codepoint1 = get_codepoint();
2133 int codepoint = codepoint1;
2135 if (JSON_UNLIKELY(codepoint1 == -1))
2137 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
2138 return token_type::parse_error;
2142 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
2145 if (JSON_LIKELY(
get() ==
'\\' and
get() ==
'u'))
2147 const int codepoint2 = get_codepoint();
2149 if (JSON_UNLIKELY(codepoint2 == -1))
2151 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
2152 return token_type::parse_error;
2156 if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
2171 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2172 return token_type::parse_error;
2177 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2178 return token_type::parse_error;
2183 if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
2185 error_message =
"invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
2186 return token_type::parse_error;
2191 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
2194 if (codepoint < 0x80)
2199 else if (codepoint <= 0x7FF)
2202 add(0xC0 | (codepoint >> 6));
2203 add(0x80 | (codepoint & 0x3F));
2205 else if (codepoint <= 0xFFFF)
2208 add(0xE0 | (codepoint >> 12));
2209 add(0x80 | ((codepoint >> 6) & 0x3F));
2210 add(0x80 | (codepoint & 0x3F));
2215 add(0xF0 | (codepoint >> 18));
2216 add(0x80 | ((codepoint >> 12) & 0x3F));
2217 add(0x80 | ((codepoint >> 6) & 0x3F));
2218 add(0x80 | (codepoint & 0x3F));
2226 error_message =
"invalid string: forbidden character after backslash";
2227 return token_type::parse_error;
2267 error_message =
"invalid string: control character must be escaped";
2268 return token_type::parse_error;
2403 if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
2405 return token_type::parse_error;
2413 if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
2415 return token_type::parse_error;
2437 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
2439 return token_type::parse_error;
2447 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
2449 return token_type::parse_error;
2457 if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2459 return token_type::parse_error;
2469 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2471 return token_type::parse_error;
2479 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
2481 return token_type::parse_error;
2489 error_message =
"invalid string: ill-formed UTF-8 byte";
2490 return token_type::parse_error;
2496 static void strtof(
float& f,
const char* str,
char** endptr) noexcept
2498 f = std::strtof(str, endptr);
2501 static void strtof(
double& f,
const char* str,
char** endptr) noexcept
2503 f = std::strtod(str, endptr);
2506 static void strtof(
long double& f,
const char* str,
char** endptr) noexcept
2508 f = std::strtold(str, endptr);
2558 token_type number_type = token_type::value_unsigned;
2566 goto scan_number_minus;
2572 goto scan_number_zero;
2586 goto scan_number_any1;
2598 number_type = token_type::value_integer;
2604 goto scan_number_zero;
2618 goto scan_number_any1;
2623 error_message =
"invalid number; expected digit after '-'";
2624 return token_type::parse_error;
2634 add(decimal_point_char);
2635 goto scan_number_decimal1;
2642 goto scan_number_exponent;
2646 goto scan_number_done;
2665 goto scan_number_any1;
2670 add(decimal_point_char);
2671 goto scan_number_decimal1;
2678 goto scan_number_exponent;
2682 goto scan_number_done;
2685 scan_number_decimal1:
2687 number_type = token_type::value_float;
2702 goto scan_number_decimal2;
2707 error_message =
"invalid number; expected digit after '.'";
2708 return token_type::parse_error;
2712 scan_number_decimal2:
2728 goto scan_number_decimal2;
2735 goto scan_number_exponent;
2739 goto scan_number_done;
2742 scan_number_exponent:
2744 number_type = token_type::value_float;
2751 goto scan_number_sign;
2766 goto scan_number_any2;
2772 "invalid number; expected '+', '-', or digit after exponent";
2773 return token_type::parse_error;
2793 goto scan_number_any2;
2798 error_message =
"invalid number; expected digit after exponent sign";
2799 return token_type::parse_error;
2819 goto scan_number_any2;
2823 goto scan_number_done;
2831 char* endptr =
nullptr;
2835 if (number_type == token_type::value_unsigned)
2837 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
2840 assert(endptr == token_buffer.data() + token_buffer.size());
2844 value_unsigned =
static_cast<number_unsigned_t
>(x);
2845 if (value_unsigned == x)
2847 return token_type::value_unsigned;
2851 else if (number_type == token_type::value_integer)
2853 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
2856 assert(endptr == token_buffer.data() + token_buffer.size());
2860 value_integer =
static_cast<number_integer_t
>(x);
2861 if (value_integer == x)
2863 return token_type::value_integer;
2870 strtof(value_float, token_buffer.data(), &endptr);
2873 assert(endptr == token_buffer.data() + token_buffer.size());
2875 return token_type::value_float;
2883 token_type scan_literal(
const char* literal_text,
const std::size_t length,
2886 assert(current == literal_text[0]);
2887 for (std::size_t i = 1; i < length; ++i)
2889 if (JSON_UNLIKELY(
get() != literal_text[i]))
2891 error_message =
"invalid literal";
2892 return token_type::parse_error;
2903 void reset() noexcept
2905 token_buffer.clear();
2906 token_string.clear();
2907 token_string.push_back(std::char_traits<char>::to_char_type(current));
2920 std::char_traits<char>::int_type
get()
2923 current = ia->get_character();
2924 if (JSON_LIKELY(current != std::char_traits<char>::eof()))
2926 token_string.push_back(std::char_traits<char>::to_char_type(current));
2935 if (JSON_LIKELY(current != std::char_traits<char>::eof()))
2937 ia->unget_character();
2938 assert(token_string.size() != 0);
2939 token_string.pop_back();
2946 token_buffer.push_back(std::char_traits<char>::to_char_type(c));
2957 return value_integer;
2963 return value_unsigned;
2975 return std::move(token_buffer);
2995 for (
const auto c : token_string)
2997 if (
'\x00' <= c and c <=
'\x1F')
3000 std::stringstream ss;
3001 ss <<
"<U+" << std::setw(4) << std::uppercase << std::setfill(
'0')
3002 << std::hex << static_cast<int>(c) <<
">";
3008 result.push_back(c);
3018 return error_message;
3032 while (current ==
' ' or current ==
'\t' or current ==
'\n' or current ==
'\r');
3038 return token_type::begin_array;
3040 return token_type::end_array;
3042 return token_type::begin_object;
3044 return token_type::end_object;
3046 return token_type::name_separator;
3048 return token_type::value_separator;
3052 return scan_literal(
"true", 4, token_type::literal_true);
3054 return scan_literal(
"false", 5, token_type::literal_false);
3056 return scan_literal(
"null", 4, token_type::literal_null);
3060 return scan_string();
3074 return scan_number();
3079 case std::char_traits<char>::eof():
3080 return token_type::end_of_input;
3084 error_message =
"invalid literal";
3085 return token_type::parse_error;
3094 std::char_traits<char>::int_type current = std::char_traits<char>::eof();
3097 std::size_t chars_read = 0;
3100 std::vector<char> token_string {};
3103 string_t token_buffer {};
3106 const char* error_message =
"";
3109 number_integer_t value_integer = 0;
3110 number_unsigned_t value_unsigned = 0;
3111 number_float_t value_float = 0;
3114 const char decimal_point_char =
'.';
3125 #include <functional> 3153 template<
typename BasicJsonType>
3156 using number_integer_t =
typename BasicJsonType::number_integer_t;
3157 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
3158 using number_float_t =
typename BasicJsonType::number_float_t;
3159 using string_t =
typename BasicJsonType::string_t;
3180 using parser_callback_t =
3181 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
3185 const parser_callback_t cb =
nullptr,
3186 const bool allow_exceptions_ =
true)
3187 : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_)
3200 void parse(
const bool strict, BasicJsonType& result)
3205 parse_internal(
true, result);
3206 result.assert_invariant();
3212 expect(token_type::end_of_input);
3224 if (result.is_discarded())
3241 if (not accept_internal())
3247 return not strict or (get_token() == token_type::end_of_input);
3257 void parse_internal(
bool keep, BasicJsonType& result)
3260 assert(not errored);
3263 if (not result.is_discarded())
3265 result.m_value.destroy(result.m_type);
3271 case token_type::begin_object:
3277 keep = callback(depth++, parse_event_t::object_start, result);
3280 if (not callback or keep)
3292 if (last_token == token_type::end_object)
3294 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
3296 result.m_value.destroy(result.m_type);
3304 BasicJsonType value;
3308 if (not expect(token_type::value_string))
3312 key = m_lexer.move_string();
3314 bool keep_tag =
false;
3319 BasicJsonType k(key);
3320 keep_tag = callback(depth, parse_event_t::key, k);
3330 if (not expect(token_type::name_separator))
3337 value.m_value.destroy(value.m_type);
3339 parse_internal(keep, value);
3341 if (JSON_UNLIKELY(errored))
3346 if (keep and keep_tag and not value.is_discarded())
3348 result.m_value.object->emplace(std::move(key), std::move(value));
3353 if (last_token == token_type::value_separator)
3360 if (not expect(token_type::end_object))
3367 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
3369 result.m_value.destroy(result.m_type);
3375 case token_type::begin_array:
3381 keep = callback(depth++, parse_event_t::array_start, result);
3384 if (not callback or keep)
3396 if (last_token == token_type::end_array)
3398 if (callback and not callback(--depth, parse_event_t::array_end, result))
3400 result.m_value.destroy(result.m_type);
3407 BasicJsonType value;
3411 value.m_value.destroy(value.m_type);
3413 parse_internal(keep, value);
3415 if (JSON_UNLIKELY(errored))
3420 if (keep and not value.is_discarded())
3422 result.m_value.array->push_back(std::move(value));
3427 if (last_token == token_type::value_separator)
3434 if (not expect(token_type::end_array))
3441 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
3443 result.m_value.destroy(result.m_type);
3449 case token_type::literal_null:
3455 case token_type::value_string:
3458 result.m_value = m_lexer.move_string();
3462 case token_type::literal_true:
3465 result.m_value =
true;
3469 case token_type::literal_false:
3472 result.m_value =
false;
3476 case token_type::value_unsigned:
3479 result.m_value = m_lexer.get_number_unsigned();
3483 case token_type::value_integer:
3486 result.m_value = m_lexer.get_number_integer();
3490 case token_type::value_float:
3493 result.m_value = m_lexer.get_number_float();
3496 if (JSON_UNLIKELY(not std::isfinite(result.m_value.number_float)))
3498 if (allow_exceptions)
3500 JSON_THROW(out_of_range::create(406,
"number overflow parsing '" +
3501 m_lexer.get_token_string() +
"'"));
3503 expect(token_type::uninitialized);
3508 case token_type::parse_error:
3511 if (not expect(token_type::uninitialized))
3521 if (not expect(token_type::literal_or_value))
3529 if (keep and callback and not callback(depth, parse_event_t::value, result))
3531 result.m_value.destroy(result.m_type);
3546 bool accept_internal()
3550 case token_type::begin_object:
3556 if (last_token == token_type::end_object)
3565 if (last_token != token_type::value_string)
3572 if (last_token != token_type::name_separator)
3579 if (not accept_internal())
3586 if (last_token == token_type::value_separator)
3593 return (last_token == token_type::end_object);
3597 case token_type::begin_array:
3603 if (last_token == token_type::end_array)
3612 if (not accept_internal())
3619 if (last_token == token_type::value_separator)
3626 return (last_token == token_type::end_array);
3630 case token_type::value_float:
3633 return std::isfinite(m_lexer.get_number_float());
3636 case token_type::literal_false:
3637 case token_type::literal_null:
3638 case token_type::literal_true:
3639 case token_type::value_integer:
3640 case token_type::value_string:
3641 case token_type::value_unsigned:
3650 token_type get_token()
3652 return (last_token = m_lexer.scan());
3658 bool expect(token_type t)
3660 if (JSON_UNLIKELY(t != last_token))
3664 if (allow_exceptions)
3677 [[noreturn]]
void throw_exception()
const 3680 if (last_token == token_type::parse_error)
3682 error_msg +=
std::string(m_lexer.get_error_message()) +
"; last read: '" +
3683 m_lexer.get_token_string() +
"'";
3687 error_msg +=
"unexpected " +
std::string(lexer_t::token_type_name(last_token));
3690 if (expected != token_type::uninitialized)
3692 error_msg +=
"; expected " +
std::string(lexer_t::token_type_name(expected));
3702 const parser_callback_t callback =
nullptr;
3704 token_type last_token = token_type::uninitialized;
3708 bool errored =
false;
3710 token_type expected = token_type::uninitialized;
3712 const bool allow_exceptions =
true;
3739 using difference_type = std::ptrdiff_t;
3740 static constexpr difference_type begin_value = 0;
3741 static constexpr difference_type end_value = begin_value + 1;
3744 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
3747 constexpr difference_type get_value()
const noexcept
3767 return m_it == begin_value;
3773 return m_it == end_value;
3778 return lhs.m_it == rhs.m_it;
3783 return lhs.m_it < rhs.m_it;
3788 auto result = *
this;
3795 return lhs.m_it - rhs.m_it;
3806 auto result = *
this;
3819 auto result = *
this;
3858 typename BasicJsonType::object_t::iterator object_iterator {};
3860 typename BasicJsonType::array_t::iterator array_iterator {};
3872 #include <type_traits> 3914 template<
typename BasicJsonType>
3919 friend BasicJsonType;
3922 using object_t =
typename BasicJsonType::object_t;
3923 using array_t =
typename BasicJsonType::array_t;
3925 static_assert(
is_basic_json<
typename std::remove_const<BasicJsonType>::type>::value,
3926 "iter_impl only accepts (const) basic_json");
3942 using pointer =
typename std::conditional<std::is_const<BasicJsonType>::value,
3943 typename BasicJsonType::const_pointer,
3944 typename BasicJsonType::pointer>::type;
3947 typename std::conditional<std::is_const<BasicJsonType>::value,
3948 typename BasicJsonType::const_reference,
3949 typename BasicJsonType::reference>::type;
3962 assert(m_object !=
nullptr);
3964 switch (m_object->m_type)
3968 m_it.object_iterator =
typename object_t::iterator();
3974 m_it.array_iterator =
typename array_t::iterator();
4001 : m_object(other.m_object), m_it(other.m_it) {}
4011 m_object = other.m_object;
4021 void set_begin() noexcept
4023 assert(m_object !=
nullptr);
4025 switch (m_object->m_type)
4029 m_it.object_iterator = m_object->m_value.object->begin();
4035 m_it.array_iterator = m_object->m_value.array->begin();
4042 m_it.primitive_iterator.set_end();
4048 m_it.primitive_iterator.set_begin();
4058 void set_end() noexcept
4060 assert(m_object !=
nullptr);
4062 switch (m_object->m_type)
4066 m_it.object_iterator = m_object->m_value.object->end();
4072 m_it.array_iterator = m_object->m_value.array->end();
4078 m_it.primitive_iterator.set_end();
4091 assert(m_object !=
nullptr);
4093 switch (m_object->m_type)
4097 assert(m_it.object_iterator != m_object->m_value.object->end());
4098 return m_it.object_iterator->second;
4103 assert(m_it.array_iterator != m_object->m_value.array->end());
4104 return *m_it.array_iterator;
4108 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4112 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
4117 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4128 assert(m_object !=
nullptr);
4130 switch (m_object->m_type)
4134 assert(m_it.object_iterator != m_object->m_value.object->end());
4135 return &(m_it.object_iterator->second);
4140 assert(m_it.array_iterator != m_object->m_value.array->end());
4141 return &*m_it.array_iterator;
4146 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
4151 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4162 auto result = *
this;
4173 assert(m_object !=
nullptr);
4175 switch (m_object->m_type)
4179 std::advance(m_it.object_iterator, 1);
4185 std::advance(m_it.array_iterator, 1);
4191 ++m_it.primitive_iterator;
4205 auto result = *
this;
4216 assert(m_object !=
nullptr);
4218 switch (m_object->m_type)
4222 std::advance(m_it.object_iterator, -1);
4228 std::advance(m_it.array_iterator, -1);
4234 --m_it.primitive_iterator;
4249 if (JSON_UNLIKELY(m_object != other.m_object))
4251 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
4254 assert(m_object !=
nullptr);
4256 switch (m_object->m_type)
4275 return not operator==(other);
4285 if (JSON_UNLIKELY(m_object != other.m_object))
4287 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
4290 assert(m_object !=
nullptr);
4292 switch (m_object->m_type)
4295 JSON_THROW(invalid_iterator::create(213,
"cannot compare order of object iterators"));
4311 return not other.operator < (*this);
4320 return not operator<=(other);
4338 assert(m_object !=
nullptr);
4340 switch (m_object->m_type)
4343 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
4347 std::advance(m_it.array_iterator, i);
4353 m_it.primitive_iterator += i;
4367 return operator+=(-i);
4376 auto result = *
this;
4398 auto result = *
this;
4409 assert(m_object !=
nullptr);
4411 switch (m_object->m_type)
4414 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
4430 assert(m_object !=
nullptr);
4432 switch (m_object->m_type)
4435 JSON_THROW(invalid_iterator::create(208,
"cannot use operator[] for object iterators"));
4438 return *std::next(m_it.array_iterator, n);
4441 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4445 if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
4450 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
4459 typename object_t::key_type
key()
const 4461 assert(m_object !=
nullptr);
4463 if (JSON_LIKELY(m_object->is_object()))
4465 return m_it.object_iterator->first;
4468 JSON_THROW(invalid_iterator::create(207,
"cannot use key() for non-object iterators"));
4507 class iteration_proxy_internal
4511 IteratorType anchor;
4513 std::size_t array_index = 0;
4516 explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
4519 iteration_proxy_internal& operator*()
4525 iteration_proxy_internal& operator++()
4534 bool operator!=(
const iteration_proxy_internal& o)
const noexcept
4536 return anchor != o.anchor;
4542 assert(anchor.m_object !=
nullptr);
4544 switch (anchor.m_object->type())
4548 return std::to_string(array_index);
4552 return anchor.key();
4561 typename IteratorType::reference value()
const 4563 return anchor.value();
4568 typename IteratorType::reference container;
4573 : container(cont) {}
4576 iteration_proxy_internal
begin() noexcept
4578 return iteration_proxy_internal(container.begin());
4582 iteration_proxy_internal
end() noexcept
4584 return iteration_proxy_internal(container.end());
4623 template<
typename Base>
4627 using difference_type = std::ptrdiff_t;
4691 return *(this->operator+(n));
4695 auto key() const -> decltype(
std::declval<Base>().key())
4697 auto it = --this->base();
4704 auto it = --this->base();
4705 return it.operator * ();
4714 #include <algorithm> 4730 virtual void write_character(CharType c) = 0;
4731 virtual void write_characters(
const CharType* s, std::size_t length) = 0;
4736 template<
typename CharType>
4740 template<
typename CharType>
4746 void write_character(CharType c)
override 4751 void write_characters(
const CharType* s, std::size_t length)
override 4753 std::copy(s, s + length, std::back_inserter(v));
4757 std::vector<CharType>& v;
4761 template<
typename CharType>
4767 void write_character(CharType c)
override 4772 void write_characters(
const CharType* s, std::size_t length)
override 4774 stream.write(s, static_cast<std::streamsize>(length));
4778 std::basic_ostream<CharType>& stream;
4782 template<
typename CharType,
typename StringType = std::basic_
string<CharType>>
4788 void write_character(CharType c)
override 4793 void write_characters(
const CharType* s, std::size_t length)
override 4795 str.append(s, length);
4802 template<
typename CharType,
typename StringType = std::basic_
string<CharType>>
4829 #include <algorithm> 4864 template<
typename BasicJsonType>
4867 using number_integer_t =
typename BasicJsonType::number_integer_t;
4868 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
4869 using string_t =
typename BasicJsonType::string_t;
4894 const auto res = parse_cbor_internal();
4915 const auto res = parse_msgpack_internal();
4936 const auto res = parse_ubjson_internal();
4954 return (*reinterpret_cast<char*>(&num) == 1);
4963 BasicJsonType parse_cbor_internal(
const bool get_char =
true)
4965 switch (get_char ?
get() : current)
4968 case std::char_traits<char>::eof():
4996 return static_cast<number_unsigned_t
>(current);
4999 return get_number<uint8_t>();
5002 return get_number<uint16_t>();
5005 return get_number<uint32_t>();
5008 return get_number<uint64_t>();
5035 return static_cast<int8_t
>(0x20 - 1 - current);
5039 return static_cast<number_integer_t
>(-1) - get_number<uint8_t>();
5044 return static_cast<number_integer_t
>(-1) - get_number<uint16_t>();
5049 return static_cast<number_integer_t
>(-1) - get_number<uint32_t>();
5054 return static_cast<number_integer_t
>(-1) -
5055 static_cast<number_integer_t>(get_number<uint64_t>());
5089 return get_cbor_string();
5118 return get_cbor_array(current & 0x1F);
5123 return get_cbor_array(get_number<uint8_t>());
5128 return get_cbor_array(get_number<uint16_t>());
5133 return get_cbor_array(get_number<uint32_t>());
5138 return get_cbor_array(get_number<uint64_t>());
5144 while (
get() != 0xFF)
5146 result.push_back(parse_cbor_internal(
false));
5177 return get_cbor_object(current & 0x1F);
5182 return get_cbor_object(get_number<uint8_t>());
5187 return get_cbor_object(get_number<uint16_t>());
5192 return get_cbor_object(get_number<uint32_t>());
5197 return get_cbor_object(get_number<uint64_t>());
5203 while (
get() != 0xFF)
5205 auto key = get_cbor_string();
5206 result[key] = parse_cbor_internal();
5228 const int byte1 =
get();
5230 const int byte2 =
get();
5241 const int half = (byte1 << 8) + byte2;
5242 const int exp = (half >> 10) & 0x1F;
5243 const int mant = half & 0x3FF;
5247 val = std::ldexp(mant, -24);
5251 val = std::ldexp(mant + 1024, exp - 25);
5255 val = (mant == 0) ? std::numeric_limits<double>::infinity()
5256 : std::numeric_limits<double>::quiet_NaN();
5258 return (half & 0x8000) != 0 ? -val : val;
5263 return get_number<float>();
5268 return get_number<double>();
5273 std::stringstream ss;
5274 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5275 JSON_THROW(
parse_error::create(112, chars_read,
"error reading CBOR; last byte: 0x" + ss.str()));
5280 BasicJsonType parse_msgpack_internal()
5285 case std::char_traits<char>::eof():
5417 return static_cast<number_unsigned_t
>(current);
5437 return get_msgpack_object(current & 0x0F);
5458 return get_msgpack_array(current & 0x0F);
5494 return get_msgpack_string();
5506 return get_number<float>();
5509 return get_number<double>();
5512 return get_number<uint8_t>();
5515 return get_number<uint16_t>();
5518 return get_number<uint32_t>();
5521 return get_number<uint64_t>();
5524 return get_number<int8_t>();
5527 return get_number<int16_t>();
5530 return get_number<int32_t>();
5533 return get_number<int64_t>();
5538 return get_msgpack_string();
5542 return get_msgpack_array(get_number<uint16_t>());
5547 return get_msgpack_array(get_number<uint32_t>());
5552 return get_msgpack_object(get_number<uint16_t>());
5557 return get_msgpack_object(get_number<uint32_t>());
5593 return static_cast<int8_t
>(current);
5597 std::stringstream ss;
5598 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5600 "error reading MessagePack; last byte: 0x" + ss.str()));
5610 BasicJsonType parse_ubjson_internal(
const bool get_char =
true)
5612 return get_ubjson_value(get_char ? get_ignore_noop() : current);
5627 return (current = ia->get_character());
5633 int get_ignore_noop()
5639 while (current ==
'N');
5657 template<
typename NumberType> NumberType get_number()
5660 std::array<uint8_t, sizeof(NumberType)> vec;
5661 for (std::size_t i = 0; i <
sizeof(NumberType); ++i)
5667 if (is_little_endian)
5669 vec[
sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
5673 vec[i] =
static_cast<uint8_t
>(current);
5679 std::memcpy(&result, vec.data(),
sizeof(NumberType));
5696 template<
typename NumberType>
5697 string_t get_string(
const NumberType len)
5700 std::generate_n(std::back_inserter(result), len, [
this]()
5704 return static_cast<char>(current);
5721 string_t get_cbor_string()
5753 return get_string(current & 0x1F);
5758 return get_string(get_number<uint8_t>());
5763 return get_string(get_number<uint16_t>());
5768 return get_string(get_number<uint32_t>());
5773 return get_string(get_number<uint64_t>());
5779 while (
get() != 0xFF)
5781 result.append(get_cbor_string());
5788 std::stringstream ss;
5789 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5790 JSON_THROW(
parse_error::create(113, chars_read,
"expected a CBOR string; last byte: 0x" + ss.str()));
5795 template<
typename NumberType>
5796 BasicJsonType get_cbor_array(
const NumberType len)
5799 std::generate_n(std::back_inserter(*result.m_value.array), len, [
this]()
5801 return parse_cbor_internal();
5806 template<
typename NumberType>
5807 BasicJsonType get_cbor_object(
const NumberType len)
5810 std::generate_n(std::inserter(*result.m_value.object,
5811 result.m_value.object->end()),
5815 auto key = get_cbor_string();
5816 auto val = parse_cbor_internal();
5817 return std::make_pair(std::move(key), std::move(val));
5833 string_t get_msgpack_string()
5873 return get_string(current & 0x1F);
5878 return get_string(get_number<uint8_t>());
5883 return get_string(get_number<uint16_t>());
5888 return get_string(get_number<uint32_t>());
5893 std::stringstream ss;
5894 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5896 "expected a MessagePack string; last byte: 0x" + ss.str()));
5901 template<
typename NumberType>
5902 BasicJsonType get_msgpack_array(
const NumberType len)
5905 std::generate_n(std::back_inserter(*result.m_value.array), len, [
this]()
5907 return parse_msgpack_internal();
5912 template<
typename NumberType>
5913 BasicJsonType get_msgpack_object(
const NumberType len)
5916 std::generate_n(std::inserter(*result.m_value.object,
5917 result.m_value.object->end()),
5921 auto key = get_msgpack_string();
5922 auto val = parse_msgpack_internal();
5923 return std::make_pair(std::move(key), std::move(val));
5944 string_t get_ubjson_string(
const bool get_char =
true)
5956 return get_string(get_number<uint8_t>());
5958 return get_string(get_number<int8_t>());
5960 return get_string(get_number<int16_t>());
5962 return get_string(get_number<int32_t>());
5964 return get_string(get_number<int64_t>());
5966 std::stringstream ss;
5967 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5969 "expected a UBJSON string; last byte: 0x" + ss.str()));
5981 std::pair<std::size_t, int> get_ubjson_size_type()
5983 std::size_t sz = string_t::npos;
5996 std::stringstream ss;
5997 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5999 "expected '#' after UBJSON type information; last byte: 0x" + ss.str()));
6001 sz = parse_ubjson_internal();
6003 else if (current ==
'#')
6005 sz = parse_ubjson_internal();
6008 return std::make_pair(sz, tc);
6011 BasicJsonType get_ubjson_value(
const int prefix)
6015 case std::char_traits<char>::eof():
6027 return get_number<uint8_t>();
6029 return get_number<int8_t>();
6031 return get_number<int16_t>();
6033 return get_number<int32_t>();
6035 return get_number<int64_t>();
6037 return get_number<float>();
6039 return get_number<double>();
6045 if (JSON_UNLIKELY(current > 127))
6047 std::stringstream ss;
6048 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
6050 "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + ss.str()));
6052 return string_t(1, static_cast<char>(current));
6056 return get_ubjson_string();
6059 return get_ubjson_array();
6062 return get_ubjson_object();
6065 std::stringstream ss;
6066 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
6068 "error reading UBJSON; last byte: 0x" + ss.str()));
6072 BasicJsonType get_ubjson_array()
6075 const auto size_and_type = get_ubjson_size_type();
6077 if (size_and_type.first != string_t::npos)
6079 if (JSON_UNLIKELY(size_and_type.first > result.max_size()))
6081 JSON_THROW(out_of_range::create(408,
6082 "excessive array size: " + std::to_string(size_and_type.first)));
6085 if (size_and_type.second != 0)
6087 if (size_and_type.second !=
'N')
6089 std::generate_n(std::back_inserter(*result.m_value.array),
6090 size_and_type.first, [
this, size_and_type]()
6092 return get_ubjson_value(size_and_type.second);
6098 std::generate_n(std::back_inserter(*result.m_value.array),
6099 size_and_type.first, [
this]()
6101 return parse_ubjson_internal();
6107 while (current !=
']')
6109 result.push_back(parse_ubjson_internal(
false));
6117 BasicJsonType get_ubjson_object()
6120 const auto size_and_type = get_ubjson_size_type();
6122 if (size_and_type.first != string_t::npos)
6124 if (JSON_UNLIKELY(size_and_type.first > result.max_size()))
6126 JSON_THROW(out_of_range::create(408,
6127 "excessive object size: " + std::to_string(size_and_type.first)));
6130 if (size_and_type.second != 0)
6132 std::generate_n(std::inserter(*result.m_value.object,
6133 result.m_value.object->end()),
6134 size_and_type.first, [
this, size_and_type]()
6136 auto key = get_ubjson_string();
6137 auto val = get_ubjson_value(size_and_type.second);
6138 return std::make_pair(std::move(key), std::move(val));
6143 std::generate_n(std::inserter(*result.m_value.object,
6144 result.m_value.object->end()),
6145 size_and_type.first, [
this]()
6147 auto key = get_ubjson_string();
6148 auto val = parse_ubjson_internal();
6149 return std::make_pair(std::move(key), std::move(val));
6155 while (current !=
'}')
6157 auto key = get_ubjson_string(
false);
6158 result[std::move(key)] = parse_ubjson_internal();
6170 void expect_eof()
const 6172 if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
6182 void unexpect_eof()
const 6184 if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
6195 int current = std::char_traits<char>::eof();
6198 std::size_t chars_read = 0;
6201 const bool is_little_endian = little_endianess();
6209 #include <algorithm> 6231 template<
typename BasicJsonType,
typename CharType>
6254 oa->write_character(static_cast<CharType>(0xF6));
6260 oa->write_character(j.m_value.boolean
6261 ? static_cast<CharType>(0xF5)
6262 : static_cast<CharType>(0xF4));
6268 if (j.m_value.number_integer >= 0)
6273 if (j.m_value.number_integer <= 0x17)
6275 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6277 else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
6279 oa->write_character(static_cast<CharType>(0x18));
6280 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6282 else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
6284 oa->write_character(static_cast<CharType>(0x19));
6285 write_number(static_cast<uint16_t>(j.m_value.number_integer));
6287 else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
6289 oa->write_character(static_cast<CharType>(0x1A));
6290 write_number(static_cast<uint32_t>(j.m_value.number_integer));
6294 oa->write_character(static_cast<CharType>(0x1B));
6295 write_number(static_cast<uint64_t>(j.m_value.number_integer));
6302 const auto positive_number = -1 - j.m_value.number_integer;
6303 if (j.m_value.number_integer >= -24)
6305 write_number(static_cast<uint8_t>(0x20 + positive_number));
6307 else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
6309 oa->write_character(static_cast<CharType>(0x38));
6310 write_number(static_cast<uint8_t>(positive_number));
6312 else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
6314 oa->write_character(static_cast<CharType>(0x39));
6315 write_number(static_cast<uint16_t>(positive_number));
6317 else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
6319 oa->write_character(static_cast<CharType>(0x3A));
6320 write_number(static_cast<uint32_t>(positive_number));
6324 oa->write_character(static_cast<CharType>(0x3B));
6325 write_number(static_cast<uint64_t>(positive_number));
6333 if (j.m_value.number_unsigned <= 0x17)
6335 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
6337 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
6339 oa->write_character(static_cast<CharType>(0x18));
6340 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
6342 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
6344 oa->write_character(static_cast<CharType>(0x19));
6345 write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
6347 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
6349 oa->write_character(static_cast<CharType>(0x1A));
6350 write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
6354 oa->write_character(static_cast<CharType>(0x1B));
6355 write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
6362 oa->write_character(static_cast<CharType>(0xFB));
6363 write_number(j.m_value.number_float);
6370 const auto N = j.m_value.string->size();
6373 write_number(static_cast<uint8_t>(0x60 + N));
6375 else if (N <= (std::numeric_limits<uint8_t>::max)())
6377 oa->write_character(static_cast<CharType>(0x78));
6378 write_number(static_cast<uint8_t>(N));
6380 else if (N <= (std::numeric_limits<uint16_t>::max)())
6382 oa->write_character(static_cast<CharType>(0x79));
6383 write_number(static_cast<uint16_t>(N));
6385 else if (N <= (std::numeric_limits<uint32_t>::max)())
6387 oa->write_character(static_cast<CharType>(0x7A));
6388 write_number(static_cast<uint32_t>(N));
6391 else if (N <= (std::numeric_limits<uint64_t>::max)())
6393 oa->write_character(static_cast<CharType>(0x7B));
6394 write_number(static_cast<uint64_t>(N));
6399 oa->write_characters(
6400 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
6401 j.m_value.string->size());
6408 const auto N = j.m_value.array->size();
6411 write_number(static_cast<uint8_t>(0x80 + N));
6413 else if (N <= (std::numeric_limits<uint8_t>::max)())
6415 oa->write_character(static_cast<CharType>(0x98));
6416 write_number(static_cast<uint8_t>(N));
6418 else if (N <= (std::numeric_limits<uint16_t>::max)())
6420 oa->write_character(static_cast<CharType>(0x99));
6421 write_number(static_cast<uint16_t>(N));
6423 else if (N <= (std::numeric_limits<uint32_t>::max)())
6425 oa->write_character(static_cast<CharType>(0x9A));
6426 write_number(static_cast<uint32_t>(N));
6429 else if (N <= (std::numeric_limits<uint64_t>::max)())
6431 oa->write_character(static_cast<CharType>(0x9B));
6432 write_number(static_cast<uint64_t>(N));
6437 for (
const auto& el : *j.m_value.array)
6447 const auto N = j.m_value.object->size();
6450 write_number(static_cast<uint8_t>(0xA0 + N));
6452 else if (N <= (std::numeric_limits<uint8_t>::max)())
6454 oa->write_character(static_cast<CharType>(0xB8));
6455 write_number(static_cast<uint8_t>(N));
6457 else if (N <= (std::numeric_limits<uint16_t>::max)())
6459 oa->write_character(static_cast<CharType>(0xB9));
6460 write_number(static_cast<uint16_t>(N));
6462 else if (N <= (std::numeric_limits<uint32_t>::max)())
6464 oa->write_character(static_cast<CharType>(0xBA));
6465 write_number(static_cast<uint32_t>(N));
6468 else if (N <= (std::numeric_limits<uint64_t>::max)())
6470 oa->write_character(static_cast<CharType>(0xBB));
6471 write_number(static_cast<uint64_t>(N));
6476 for (
const auto& el : *j.m_value.object)
6478 write_cbor(el.first);
6479 write_cbor(el.second);
6498 oa->write_character(static_cast<CharType>(0xC0));
6504 oa->write_character(j.m_value.boolean
6505 ? static_cast<CharType>(0xC3)
6506 : static_cast<CharType>(0xC2));
6512 if (j.m_value.number_integer >= 0)
6517 if (j.m_value.number_unsigned < 128)
6520 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6522 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
6525 oa->write_character(static_cast<CharType>(0xCC));
6526 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6528 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
6531 oa->write_character(static_cast<CharType>(0xCD));
6532 write_number(static_cast<uint16_t>(j.m_value.number_integer));
6534 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
6537 oa->write_character(static_cast<CharType>(0xCE));
6538 write_number(static_cast<uint32_t>(j.m_value.number_integer));
6540 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
6543 oa->write_character(static_cast<CharType>(0xCF));
6544 write_number(static_cast<uint64_t>(j.m_value.number_integer));
6549 if (j.m_value.number_integer >= -32)
6552 write_number(static_cast<int8_t>(j.m_value.number_integer));
6554 else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and
6555 j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
6558 oa->write_character(static_cast<CharType>(0xD0));
6559 write_number(static_cast<int8_t>(j.m_value.number_integer));
6561 else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and
6562 j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
6565 oa->write_character(static_cast<CharType>(0xD1));
6566 write_number(static_cast<int16_t>(j.m_value.number_integer));
6568 else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and
6569 j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
6572 oa->write_character(static_cast<CharType>(0xD2));
6573 write_number(static_cast<int32_t>(j.m_value.number_integer));
6575 else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and
6576 j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
6579 oa->write_character(static_cast<CharType>(0xD3));
6580 write_number(static_cast<int64_t>(j.m_value.number_integer));
6588 if (j.m_value.number_unsigned < 128)
6591 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6593 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
6596 oa->write_character(static_cast<CharType>(0xCC));
6597 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6599 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
6602 oa->write_character(static_cast<CharType>(0xCD));
6603 write_number(static_cast<uint16_t>(j.m_value.number_integer));
6605 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
6608 oa->write_character(static_cast<CharType>(0xCE));
6609 write_number(static_cast<uint32_t>(j.m_value.number_integer));
6611 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
6614 oa->write_character(static_cast<CharType>(0xCF));
6615 write_number(static_cast<uint64_t>(j.m_value.number_integer));
6622 oa->write_character(static_cast<CharType>(0xCB));
6623 write_number(j.m_value.number_float);
6630 const auto N = j.m_value.string->size();
6634 write_number(static_cast<uint8_t>(0xA0 | N));
6636 else if (N <= (std::numeric_limits<uint8_t>::max)())
6639 oa->write_character(static_cast<CharType>(0xD9));
6640 write_number(static_cast<uint8_t>(N));
6642 else if (N <= (std::numeric_limits<uint16_t>::max)())
6645 oa->write_character(static_cast<CharType>(0xDA));
6646 write_number(static_cast<uint16_t>(N));
6648 else if (N <= (std::numeric_limits<uint32_t>::max)())
6651 oa->write_character(static_cast<CharType>(0xDB));
6652 write_number(static_cast<uint32_t>(N));
6656 oa->write_characters(
6657 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
6658 j.m_value.string->size());
6665 const auto N = j.m_value.array->size();
6669 write_number(static_cast<uint8_t>(0x90 | N));
6671 else if (N <= (std::numeric_limits<uint16_t>::max)())
6674 oa->write_character(static_cast<CharType>(0xDC));
6675 write_number(static_cast<uint16_t>(N));
6677 else if (N <= (std::numeric_limits<uint32_t>::max)())
6680 oa->write_character(static_cast<CharType>(0xDD));
6681 write_number(static_cast<uint32_t>(N));
6685 for (
const auto& el : *j.m_value.array)
6695 const auto N = j.m_value.object->size();
6699 write_number(static_cast<uint8_t>(0x80 | (N & 0xF)));
6701 else if (N <= (std::numeric_limits<uint16_t>::max)())
6704 oa->write_character(static_cast<CharType>(0xDE));
6705 write_number(static_cast<uint16_t>(N));
6707 else if (N <= (std::numeric_limits<uint32_t>::max)())
6710 oa->write_character(static_cast<CharType>(0xDF));
6711 write_number(static_cast<uint32_t>(N));
6715 for (
const auto& el : *j.m_value.object)
6717 write_msgpack(el.first);
6718 write_msgpack(el.second);
6735 const bool use_type,
const bool add_prefix =
true)
6743 oa->write_character(static_cast<CharType>(
'Z'));
6751 oa->write_character(j.m_value.boolean
6752 ? static_cast<CharType>(
'T')
6753 : static_cast<CharType>(
'F'));
6759 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
6765 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
6771 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
6779 oa->write_character(static_cast<CharType>(
'S'));
6781 write_number_with_ubjson_prefix(j.m_value.string->size(),
true);
6782 oa->write_characters(
6783 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
6784 j.m_value.string->size());
6792 oa->write_character(static_cast<CharType>(
'['));
6795 bool prefix_required =
true;
6796 if (use_type and not j.m_value.array->empty())
6799 const char first_prefix = ubjson_prefix(j.front());
6800 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
6801 [
this, first_prefix](
const BasicJsonType & v)
6803 return ubjson_prefix(v) == first_prefix;
6808 prefix_required =
false;
6809 oa->write_character(static_cast<CharType>(
'$'));
6810 oa->write_character(static_cast<CharType>(first_prefix));
6816 oa->write_character(static_cast<CharType>(
'#'));
6817 write_number_with_ubjson_prefix(j.m_value.array->size(),
true);
6820 for (
const auto& el : *j.m_value.array)
6822 write_ubjson(el, use_count, use_type, prefix_required);
6827 oa->write_character(static_cast<CharType>(
']'));
6837 oa->write_character(static_cast<CharType>(
'{'));
6840 bool prefix_required =
true;
6841 if (use_type and not j.m_value.object->empty())
6844 const char first_prefix = ubjson_prefix(j.front());
6845 const bool same_prefix = std::all_of(j.begin(), j.end(),
6846 [
this, first_prefix](
const BasicJsonType & v)
6848 return ubjson_prefix(v) == first_prefix;
6853 prefix_required =
false;
6854 oa->write_character(static_cast<CharType>(
'$'));
6855 oa->write_character(static_cast<CharType>(first_prefix));
6861 oa->write_character(static_cast<CharType>(
'#'));
6862 write_number_with_ubjson_prefix(j.m_value.object->size(),
true);
6865 for (
const auto& el : *j.m_value.object)
6867 write_number_with_ubjson_prefix(el.first.size(),
true);
6868 oa->write_characters(
6869 reinterpret_cast<const CharType*>(el.first.c_str()),
6871 write_ubjson(el.second, use_count, use_type, prefix_required);
6876 oa->write_character(static_cast<CharType>(
'}'));
6898 template<
typename NumberType>
6899 void write_number(
const NumberType n)
6902 std::array<CharType, sizeof(NumberType)> vec;
6903 std::memcpy(vec.data(), &n,
sizeof(NumberType));
6906 if (is_little_endian)
6909 std::reverse(vec.begin(), vec.end());
6912 oa->write_characters(vec.data(),
sizeof(NumberType));
6916 template<
typename NumberType,
typename std::enable_if<
6917 std::is_floating_point<NumberType>::value,
int>::type = 0>
6918 void write_number_with_ubjson_prefix(
const NumberType n,
6919 const bool add_prefix)
6923 oa->write_character(static_cast<CharType>(
'D'));
6929 template<
typename NumberType,
typename std::enable_if<
6930 std::is_unsigned<NumberType>::value,
int>::type = 0>
6931 void write_number_with_ubjson_prefix(
const NumberType n,
6932 const bool add_prefix)
6934 if (n <= static_cast<uint64_t>((std::numeric_limits<int8_t>::max)()))
6938 oa->write_character(static_cast<CharType>(
'i'));
6940 write_number(static_cast<uint8_t>(n));
6942 else if (n <= (std::numeric_limits<uint8_t>::max)())
6946 oa->write_character(static_cast<CharType>(
'U'));
6948 write_number(static_cast<uint8_t>(n));
6950 else if (n <= static_cast<uint64_t>((std::numeric_limits<int16_t>::max)()))
6954 oa->write_character(static_cast<CharType>(
'I'));
6956 write_number(static_cast<int16_t>(n));
6958 else if (n <= static_cast<uint64_t>((std::numeric_limits<int32_t>::max)()))
6962 oa->write_character(static_cast<CharType>(
'l'));
6964 write_number(static_cast<int32_t>(n));
6966 else if (n <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)()))
6970 oa->write_character(static_cast<CharType>(
'L'));
6972 write_number(static_cast<int64_t>(n));
6976 JSON_THROW(out_of_range::create(407,
"number overflow serializing " + std::to_string(n)));
6981 template<
typename NumberType,
typename std::enable_if<
6982 std::is_signed<NumberType>::value and
6983 not std::is_floating_point<NumberType>::value,
int>::type = 0>
6984 void write_number_with_ubjson_prefix(
const NumberType n,
6985 const bool add_prefix)
6987 if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)())
6991 oa->write_character(static_cast<CharType>(
'i'));
6993 write_number(static_cast<int8_t>(n));
6995 else if (static_cast<int64_t>((std::numeric_limits<uint8_t>::min)()) <= n and n <= static_cast<int64_t>((std::numeric_limits<uint8_t>::max)()))
6999 oa->write_character(static_cast<CharType>(
'U'));
7001 write_number(static_cast<uint8_t>(n));
7003 else if ((std::numeric_limits<int16_t>::min)() <= n and n <= (std::numeric_limits<int16_t>::max)())
7007 oa->write_character(static_cast<CharType>(
'I'));
7009 write_number(static_cast<int16_t>(n));
7011 else if ((std::numeric_limits<int32_t>::min)() <= n and n <= (std::numeric_limits<int32_t>::max)())
7015 oa->write_character(static_cast<CharType>(
'l'));
7017 write_number(static_cast<int32_t>(n));
7019 else if ((std::numeric_limits<int64_t>::min)() <= n and n <= (std::numeric_limits<int64_t>::max)())
7023 oa->write_character(static_cast<CharType>(
'L'));
7025 write_number(static_cast<int64_t>(n));
7030 JSON_THROW(out_of_range::create(407,
"number overflow serializing " + std::to_string(n)));
7044 char ubjson_prefix(
const BasicJsonType& j)
const noexcept
7052 return j.m_value.boolean ?
'T' :
'F';
7056 if ((std::numeric_limits<int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
7060 else if ((std::numeric_limits<uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
7064 else if ((std::numeric_limits<int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
7068 else if ((std::numeric_limits<int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
7080 if (j.m_value.number_unsigned <= (std::numeric_limits<int8_t>::max)())
7084 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
7088 else if (j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max)())
7092 else if (j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max)())
7132 #include <algorithm> 7146 #include <type_traits> 7186 template <
typename Target,
typename Source>
7187 Target reinterpret_bits(
const Source source)
7189 static_assert(
sizeof(Target) ==
sizeof(Source),
"size mismatch");
7192 std::memcpy(&target, &source,
sizeof(Source));
7198 static constexpr
int kPrecision = 64;
7203 constexpr
diyfp() noexcept : f(0), e(0) {}
7204 constexpr
diyfp(uint64_t f_,
int e_) noexcept : f(f_), e(e_) {}
7215 return diyfp(x.f - y.f, x.e);
7224 static_assert(kPrecision == 64,
"internal error");
7249 const uint64_t u_lo = x.f & 0xFFFFFFFF;
7250 const uint64_t u_hi = x.f >> 32;
7251 const uint64_t v_lo = y.f & 0xFFFFFFFF;
7252 const uint64_t v_hi = y.f >> 32;
7254 const uint64_t p0 = u_lo * v_lo;
7255 const uint64_t p1 = u_lo * v_hi;
7256 const uint64_t p2 = u_hi * v_lo;
7257 const uint64_t p3 = u_hi * v_hi;
7259 const uint64_t p0_hi = p0 >> 32;
7260 const uint64_t p1_lo = p1 & 0xFFFFFFFF;
7261 const uint64_t p1_hi = p1 >> 32;
7262 const uint64_t p2_lo = p2 & 0xFFFFFFFF;
7263 const uint64_t p2_hi = p2 >> 32;
7265 uint64_t Q = p0_hi + p1_lo + p2_lo;
7276 Q += uint64_t{1} << (64 - 32 - 1);
7278 const uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32);
7280 return diyfp(h, x.e + y.e + 64);
7291 while ((x.f >> 63) == 0)
7306 const int delta = x.e - target_exponent;
7309 assert(((x.f << delta) >> delta) == x.f);
7311 return diyfp(x.f << delta, target_exponent);
7328 template <
typename FloatType>
7331 assert(std::isfinite(value));
7341 static_assert(std::numeric_limits<FloatType>::is_iec559,
7342 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
7344 constexpr
int kPrecision = std::numeric_limits<FloatType>::digits;
7345 constexpr
int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
7346 constexpr
int kMinExp = 1 - kBias;
7347 constexpr uint64_t kHiddenBit = uint64_t{1} << (kPrecision - 1);
7349 using bits_type =
typename std::conditional< kPrecision == 24, uint32_t, uint64_t >::type;
7351 const uint64_t bits = reinterpret_bits<bits_type>(value);
7352 const uint64_t E = bits >> (kPrecision - 1);
7353 const uint64_t F = bits & (kHiddenBit - 1);
7355 const bool is_denormal = (E == 0);
7356 const diyfp v = is_denormal
7358 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
7381 const bool lower_boundary_is_closer = (F == 0 and E > 1);
7382 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
7383 const diyfp m_minus = lower_boundary_is_closer
7384 ? diyfp(4 * v.f - 1, v.e - 2)
7385 : diyfp(2 * v.f - 1, v.e - 1);
7388 const diyfp w_plus = diyfp::normalize(m_plus);
7391 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
7393 return {diyfp::normalize(v), w_minus, w_plus};
7451 constexpr
int kAlpha = -60;
7452 constexpr
int kGamma = -32;
7520 constexpr
int kCachedPowersSize = 79;
7521 constexpr
int kCachedPowersMinDecExp = -300;
7522 constexpr
int kCachedPowersDecStep = 8;
7526 { 0xAB70FE17C79AC6CA, -1060, -300 },
7527 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
7528 { 0xBE5691EF416BD60C, -1007, -284 },
7529 { 0x8DD01FAD907FFC3C, -980, -276 },
7530 { 0xD3515C2831559A83, -954, -268 },
7531 { 0x9D71AC8FADA6C9B5, -927, -260 },
7532 { 0xEA9C227723EE8BCB, -901, -252 },
7533 { 0xAECC49914078536D, -874, -244 },
7534 { 0x823C12795DB6CE57, -847, -236 },
7535 { 0xC21094364DFB5637, -821, -228 },
7536 { 0x9096EA6F3848984F, -794, -220 },
7537 { 0xD77485CB25823AC7, -768, -212 },
7538 { 0xA086CFCD97BF97F4, -741, -204 },
7539 { 0xEF340A98172AACE5, -715, -196 },
7540 { 0xB23867FB2A35B28E, -688, -188 },
7541 { 0x84C8D4DFD2C63F3B, -661, -180 },
7542 { 0xC5DD44271AD3CDBA, -635, -172 },
7543 { 0x936B9FCEBB25C996, -608, -164 },
7544 { 0xDBAC6C247D62A584, -582, -156 },
7545 { 0xA3AB66580D5FDAF6, -555, -148 },
7546 { 0xF3E2F893DEC3F126, -529, -140 },
7547 { 0xB5B5ADA8AAFF80B8, -502, -132 },
7548 { 0x87625F056C7C4A8B, -475, -124 },
7549 { 0xC9BCFF6034C13053, -449, -116 },
7550 { 0x964E858C91BA2655, -422, -108 },
7551 { 0xDFF9772470297EBD, -396, -100 },
7552 { 0xA6DFBD9FB8E5B88F, -369, -92 },
7553 { 0xF8A95FCF88747D94, -343, -84 },
7554 { 0xB94470938FA89BCF, -316, -76 },
7555 { 0x8A08F0F8BF0F156B, -289, -68 },
7556 { 0xCDB02555653131B6, -263, -60 },
7557 { 0x993FE2C6D07B7FAC, -236, -52 },
7558 { 0xE45C10C42A2B3B06, -210, -44 },
7559 { 0xAA242499697392D3, -183, -36 },
7560 { 0xFD87B5F28300CA0E, -157, -28 },
7561 { 0xBCE5086492111AEB, -130, -20 },
7562 { 0x8CBCCC096F5088CC, -103, -12 },
7563 { 0xD1B71758E219652C, -77, -4 },
7564 { 0x9C40000000000000, -50, 4 },
7565 { 0xE8D4A51000000000, -24, 12 },
7566 { 0xAD78EBC5AC620000, 3, 20 },
7567 { 0x813F3978F8940984, 30, 28 },
7568 { 0xC097CE7BC90715B3, 56, 36 },
7569 { 0x8F7E32CE7BEA5C70, 83, 44 },
7570 { 0xD5D238A4ABE98068, 109, 52 },
7571 { 0x9F4F2726179A2245, 136, 60 },
7572 { 0xED63A231D4C4FB27, 162, 68 },
7573 { 0xB0DE65388CC8ADA8, 189, 76 },
7574 { 0x83C7088E1AAB65DB, 216, 84 },
7575 { 0xC45D1DF942711D9A, 242, 92 },
7576 { 0x924D692CA61BE758, 269, 100 },
7577 { 0xDA01EE641A708DEA, 295, 108 },
7578 { 0xA26DA3999AEF774A, 322, 116 },
7579 { 0xF209787BB47D6B85, 348, 124 },
7580 { 0xB454E4A179DD1877, 375, 132 },
7581 { 0x865B86925B9BC5C2, 402, 140 },
7582 { 0xC83553C5C8965D3D, 428, 148 },
7583 { 0x952AB45CFA97A0B3, 455, 156 },
7584 { 0xDE469FBD99A05FE3, 481, 164 },
7585 { 0xA59BC234DB398C25, 508, 172 },
7586 { 0xF6C69A72A3989F5C, 534, 180 },
7587 { 0xB7DCBF5354E9BECE, 561, 188 },
7588 { 0x88FCF317F22241E2, 588, 196 },
7589 { 0xCC20CE9BD35C78A5, 614, 204 },
7590 { 0x98165AF37B2153DF, 641, 212 },
7591 { 0xE2A0B5DC971F303A, 667, 220 },
7592 { 0xA8D9D1535CE3B396, 694, 228 },
7593 { 0xFB9B7CD9A4A7443C, 720, 236 },
7594 { 0xBB764C4CA7A44410, 747, 244 },
7595 { 0x8BAB8EEFB6409C1A, 774, 252 },
7596 { 0xD01FEF10A657842C, 800, 260 },
7597 { 0x9B10A4E5E9913129, 827, 268 },
7598 { 0xE7109BFBA19C0C9D, 853, 276 },
7599 { 0xAC2820D9623BF429, 880, 284 },
7600 { 0x80444B5E7AA7CF85, 907, 292 },
7601 { 0xBF21E44003ACDD2D, 933, 300 },
7602 { 0x8E679C2F5E44FF8F, 960, 308 },
7603 { 0xD433179D9C8CB841, 986, 316 },
7604 { 0x9E19DB92B4E31BA9, 1013, 324 },
7613 const int f = kAlpha - e - 1;
7614 const int k = (f * 78913) / (1 << 18) + (f > 0);
7616 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
7618 assert(index < kCachedPowersSize);
7619 static_cast<void>(kCachedPowersSize);
7622 assert(kAlpha <= cached.e + e + 64);
7623 assert(kGamma >= cached.e + e + 64);
7635 if (n >= 1000000000)
7641 else if (n >= 100000000)
7646 else if (n >= 10000000)
7651 else if (n >= 1000000)
7656 else if (n >= 100000)
7661 else if (n >= 10000)
7688 inline void grisu2_round(
char* buf,
int len, uint64_t dist, uint64_t delta,
7689 uint64_t rest, uint64_t ten_k)
7692 assert(dist <= delta);
7693 assert(rest <= delta);
7716 and delta - rest >= ten_k
7717 and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
7719 assert(buf[len - 1] !=
'0');
7732 static_assert(kAlpha >= -60,
"internal error");
7733 static_assert(kGamma <= -32,
"internal error");
7747 assert(M_plus.e >= kAlpha);
7748 assert(M_plus.e <= kGamma);
7750 uint64_t delta = diyfp::sub(M_plus, M_minus).f;
7751 uint64_t dist = diyfp::sub(M_plus, w ).f;
7760 const diyfp one(uint64_t{1} << -M_plus.e, M_plus.e);
7762 uint32_t p1 =
static_cast<uint32_t
>(M_plus.f >> -one.e);
7763 uint64_t p2 = M_plus.f & (one.f - 1);
7799 const uint32_t d = p1 / pow10;
7800 const uint32_t r = p1 % pow10;
7806 buffer[length++] =
static_cast<char>(
'0' + d);
7825 const uint64_t rest = (uint64_t{p1} << -one.e) + p2;
7830 decimal_exponent += n;
7841 const uint64_t ten_n = uint64_t{pow10} << -one.e;
7842 grisu2_round(buffer, length, dist, delta, rest, ten_n);
7903 assert(p2 <= UINT64_MAX / 10);
7905 const uint64_t d = p2 >> -one.e;
7906 const uint64_t r = p2 & (one.f - 1);
7913 buffer[length++] =
static_cast<char>(
'0' + d);
7938 decimal_exponent -= m;
7946 const uint64_t ten_m = one.f;
7947 grisu2_round(buffer, length, dist, delta, p2, ten_m);
7969 inline void grisu2(
char* buf,
int& len,
int& decimal_exponent,
7972 assert(m_plus.e == m_minus.e);
7973 assert(m_plus.e == v.e);