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)
4275 return not operator==(other);
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};