30 #ifndef NLOHMANN_JSON_HPP 31 #define NLOHMANN_JSON_HPP 33 #define NLOHMANN_JSON_VERSION_MAJOR 3 34 #define NLOHMANN_JSON_VERSION_MINOR 4 35 #define NLOHMANN_JSON_VERSION_PATCH 0 42 #include <initializer_list> 50 #ifndef NLOHMANN_JSON_FWD_HPP 51 #define NLOHMANN_JSON_FWD_HPP 73 template<
typename T =
void,
typename SFINAE =
void>
76 template<
template<
typename U,
typename V,
typename... Args>
class ObjectType =
78 template<
typename U,
typename... Args>
class ArrayType = std::vector,
79 class StringType = std::string,
class BooleanType = bool,
80 class NumberIntegerType = std::int64_t,
81 class NumberUnsignedType = std::uint64_t,
82 class NumberFloatType =
double,
83 template<
typename U>
class AllocatorType = std::allocator,
84 template<
typename T,
typename SFINAE =
void>
class JSONSerializer =
99 template<
typename BasicJsonType>
122 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) 123 #if defined(__clang__) 124 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 125 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" 127 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) 128 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 129 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" 135 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 136 #pragma GCC diagnostic push 137 #pragma GCC diagnostic ignored "-Wfloat-equal" 141 #if defined(__clang__) 142 #pragma GCC diagnostic push 143 #pragma GCC diagnostic ignored "-Wdocumentation" 147 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 148 #define JSON_DEPRECATED __attribute__((deprecated)) 149 #elif defined(_MSC_VER) 150 #define JSON_DEPRECATED __declspec(deprecated) 152 #define JSON_DEPRECATED 156 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) 157 #define JSON_THROW(exception) throw exception 159 #define JSON_CATCH(exception) catch(exception) 160 #define JSON_INTERNAL_CATCH(exception) catch(exception) 162 #define JSON_THROW(exception) std::abort() 163 #define JSON_TRY if(true) 164 #define JSON_CATCH(exception) if(false) 165 #define JSON_INTERNAL_CATCH(exception) if(false) 169 #if defined(JSON_THROW_USER) 171 #define JSON_THROW JSON_THROW_USER 173 #if defined(JSON_TRY_USER) 175 #define JSON_TRY JSON_TRY_USER 177 #if defined(JSON_CATCH_USER) 179 #define JSON_CATCH JSON_CATCH_USER 180 #undef JSON_INTERNAL_CATCH 181 #define JSON_INTERNAL_CATCH JSON_CATCH_USER 183 #if defined(JSON_INTERNAL_CATCH_USER) 184 #undef JSON_INTERNAL_CATCH 185 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER 189 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 190 #define JSON_LIKELY(x) __builtin_expect(!!(x), 1) 191 #define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0) 193 #define JSON_LIKELY(x) x 194 #define JSON_UNLIKELY(x) x 198 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 199 #define JSON_HAS_CPP_17 200 #define JSON_HAS_CPP_14 201 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) 202 #define JSON_HAS_CPP_14 210 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ 211 template<typename BasicJsonType> \ 212 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ 214 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \ 215 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \ 216 auto it = std::find_if(std::begin(m), std::end(m), \ 217 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \ 219 return ej_pair.first == e; \ 221 j = ((it != std::end(m)) ? it : std::begin(m))->second; \ 223 template<typename BasicJsonType> \ 224 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ 226 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \ 227 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \ 228 auto it = std::find_if(std::begin(m), std::end(m), \ 229 [j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \ 231 return ej_pair.second == j; \ 233 e = ((it != std::end(m)) ? it : std::begin(m))->first; \ 239 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ 240 template<template<typename, typename, typename...> class ObjectType, \ 241 template<typename, typename...> class ArrayType, \ 242 class StringType, class BooleanType, class NumberIntegerType, \ 243 class NumberUnsignedType, class NumberFloatType, \ 244 template<typename> class AllocatorType, \ 245 template<typename, typename = void> class JSONSerializer> 247 #define NLOHMANN_BASIC_JSON_TPL \ 248 basic_json<ObjectType, ArrayType, StringType, BooleanType, \ 249 NumberIntegerType, NumberUnsignedType, NumberFloatType, \ 250 AllocatorType, JSONSerializer> 257 #include <type_traits> 264 template<
bool B,
typename T =
void>
268 using uncvref_t =
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
272 template<std::size_t... Ints>
277 static constexpr std::size_t
size() noexcept
279 return sizeof...(Ints);
283 template<
class Sequence1,
class Sequence2>
286 template<std::size_t... I1, std::size_t... I2>
290 template<std::
size_t N>
293 typename make_index_sequence < N - N / 2 >::type > {};
298 template<
typename... Ts>
322 #include <type_traits> 332 #include <type_traits> 360 void operator=(
nonesuch const&) =
delete;
363 template <
class Default,
365 template <
class...>
class Op,
373 template <
class Default,
template <
class...>
class Op,
class... Args>
380 template <
template <
class...>
class Op,
class... Args>
383 template <
template <
class...>
class Op,
class... Args>
386 template <
class Default,
template <
class...>
class Op,
class... Args>
389 template <
class Default,
template <
class...>
class Op,
class... Args>
392 template <
class Expected,
template <
class...>
class Op,
class... Args>
395 template <
class To,
template <
class...>
class Op,
class... Args>
438 template <
typename T>
441 template <
typename T>
444 template <
typename T>
447 template <
typename T>
450 template <
typename T>
453 template <
typename T>
456 template <
typename T>
459 template <
typename T>
462 template <
typename T,
typename... Args>
465 template <
typename T,
typename... Args>
468 template <
typename T,
typename U>
472 template <
typename BasicJsonType,
typename T,
typename =
void>
475 template <
typename BasicJsonType,
typename T>
479 using serializer =
typename BasicJsonType::template json_serializer<T, void>;
488 template <
typename BasicJsonType,
typename T,
typename =
void>
491 template<
typename BasicJsonType,
typename T>
494 using serializer =
typename BasicJsonType::template json_serializer<T, void>;
503 template <
typename BasicJsonType,
typename T,
typename =
void>
506 template <
typename BasicJsonType,
typename T>
509 using serializer =
typename BasicJsonType::template json_serializer<T, void>;
521 template <
typename T,
typename =
void>
524 template <
typename T>
541 template <
typename T,
typename =
void>
544 template <
typename T>
547 template <
typename BasicJsonType,
typename CompatibleObjectType,
551 template <
typename BasicJsonType,
typename CompatibleObjectType>
553 BasicJsonType, CompatibleObjectType,
562 std::is_constructible<
typename object_t::key_type,
563 typename CompatibleObjectType::key_type>
::value and
564 std::is_constructible<
typename object_t::mapped_type,
565 typename CompatibleObjectType::mapped_type>
::value;
568 template <
typename BasicJsonType,
typename CompatibleObjectType>
572 template <
typename BasicJsonType,
typename ConstructibleObjectType,
576 template <
typename BasicJsonType,
typename ConstructibleObjectType>
578 BasicJsonType, ConstructibleObjectType,
591 template <
typename BasicJsonType,
typename ConstructibleObjectType>
594 ConstructibleObjectType> {};
596 template <
typename BasicJsonType,
typename CompatibleStringType,
600 template <
typename BasicJsonType,
typename CompatibleStringType>
602 BasicJsonType, CompatibleStringType,
606 static constexpr
auto value =
610 template <
typename BasicJsonType,
typename ConstructibleStringType>
614 template <
typename BasicJsonType,
typename ConstructibleStringType,
618 template <
typename BasicJsonType,
typename ConstructibleStringType>
620 BasicJsonType, ConstructibleStringType,
624 static constexpr
auto value =
625 std::is_constructible<ConstructibleStringType,
626 typename BasicJsonType::string_t>
::value;
629 template <
typename BasicJsonType,
typename ConstructibleStringType>
633 template <
typename BasicJsonType,
typename CompatibleArrayType,
typename =
void>
636 template <
typename BasicJsonType,
typename CompatibleArrayType>
638 BasicJsonType, CompatibleArrayType,
645 std::iterator_traits<CompatibleArrayType>>
::value >>
647 static constexpr
bool value =
648 std::is_constructible<BasicJsonType,
649 typename CompatibleArrayType::value_type>
::value;
652 template <
typename BasicJsonType,
typename CompatibleArrayType>
656 template <
typename BasicJsonType,
typename ConstructibleArrayType,
typename =
void>
659 template <
typename BasicJsonType,
typename ConstructibleArrayType>
661 BasicJsonType, ConstructibleArrayType,
663 typename BasicJsonType::value_type>
::value >>
666 template <
typename BasicJsonType,
typename ConstructibleArrayType>
668 BasicJsonType, ConstructibleArrayType,
669 enable_if_t<not std::is_same<ConstructibleArrayType,
670 typename BasicJsonType::value_type>
::value and
674 detected_t<value_type_t, ConstructibleArrayType>>
::value >>
676 static constexpr
bool value =
682 std::iterator_traits<ConstructibleArrayType >>
::value and
686 typename ConstructibleArrayType::value_type>::value or
688 BasicJsonType,
typename ConstructibleArrayType::value_type >::value);
691 template <
typename BasicJsonType,
typename ConstructibleArrayType>
695 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType,
699 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType>
701 RealIntegerType, CompatibleNumberIntegerType,
703 std::is_integral<CompatibleNumberIntegerType>
::value and
704 not std::is_same<bool, CompatibleNumberIntegerType>
::value >>
710 static constexpr
auto value =
711 std::is_constructible<RealIntegerType,
712 CompatibleNumberIntegerType>
::value and
713 CompatibleLimits::is_integer and
714 RealLimits::is_signed == CompatibleLimits::is_signed;
717 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType>
720 CompatibleNumberIntegerType> {};
722 template <
typename BasicJsonType,
typename CompatibleType,
typename =
void>
725 template <
typename BasicJsonType,
typename CompatibleType>
727 BasicJsonType, CompatibleType,
730 static constexpr
bool value =
734 template <
typename BasicJsonType,
typename CompatibleType>
760 std::size_t chars_read_total = 0;
762 std::size_t chars_read_current_line = 0;
764 std::size_t lines_read = 0;
767 constexpr
operator size_t()
const 769 return chars_read_total;
817 const char*
what() const noexcept
override 826 exception(
int id_,
const char* what_arg) : id(id_),
m(what_arg) {}
830 return "[json.exception." + ename +
"." + std::to_string(id_) +
"] ";
835 std::runtime_error
m;
897 position_string(pos) +
": " + what_arg;
904 (byte_ != 0 ? (
" at byte " + std::to_string(byte_)) :
"") +
922 :
exception(id_, what_arg), byte(byte_) {}
926 return " at line " + std::to_string(pos.
lines_read + 1) +
1184 static constexpr std::array<std::uint8_t, 8> order = {{
1190 const auto l_index =
static_cast<std::size_t
>(lhs);
1191 const auto r_index =
static_cast<std::size_t
>(rhs);
1192 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
1200 #include <algorithm> 1203 #include <forward_list> 1208 #include <type_traits> 1209 #include <unordered_map> 1228 template<
typename BasicJsonType>
1229 void from_json(
const BasicJsonType& j,
typename std::nullptr_t& n)
1239 template<
typename BasicJsonType,
typename ArithmeticType,
1245 switch (static_cast<value_t>(j))
1249 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1254 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1259 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1268 template<
typename BasicJsonType>
1269 void from_json(
const BasicJsonType& j,
typename BasicJsonType::boolean_t& b)
1275 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
1278 template<
typename BasicJsonType>
1279 void from_json(
const BasicJsonType& j,
typename BasicJsonType::string_t& s)
1285 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1289 typename BasicJsonType,
typename ConstructibleStringType,
1292 not std::is_same<
typename BasicJsonType::string_t,
1293 ConstructibleStringType>
::value,
1295 void from_json(
const BasicJsonType& j, ConstructibleStringType& s)
1302 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1305 template<
typename BasicJsonType>
1306 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_float_t& val)
1311 template<
typename BasicJsonType>
1312 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_unsigned_t& val)
1317 template<
typename BasicJsonType>
1318 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_integer_t& val)
1323 template<
typename BasicJsonType,
typename EnumType,
1327 typename std::underlying_type<EnumType>::type val;
1329 e =
static_cast<EnumType
>(val);
1333 template<
typename BasicJsonType,
typename T,
typename Allocator,
1335 void from_json(
const BasicJsonType& j, std::forward_list<T, Allocator>&
l)
1341 std::transform(j.rbegin(), j.rend(),
1342 std::front_inserter(l), [](
const BasicJsonType & i)
1344 return i.template get<T>();
1349 template<
typename BasicJsonType,
typename T,
1350 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1358 std::copy(j.m_value.array->begin(), j.m_value.array->end(),
std::begin(l));
1361 template<
typename BasicJsonType>
1364 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
1367 template <
typename BasicJsonType,
typename T, std::
size_t N>
1370 -> decltype(j.template get<T>(),
void())
1372 for (std::size_t i = 0; i < N; ++i)
1374 arr[i] = j.at(i).template get<T>();
1378 template<
typename BasicJsonType,
typename ConstructibleArrayType>
1381 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
1382 j.template get<typename ConstructibleArrayType::value_type>(),
1387 arr.reserve(j.size());
1388 std::transform(j.begin(), j.end(),
1389 std::inserter(arr,
end(arr)), [](
const BasicJsonType & i)
1393 return i.template get<typename ConstructibleArrayType::value_type>();
1397 template <
typename BasicJsonType,
typename ConstructibleArrayType>
1404 j.begin(), j.end(), std::inserter(arr,
end(arr)),
1405 [](
const BasicJsonType & i)
1409 return i.template get<typename ConstructibleArrayType::value_type>();
1413 template <
typename BasicJsonType,
typename ConstructibleArrayType,
1421 auto from_json(
const BasicJsonType& j, ConstructibleArrayType& arr)
1423 j.template get<typename ConstructibleArrayType::value_type>(),
1435 template<
typename BasicJsonType,
typename ConstructibleObjectType,
1437 void from_json(
const BasicJsonType& j, ConstructibleObjectType& obj)
1444 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1445 using value_type =
typename ConstructibleObjectType::value_type;
1447 inner_object->begin(), inner_object->end(),
1448 std::inserter(obj, obj.begin()),
1449 [](
typename BasicJsonType::object_t::value_type
const &
p)
1451 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
1459 template<
typename BasicJsonType,
typename ArithmeticType,
1465 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1469 switch (static_cast<value_t>(j))
1473 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1478 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1483 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1488 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1497 template<
typename BasicJsonType,
typename A1,
typename A2>
1500 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
1503 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1506 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
1509 template<
typename BasicJsonType,
typename... Args>
1510 void from_json(
const BasicJsonType& j, std::tuple<Args...>& t)
1515 template <
typename BasicJsonType,
typename Key,
typename Value,
typename Compare,
typename Allocator,
1517 typename BasicJsonType::string_t, Key>::value>>
1518 void from_json(
const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>&
m)
1524 for (
const auto&
p : j)
1530 m.emplace(
p.at(0).template get<Key>(),
p.at(1).template get<Value>());
1534 template <
typename BasicJsonType,
typename Key,
typename Value,
typename Hash,
typename KeyEqual,
typename Allocator,
1536 typename BasicJsonType::string_t, Key>::value>>
1537 void from_json(
const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>&
m)
1543 for (
const auto&
p : j)
1549 m.emplace(
p.at(0).template get<Key>(),
p.at(1).template get<Value>());
1555 template<
typename BasicJsonType,
typename T>
1580 #include <type_traits> 1623 std::size_t array_index = 0;
1625 mutable std::size_t array_index_last = 0;
1652 return anchor == o.anchor;
1658 return anchor != o.anchor;
1664 assert(anchor.m_object !=
nullptr);
1666 switch (anchor.m_object->type())
1671 if (array_index != array_index_last)
1673 array_index_str = std::to_string(array_index);
1674 array_index_last = array_index;
1676 return array_index_str;
1681 return anchor.key();
1690 typename IteratorType::reference
value()
const 1692 return anchor.value();
1702 : container(cont) {}
1733 template<
typename BasicJsonType>
1734 static void construct(BasicJsonType& j,
typename BasicJsonType::boolean_t b) noexcept
1738 j.assert_invariant();
1745 template<
typename BasicJsonType>
1746 static void construct(BasicJsonType& j,
const typename BasicJsonType::string_t& s)
1750 j.assert_invariant();
1753 template<
typename BasicJsonType>
1754 static void construct(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
1757 j.m_value = std::move(s);
1758 j.assert_invariant();
1761 template<
typename BasicJsonType,
typename CompatibleStringType,
1764 static void construct(BasicJsonType& j,
const CompatibleStringType& str)
1767 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
1768 j.assert_invariant();
1775 template<
typename BasicJsonType>
1776 static void construct(BasicJsonType& j,
typename BasicJsonType::number_float_t val) noexcept
1780 j.assert_invariant();
1787 template<
typename BasicJsonType>
1788 static void construct(BasicJsonType& j,
typename BasicJsonType::number_unsigned_t val) noexcept
1792 j.assert_invariant();
1799 template<
typename BasicJsonType>
1800 static void construct(BasicJsonType& j,
typename BasicJsonType::number_integer_t val) noexcept
1804 j.assert_invariant();
1811 template<
typename BasicJsonType>
1812 static void construct(BasicJsonType& j,
const typename BasicJsonType::array_t& arr)
1816 j.assert_invariant();
1819 template<
typename BasicJsonType>
1820 static void construct(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
1823 j.m_value = std::move(arr);
1824 j.assert_invariant();
1827 template<
typename BasicJsonType,
typename CompatibleArrayType,
1830 static void construct(BasicJsonType& j,
const CompatibleArrayType& arr)
1835 j.m_value.array = j.template create<typename BasicJsonType::array_t>(
begin(arr),
end(arr));
1836 j.assert_invariant();
1839 template<
typename BasicJsonType>
1840 static void construct(BasicJsonType& j,
const std::vector<bool>& arr)
1844 j.m_value.array->reserve(arr.size());
1845 for (
const bool x : arr)
1847 j.m_value.array->push_back(
x);
1849 j.assert_invariant();
1852 template<
typename BasicJsonType,
typename T,
1854 static void construct(BasicJsonType& j,
const std::valarray<T>& arr)
1858 j.m_value.array->resize(arr.size());
1860 j.assert_invariant();
1867 template<
typename BasicJsonType>
1868 static void construct(BasicJsonType& j,
const typename BasicJsonType::object_t& obj)
1872 j.assert_invariant();
1875 template<
typename BasicJsonType>
1876 static void construct(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
1879 j.m_value = std::move(obj);
1880 j.assert_invariant();
1883 template<
typename BasicJsonType,
typename CompatibleObjectType,
1885 static void construct(BasicJsonType& j,
const CompatibleObjectType& obj)
1891 j.m_value.object = j.template create<typename BasicJsonType::object_t>(
begin(obj),
end(obj));
1892 j.assert_invariant();
1900 template<
typename BasicJsonType,
typename T,
1907 template<
typename BasicJsonType,
typename CompatibleString,
1909 void to_json(BasicJsonType& j,
const CompatibleString& s)
1914 template<
typename BasicJsonType>
1915 void to_json(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
1920 template<
typename BasicJsonType,
typename FloatType,
1922 void to_json(BasicJsonType& j, FloatType val) noexcept
1927 template<
typename BasicJsonType,
typename CompatibleNumberUnsignedType,
1929 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
1934 template<
typename BasicJsonType,
typename CompatibleNumberIntegerType,
1936 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
1941 template<
typename BasicJsonType,
typename EnumType,
1942 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
1943 void to_json(BasicJsonType& j, EnumType e) noexcept
1945 using underlying_type =
typename std::underlying_type<EnumType>::type;
1949 template<
typename BasicJsonType>
1950 void to_json(BasicJsonType& j,
const std::vector<bool>& e)
1955 template <
typename BasicJsonType,
typename CompatibleArrayType,
1957 CompatibleArrayType>::value and
1959 BasicJsonType, CompatibleArrayType>::value and
1963 void to_json(BasicJsonType& j,
const CompatibleArrayType& arr)
1968 template<
typename BasicJsonType,
typename T,
1970 void to_json(BasicJsonType& j,
const std::valarray<T>& arr)
1975 template<
typename BasicJsonType>
1976 void to_json(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
1981 template<
typename BasicJsonType,
typename CompatibleObjectType,
1983 void to_json(BasicJsonType& j,
const CompatibleObjectType& obj)
1988 template<
typename BasicJsonType>
1989 void to_json(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
1995 typename BasicJsonType,
typename T, std::size_t N,
1996 enable_if_t<not std::is_constructible<
typename BasicJsonType::string_t,
2004 template<
typename BasicJsonType,
typename... Args>
2005 void to_json(BasicJsonType& j,
const std::pair<Args...>&
p)
2007 j = {p.first, p.second};
2011 template<
typename BasicJsonType,
typename T,
2015 j = {{b.key(), b.value()}};
2018 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
2021 j = {std::get<Idx>(t)...};
2024 template<
typename BasicJsonType,
typename... Args>
2025 void to_json(BasicJsonType& j,
const std::tuple<Args...>& t)
2032 template<
typename BasicJsonType,
typename T>
2034 -> decltype(
to_json(j,
std::forward<T>(val)),
void())
2036 return to_json(j, std::forward<T>(val));
2059 #include <type_traits> 2090 virtual std::char_traits<char>::int_type get_character() = 0;
2117 : is(i), sb(*i.rdbuf())
2145 : cursor(b), limit(b +
l)
2159 return std::char_traits<char>::to_int_type(*(cursor++));
2162 return std::char_traits<char>::eof();
2172 template<
typename W
ideStringType,
size_t T>
2176 static void fill_buffer(
const WideStringType& str,
size_t& current_wchar,
std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
size_t& utf8_bytes_index,
size_t& utf8_bytes_filled)
2178 utf8_bytes_index = 0;
2180 if (current_wchar == str.size())
2182 utf8_bytes[0] = std::char_traits<char>::eof();
2183 utf8_bytes_filled = 1;
2188 const auto wc =
static_cast<int>(str[current_wchar++]);
2194 utf8_bytes_filled = 1;
2196 else if (wc <= 0x7FF)
2198 utf8_bytes[0] = 0xC0 | ((wc >> 6) & 0x1F);
2199 utf8_bytes[1] = 0x80 | (wc & 0x3F);
2200 utf8_bytes_filled = 2;
2202 else if (wc <= 0xFFFF)
2204 utf8_bytes[0] = 0xE0 | ((wc >> 12) & 0x0F);
2205 utf8_bytes[1] = 0x80 | ((wc >> 6) & 0x3F);
2206 utf8_bytes[2] = 0x80 | (wc & 0x3F);
2207 utf8_bytes_filled = 3;
2209 else if (wc <= 0x10FFFF)
2211 utf8_bytes[0] = 0xF0 | ((wc >> 18) & 0x07);
2212 utf8_bytes[1] = 0x80 | ((wc >> 12) & 0x3F);
2213 utf8_bytes[2] = 0x80 | ((wc >> 6) & 0x3F);
2214 utf8_bytes[3] = 0x80 | (wc & 0x3F);
2215 utf8_bytes_filled = 4;
2221 utf8_bytes_filled = 1;
2227 template<
typename W
ideStringType>
2231 static void fill_buffer(
const WideStringType& str,
size_t& current_wchar,
std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
size_t& utf8_bytes_index,
size_t& utf8_bytes_filled)
2233 utf8_bytes_index = 0;
2235 if (current_wchar == str.size())
2237 utf8_bytes[0] = std::char_traits<char>::eof();
2238 utf8_bytes_filled = 1;
2243 const auto wc =
static_cast<int>(str[current_wchar++]);
2249 utf8_bytes_filled = 1;
2251 else if (wc <= 0x7FF)
2253 utf8_bytes[0] = 0xC0 | ((wc >> 6));
2254 utf8_bytes[1] = 0x80 | (wc & 0x3F);
2255 utf8_bytes_filled = 2;
2257 else if (0xD800 > wc or wc >= 0xE000)
2259 utf8_bytes[0] = 0xE0 | ((wc >> 12));
2260 utf8_bytes[1] = 0x80 | ((wc >> 6) & 0x3F);
2261 utf8_bytes[2] = 0x80 | (wc & 0x3F);
2262 utf8_bytes_filled = 3;
2266 if (current_wchar < str.size())
2268 const auto wc2 =
static_cast<int>(str[current_wchar++]);
2269 const int charcode = 0x10000 + (((wc & 0x3FF) << 10) | (wc2 & 0x3FF));
2270 utf8_bytes[0] = 0xf0 | (charcode >> 18);
2271 utf8_bytes[1] = 0x80 | ((charcode >> 12) & 0x3F);
2272 utf8_bytes[2] = 0x80 | ((charcode >> 6) & 0x3F);
2273 utf8_bytes[3] = 0x80 | (charcode & 0x3F);
2274 utf8_bytes_filled = 4;
2281 utf8_bytes_filled = 1;
2288 template<
typename W
ideStringType>
2299 if (utf8_bytes_index == utf8_bytes_filled)
2301 fill_buffer<sizeof(typename WideStringType::value_type)>();
2303 assert(utf8_bytes_filled > 0);
2304 assert(utf8_bytes_index == 0);
2308 assert(utf8_bytes_filled > 0);
2309 assert(utf8_bytes_index < utf8_bytes_filled);
2310 return utf8_bytes[utf8_bytes_index++];
2324 std::size_t current_wchar = 0;
2327 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
2330 std::size_t utf8_bytes_index = 0;
2332 std::size_t utf8_bytes_filled = 0;
2358 template<
typename CharT,
2359 typename std::enable_if<
2361 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2362 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
2365 : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
2370 template<
typename CharT,
2371 typename std::enable_if<
2373 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2374 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
2378 std::strlen(reinterpret_cast<const char*>(b))) {}
2381 template<
class IteratorType,
2382 typename std::enable_if<
2383 std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>
::value,
2390 const auto is_contiguous = std::accumulate(
2391 first, last, std::pair<bool, int>(
true, 0),
2392 [&first](std::pair<bool, int> res, decltype(*first) val)
2394 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
2397 assert(is_contiguous);
2402 sizeof(
typename std::iterator_traits<IteratorType>::value_type) == 1,
2403 "each element in the iterator range must have the size of 1 byte");
2405 const auto len =
static_cast<size_t>(std::distance(first, last));
2409 ia = std::make_shared<input_buffer_adapter>(
reinterpret_cast<const char*
>(&(*first)), len);
2414 ia = std::make_shared<input_buffer_adapter>(
nullptr, len);
2419 template<
class T, std::
size_t N>
2424 template<
class ContiguousContainer,
typename 2426 std::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::
value,
2450 #include <initializer_list> 2474 template<
typename BasicJsonType>
2510 case token_type::uninitialized:
2511 return "<uninitialized>";
2512 case token_type::literal_true:
2513 return "true literal";
2514 case token_type::literal_false:
2515 return "false literal";
2516 case token_type::literal_null:
2517 return "null literal";
2518 case token_type::value_string:
2519 return "string literal";
2523 return "number literal";
2524 case token_type::begin_array:
2526 case token_type::begin_object:
2528 case token_type::end_array:
2530 case token_type::end_object:
2532 case token_type::name_separator:
2534 case token_type::value_separator:
2536 case token_type::parse_error:
2537 return "<parse error>";
2538 case token_type::end_of_input:
2539 return "end of input";
2540 case token_type::literal_or_value:
2541 return "'[', '{', or a literal";
2544 return "unknown token";
2550 : ia(
std::move(adapter)), decimal_point_char(get_decimal_point()) {}
2567 const auto loc = localeconv();
2568 assert(loc !=
nullptr);
2569 return (loc->decimal_point ==
nullptr) ?
'.' : *(loc->decimal_point);
2594 assert(current ==
'u');
2597 const auto factors = { 12, 8, 4, 0 };
2598 for (
const auto factor : factors)
2602 if (current >=
'0' and current <=
'9')
2604 codepoint += ((current - 0x30) << factor);
2606 else if (current >=
'A' and current <=
'F')
2608 codepoint += ((current - 0x37) << factor);
2610 else if (current >=
'a' and current <=
'f')
2612 codepoint += ((current - 0x57) << factor);
2620 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
2641 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
2653 error_message =
"invalid string: ill-formed UTF-8 byte";
2682 assert(current ==
'\"');
2690 case std::char_traits<char>::eof():
2692 error_message =
"invalid string: missing closing quote";
2693 return token_type::parse_error;
2699 return token_type::value_string;
2743 const int codepoint1 = get_codepoint();
2744 int codepoint = codepoint1;
2748 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
2749 return token_type::parse_error;
2753 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
2758 const int codepoint2 = get_codepoint();
2762 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
2763 return token_type::parse_error;
2767 if (
JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
2782 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2783 return token_type::parse_error;
2788 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2789 return token_type::parse_error;
2794 if (
JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
2796 error_message =
"invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
2797 return token_type::parse_error;
2802 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
2805 if (codepoint < 0x80)
2810 else if (codepoint <= 0x7FF)
2813 add(0xC0 | (codepoint >> 6));
2814 add(0x80 | (codepoint & 0x3F));
2816 else if (codepoint <= 0xFFFF)
2819 add(0xE0 | (codepoint >> 12));
2820 add(0x80 | ((codepoint >> 6) & 0x3F));
2821 add(0x80 | (codepoint & 0x3F));
2826 add(0xF0 | (codepoint >> 18));
2827 add(0x80 | ((codepoint >> 12) & 0x3F));
2828 add(0x80 | ((codepoint >> 6) & 0x3F));
2829 add(0x80 | (codepoint & 0x3F));
2837 error_message =
"invalid string: forbidden character after backslash";
2838 return token_type::parse_error;
2847 error_message =
"invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
2848 return token_type::parse_error;
2853 error_message =
"invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
2854 return token_type::parse_error;
2859 error_message =
"invalid string: control character U+0002 (STX) must be escaped to \\u0002";
2860 return token_type::parse_error;
2865 error_message =
"invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
2866 return token_type::parse_error;
2871 error_message =
"invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
2872 return token_type::parse_error;
2877 error_message =
"invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
2878 return token_type::parse_error;
2883 error_message =
"invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
2884 return token_type::parse_error;
2889 error_message =
"invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
2890 return token_type::parse_error;
2895 error_message =
"invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
2896 return token_type::parse_error;
2901 error_message =
"invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
2902 return token_type::parse_error;
2907 error_message =
"invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
2908 return token_type::parse_error;
2913 error_message =
"invalid string: control character U+000B (VT) must be escaped to \\u000B";
2914 return token_type::parse_error;
2919 error_message =
"invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
2920 return token_type::parse_error;
2925 error_message =
"invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
2926 return token_type::parse_error;
2931 error_message =
"invalid string: control character U+000E (SO) must be escaped to \\u000E";
2932 return token_type::parse_error;
2937 error_message =
"invalid string: control character U+000F (SI) must be escaped to \\u000F";
2938 return token_type::parse_error;
2943 error_message =
"invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
2944 return token_type::parse_error;
2949 error_message =
"invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
2950 return token_type::parse_error;
2955 error_message =
"invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
2956 return token_type::parse_error;
2961 error_message =
"invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
2962 return token_type::parse_error;
2967 error_message =
"invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
2968 return token_type::parse_error;
2973 error_message =
"invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
2974 return token_type::parse_error;
2979 error_message =
"invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
2980 return token_type::parse_error;
2985 error_message =
"invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
2986 return token_type::parse_error;
2991 error_message =
"invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
2992 return token_type::parse_error;
2997 error_message =
"invalid string: control character U+0019 (EM) must be escaped to \\u0019";
2998 return token_type::parse_error;
3003 error_message =
"invalid string: control character U+001A (SUB) must be escaped to \\u001A";
3004 return token_type::parse_error;
3009 error_message =
"invalid string: control character U+001B (ESC) must be escaped to \\u001B";
3010 return token_type::parse_error;
3015 error_message =
"invalid string: control character U+001C (FS) must be escaped to \\u001C";
3016 return token_type::parse_error;
3021 error_message =
"invalid string: control character U+001D (GS) must be escaped to \\u001D";
3022 return token_type::parse_error;
3027 error_message =
"invalid string: control character U+001E (RS) must be escaped to \\u001E";
3028 return token_type::parse_error;
3033 error_message =
"invalid string: control character U+001F (US) must be escaped to \\u001F";
3034 return token_type::parse_error;
3171 return token_type::parse_error;
3179 if (
JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
3181 return token_type::parse_error;
3203 if (
JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
3205 return token_type::parse_error;
3213 if (
JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
3215 return token_type::parse_error;
3223 if (
JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
3225 return token_type::parse_error;
3235 if (
JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
3237 return token_type::parse_error;
3245 if (
JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
3247 return token_type::parse_error;
3255 error_message =
"invalid string: ill-formed UTF-8 byte";
3256 return token_type::parse_error;
3262 static void strtof(
float& f,
const char* str,
char** endptr) noexcept
3264 f = std::strtof(str, endptr);
3267 static void strtof(
double& f,
const char* str,
char** endptr) noexcept
3269 f = std::strtod(str, endptr);
3272 static void strtof(
long double& f,
const char* str,
char** endptr) noexcept
3274 f = std::strtold(str, endptr);
3324 token_type number_type = token_type::value_unsigned;
3332 goto scan_number_minus;
3338 goto scan_number_zero;
3352 goto scan_number_any1;
3366 number_type = token_type::value_integer;
3372 goto scan_number_zero;
3386 goto scan_number_any1;
3391 error_message =
"invalid number; expected digit after '-'";
3392 return token_type::parse_error;
3402 add(decimal_point_char);
3403 goto scan_number_decimal1;
3410 goto scan_number_exponent;
3414 goto scan_number_done;
3433 goto scan_number_any1;
3438 add(decimal_point_char);
3439 goto scan_number_decimal1;
3446 goto scan_number_exponent;
3450 goto scan_number_done;
3453 scan_number_decimal1:
3455 number_type = token_type::value_float;
3470 goto scan_number_decimal2;
3475 error_message =
"invalid number; expected digit after '.'";
3476 return token_type::parse_error;
3480 scan_number_decimal2:
3496 goto scan_number_decimal2;
3503 goto scan_number_exponent;
3507 goto scan_number_done;
3510 scan_number_exponent:
3512 number_type = token_type::value_float;
3519 goto scan_number_sign;
3534 goto scan_number_any2;
3540 "invalid number; expected '+', '-', or digit after exponent";
3541 return token_type::parse_error;
3561 goto scan_number_any2;
3566 error_message =
"invalid number; expected digit after exponent sign";
3567 return token_type::parse_error;
3587 goto scan_number_any2;
3591 goto scan_number_done;
3599 char* endptr =
nullptr;
3603 if (number_type == token_type::value_unsigned)
3605 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
3608 assert(endptr == token_buffer.data() + token_buffer.size());
3613 if (value_unsigned ==
x)
3615 return token_type::value_unsigned;
3619 else if (number_type == token_type::value_integer)
3621 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
3624 assert(endptr == token_buffer.data() + token_buffer.size());
3629 if (value_integer ==
x)
3631 return token_type::value_integer;
3638 strtof(value_float, token_buffer.data(), &endptr);
3641 assert(endptr == token_buffer.data() + token_buffer.size());
3643 return token_type::value_float;
3654 assert(current == literal_text[0]);
3655 for (std::size_t i = 1; i < length; ++i)
3659 error_message =
"invalid literal";
3660 return token_type::parse_error;
3673 token_buffer.clear();
3674 token_string.clear();
3675 token_string.push_back(std::char_traits<char>::to_char_type(current));
3688 std::char_traits<char>::int_type
get()
3690 ++position.chars_read_total;
3691 ++position.chars_read_current_line;
3700 current = ia->get_character();
3703 if (
JSON_LIKELY(current != std::char_traits<char>::eof()))
3705 token_string.push_back(std::char_traits<char>::to_char_type(current));
3708 if (current ==
'\n')
3710 ++position.lines_read;
3711 ++position.chars_read_current_line = 0;
3729 --position.chars_read_total;
3732 if (position.chars_read_current_line == 0)
3734 if (position.lines_read > 0)
3736 --position.lines_read;
3741 --position.chars_read_current_line;
3744 if (
JSON_LIKELY(current != std::char_traits<char>::eof()))
3746 assert(token_string.size() != 0);
3747 token_string.pop_back();
3754 token_buffer.push_back(std::char_traits<char>::to_char_type(c));
3765 return value_integer;
3771 return value_unsigned;
3783 return token_buffer;
3803 for (
const auto c : token_string)
3805 if (
'\x00' <=
c and
c <=
'\x1F')
3809 snprintf(cs, 9,
"<U+%.4X>", static_cast<unsigned char>(
c));
3815 result.push_back(
c);
3825 return error_message;
3841 return get() == 0xBB and
get() == 0xBF;
3853 if (position.chars_read_total == 0 and not skip_bom())
3855 error_message =
"invalid BOM; must be 0xEF 0xBB 0xBF if given";
3856 return token_type::parse_error;
3864 while (current ==
' ' or current ==
'\t' or current ==
'\n' or current ==
'\r');
3870 return token_type::begin_array;
3872 return token_type::end_array;
3874 return token_type::begin_object;
3876 return token_type::end_object;
3878 return token_type::name_separator;
3880 return token_type::value_separator;
3884 return scan_literal(
"true", 4, token_type::literal_true);
3886 return scan_literal(
"false", 5, token_type::literal_false);
3888 return scan_literal(
"null", 4, token_type::literal_null);
3892 return scan_string();
3906 return scan_number();
3911 case std::char_traits<char>::eof():
3912 return token_type::end_of_input;
3916 error_message =
"invalid literal";
3917 return token_type::parse_error;
3926 std::char_traits<char>::int_type current = std::char_traits<char>::eof();
3929 bool next_unget =
false;
3935 std::vector<char> token_string {};
3941 const char* error_message =
"";
3949 const char decimal_point_char =
'.';
3960 #include <functional> 3983 template <
typename T>
3986 template <
typename T>
3988 decltype(std::declval<T&>().
boolean(std::declval<bool>()));
3990 template <
typename T,
typename Integer>
3994 template <
typename T,
typename Un
signed>
3998 template <
typename T,
typename Float,
typename String>
4000 std::declval<Float>(), std::declval<const String&>()));
4002 template <
typename T,
typename String>
4004 decltype(std::declval<T&>().
string(std::declval<String&>()));
4006 template <
typename T>
4008 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
4010 template <
typename T,
typename String>
4012 decltype(std::declval<T&>().key(std::declval<String&>()));
4014 template <
typename T>
4017 template <
typename T>
4019 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
4021 template <
typename T>
4024 template <
typename T,
typename Exception>
4026 std::declval<std::size_t>(), std::declval<const std::string&>(),
4027 std::declval<const Exception&>()));
4029 template <
typename SAX,
typename BasicJsonType>
4034 "BasicJsonType must be of type basic_json<...>");
4061 template <
typename SAX,
typename BasicJsonType>
4066 "BasicJsonType must be of type basic_json<...>");
4076 "Missing/invalid function: bool null()");
4078 "Missing/invalid function: bool boolean(bool)");
4080 "Missing/invalid function: bool boolean(bool)");
4084 "Missing/invalid function: bool number_integer(number_integer_t)");
4088 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
4091 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
4094 "Missing/invalid function: bool string(string_t&)");
4096 "Missing/invalid function: bool start_object(std::size_t)");
4098 "Missing/invalid function: bool key(string_t&)");
4100 "Missing/invalid function: bool end_object()");
4102 "Missing/invalid function: bool start_array(std::size_t)");
4104 "Missing/invalid function: bool end_array()");
4107 "Missing/invalid function: bool parse_error(std::size_t, const " 4108 "std::string&, const exception&)");
4138 template<
typename BasicJsonType>
4154 virtual bool null() = 0;
4161 virtual bool boolean(
bool val) = 0;
4199 virtual bool start_object(std::size_t elements) = 0;
4207 virtual bool key(
string_t& val) = 0;
4213 virtual bool end_object() = 0;
4221 virtual bool start_array(std::size_t elements) = 0;
4227 virtual bool end_array() = 0;
4236 virtual bool parse_error(std::size_t position,
4259 template<
typename BasicJsonType>
4274 :
root(r), allow_exceptions(allow_exceptions_)
4279 handle_value(
nullptr);
4315 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
4317 if (
JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4320 "excessive object size: " + std::to_string(len)));
4329 object_element = &(ref_stack.back()->m_value.object->operator[](val));
4335 ref_stack.pop_back();
4341 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
4343 if (
JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4346 "excessive array size: " + std::to_string(len)));
4354 ref_stack.pop_back();
4362 if (allow_exceptions)
4365 switch ((ex.
id / 100) % 100)
4368 JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex));
4370 JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex));
4373 JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex));
4375 JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex));
4377 JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex));
4398 template<
typename Value>
4401 if (ref_stack.empty())
4403 root = BasicJsonType(std::forward<Value>(v));
4407 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
4409 if (ref_stack.back()->is_array())
4411 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
4412 return &(ref_stack.back()->m_value.array->back());
4416 assert(object_element);
4417 *object_element = BasicJsonType(std::forward<Value>(v));
4418 return object_element;
4427 BasicJsonType* object_element =
nullptr;
4429 bool errored =
false;
4431 const bool allow_exceptions =
true;
4434 template<
typename BasicJsonType>
4447 const bool allow_exceptions_ =
true)
4448 :
root(r), callback(cb), allow_exceptions(allow_exceptions_)
4450 keep_stack.push_back(
true);
4455 handle_value(
nullptr);
4492 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start,
discarded);
4493 keep_stack.push_back(keep);
4495 auto val = handle_value(BasicJsonType::value_t::object,
true);
4496 ref_stack.push_back(val.second);
4499 if (ref_stack.back())
4501 if (
JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4504 "excessive object size: " + std::to_string(len)));
4513 BasicJsonType k = BasicJsonType(val);
4516 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
4517 key_keep_stack.push_back(keep);
4520 if (keep and ref_stack.back())
4522 object_element = &(ref_stack.back()->m_value.object->operator[](val) =
discarded);
4530 if (ref_stack.back())
4532 if (not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
4539 assert(not ref_stack.empty());
4540 assert(not keep_stack.empty());
4541 ref_stack.pop_back();
4542 keep_stack.pop_back();
4544 if (not ref_stack.empty() and ref_stack.back())
4547 if (ref_stack.back()->is_object())
4549 for (
auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
4551 if (it->is_discarded())
4553 ref_stack.back()->erase(it);
4565 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start,
discarded);
4566 keep_stack.push_back(keep);
4568 auto val = handle_value(BasicJsonType::value_t::array,
true);
4569 ref_stack.push_back(val.second);
4572 if (ref_stack.back())
4574 if (
JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4577 "excessive array size: " + std::to_string(len)));
4588 if (ref_stack.back())
4590 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
4598 assert(not ref_stack.empty());
4599 assert(not keep_stack.empty());
4600 ref_stack.pop_back();
4601 keep_stack.pop_back();
4604 if (not keep and not ref_stack.empty())
4606 if (ref_stack.back()->is_array())
4608 ref_stack.back()->m_value.array->pop_back();
4619 if (allow_exceptions)
4622 switch ((ex.
id / 100) % 100)
4625 JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex));
4627 JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex));
4630 JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex));
4632 JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex));
4634 JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex));
4664 template<
typename Value>
4665 std::pair<bool, BasicJsonType*>
handle_value(Value&& v,
const bool skip_callback =
false)
4667 assert(not keep_stack.empty());
4671 if (not keep_stack.back())
4673 return {
false,
nullptr};
4677 auto value = BasicJsonType(std::forward<Value>(v));
4685 return {
false,
nullptr};
4688 if (ref_stack.empty())
4691 return {
true, &
root};
4696 if (not ref_stack.back())
4698 return {
false,
nullptr};
4702 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
4704 if (ref_stack.back()->is_array())
4706 ref_stack.back()->m_value.array->push_back(std::move(
value));
4707 return {
true, &(ref_stack.back()->m_value.array->back())};
4712 assert(not key_keep_stack.empty());
4713 const bool store_element = key_keep_stack.back();
4714 key_keep_stack.pop_back();
4716 if (not store_element)
4718 return {
false,
nullptr};
4721 assert(object_element);
4722 *object_element = std::move(
value);
4723 return {
true, object_element};
4736 BasicJsonType* object_element =
nullptr;
4738 bool errored =
false;
4742 const bool allow_exceptions =
true;
4744 BasicJsonType
discarded = BasicJsonType::value_t::discarded;
4747 template<
typename BasicJsonType>
4838 template<
typename BasicJsonType>
4866 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
4871 const bool allow_exceptions_ =
true)
4872 : callback(cb), m_lexer(
std::move(adapter)), allow_exceptions(allow_exceptions_)
4893 sax_parse_internal(&sdp);
4894 result.assert_invariant();
4897 if (strict and (get_token() != token_type::end_of_input))
4900 m_lexer.get_token_string(),
4902 exception_message(token_type::end_of_input,
"value")));
4914 if (result.is_discarded())
4922 sax_parse_internal(&sdp);
4923 result.assert_invariant();
4926 if (strict and (get_token() != token_type::end_of_input))
4929 m_lexer.get_token_string(),
4931 exception_message(token_type::end_of_input,
"value")));
4952 return sax_parse(&sax_acceptor,
strict);
4955 template <
typename SAX>
4959 const bool result = sax_parse_internal(sax);
4962 if (result and
strict and (get_token() != token_type::end_of_input))
4964 return sax->parse_error(m_lexer.get_position(),
4965 m_lexer.get_token_string(),
4967 exception_message(token_type::end_of_input,
"value")));
4974 template <
typename SAX>
4979 std::vector<bool> states;
4981 bool skip_to_state_evaluation =
false;
4985 if (not skip_to_state_evaluation)
4990 case token_type::begin_object:
4998 if (get_token() == token_type::end_object)
5010 return sax->parse_error(m_lexer.get_position(),
5011 m_lexer.get_token_string(),
5013 exception_message(token_type::value_string,
"object key")));
5021 if (
JSON_UNLIKELY(get_token() != token_type::name_separator))
5023 return sax->parse_error(m_lexer.get_position(),
5024 m_lexer.get_token_string(),
5026 exception_message(token_type::name_separator,
"object separator")));
5030 states.push_back(
false);
5037 case token_type::begin_array:
5045 if (get_token() == token_type::end_array)
5055 states.push_back(
true);
5061 case token_type::value_float:
5063 const auto res = m_lexer.get_number_float();
5067 return sax->parse_error(m_lexer.get_position(),
5068 m_lexer.get_token_string(),
5073 if (
JSON_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
5081 case token_type::literal_false:
5090 case token_type::literal_null:
5099 case token_type::literal_true:
5108 case token_type::value_integer:
5110 if (
JSON_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
5117 case token_type::value_string:
5126 case token_type::value_unsigned:
5128 if (
JSON_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
5135 case token_type::parse_error:
5138 return sax->parse_error(m_lexer.get_position(),
5139 m_lexer.get_token_string(),
5141 exception_message(token_type::uninitialized,
"value")));
5146 return sax->parse_error(m_lexer.get_position(),
5147 m_lexer.get_token_string(),
5149 exception_message(token_type::literal_or_value,
"value")));
5155 skip_to_state_evaluation =
false;
5169 if (get_token() == token_type::value_separator)
5177 if (
JSON_LIKELY(last_token == token_type::end_array))
5188 assert(not states.empty());
5190 skip_to_state_evaluation =
true;
5195 return sax->parse_error(m_lexer.get_position(),
5196 m_lexer.get_token_string(),
5198 exception_message(token_type::end_array,
"array")));
5204 if (get_token() == token_type::value_separator)
5209 return sax->parse_error(m_lexer.get_position(),
5210 m_lexer.get_token_string(),
5212 exception_message(token_type::value_string,
"object key")));
5223 if (
JSON_UNLIKELY(get_token() != token_type::name_separator))
5225 return sax->parse_error(m_lexer.get_position(),
5226 m_lexer.get_token_string(),
5228 exception_message(token_type::name_separator,
"object separator")));
5237 if (
JSON_LIKELY(last_token == token_type::end_object))
5248 assert(not states.empty());
5250 skip_to_state_evaluation =
true;
5255 return sax->parse_error(m_lexer.get_position(),
5256 m_lexer.get_token_string(),
5258 exception_message(token_type::end_object,
"object")));
5268 return (last_token = m_lexer.scan());
5275 if (not context.empty())
5277 error_msg +=
"while parsing " + context +
" ";
5282 if (last_token == token_type::parse_error)
5284 error_msg +=
std::string(m_lexer.get_error_message()) +
"; last read: '" +
5285 m_lexer.get_token_string() +
"'";
5289 error_msg +=
"unexpected " +
std::string(lexer_t::token_type_name(last_token));
5292 if (expected != token_type::uninitialized)
5294 error_msg +=
"; expected " +
std::string(lexer_t::token_type_name(expected));
5308 const bool allow_exceptions =
true;
5363 return m_it == begin_value;
5369 return m_it == end_value;
5374 return lhs.m_it == rhs.m_it;
5379 return lhs.m_it < rhs.m_it;
5384 auto result = *
this;
5391 return lhs.m_it - rhs.m_it;
5402 auto result = *
this;
5415 auto result = *
this;
5454 typename BasicJsonType::object_t::iterator object_iterator {};
5456 typename BasicJsonType::array_t::iterator array_iterator {};
5468 #include <type_traits> 5510 template<
typename BasicJsonType>
5522 "iter_impl only accepts (const) basic_json");
5539 typename BasicJsonType::const_pointer,
5544 typename BasicJsonType::const_reference,
5558 assert(m_object !=
nullptr);
5560 switch (m_object->m_type)
5564 m_it.object_iterator =
typename object_t::iterator();
5570 m_it.array_iterator =
typename array_t::iterator();
5597 : m_object(other.m_object), m_it(other.m_it) {}
5619 assert(m_object !=
nullptr);
5621 switch (m_object->m_type)
5625 m_it.object_iterator = m_object->m_value.object->begin();
5631 m_it.array_iterator = m_object->m_value.array->begin();
5638 m_it.primitive_iterator.set_end();
5644 m_it.primitive_iterator.set_begin();
5656 assert(m_object !=
nullptr);
5658 switch (m_object->m_type)
5662 m_it.object_iterator = m_object->m_value.object->end();
5668 m_it.array_iterator = m_object->m_value.array->end();
5674 m_it.primitive_iterator.set_end();
5687 assert(m_object !=
nullptr);
5689 switch (m_object->m_type)
5693 assert(m_it.object_iterator != m_object->m_value.object->end());
5694 return m_it.object_iterator->second;
5699 assert(m_it.array_iterator != m_object->m_value.array->end());
5700 return *m_it.array_iterator;
5708 if (
JSON_LIKELY(m_it.primitive_iterator.is_begin()))
5724 assert(m_object !=
nullptr);
5726 switch (m_object->m_type)
5730 assert(m_it.object_iterator != m_object->m_value.object->end());
5731 return &(m_it.object_iterator->second);
5736 assert(m_it.array_iterator != m_object->m_value.array->end());
5737 return &*m_it.array_iterator;
5742 if (
JSON_LIKELY(m_it.primitive_iterator.is_begin()))
5758 auto result = *
this;
5769 assert(m_object !=
nullptr);
5771 switch (m_object->m_type)
5775 std::advance(m_it.object_iterator, 1);
5781 std::advance(m_it.array_iterator, 1);
5787 ++m_it.primitive_iterator;
5801 auto result = *
this;
5812 assert(m_object !=
nullptr);
5814 switch (m_object->m_type)
5818 std::advance(m_it.object_iterator, -1);
5824 std::advance(m_it.array_iterator, -1);
5830 --m_it.primitive_iterator;
5850 assert(m_object !=
nullptr);
5852 switch (m_object->m_type)
5871 return not operator==(other);
5886 assert(m_object !=
nullptr);
5888 switch (m_object->m_type)
5907 return not other.operator < (*this);
5916 return not operator<=(other);
5934 assert(m_object !=
nullptr);
5936 switch (m_object->m_type)
5943 std::advance(m_it.array_iterator, i);
5949 m_it.primitive_iterator += i;
5972 auto result = *
this;
5994 auto result = *
this;
6005 assert(m_object !=
nullptr);
6007 switch (m_object->m_type)
6026 assert(m_object !=
nullptr);
6028 switch (m_object->m_type)
6034 return *std::next(m_it.array_iterator, n);
6041 if (
JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
6055 const typename object_t::key_type&
key()
const 6057 assert(m_object !=
nullptr);
6061 return m_it.object_iterator->first;
6120 template<
typename Base>
6192 auto key() const -> decltype(
std::declval<Base>().key())
6194 auto it = --this->base();
6201 auto it = --this->base();
6202 return it.operator * ();
6211 #include <algorithm> 6227 virtual void write_character(CharType
c) = 0;
6228 virtual void write_characters(
const CharType* s, std::size_t length) = 0;
6233 template<
typename CharType>
6237 template<
typename CharType>
6252 std::copy(s, s + length, std::back_inserter(v));
6256 std::vector<CharType>&
v;
6260 template<
typename CharType>
6275 stream.write(s, static_cast<std::streamsize>(length));
6283 template<
typename CharType,
typename StringType = std::basic_
string<CharType>>
6298 str.append(s, length);
6305 template<
typename CharType,
typename StringType = std::basic_
string<CharType>>
6332 #include <algorithm> 6369 template<
typename BasicJsonType,
typename SAX = json_sax_dom_parser<BasicJsonType>>
6399 const bool strict =
true)
6402 bool result =
false;
6407 result = parse_bson_internal();
6411 result = parse_cbor_internal();
6415 result = parse_msgpack_internal();
6419 result = parse_ubjson_internal();
6440 if (
JSON_UNLIKELY(current != std::char_traits<char>::eof()))
6442 return sax->parse_error(chars_read, get_token_string(),
6443 parse_error::create(110, chars_read, exception_message(format,
"expected end of input; last byte: 0x" + get_token_string(),
"value")));
6459 return (*reinterpret_cast<char*>(&num) == 1);
6473 std::int32_t document_size;
6486 return sax->end_object();
6498 auto out = std::back_inserter(result);
6506 if (current == 0x00)
6510 *out++ =
static_cast<char>(current);
6527 template<
typename NumberType>
6532 auto last_token = get_token_string();
6533 return sax->parse_error(chars_read, last_token,
parse_error::create(112, chars_read, exception_message(
input_format_t::bson,
"string length must be at least 1, is " + std::to_string(len),
"string")));
6536 return get_string(
input_format_t::bson, len - static_cast<NumberType>(1), result) and
get() != std::char_traits<char>::eof();
6550 const std::size_t element_type_parse_position)
6552 switch (element_type)
6557 return get_number<double, true>(
input_format_t::bson, number) and sax->number_float(static_cast<number_float_t>(number),
"");
6564 return get_number<std::int32_t, true>(
input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
6569 return parse_bson_internal();
6574 return parse_bson_array();
6579 return sax->boolean(static_cast<bool>(
get()));
6602 snprintf(cr,
sizeof(cr),
"%.2hhX", static_cast<unsigned char>(element_type));
6623 while (
int element_type =
get())
6630 const std::size_t element_type_parse_position = chars_read;
6641 if (
JSON_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
6659 std::int32_t document_size;
6672 return sax->end_array();
6688 switch (get_char ?
get() : current)
6691 case std::char_traits<char>::eof():
6719 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
6770 return sax->number_integer(static_cast<int8_t>(0x20 - 1 - current));
6775 return get_number(
input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6781 return get_number(
input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6787 return get_number(
input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6793 return get_number(
input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
6794 - static_cast<number_integer_t>(number));
6829 return get_cbor_string(s) and sax->string(s);
6857 return get_cbor_array(static_cast<std::size_t>(current & 0x1F));
6862 return get_number(
input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6868 return get_number(
input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6874 return get_number(
input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6880 return get_number(
input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6884 return get_cbor_array(std::size_t(-1));
6911 return get_cbor_object(static_cast<std::size_t>(current & 0x1F));
6916 return get_number(
input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6922 return get_number(
input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6928 return get_number(
input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6934 return get_number(
input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6938 return get_cbor_object(std::size_t(-1));
6941 return sax->boolean(
false);
6944 return sax->boolean(
true);
6951 const int byte1_raw =
get();
6956 const int byte2_raw =
get();
6962 const auto byte1 =
static_cast<unsigned char>(byte1_raw);
6963 const auto byte2 =
static_cast<unsigned char>(byte2_raw);
6973 const int half = (byte1 << 8) + byte2;
6974 const double val = [&half]
6976 const int exp = (half >> 10) & 0x1F;
6977 const int mant = half & 0x3FF;
6978 assert(0 <= exp and exp <= 32);
6979 assert(0 <= mant and mant <= 1024);
6983 return std::ldexp(mant, -24);
6986 ? std::numeric_limits<double>::infinity()
6987 : std::numeric_limits<double>::quiet_NaN();
6989 return std::ldexp(mant + 1024, exp - 25);
6992 return sax->number_float((half & 0x8000) != 0
6993 ? static_cast<number_float_t>(-val)
6994 : static_cast<number_float_t>(val),
"");
7000 return get_number(
input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number),
"");
7006 return get_number(
input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number),
"");
7011 auto last_token = get_token_string();
7092 while (
get() != 0xFF)
7095 if (not get_cbor_string(chunk))
7099 result.append(chunk);
7106 auto last_token = get_token_string();
7107 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(
input_format_t::cbor,
"expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token,
"string")));
7124 if (len != std::size_t(-1))
7126 for (std::size_t i = 0; i < len; ++i)
7136 while (
get() != 0xFF)
7145 return sax->end_array();
7161 if (len != std::size_t(-1))
7163 for (std::size_t i = 0; i < len; ++i)
7166 if (
JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
7180 while (
get() != 0xFF)
7182 if (
JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
7195 return sax->end_object();
7210 case std::char_traits<char>::eof():
7342 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
7361 return get_msgpack_object(static_cast<std::size_t>(current & 0x0F));
7380 return get_msgpack_array(static_cast<std::size_t>(current & 0x0F));
7417 return get_msgpack_string(s) and sax->string(s);
7424 return sax->boolean(
false);
7427 return sax->boolean(
true);
7432 return get_number(
input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number),
"");
7438 return get_number(
input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number),
"");
7494 return get_msgpack_string(s) and sax->string(s);
7554 return sax->number_integer(static_cast<int8_t>(current));
7558 auto last_token = get_token_string();
7640 auto last_token = get_token_string();
7641 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(
input_format_t::msgpack,
"expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token,
"string")));
7657 for (std::size_t i = 0; i < len; ++i)
7665 return sax->end_array();
7680 for (std::size_t i = 0; i < len; ++i)
7683 if (
JSON_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
7695 return sax->end_object();
7711 return get_ubjson_value(get_char ? get_ignore_noop() : current);
7773 auto last_token = get_token_string();
7774 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(
input_format_t::ubjson,
"expected length type specification (U, i, I, l, L); last byte: 0x" + last_token,
"string")));
7784 switch (get_ignore_noop())
7793 result =
static_cast<std::size_t
>(number);
7804 result =
static_cast<std::size_t
>(number);
7815 result =
static_cast<std::size_t
>(number);
7826 result =
static_cast<std::size_t
>(number);
7837 result =
static_cast<std::size_t
>(number);
7843 auto last_token = get_token_string();
7844 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(
input_format_t::ubjson,
"expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token,
"size")));
7861 result.first = string_t::npos;
7868 result.second =
get();
7881 auto last_token = get_token_string();
7882 return sax->parse_error(chars_read, last_token,
parse_error::create(112, chars_read, exception_message(
input_format_t::ubjson,
"expected '#' after type information; last byte: 0x" + last_token,
"size")));
7885 return get_ubjson_size_value(result.first);
7887 else if (current ==
'#')
7889 return get_ubjson_size_value(result.first);
7902 case std::char_traits<char>::eof():
7906 return sax->boolean(
true);
7908 return sax->boolean(
false);
7946 return get_number(
input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number),
"");
7952 return get_number(
input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number),
"");
7964 auto last_token = get_token_string();
7965 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(
input_format_t::ubjson,
"byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token,
"char")));
7967 string_t s(1, static_cast<char>(current));
7968 return sax->string(s);
7974 return get_ubjson_string(s) and sax->string(s);
7978 return get_ubjson_array();
7981 return get_ubjson_object();
7985 auto last_token = get_token_string();
7996 std::pair<std::size_t, int> size_and_type;
8002 if (size_and_type.first != string_t::npos)
8004 if (
JSON_UNLIKELY(not sax->start_array(size_and_type.first)))
8009 if (size_and_type.second != 0)
8011 if (size_and_type.second !=
'N')
8013 for (std::size_t i = 0; i < size_and_type.first; ++i)
8015 if (
JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
8024 for (std::size_t i = 0; i < size_and_type.first; ++i)
8040 while (current !=
']')
8050 return sax->end_array();
8058 std::pair<std::size_t, int> size_and_type;
8065 if (size_and_type.first != string_t::npos)
8067 if (
JSON_UNLIKELY(not sax->start_object(size_and_type.first)))
8072 if (size_and_type.second != 0)
8074 for (std::size_t i = 0; i < size_and_type.first; ++i)
8076 if (
JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
8080 if (
JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
8089 for (std::size_t i = 0; i < size_and_type.first; ++i)
8091 if (
JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
8110 while (current !=
'}')
8112 if (
JSON_UNLIKELY(not get_ubjson_string(key,
false) or not sax->key(key)))
8125 return sax->end_object();
8144 return (current = ia->get_character());
8156 while (current ==
'N');
8174 template<
typename NumberType,
bool InputIsLittleEndian = false>
8178 std::array<uint8_t, sizeof(NumberType)> vec;
8179 for (std::size_t i = 0; i <
sizeof(NumberType); ++i)
8188 if (is_little_endian && !InputIsLittleEndian)
8190 vec[
sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
8194 vec[i] =
static_cast<uint8_t
>(current);
8199 std::memcpy(&result, vec.data(),
sizeof(NumberType));
8217 template<
typename NumberType>
8219 const NumberType len,
8222 bool success =
true;
8223 std::generate_n(std::back_inserter(result), len, [
this, &success, &format]()
8230 return static_cast<char>(current);
8242 if (
JSON_UNLIKELY(current == std::char_traits<char>::eof()))
8244 return sax->parse_error(chars_read,
"<end of file>",
8245 parse_error::create(110, chars_read, exception_message(format,
"unexpected end of input", context)));
8256 snprintf(cr, 3,
"%.2hhX", static_cast<unsigned char>(current));
8270 std::string error_msg =
"syntax error while parsing ";
8275 error_msg +=
"CBOR";
8279 error_msg +=
"MessagePack";
8283 error_msg +=
"UBJSON";
8287 error_msg +=
"BSON";
8296 return error_msg +
" " + context +
": " + detail;
8304 int current = std::char_traits<char>::eof();
8307 std::size_t chars_read = 0;
8310 const bool is_little_endian = little_endianess();
8321 #include <algorithm> 8343 template<
typename BasicJsonType,
typename CharType>
8369 write_bson_object(*j.m_value.object);
8389 oa->write_character(to_char_type(0xF6));
8395 oa->write_character(j.m_value.boolean
8396 ? to_char_type(0xF5)
8397 : to_char_type(0xF4));
8403 if (j.m_value.number_integer >= 0)
8408 if (j.m_value.number_integer <= 0x17)
8410 write_number(static_cast<uint8_t>(j.m_value.number_integer));
8414 oa->write_character(to_char_type(0x18));
8415 write_number(static_cast<uint8_t>(j.m_value.number_integer));
8419 oa->write_character(to_char_type(0x19));
8420 write_number(static_cast<uint16_t>(j.m_value.number_integer));
8424 oa->write_character(to_char_type(0x1A));
8425 write_number(static_cast<uint32_t>(j.m_value.number_integer));
8429 oa->write_character(to_char_type(0x1B));
8430 write_number(static_cast<uint64_t>(j.m_value.number_integer));
8437 const auto positive_number = -1 - j.m_value.number_integer;
8438 if (j.m_value.number_integer >= -24)
8440 write_number(static_cast<uint8_t>(0x20 + positive_number));
8444 oa->write_character(to_char_type(0x38));
8445 write_number(static_cast<uint8_t>(positive_number));
8449 oa->write_character(to_char_type(0x39));
8450 write_number(static_cast<uint16_t>(positive_number));
8454 oa->write_character(to_char_type(0x3A));
8455 write_number(static_cast<uint32_t>(positive_number));
8459 oa->write_character(to_char_type(0x3B));
8460 write_number(static_cast<uint64_t>(positive_number));
8468 if (j.m_value.number_unsigned <= 0x17)
8470 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
8474 oa->write_character(to_char_type(0x18));
8475 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
8479 oa->write_character(to_char_type(0x19));
8480 write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
8484 oa->write_character(to_char_type(0x1A));
8485 write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
8489 oa->write_character(to_char_type(0x1B));
8490 write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
8497 oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
8498 write_number(j.m_value.number_float);
8505 const auto N = j.m_value.string->size();
8508 write_number(static_cast<uint8_t>(0x60 + N));
8512 oa->write_character(to_char_type(0x78));
8513 write_number(static_cast<uint8_t>(N));
8517 oa->write_character(to_char_type(0x79));
8518 write_number(static_cast<uint16_t>(N));
8522 oa->write_character(to_char_type(0x7A));
8523 write_number(static_cast<uint32_t>(N));
8528 oa->write_character(to_char_type(0x7B));
8529 write_number(static_cast<uint64_t>(N));
8534 oa->write_characters(
8535 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
8536 j.m_value.string->size());
8543 const auto N = j.m_value.array->size();
8546 write_number(static_cast<uint8_t>(0x80 + N));
8550 oa->write_character(to_char_type(0x98));
8551 write_number(static_cast<uint8_t>(N));
8555 oa->write_character(to_char_type(0x99));
8556 write_number(static_cast<uint16_t>(N));
8560 oa->write_character(to_char_type(0x9A));
8561 write_number(static_cast<uint32_t>(N));
8566 oa->write_character(to_char_type(0x9B));
8567 write_number(static_cast<uint64_t>(N));
8572 for (
const auto& el : *j.m_value.array)
8582 const auto N = j.m_value.object->size();
8585 write_number(static_cast<uint8_t>(0xA0 + N));
8589 oa->write_character(to_char_type(0xB8));
8590 write_number(static_cast<uint8_t>(N));
8594 oa->write_character(to_char_type(0xB9));
8595 write_number(static_cast<uint16_t>(N));
8599 oa->write_character(to_char_type(0xBA));
8600 write_number(static_cast<uint32_t>(N));
8605 oa->write_character(to_char_type(0xBB));
8606 write_number(static_cast<uint64_t>(N));
8611 for (
const auto& el : *j.m_value.object)
8613 write_cbor(el.first);
8614 write_cbor(el.second);
8633 oa->write_character(to_char_type(0xC0));
8639 oa->write_character(j.m_value.boolean
8640 ? to_char_type(0xC3)
8641 : to_char_type(0xC2));
8647 if (j.m_value.number_integer >= 0)
8652 if (j.m_value.number_unsigned < 128)
8655 write_number(static_cast<uint8_t>(j.m_value.number_integer));
8660 oa->write_character(to_char_type(0xCC));
8661 write_number(static_cast<uint8_t>(j.m_value.number_integer));
8666 oa->write_character(to_char_type(0xCD));
8667 write_number(static_cast<uint16_t>(j.m_value.number_integer));
8672 oa->write_character(to_char_type(0xCE));
8673 write_number(static_cast<uint32_t>(j.m_value.number_integer));
8678 oa->write_character(to_char_type(0xCF));
8679 write_number(static_cast<uint64_t>(j.m_value.number_integer));
8684 if (j.m_value.number_integer >= -32)
8687 write_number(static_cast<int8_t>(j.m_value.number_integer));
8693 oa->write_character(to_char_type(0xD0));
8694 write_number(static_cast<int8_t>(j.m_value.number_integer));
8700 oa->write_character(to_char_type(0xD1));
8701 write_number(static_cast<int16_t>(j.m_value.number_integer));
8707 oa->write_character(to_char_type(0xD2));
8708 write_number(static_cast<int32_t>(j.m_value.number_integer));
8714 oa->write_character(to_char_type(0xD3));
8715 write_number(static_cast<int64_t>(j.m_value.number_integer));
8723 if (j.m_value.number_unsigned < 128)
8726 write_number(static_cast<uint8_t>(j.m_value.number_integer));
8731 oa->write_character(to_char_type(0xCC));
8732 write_number(static_cast<uint8_t>(j.m_value.number_integer));
8737 oa->write_character(to_char_type(0xCD));
8738 write_number(static_cast<uint16_t>(j.m_value.number_integer));
8743 oa->write_character(to_char_type(0xCE));
8744 write_number(static_cast<uint32_t>(j.m_value.number_integer));
8749 oa->write_character(to_char_type(0xCF));
8750 write_number(static_cast<uint64_t>(j.m_value.number_integer));
8757 oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
8758 write_number(j.m_value.number_float);
8765 const auto N = j.m_value.string->size();
8769 write_number(static_cast<uint8_t>(0xA0 | N));
8774 oa->write_character(to_char_type(0xD9));
8775 write_number(static_cast<uint8_t>(N));
8780 oa->write_character(to_char_type(0xDA));
8781 write_number(static_cast<uint16_t>(N));
8786 oa->write_character(to_char_type(0xDB));
8787 write_number(static_cast<uint32_t>(N));
8791 oa->write_characters(
8792 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
8793 j.m_value.string->size());
8800 const auto N = j.m_value.array->size();
8804 write_number(static_cast<uint8_t>(0x90 | N));
8809 oa->write_character(to_char_type(0xDC));
8810 write_number(static_cast<uint16_t>(N));
8815 oa->write_character(to_char_type(0xDD));
8816 write_number(static_cast<uint32_t>(N));
8820 for (
const auto& el : *j.m_value.array)
8830 const auto N = j.m_value.object->size();
8834 write_number(static_cast<uint8_t>(0x80 | (N & 0xF)));
8839 oa->write_character(to_char_type(0xDE));
8840 write_number(static_cast<uint16_t>(N));
8845 oa->write_character(to_char_type(0xDF));
8846 write_number(static_cast<uint32_t>(N));
8850 for (
const auto& el : *j.m_value.object)
8852 write_msgpack(el.first);
8853 write_msgpack(el.second);
8870 const bool use_type,
const bool add_prefix =
true)
8878 oa->write_character(to_char_type(
'Z'));
8887 oa->write_character(j.m_value.boolean
8889 : to_char_type(
'F'));
8896 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
8902 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
8908 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
8916 oa->write_character(to_char_type(
'S'));
8918 write_number_with_ubjson_prefix(j.m_value.string->size(),
true);
8919 oa->write_characters(
8920 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
8921 j.m_value.string->size());
8929 oa->write_character(to_char_type(
'['));
8932 bool prefix_required =
true;
8933 if (use_type and not j.m_value.array->empty())
8936 const CharType first_prefix = ubjson_prefix(j.front());
8937 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
8938 [
this, first_prefix](
const BasicJsonType & v)
8940 return ubjson_prefix(v) == first_prefix;
8945 prefix_required =
false;
8946 oa->write_character(to_char_type(
'$'));
8947 oa->write_character(first_prefix);
8953 oa->write_character(to_char_type(
'#'));
8954 write_number_with_ubjson_prefix(j.m_value.array->size(),
true);
8957 for (
const auto& el : *j.m_value.array)
8959 write_ubjson(el, use_count, use_type, prefix_required);
8964 oa->write_character(to_char_type(
']'));
8974 oa->write_character(to_char_type(
'{'));
8977 bool prefix_required =
true;
8978 if (use_type and not j.m_value.object->empty())
8981 const CharType first_prefix = ubjson_prefix(j.front());
8982 const bool same_prefix = std::all_of(j.begin(), j.end(),
8983 [
this, first_prefix](
const BasicJsonType & v)
8985 return ubjson_prefix(v) == first_prefix;
8990 prefix_required =
false;
8991 oa->write_character(to_char_type(
'$'));
8992 oa->write_character(first_prefix);
8998 oa->write_character(to_char_type(
'#'));
8999 write_number_with_ubjson_prefix(j.m_value.object->size(),
true);
9002 for (
const auto& el : *j.m_value.object)
9004 write_number_with_ubjson_prefix(el.first.size(),
true);
9005 oa->write_characters(
9006 reinterpret_cast<const CharType*>(el.first.c_str()),
9008 write_ubjson(el.second, use_count, use_type, prefix_required);
9013 oa->write_character(to_char_type(
'}'));
9035 const auto it = name.find(static_cast<typename string_t::value_type>(0));
9039 "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) +
")"));
9042 return 1ul + name.size() + 1u;
9049 const std::uint8_t element_type)
9051 oa->write_character(to_char_type(element_type));
9052 oa->write_characters(
9053 reinterpret_cast<const CharType*>(name.c_str()),
9063 write_bson_entry_header(name, 0x08);
9064 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
9073 write_bson_entry_header(name, 0x01);
9074 write_number<double, true>(
value);
9082 return sizeof(std::int32_t) + value.size() + 1ul;
9091 write_bson_entry_header(name, 0x02);
9093 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(value.size() + 1ul));
9094 oa->write_characters(
9095 reinterpret_cast<const CharType*>(value.c_str()),
9104 write_bson_entry_header(name, 0x0A);
9114 return sizeof(std::int32_t);
9118 return sizeof(std::int64_t);
9126 const std::int64_t
value)
9130 write_bson_entry_header(name, 0x10);
9131 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(
value));
9135 write_bson_entry_header(name, 0x12);
9136 write_number<std::int64_t, true>(
static_cast<std::int64_t
>(
value));
9146 ?
sizeof(std::int32_t)
9147 :
sizeof(std::int64_t);
9154 const std::uint64_t
value)
9158 write_bson_entry_header(name, 0x10 );
9159 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(
value));
9163 write_bson_entry_header(name, 0x12 );
9164 write_number<std::int64_t, true>(
static_cast<std::int64_t
>(
value));
9176 const typename BasicJsonType::object_t&
value)
9178 write_bson_entry_header(name, 0x03);
9179 write_bson_object(value);
9187 std::size_t embedded_document_size = 0ul;
9188 std::size_t array_index = 0ul;
9190 for (
const auto& el : value)
9192 embedded_document_size += calc_bson_element_size(std::to_string(array_index++), el);
9195 return sizeof(std::int32_t) + embedded_document_size + 1ul;
9202 const typename BasicJsonType::array_t&
value)
9204 write_bson_entry_header(name, 0x04);
9205 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(calc_bson_array_size(value)));
9207 std::size_t array_index = 0ul;
9209 for (
const auto& el : value)
9211 write_bson_element(std::to_string(array_index++), el);
9214 oa->write_character(to_char_type(0x00));
9222 const BasicJsonType& j)
9224 const auto header_size = calc_bson_entry_header_size(name);
9228 return header_size + calc_bson_object_size(*j.m_value.object);
9231 return header_size + calc_bson_array_size(*j.m_value.array);
9234 return header_size + 1ul;
9237 return header_size + 8ul;
9240 return header_size + calc_bson_integer_size(j.m_value.number_integer);
9243 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
9246 return header_size + calc_bson_string_size(*j.m_value.string);
9249 return header_size + 0ul;
9267 const BasicJsonType& j)
9272 return write_bson_object_entry(name, *j.m_value.object);
9275 return write_bson_array(name, *j.m_value.array);
9278 return write_bson_boolean(name, j.m_value.boolean);
9281 return write_bson_double(name, j.m_value.number_float);
9284 return write_bson_integer(name, j.m_value.number_integer);
9287 return write_bson_unsigned(name, j.m_value.number_unsigned);
9290 return write_bson_string(name, *j.m_value.string);
9293 return write_bson_null(name);
9311 std::size_t document_size = std::accumulate(value.begin(), value.end(), 0ul,
9312 [](
size_t result,
const typename BasicJsonType::object_t::value_type & el)
9314 return result += calc_bson_element_size(el.first, el.second);
9317 return sizeof(std::int32_t) + document_size + 1ul;
9326 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(calc_bson_object_size(value)));
9328 for (
const auto& el : value)
9330 write_bson_element(el.first, el.second);
9333 oa->write_character(to_char_type(0x00));
9342 return to_char_type(0xFA);
9347 return to_char_type(0xFB);
9356 return to_char_type(0xCA);
9361 return to_char_type(0xCB);
9369 template<
typename NumberType,
typename std::enable_if<
9372 const bool add_prefix)
9376 oa->write_character(get_ubjson_float_prefix(n));
9382 template<
typename NumberType,
typename std::enable_if<
9385 const bool add_prefix)
9391 oa->write_character(to_char_type(
'i'));
9393 write_number(static_cast<uint8_t>(n));
9399 oa->write_character(to_char_type(
'U'));
9401 write_number(static_cast<uint8_t>(n));
9407 oa->write_character(to_char_type(
'I'));
9409 write_number(static_cast<int16_t>(n));
9415 oa->write_character(to_char_type(
'l'));
9417 write_number(static_cast<int32_t>(n));
9423 oa->write_character(to_char_type(
'L'));
9425 write_number(static_cast<int64_t>(n));
9434 template<
typename NumberType,
typename std::enable_if<
9436 not std::is_floating_point<NumberType>::value,
int>::type = 0>
9438 const bool add_prefix)
9444 oa->write_character(to_char_type(
'i'));
9446 write_number(static_cast<int8_t>(n));
9452 oa->write_character(to_char_type(
'U'));
9454 write_number(static_cast<uint8_t>(n));
9460 oa->write_character(to_char_type(
'I'));
9462 write_number(static_cast<int16_t>(n));
9468 oa->write_character(to_char_type(
'l'));
9470 write_number(static_cast<int32_t>(n));
9476 oa->write_character(to_char_type(
'L'));
9478 write_number(static_cast<int64_t>(n));
9505 return j.m_value.boolean ?
'T' :
'F';
9552 return get_ubjson_float_prefix(j.m_value.number_float);
9593 template<
typename NumberType,
bool OutputIsLittleEndian = false>
9597 std::array<CharType, sizeof(NumberType)> vec;
9598 std::memcpy(vec.data(), &n,
sizeof(NumberType));
9601 if (is_little_endian and not OutputIsLittleEndian)
9604 std::reverse(vec.begin(), vec.end());
9607 oa->write_characters(vec.data(),
sizeof(NumberType));
9615 template <
typename C = CharType,
9619 return *
reinterpret_cast<char*
>(&
x);
9622 template <
typename C = CharType,
9626 static_assert(
sizeof(std::uint8_t) ==
sizeof(CharType),
"size of CharType must be equal to std::uint8_t");
9629 std::memcpy(&result, &
x,
sizeof(
x));
9633 template<
typename C = CharType,
9640 template <
typename InputCharType,
typename C = CharType,
9643 std::is_signed<char>::value and
9644 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
9664 #include <algorithm> 9675 #include <type_traits> 9715 template <
typename Target,
typename Source>
9718 static_assert(
sizeof(Target) ==
sizeof(Source),
"size mismatch");
9721 std::memcpy(&target, &source,
sizeof(Source));
9727 static constexpr
int kPrecision = 64;
9732 constexpr
diyfp(uint64_t f_,
int e_) noexcept : f(f_), e(e_) {}
9743 return {
x.f - y.f,
x.e};
9752 static_assert(kPrecision == 64,
"internal error");
9777 const uint64_t u_lo =
x.f & 0xFFFFFFFF;
9778 const uint64_t u_hi =
x.f >> 32;
9779 const uint64_t v_lo = y.f & 0xFFFFFFFF;
9780 const uint64_t v_hi = y.f >> 32;
9782 const uint64_t p0 = u_lo * v_lo;
9783 const uint64_t p1 = u_lo * v_hi;
9784 const uint64_t p2 = u_hi * v_lo;
9785 const uint64_t p3 = u_hi * v_hi;
9787 const uint64_t p0_hi = p0 >> 32;
9788 const uint64_t p1_lo = p1 & 0xFFFFFFFF;
9789 const uint64_t p1_hi = p1 >> 32;
9790 const uint64_t p2_lo = p2 & 0xFFFFFFFF;
9791 const uint64_t p2_hi = p2 >> 32;
9793 uint64_t Q = p0_hi + p1_lo + p2_lo;
9804 Q += uint64_t{1} << (64 - 32 - 1);
9806 const uint64_t
h = p3 + p2_hi + p1_hi + (Q >> 32);
9808 return {
h,
x.e + y.e + 64};
9819 while ((
x.f >> 63) == 0)
9834 const int delta =
x.e - target_exponent;
9837 assert(((
x.f << delta) >> delta) ==
x.f);
9839 return {
x.f << delta, target_exponent};
9856 template <
typename FloatType>
9859 assert(std::isfinite(value));
9869 static_assert(std::numeric_limits<FloatType>::is_iec559,
9870 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
9872 constexpr
int kPrecision = std::numeric_limits<FloatType>::digits;
9873 constexpr
int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
9874 constexpr
int kMinExp = 1 - kBias;
9875 constexpr uint64_t kHiddenBit = uint64_t{1} << (kPrecision - 1);
9877 using bits_type =
typename std::conditional< kPrecision == 24, uint32_t, uint64_t >::type;
9879 const uint64_t bits = reinterpret_bits<bits_type>(
value);
9880 const uint64_t E = bits >> (kPrecision - 1);
9881 const uint64_t F = bits & (kHiddenBit - 1);
9883 const bool is_denormal = (E == 0);
9884 const diyfp v = is_denormal
9886 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
9909 const bool lower_boundary_is_closer = (F == 0 and E > 1);
9910 const diyfp m_plus = diyfp(2 * v.
f + 1, v.
e - 1);
9911 const diyfp m_minus = lower_boundary_is_closer
9912 ? diyfp(4 * v.
f - 1, v.
e - 2)
9913 : diyfp(2 * v.
f - 1, v.
e - 1);
9916 const diyfp w_plus = diyfp::normalize(m_plus);
9919 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.
e);
9921 return {diyfp::normalize(v), w_minus, w_plus};
10048 constexpr
int kCachedPowersSize = 79;
10049 constexpr
int kCachedPowersMinDecExp = -300;
10050 constexpr
int kCachedPowersDecStep = 8;
10054 { 0xAB70FE17C79AC6CA, -1060, -300 },
10055 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
10056 { 0xBE5691EF416BD60C, -1007, -284 },
10057 { 0x8DD01FAD907FFC3C, -980, -276 },
10058 { 0xD3515C2831559A83, -954, -268 },
10059 { 0x9D71AC8FADA6C9B5, -927, -260 },
10060 { 0xEA9C227723EE8BCB, -901, -252 },
10061 { 0xAECC49914078536D, -874, -244 },
10062 { 0x823C12795DB6CE57, -847, -236 },
10063 { 0xC21094364DFB5637, -821, -228 },
10064 { 0x9096EA6F3848984F, -794, -220 },
10065 { 0xD77485CB25823AC7, -768, -212 },
10066 { 0xA086CFCD97BF97F4, -741, -204 },
10067 { 0xEF340A98172AACE5, -715, -196 },
10068 { 0xB23867FB2A35B28E, -688, -188 },
10069 { 0x84C8D4DFD2C63F3B, -661, -180 },
10070 { 0xC5DD44271AD3CDBA, -635, -172 },
10071 { 0x936B9FCEBB25C996, -608, -164 },
10072 { 0xDBAC6C247D62A584, -582, -156 },
10073 { 0xA3AB66580D5FDAF6, -555, -148 },
10074 { 0xF3E2F893DEC3F126, -529, -140 },
10075 { 0xB5B5ADA8AAFF80B8, -502, -132 },
10076 { 0x87625F056C7C4A8B, -475, -124 },
10077 { 0xC9BCFF6034C13053, -449, -116 },
10078 { 0x964E858C91BA2655, -422, -108 },
10079 { 0xDFF9772470297EBD, -396, -100 },
10080 { 0xA6DFBD9FB8E5B88F, -369, -92 },
10081 { 0xF8A95FCF88747D94, -343, -84 },
10082 { 0xB94470938FA89BCF, -316, -76 },
10083 { 0x8A08F0F8BF0F156B, -289, -68 },
10084 { 0xCDB02555653131B6, -263, -60 },
10085 { 0x993FE2C6D07B7FAC, -236, -52 },
10086 { 0xE45C10C42A2B3B06, -210, -44 },
10087 { 0xAA242499697392D3, -183, -36 },
10088 { 0xFD87B5F28300CA0E, -157, -28 },
10089 { 0xBCE5086492111AEB, -130, -20 },
10090 { 0x8CBCCC096F5088CC, -103, -12 },
10091 { 0xD1B71758E219652C, -77, -4 },
10092 { 0x9C40000000000000, -50, 4 },
10093 { 0xE8D4A51000000000, -24, 12 },
10094 { 0xAD78EBC5AC620000, 3, 20 },
10095 { 0x813F3978F8940984, 30, 28 },
10096 { 0xC097CE7BC90715B3, 56, 36 },
10097 { 0x8F7E32CE7BEA5C70, 83, 44 },
10098 { 0xD5D238A4ABE98068, 109, 52 },
10099 { 0x9F4F2726179A2245, 136, 60 },
10100 { 0xED63A231D4C4FB27, 162, 68 },
10101 { 0xB0DE65388CC8ADA8, 189, 76 },
10102 { 0x83C7088E1AAB65DB, 216, 84 },
10103 { 0xC45D1DF942711D9A, 242, 92 },
10104 { 0x924D692CA61BE758, 269, 100 },
10105 { 0xDA01EE641A708DEA, 295, 108 },
10106 { 0xA26DA3999AEF774A, 322, 116 },
10107 { 0xF209787BB47D6B85, 348, 124 },
10108 { 0xB454E4A179DD1877, 375, 132 },
10109 { 0x865B86925B9BC5C2, 402, 140 },
10110 { 0xC83553C5C8965D3D, 428, 148 },
10111 { 0x952AB45CFA97A0B3, 455, 156 },
10112 { 0xDE469FBD99A05FE3, 481, 164 },
10113 { 0xA59BC234DB398C25, 508, 172 },
10114 { 0xF6C69A72A3989F5C, 534, 180 },
10115 { 0xB7DCBF5354E9BECE, 561, 188 },
10116 { 0x88FCF317F22241E2, 588, 196 },
10117 { 0xCC20CE9BD35C78A5, 614, 204 },
10118 { 0x98165AF37B2153DF, 641, 212 },
10119 { 0xE2A0B5DC971F303A, 667, 220 },
10120 { 0xA8D9D1535CE3B396, 694, 228 },
10121 { 0xFB9B7CD9A4A7443C, 720, 236 },
10122 { 0xBB764C4CA7A44410, 747, 244 },
10123 { 0x8BAB8EEFB6409C1A, 774, 252 },
10124 { 0xD01FEF10A657842C, 800, 260 },
10125 { 0x9B10A4E5E9913129, 827, 268 },
10126 { 0xE7109BFBA19C0C9D, 853, 276 },
10127 { 0xAC2820D9623BF429, 880, 284 },
10128 { 0x80444B5E7AA7CF85, 907, 292 },
10129 { 0xBF21E44003ACDD2D, 933, 300 },
10130 { 0x8E679C2F5E44FF8F, 960, 308 },
10131 { 0xD433179D9C8CB841, 986, 316 },
10132 { 0x9E19DB92B4E31BA9, 1013, 324 },
10139 assert(e >= -1500);
10141 const int f = kAlpha - e - 1;
10142 const int k = (f * 78913) / (1 << 18) +
static_cast<int>(f > 0);
10144 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
10145 assert(index >= 0);
10146 assert(index < kCachedPowersSize);
10147 static_cast<void>(kCachedPowersSize);
10150 assert(kAlpha <= cached.
e + e + 64);
10151 assert(kGamma >= cached.
e + e + 64);
10163 if (n >= 1000000000)
10165 pow10 = 1000000000;
10169 else if (n >= 100000000)
10174 else if (n >= 10000000)
10179 else if (n >= 1000000)
10184 else if (n >= 100000)
10189 else if (n >= 10000)
10194 else if (n >= 1000)
10217 uint64_t rest, uint64_t ten_k)
10220 assert(dist <= delta);
10221 assert(rest <= delta);
10244 and delta - rest >= ten_k
10245 and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
10247 assert(buf[len - 1] !=
'0');
10260 static_assert(kAlpha >= -60,
"internal error");
10261 static_assert(kGamma <= -32,
"internal error");
10275 assert(M_plus.
e >= kAlpha);
10276 assert(M_plus.
e <= kGamma);
10278 uint64_t delta = diyfp::sub(M_plus, M_minus).f;
10279 uint64_t dist = diyfp::sub(M_plus, w ).f;
10288 const diyfp one(uint64_t{1} << -M_plus.
e, M_plus.
e);
10290 auto p1 =
static_cast<uint32_t
>(M_plus.
f >> -one.e);
10291 uint64_t p2 = M_plus.
f & (one.f - 1);
10327 const uint32_t d = p1 / pow10;
10328 const uint32_t r = p1 % pow10;
10334 buffer[length++] =
static_cast<char>(
'0' + d);
10353 const uint64_t rest = (uint64_t{p1} << -one.e) + p2;
10358 decimal_exponent += n;
10369 const uint64_t ten_n = uint64_t{pow10} << -one.e;
10370 grisu2_round(buffer, length, dist, delta, rest, ten_n);
10420 assert(p2 > delta);
10431 assert(p2 <= UINT64_MAX / 10);
10433 const uint64_t d = p2 >> -one.e;
10434 const uint64_t r = p2 & (one.f - 1);
10441 buffer[length++] =
static_cast<char>(
'0' + d);
10466 decimal_exponent -=
m;
10474 const uint64_t ten_m = one.f;
10497 inline void grisu2(
char* buf,
int& len,
int& decimal_exponent,
10500 assert(m_plus.
e == m_minus.
e);
10501 assert(m_plus.
e == v.
e);
10514 const diyfp c_minus_k(cached.
f, cached.
e);
10517 const diyfp w = diyfp::mul(v, c_minus_k);
10518 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
10519 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
10542 const diyfp M_minus(w_minus.
f + 1, w_minus.
e);
10543 const diyfp M_plus (w_plus.
f - 1, w_plus.
e );
10545 decimal_exponent = -cached.
k;
10555 template <
typename FloatType>
10558 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
10559 "internal error: not enough precision");
10561 assert(std::isfinite(value));
10609 auto k =
static_cast<uint32_t
>(e);
10615 *buf++ =
static_cast<char>(
'0' + k);
10619 *buf++ =
static_cast<char>(
'0' + k / 10);
10621 *buf++ =
static_cast<char>(
'0' + k);
10625 *buf++ =
static_cast<char>(
'0' + k / 100);
10627 *buf++ =
static_cast<char>(
'0' + k / 10);
10629 *buf++ =
static_cast<char>(
'0' + k);
10645 int min_exp,
int max_exp)
10647 assert(min_exp < 0);
10648 assert(max_exp > 0);
10651 const int n = len + decimal_exponent;
10657 if (k <= n and n <= max_exp)
10662 std::memset(buf + k,
'0', static_cast<size_t>(n - k));
10666 return buf + (n + 2);
10669 if (0 < n and n <= max_exp)
10676 std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
10678 return buf + (k + 1);
10681 if (min_exp < n and n <= 0)
10686 std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
10689 std::memset(buf + 2,
'0', static_cast<size_t>(-n));
10690 return buf + (2 + (-n) + k);
10705 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
10726 template <
typename FloatType>
10729 static_cast<void>(last);
10730 assert(std::isfinite(value));
10733 if (std::signbit(value))
10748 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
10755 int decimal_exponent = 0;
10758 assert(len <= std::numeric_limits<FloatType>::max_digits10);
10761 constexpr
int kMinExp = -4;
10763 constexpr
int kMaxExp = std::numeric_limits<FloatType>::digits10;
10765 assert(last - first >= kMaxExp + 2);
10766 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
10767 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
10802 template<
typename BasicJsonType>
10809 static constexpr uint8_t UTF8_ACCEPT = 0;
10810 static constexpr uint8_t UTF8_REJECT = 1;
10821 , loc(
std::localeconv())
10822 , thousands_sep(loc->thousands_sep == nullptr ?
'\0' : * (loc->thousands_sep))
10823 , decimal_point(loc->decimal_point == nullptr ?
'\0' : * (loc->decimal_point))
10824 , indent_char(ichar)
10825 , indent_string(512, indent_char)
10826 , error_handler(error_handler_)
10853 void dump(
const BasicJsonType& val,
const bool pretty_print,
10854 const bool ensure_ascii,
10855 const unsigned int indent_step,
10856 const unsigned int current_indent = 0)
10858 switch (val.m_type)
10862 if (val.m_value.object->empty())
10864 o->write_characters(
"{}", 2);
10870 o->write_characters(
"{\n", 2);
10873 const auto new_indent = current_indent + indent_step;
10876 indent_string.resize(indent_string.size() * 2,
' ');
10880 auto i = val.m_value.object->cbegin();
10881 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
10883 o->write_characters(indent_string.c_str(), new_indent);
10884 o->write_character(
'\"');
10885 dump_escaped(i->first, ensure_ascii);
10886 o->write_characters(
"\": ", 3);
10887 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
10888 o->write_characters(
",\n", 2);
10892 assert(i != val.m_value.object->cend());
10893 assert(std::next(i) == val.m_value.object->cend());
10894 o->write_characters(indent_string.c_str(), new_indent);
10895 o->write_character(
'\"');
10896 dump_escaped(i->first, ensure_ascii);
10897 o->write_characters(
"\": ", 3);
10898 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
10900 o->write_character(
'\n');
10901 o->write_characters(indent_string.c_str(), current_indent);
10902 o->write_character(
'}');
10906 o->write_character(
'{');
10909 auto i = val.m_value.object->cbegin();
10910 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
10912 o->write_character(
'\"');
10913 dump_escaped(i->first, ensure_ascii);
10914 o->write_characters(
"\":", 2);
10915 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
10916 o->write_character(
',');
10920 assert(i != val.m_value.object->cend());
10921 assert(std::next(i) == val.m_value.object->cend());
10922 o->write_character(
'\"');
10923 dump_escaped(i->first, ensure_ascii);
10924 o->write_characters(
"\":", 2);
10925 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
10927 o->write_character(
'}');
10935 if (val.m_value.array->empty())
10937 o->write_characters(
"[]", 2);
10943 o->write_characters(
"[\n", 2);
10946 const auto new_indent = current_indent + indent_step;
10949 indent_string.resize(indent_string.size() * 2,
' ');
10953 for (
auto i = val.m_value.array->cbegin();
10954 i != val.m_value.array->cend() - 1; ++i)
10956 o->write_characters(indent_string.c_str(), new_indent);
10957 dump(*i,
true, ensure_ascii, indent_step, new_indent);
10958 o->write_characters(
",\n", 2);
10962 assert(not val.m_value.array->empty());
10963 o->write_characters(indent_string.c_str(), new_indent);
10964 dump(val.m_value.array->back(),
true, ensure_ascii, indent_step, new_indent);
10966 o->write_character(
'\n');
10967 o->write_characters(indent_string.c_str(), current_indent);
10968 o->write_character(
']');
10972 o->write_character(
'[');
10975 for (
auto i = val.m_value.array->cbegin();
10976 i != val.m_value.array->cend() - 1; ++i)
10978 dump(*i,
false, ensure_ascii, indent_step, current_indent);
10979 o->write_character(
',');
10983 assert(not val.m_value.array->empty());
10984 dump(val.m_value.array->back(),
false, ensure_ascii, indent_step, current_indent);
10986 o->write_character(
']');
10994 o->write_character(
'\"');
10995 dump_escaped(*val.m_value.string, ensure_ascii);
10996 o->write_character(
'\"');
11002 if (val.m_value.boolean)
11004 o->write_characters(
"true", 4);
11008 o->write_characters(
"false", 5);
11015 dump_integer(val.m_value.number_integer);
11021 dump_integer(val.m_value.number_unsigned);
11027 dump_float(val.m_value.number_float);
11033 o->write_characters(
"<discarded>", 11);
11039 o->write_characters(
"null", 4);
11062 uint32_t codepoint;
11063 uint8_t state = UTF8_ACCEPT;
11064 std::size_t bytes = 0;
11067 std::size_t bytes_after_last_accept = 0;
11068 std::size_t undumped_chars = 0;
11070 for (std::size_t i = 0; i < s.size(); ++i)
11072 const auto byte =
static_cast<uint8_t
>(s[i]);
11074 switch (decode(state, codepoint, byte))
11082 string_buffer[bytes++] =
'\\';
11083 string_buffer[bytes++] =
'b';
11089 string_buffer[bytes++] =
'\\';
11090 string_buffer[bytes++] =
't';
11096 string_buffer[bytes++] =
'\\';
11097 string_buffer[bytes++] =
'n';
11103 string_buffer[bytes++] =
'\\';
11104 string_buffer[bytes++] =
'f';
11110 string_buffer[bytes++] =
'\\';
11111 string_buffer[bytes++] =
'r';
11117 string_buffer[bytes++] =
'\\';
11118 string_buffer[bytes++] =
'\"';
11124 string_buffer[bytes++] =
'\\';
11125 string_buffer[bytes++] =
'\\';
11133 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
11135 if (codepoint <= 0xFFFF)
11137 std::snprintf(string_buffer.data() + bytes, 7,
"\\u%04x",
11138 static_cast<uint16_t
>(codepoint));
11143 std::snprintf(string_buffer.data() + bytes, 13,
"\\u%04x\\u%04x",
11144 static_cast<uint16_t
>(0xD7C0 + (codepoint >> 10)),
11145 static_cast<uint16_t
>(0xDC00 + (codepoint & 0x3FF)));
11153 string_buffer[bytes++] = s[i];
11162 if (string_buffer.size() - bytes < 13)
11164 o->write_characters(string_buffer.data(), bytes);
11169 bytes_after_last_accept = bytes;
11170 undumped_chars = 0;
11176 switch (error_handler)
11181 snprintf(&sn[0], sn.size(),
"%.2X", byte);
11192 if (undumped_chars > 0)
11199 bytes = bytes_after_last_accept;
11206 string_buffer[bytes++] =
'\\';
11207 string_buffer[bytes++] =
'u';
11208 string_buffer[bytes++] =
'f';
11209 string_buffer[bytes++] =
'f';
11210 string_buffer[bytes++] =
'f';
11211 string_buffer[bytes++] =
'd';
11219 bytes_after_last_accept = bytes;
11222 undumped_chars = 0;
11225 state = UTF8_ACCEPT;
11234 if (not ensure_ascii)
11237 string_buffer[bytes++] = s[i];
11251 o->write_characters(string_buffer.data(), bytes);
11257 switch (error_handler)
11262 snprintf(&sn[0], sn.size(),
"%.2X",
static_cast<uint8_t
>(s.back()));
11269 o->write_characters(string_buffer.data(), bytes_after_last_accept);
11276 o->write_characters(string_buffer.data(), bytes_after_last_accept);
11280 o->write_characters(
"\\ufffd", 6);
11284 o->write_characters(
"\xEF\xBF\xBD", 3);
11310 o->write_character(
'0');
11314 const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not (x >= 0);
11320 assert(i < number_buffer.size() - 1);
11322 const auto digit = std::labs(static_cast<long>(x % 10));
11323 number_buffer[i++] =
static_cast<char>(
'0' + digit);
11330 assert(i < number_buffer.size() - 2);
11331 number_buffer[i++] =
'-';
11334 std::reverse(number_buffer.begin(), number_buffer.begin() + i);
11335 o->write_characters(number_buffer.data(), i);
11349 if (not std::isfinite(x))
11351 o->write_characters(
"null", 4);
11360 static constexpr
bool is_ieee_single_or_double
11361 = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and std::numeric_limits<number_float_t>::max_exponent == 128) or
11362 (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and std::numeric_limits<number_float_t>::max_exponent == 1024);
11364 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
11369 char*
begin = number_buffer.data();
11372 o->write_characters(begin, static_cast<size_t>(end - begin));
11378 static constexpr
auto d = std::numeric_limits<number_float_t>::max_digits10;
11381 std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(),
"%.*g", d,
x);
11386 assert(static_cast<std::size_t>(len) < number_buffer.size());
11389 if (thousands_sep !=
'\0')
11391 const auto end = std::remove(number_buffer.begin(),
11392 number_buffer.begin() + len, thousands_sep);
11393 std::fill(
end, number_buffer.end(),
'\0');
11394 assert((
end - number_buffer.begin()) <= len);
11395 len = (
end - number_buffer.begin());
11399 if (decimal_point !=
'\0' and decimal_point !=
'.')
11401 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
11402 if (dec_pos != number_buffer.end())
11408 o->write_characters(number_buffer.data(),
static_cast<std::size_t
>(len));
11411 const bool value_is_int_like =
11412 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
11415 return (
c ==
'.' or
c ==
'e');
11418 if (value_is_int_like)
11420 o->write_characters(
".0", 2);
11445 static uint8_t
decode(uint8_t& state, uint32_t& codep,
const uint8_t byte) noexcept
11447 static const std::array<uint8_t, 400> utf8d =
11450 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11451 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11452 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11453 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11454 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
11455 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
11456 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
11457 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
11458 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
11459 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
11460 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1,
11461 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
11462 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1,
11463 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
11467 const uint8_t
type = utf8d[byte];
11469 codep = (state != UTF8_ACCEPT)
11470 ? (byte & 0x3fu) | (codep << 6)
11471 : static_cast<uint32_t>(0xff >> type) & (byte);
11473 state = utf8d[256u + state * 16u +
type];
11482 std::array<char, 64> number_buffer{{}};
11485 const std::lconv* loc =
nullptr;
11487 const char thousands_sep =
'\0';
11489 const char decimal_point =
'\0';
11492 std::array<char, 512> string_buffer{{}};
11508 #include <initializer_list> 11518 template<
typename BasicJsonType>
11525 : owned_value(
std::move(
value)), value_ref(&owned_value), is_rvalue(true)
11529 : value_ref(const_cast<
value_type*>(&value)), is_rvalue(false)
11533 : owned_value(init), value_ref(&owned_value), is_rvalue(true)
11540 : owned_value(
std::forward<Args>(
args)...), value_ref(&owned_value),
11554 return std::move(*value_ref);
11561 return *
static_cast<value_type const*
>(value_ref);
11566 return static_cast<value_type const*
>(value_ref);
11570 mutable value_type owned_value =
nullptr;
11571 value_type* value_ref =
nullptr;
11594 template<
typename BasicJsonType>
11624 : reference_tokens(split(s))
11644 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
11648 return a +
"/" + escape(b);
11655 return to_string();
11667 std::size_t processed_chars = 0;
11668 const int res = std::stoi(s, &processed_chars);
11691 auto last = reference_tokens.back();
11692 reference_tokens.pop_back();
11699 return reference_tokens.empty();
11724 using size_type =
typename BasicJsonType::size_type;
11729 for (
const auto& reference_token : reference_tokens)
11731 switch (result->m_type)
11735 if (reference_token ==
"0")
11738 result = &result->operator[](0);
11743 result = &result->operator[](reference_token);
11751 result = &result->operator[](reference_token);
11760 result = &result->operator[](
static_cast<size_type
>(array_index(reference_token)));
11804 using size_type =
typename BasicJsonType::size_type;
11805 for (
const auto& reference_token : reference_tokens)
11812 std::all_of(reference_token.begin(), reference_token.end(),
11815 return (
x >=
'0' and
x <=
'9');
11819 *ptr = (nums or reference_token ==
"-")
11824 switch (ptr->m_type)
11829 ptr = &ptr->operator[](reference_token);
11836 if (
JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0'))
11839 "array index '" + reference_token +
11840 "' must not begin with '0'"));
11843 if (reference_token ==
"-")
11846 ptr = &ptr->operator[](ptr->m_value.array->size());
11853 ptr = &ptr->operator[](
11854 static_cast<size_type
>(array_index(reference_token)));
11880 using size_type =
typename BasicJsonType::size_type;
11881 for (
const auto& reference_token : reference_tokens)
11883 switch (ptr->m_type)
11888 ptr = &ptr->at(reference_token);
11898 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11899 ") is out of range"));
11903 if (
JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0'))
11906 "array index '" + reference_token +
11907 "' must not begin with '0'"));
11913 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
11945 using size_type =
typename BasicJsonType::size_type;
11946 for (
const auto& reference_token : reference_tokens)
11948 switch (ptr->m_type)
11953 ptr = &ptr->operator[](reference_token);
11963 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11964 ") is out of range"));
11968 if (
JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0'))
11971 "array index '" + reference_token +
11972 "' must not begin with '0'"));
11978 ptr = &ptr->operator[](
11979 static_cast<size_type
>(array_index(reference_token)));
12004 using size_type =
typename BasicJsonType::size_type;
12005 for (
const auto& reference_token : reference_tokens)
12007 switch (ptr->m_type)
12012 ptr = &ptr->at(reference_token);
12022 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12023 ") is out of range"));
12027 if (
JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0'))
12030 "array index '" + reference_token +
12031 "' must not begin with '0'"));
12037 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
12065 std::vector<std::string> result;
12068 if (reference_string.empty())
12077 "JSON pointer must be empty or begin with '/' - was: '" +
12078 reference_string +
"'"));
12086 std::size_t slash = reference_string.find_first_of(
'/', 1),
12093 start = (slash == std::string::npos) ? 0 : slash + 1,
12095 slash = reference_string.find_first_of(
'/', start))
12099 auto reference_token = reference_string.substr(start, slash - start);
12102 for (std::size_t pos = reference_token.find_first_of(
'~');
12103 pos != std::string::npos;
12104 pos = reference_token.find_first_of(
'~', pos + 1))
12106 assert(reference_token[pos] ==
'~');
12110 (reference_token[pos + 1] !=
'0' and
12111 reference_token[pos + 1] !=
'1')))
12118 unescape(reference_token);
12119 result.push_back(reference_token);
12141 assert(not f.empty());
12142 for (
auto pos = s.find(f);
12143 pos != std::string::npos;
12144 s.replace(pos, f.size(), t),
12145 pos = s.find(f, pos + t.size()))
12152 replace_substring(s,
"~",
"~0");
12153 replace_substring(s,
"/",
"~1");
12160 replace_substring(s,
"~1",
"/");
12161 replace_substring(s,
"~0",
"~");
12172 const BasicJsonType&
value,
12173 BasicJsonType& result)
12175 switch (value.m_type)
12179 if (value.m_value.array->empty())
12182 result[reference_string] =
nullptr;
12187 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
12189 flatten(reference_string +
"/" + std::to_string(i),
12190 value.m_value.array->operator[](i), result);
12198 if (value.m_value.object->empty())
12201 result[reference_string] =
nullptr;
12206 for (
const auto& element : *value.m_value.object)
12208 flatten(reference_string +
"/" + escape(element.first), element.second, result);
12217 result[reference_string] =
value;
12233 static BasicJsonType
12241 BasicJsonType result;
12244 for (
const auto& element : *value.m_value.object)
12264 return (lhs.reference_tokens == rhs.reference_tokens);
12270 return not (lhs == rhs);
12291 template<
typename,
typename>
12303 template<
typename BasicJsonType,
typename ValueType>
12304 static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
12320 template <
typename BasicJsonType,
typename ValueType>
12321 static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
12426 friend ::nlohmann::json_pointer<basic_json>;
12427 friend ::nlohmann::detail::parser<basic_json>;
12428 friend ::nlohmann::detail::serializer<basic_json>;
12429 template<
typename BasicJsonType>
12430 friend class ::nlohmann::detail::iter_impl;
12431 template<
typename BasicJsonType,
typename CharType>
12432 friend class ::nlohmann::detail::binary_writer;
12433 template<
typename BasicJsonType,
typename SAX>
12434 friend class ::nlohmann::detail::binary_reader;
12435 template<
typename BasicJsonType>
12436 friend class ::nlohmann::detail::json_sax_dom_parser;
12437 template<
typename BasicJsonType>
12438 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
12448 template<
typename BasicJsonType>
12450 template<
typename BasicJsonType>
12452 template<
typename Iterator>
12456 template<
typename CharType>
12468 template<
typename T,
typename SFINAE>
12529 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
12531 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
12583 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
12584 result[
"name"] =
"JSON for Modern C++";
12585 result[
"url"] =
"https://github.com/nlohmann/json";
12586 result[
"version"][
"string"] =
12595 result[
"platform"] =
"win32";
12596 #elif defined __linux__ 12597 result[
"platform"] =
"linux";
12598 #elif defined __APPLE__ 12599 result[
"platform"] =
"apple";
12600 #elif defined __unix__ 12601 result[
"platform"] =
"unix";
12603 result[
"platform"] =
"unknown";
12606 #if defined(__ICC) || defined(__INTEL_COMPILER) 12607 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
12608 #elif defined(__clang__) 12609 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
12610 #elif defined(__GNUC__) || defined(__GNUG__) 12611 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(__GNUC_PATCHLEVEL__)}};
12612 #elif defined(__HP_cc) || defined(__HP_aCC) 12613 result[
"compiler"] =
"hp" 12614 #elif defined(__IBMCPP__) 12615 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
12616 #elif defined(_MSC_VER) 12617 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
12618 #elif defined(__PGI) 12619 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
12620 #elif defined(__SUNPRO_CC) 12621 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
12623 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
12627 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
12629 result[
"compiler"][
"c++"] =
"unknown";
12644 #if defined(JSON_HAS_CPP_14) 12735 using object_t = ObjectType<StringType,
12738 AllocatorType<std::pair<
const StringType,
12785 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
13082 template<
typename T,
typename... Args>
13085 AllocatorType<T> alloc;
13086 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
13088 auto deleter = [&](T *
object)
13090 AllocatorTraits::deallocate(alloc,
object, 1);
13092 std::unique_ptr<T, decltype(deleter)>
object(AllocatorTraits::allocate(alloc, 1), deleter);
13093 AllocatorTraits::construct(alloc,
object.
get(), std::forward<Args>(
args)...);
13094 assert(
object !=
nullptr);
13095 return object.release();
13160 object = create<object_t>();
13166 array = create<array_t>();
13172 string = create<string_t>(
"");
13221 string = create<string_t>(
value);
13227 string = create<string_t>(std::move(
value));
13233 object = create<object_t>(
value);
13239 object = create<object_t>(std::move(
value));
13245 array = create<array_t>(
value);
13251 array = create<array_t>(std::move(
value));
13260 AllocatorType<object_t> alloc;
13261 std::allocator_traits<decltype(alloc)>::destroy(alloc,
object);
13262 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
object, 1);
13268 AllocatorType<array_t> alloc;
13269 std::allocator_traits<decltype(alloc)>::destroy(alloc,
array);
13270 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
array, 1);
13276 AllocatorType<string_t> alloc;
13277 std::allocator_traits<decltype(alloc)>::destroy(alloc,
string);
13278 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
string, 1);
13418 : m_type(v), m_value(v)
13420 assert_invariant();
13444 assert_invariant();
13504 template <
typename CompatibleType,
13510 std::forward<CompatibleType>(val))))
13513 assert_invariant();
13542 template <
typename BasicJsonType,
13547 using other_boolean_t =
typename BasicJsonType::boolean_t;
13548 using other_number_float_t =
typename BasicJsonType::number_float_t;
13549 using other_number_integer_t =
typename BasicJsonType::number_integer_t;
13550 using other_number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
13551 using other_string_t =
typename BasicJsonType::string_t;
13552 using other_object_t =
typename BasicJsonType::object_t;
13553 using other_array_t =
typename BasicJsonType::array_t;
13555 switch (val.type())
13585 assert_invariant();
13663 bool type_deduction =
true,
13668 bool is_an_object = std::all_of(init.begin(), init.end(),
13671 return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
13675 if (not type_deduction)
13680 is_an_object =
false;
13698 auto element = element_ref.moved_or_copied();
13699 m_value.object->emplace(
13700 std::move(*((*element.m_value.array)[0].m_value.string)),
13701 std::move((*element.m_value.array)[1]));
13708 m_value.array = create<array_t>(init.begin(), init.end());
13711 assert_invariant();
13824 m_value.array = create<array_t>(cnt, val);
13825 assert_invariant();
13883 template<
class InputIT,
typename std::enable_if<
13888 assert(first.m_object !=
nullptr);
13889 assert(last.m_object !=
nullptr);
13898 m_type = first.m_object->m_type;
13909 if (
JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
13910 or not last.m_it.primitive_iterator.is_end()))
13925 m_value.number_integer = first.m_object->m_value.number_integer;
13931 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
13937 m_value.number_float = first.m_object->m_value.number_float;
13943 m_value.boolean = first.m_object->m_value.boolean;
13949 m_value = *first.m_object->m_value.string;
13955 m_value.object = create<object_t>(first.m_it.object_iterator,
13956 last.m_it.object_iterator);
13962 m_value.array = create<array_t>(first.m_it.array_iterator,
13963 last.m_it.array_iterator);
13972 assert_invariant();
13982 : basic_json(ref.moved_or_copied())
14011 : m_type(other.m_type)
14064 assert_invariant();
14094 : m_type(
std::move(other.m_type)),
14095 m_value(
std::move(other.m_value))
14098 other.assert_invariant();
14102 other.m_value = {};
14104 assert_invariant();
14141 swap(m_type, other.m_type);
14142 swap(m_value, other.m_value);
14144 assert_invariant();
14165 assert_invariant();
14166 m_value.destroy(m_type);
14222 const char indent_char =
' ',
14223 const bool ensure_ascii =
false,
14231 s.
dump(*
this,
true, ensure_ascii, static_cast<unsigned int>(indent));
14235 s.
dump(*
this,
false, ensure_ascii, 0);
14305 return is_null() or is_string() or is_boolean() or is_number();
14332 return is_array() or is_object();
14406 return is_number_integer() or is_number_float();
14625 return m_value.boolean;
14634 return is_object() ? m_value.object :
nullptr;
14640 return is_object() ? m_value.object :
nullptr;
14646 return is_array() ? m_value.array :
nullptr;
14652 return is_array() ? m_value.array :
nullptr;
14658 return is_string() ? m_value.string :
nullptr;
14664 return is_string() ? m_value.string :
nullptr;
14670 return is_boolean() ? &m_value.boolean :
nullptr;
14676 return is_boolean() ? &m_value.boolean :
nullptr;
14682 return is_number_integer() ? &m_value.number_integer :
nullptr;
14688 return is_number_integer() ? &m_value.number_integer :
nullptr;
14694 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
14700 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
14706 return is_number_float() ? &m_value.number_float :
nullptr;
14712 return is_number_float() ? &m_value.number_float :
nullptr;
14726 template<
typename ReferenceType,
typename ThisType>
14730 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
14762 basic_json
get()
const 14785 BasicJsonType
get()
const 14829 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
14830 detail::enable_if_t <
14831 not detail::is_basic_json<ValueType>::value and
14832 detail::has_from_json<basic_json_t, ValueType>::value and
14833 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
14835 ValueType
get()
const noexcept(noexcept(
14842 "get() cannot be used with reference types, you might want to use get_ref()");
14844 "types must be DefaultConstructible when used with get()");
14882 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
14883 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
14884 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
14886 ValueType
get()
const noexcept(noexcept(
14890 "get() cannot be used with reference types, you might want to use get_ref()");
14927 template<
typename ValueType,
14932 ValueType &
get_to(ValueType& v)
const noexcept(noexcept(
14966 template<
typename PointerType,
typename std::enable_if<
14971 return get_impl_ptr(static_cast<PointerType>(
nullptr));
14978 template<
typename PointerType,
typename std::enable_if<
14979 std::is_pointer<PointerType>::value and
14980 std::is_const<typename std::remove_pointer<PointerType>::type>
::value,
int>::type = 0>
14984 return get_impl_ptr(static_cast<PointerType>(
nullptr));
15014 template<
typename PointerType,
typename std::enable_if<
15015 std::is_pointer<PointerType>::value,
int>::type = 0>
15016 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
15019 return get_ptr<PointerType>();
15026 template<
typename PointerType,
typename std::enable_if<
15027 std::is_pointer<PointerType>::value,
int>::type = 0>
15028 constexpr
auto get()
const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
15031 return get_ptr<PointerType>();
15060 template<
typename ReferenceType,
typename std::enable_if<
15065 return get_ref_impl<ReferenceType>(*this);
15072 template<
typename ReferenceType,
typename std::enable_if<
15073 std::is_reference<ReferenceType>::value and
15074 std::is_const<typename std::remove_reference<ReferenceType>::type>
::value,
int>::type = 0>
15078 return get_ref_impl<ReferenceType>(*this);
15110 template <
typename ValueType,
typename std::enable_if <
15112 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
15116 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015 15117 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
15118 #if defined(JSON_HAS_CPP_17) && defined(_MSC_VER) and _MSC_VER <= 1914 15123 ,
int >::type = 0 >
15124 operator ValueType()
const 15127 return get<ValueType>();
15174 return m_value.array->at(idx);
15221 return m_value.array->at(idx);
15272 return m_value.object->at(key);
15323 return m_value.object->at(key);
15368 m_value.array = create<array_t>();
15369 assert_invariant();
15376 if (idx >= m_value.array->size())
15378 m_value.array->insert(m_value.array->end(),
15379 idx - m_value.array->size() + 1,
15383 return m_value.array->operator[](idx);
15413 return m_value.
array->operator[](idx);
15452 m_value.object = create<object_t>();
15453 assert_invariant();
15459 return m_value.object->operator[](key);
15500 assert(m_value.object->find(key) != m_value.object->end());
15534 template<
typename T>
15542 assert_invariant();
15548 return m_value.object->operator[](key);
15584 template<
typename T>
15590 assert(m_value.object->find(key) != m_value.object->end());
15645 template<
class ValueType,
typename std::enable_if<
15647 ValueType
value(
const typename object_t::key_type& key,
const ValueType& default_value)
const 15653 const auto it = find(key);
15659 return default_value;
15669 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 15715 template<
class ValueType,
typename std::enable_if<
15716 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
15729 return default_value;
15877 template<
class IteratorType,
typename std::enable_if<
15889 IteratorType result =
end();
15899 if (
JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
15906 AllocatorType<string_t> alloc;
15907 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
15908 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
15909 m_value.string =
nullptr;
15913 assert_invariant();
15919 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
15925 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
15982 template<
class IteratorType,
typename std::enable_if<
15984 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>::type
15986 IteratorType
erase(IteratorType first, IteratorType last)
15989 if (
JSON_UNLIKELY(
this != first.m_object or
this != last.m_object))
15994 IteratorType result =
end();
16004 if (
JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
16005 or not last.m_it.primitive_iterator.is_end()))
16012 AllocatorType<string_t> alloc;
16013 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
16014 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
16015 m_value.string =
nullptr;
16019 assert_invariant();
16025 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
16026 last.m_it.object_iterator);
16032 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
16033 last.m_it.array_iterator);
16078 return m_value.object->erase(key);
16118 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
16158 template<
typename KeyT>
16161 auto result =
end();
16165 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
16175 template<
typename KeyT>
16178 auto result = cend();
16182 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
16209 template<
typename KeyT>
16213 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
16560 return ref.items();
16569 return ref.items();
16701 return m_value.array->empty();
16707 return m_value.object->empty();
16773 return m_value.array->size();
16779 return m_value.object->size();
16837 return m_value.array->max_size();
16843 return m_value.object->max_size();
16906 m_value.number_integer = 0;
16912 m_value.number_unsigned = 0;
16918 m_value.number_float = 0.0;
16924 m_value.boolean =
false;
16930 m_value.string->clear();
16936 m_value.array->clear();
16942 m_value.object->clear();
16984 assert_invariant();
16988 m_value.array->push_back(std::move(val));
16999 push_back(std::move(val));
17020 assert_invariant();
17024 m_value.array->push_back(val);
17070 assert_invariant();
17074 m_value.object->insert(val);
17114 if (is_object() and init.size() == 2 and (*init.begin())->is_string())
17116 basic_json&& key = init.begin()->moved_or_copied();
17117 push_back(
typename object_t::value_type(
17118 std::move(key.
get_ref<
string_t&>()), (init.begin() + 1)->moved_or_copied()));
17122 push_back(basic_json(init));
17157 template<
class... Args>
17171 assert_invariant();
17175 m_value.array->emplace_back(std::forward<Args>(
args)...);
17205 template<
class... Args>
17219 assert_invariant();
17223 auto res = m_value.object->emplace(std::forward<Args>(
args)...);
17226 it.m_it.object_iterator = res.first;
17229 return {it, res.second};
17235 template<
typename... Args>
17239 assert(m_value.array !=
nullptr);
17286 return insert_iterator(pos, val);
17298 return insert(pos, val);
17337 return insert_iterator(pos, cnt, val);
17441 return insert_iterator(pos, ilist.begin(), ilist.end());
17515 m_value.object = create<object_t>();
17516 assert_invariant();
17528 for (
auto it = j.
cbegin(); it != j.
cend(); ++it)
17530 m_value.object->operator[](it.key()) = it.value();
17566 m_value.object = create<object_t>();
17567 assert_invariant();
17583 or not last.
m_object->is_object()))
17588 for (
auto it = first; it != last; ++it)
17590 m_value.object->operator[](it.key()) = it.value();
17618 std::swap(m_type, other.m_type);
17619 std::swap(m_value, other.m_value);
17620 assert_invariant();
17648 std::swap(*(m_value.array), other);
17681 std::swap(*(m_value.object), other);
17714 std::swap(*(m_value.string), other);
17773 const auto lhs_type = lhs.type();
17774 const auto rhs_type = rhs.type();
17776 if (lhs_type == rhs_type)
17781 return (*lhs.m_value.array == *rhs.m_value.array);
17784 return (*lhs.m_value.object == *rhs.m_value.object);
17790 return (*lhs.m_value.string == *rhs.m_value.string);
17793 return (lhs.m_value.boolean == rhs.m_value.boolean);
17796 return (lhs.m_value.number_integer == rhs.m_value.number_integer);
17799 return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
17802 return (lhs.m_value.number_float == rhs.m_value.number_float);
17810 return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
17814 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
17818 return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
17822 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
17826 return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
17830 return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
17840 template<
typename ScalarType,
typename std::enable_if<
17844 return (lhs == basic_json(rhs));
17851 template<
typename ScalarType,
typename std::enable_if<
17852 std::is_scalar<ScalarType>::value,
int>::type = 0>
17855 return (basic_json(lhs) == rhs);
17878 return not (lhs == rhs);
17885 template<
typename ScalarType,
typename std::enable_if<
17886 std::is_scalar<ScalarType>::value,
int>::type = 0>
17889 return (lhs != basic_json(rhs));
17896 template<
typename ScalarType,
typename std::enable_if<
17897 std::is_scalar<ScalarType>::value,
int>::type = 0>
17900 return (basic_json(lhs) != rhs);
17931 const auto lhs_type = lhs.type();
17932 const auto rhs_type = rhs.type();
17934 if (lhs_type == rhs_type)
17939 return (*lhs.m_value.array) < (*rhs.m_value.array);
17942 return *lhs.m_value.object < *rhs.m_value.object;
17948 return *lhs.m_value.string < *rhs.m_value.string;
17951 return lhs.m_value.boolean < rhs.m_value.boolean;
17954 return lhs.m_value.number_integer < rhs.m_value.number_integer;
17957 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
17960 return lhs.m_value.number_float < rhs.m_value.number_float;
17968 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
17972 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
17976 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
17980 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
17984 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
17988 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
18001 template<
typename ScalarType,
typename std::enable_if<
18002 std::is_scalar<ScalarType>::value,
int>::type = 0>
18005 return (lhs < basic_json(rhs));
18012 template<
typename ScalarType,
typename std::enable_if<
18013 std::is_scalar<ScalarType>::value,
int>::type = 0>
18016 return (basic_json(lhs) < rhs);
18040 return not (rhs < lhs);
18047 template<
typename ScalarType,
typename std::enable_if<
18048 std::is_scalar<ScalarType>::value,
int>::type = 0>
18051 return (lhs <= basic_json(rhs));
18058 template<
typename ScalarType,
typename std::enable_if<
18059 std::is_scalar<ScalarType>::value,
int>::type = 0>
18062 return (basic_json(lhs) <= rhs);
18086 return not (lhs <= rhs);
18093 template<
typename ScalarType,
typename std::enable_if<
18094 std::is_scalar<ScalarType>::value,
int>::type = 0>
18097 return (lhs > basic_json(rhs));
18104 template<
typename ScalarType,
typename std::enable_if<
18105 std::is_scalar<ScalarType>::value,
int>::type = 0>
18108 return (basic_json(lhs) > rhs);
18132 return not (lhs < rhs);
18139 template<
typename ScalarType,
typename std::enable_if<
18140 std::is_scalar<ScalarType>::value,
int>::type = 0>
18143 return (lhs >= basic_json(rhs));
18150 template<
typename ScalarType,
typename std::enable_if<
18151 std::is_scalar<ScalarType>::value,
int>::type = 0>
18154 return (basic_json(lhs) >= rhs);
18197 friend std::ostream&
operator<<(std::ostream& o,
const basic_json& j)
18200 const bool pretty_print = (o.width() > 0);
18201 const auto indentation = (pretty_print ? o.width() : 0);
18208 s.
dump(j, pretty_print,
false, static_cast<unsigned int>(indentation));
18221 friend std::ostream&
operator>>(
const basic_json& j, std::ostream& o)
18302 const bool allow_exceptions =
true)
18305 parser(i, cb, allow_exceptions).
parse(
true, result);
18370 template <
typename SAX>
18373 const bool strict =
true)
18432 template<
class IteratorType,
typename std::enable_if<
18434 std::random_access_iterator_tag,
18435 typename std::iterator_traits<IteratorType>::iterator_category>
::value,
int>::type = 0>
18436 static basic_json
parse(IteratorType first, IteratorType last,
18438 const bool allow_exceptions =
true)
18445 template<
class IteratorType,
typename std::enable_if<
18447 std::random_access_iterator_tag,
18448 typename std::iterator_traits<IteratorType>::iterator_category>
::value,
int>::type = 0>
18449 static bool accept(IteratorType first, IteratorType last)
18454 template<
class IteratorType,
class SAX,
typename std::enable_if<
18456 std::random_access_iterator_tag,
18457 typename std::iterator_traits<IteratorType>::iterator_category>
::value,
int>::type = 0>
18458 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
18474 return operator>>(i, j);
18560 return "discarded";
18675 static std::vector<uint8_t>
to_cbor(
const basic_json& j)
18677 std::vector<uint8_t> result;
18678 to_cbor(j, result);
18773 std::vector<uint8_t> result;
18774 to_msgpack(j, result);
18869 const bool use_size =
false,
18870 const bool use_type =
false)
18872 std::vector<uint8_t> result;
18873 to_ubjson(j, result, use_size, use_type);
18878 const bool use_size =
false,
const bool use_type =
false)
18884 const bool use_size =
false,
const bool use_type =
false)
18945 static std::vector<uint8_t>
to_bson(
const basic_json& j)
18947 std::vector<uint8_t> result;
18948 to_bson(j, result);
19072 const bool strict =
true,
19073 const bool allow_exceptions =
true)
19084 template<
typename A1,
typename A2,
19087 const bool strict =
true,
19088 const bool allow_exceptions =
true)
19177 const bool strict =
true,
19178 const bool allow_exceptions =
true)
19189 template<
typename A1,
typename A2,
19190 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
19192 const bool strict =
true,
19193 const bool allow_exceptions =
true)
19261 const bool strict =
true,
19262 const bool allow_exceptions =
true)
19273 template<
typename A1,
typename A2,
19274 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
19276 const bool strict =
true,
19277 const bool allow_exceptions =
true)
19344 const bool strict =
true,
19345 const bool allow_exceptions =
true)
19356 template<
typename A1,
typename A2,
19357 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
19359 const bool strict =
true,
19360 const bool allow_exceptions =
true)
19651 basic_json
patch(
const basic_json& json_patch)
const 19654 basic_json result = *
this;
19657 enum class patch_operations {add,
remove,
replace, move, copy, test, invalid};
19663 return patch_operations::add;
19665 if (op ==
"remove")
19667 return patch_operations::remove;
19669 if (op ==
"replace")
19675 return patch_operations::move;
19679 return patch_operations::copy;
19683 return patch_operations::test;
19686 return patch_operations::invalid;
19690 const auto operation_add = [&result](
json_pointer & ptr, basic_json val)
19701 if (top_pointer != ptr)
19703 result.
at(top_pointer);
19707 const auto last_path = ptr.
pop_back();
19708 basic_json& parent = result[ptr];
19716 parent[last_path] = val;
19722 if (last_path ==
"-")
19754 const auto operation_remove = [&result](
json_pointer & ptr)
19757 const auto last_path = ptr.
pop_back();
19758 basic_json& parent = result.
at(ptr);
19764 auto it = parent.
find(last_path);
19788 for (
const auto& val : json_patch)
19791 const auto get_value = [&val](
const std::string & op,
19793 bool string_type) -> basic_json &
19796 auto it = val.m_value.object->find(member);
19799 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
19808 if (
JSON_UNLIKELY(string_type and not it->second.is_string()))
19824 const std::string op = get_value(
"op",
"op",
true);
19828 switch (get_op(op))
19830 case patch_operations::add:
19832 operation_add(ptr, get_value(
"add",
"value",
false));
19836 case patch_operations::remove:
19838 operation_remove(ptr);
19845 result.
at(ptr) = get_value(
"replace",
"value",
false);
19849 case patch_operations::move:
19851 const std::string from_path = get_value(
"move",
"from",
true);
19855 basic_json v = result.
at(from_ptr);
19861 operation_remove(from_ptr);
19862 operation_add(ptr, v);
19866 case patch_operations::copy:
19868 const std::string from_path = get_value(
"copy",
"from",
true);
19872 basic_json v = result.
at(from_ptr);
19877 operation_add(ptr, v);
19881 case patch_operations::test:
19883 bool success =
false;
19888 success = (result.
at(ptr) == get_value(
"test",
"value",
false));
19904 case patch_operations::invalid:
19949 static basic_json
diff(
const basic_json& source,
const basic_json& target,
19956 if (source == target)
19961 if (source.
type() != target.
type())
19966 {
"op",
"replace"}, {
"path",
path}, {
"value", target}
19971 switch (source.
type())
19977 while (i < source.
size() and i < target.
size())
19980 auto temp_diff = diff(source[i], target[i],
path +
"/" + std::to_string(i));
19981 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
19990 while (i < source.
size())
19997 {
"path",
path +
"/" + std::to_string(i)}
20003 while (i < target.
size())
20008 {
"path",
path +
"/" + std::to_string(i)},
20009 {
"value", target[i]}
20020 for (
auto it = source.
cbegin(); it != source.
cend(); ++it)
20025 if (target.
find(it.key()) != target.
end())
20028 auto temp_diff = diff(it.value(), target[it.key()],
path +
"/" + key);
20029 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
20036 {
"op",
"remove"}, {
"path",
path +
"/" + key}
20042 for (
auto it = target.
cbegin(); it != target.
cend(); ++it)
20044 if (source.
find(it.key()) == source.
end())
20050 {
"op",
"add"}, {
"path",
path +
"/" + key},
20051 {
"value", it.value()}
20064 {
"op",
"replace"}, {
"path",
path}, {
"value", target}
20129 if (not is_object())
20133 for (
auto it = patch.
begin(); it != patch.
end(); ++it)
20135 if (it.value().is_null())
20141 operator[](it.key()).merge_patch(it.value());
20175 const auto&
h = hash<nlohmann::json::string_t>();
20176 return h(j.
dump());
20253 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 20254 #pragma GCC diagnostic pop 20256 #if defined(__clang__) 20257 #pragma GCC diagnostic pop 20261 #undef JSON_INTERNAL_CATCH 20266 #undef JSON_UNLIKELY 20267 #undef JSON_DEPRECATED 20268 #undef JSON_HAS_CPP_14 20269 #undef JSON_HAS_CPP_17 20270 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION 20271 #undef NLOHMANN_BASIC_JSON_TPL json_value(string_t &&value)
constructor for rvalue strings
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix)
static constexpr CharType get_ubjson_float_prefix(float)
object_t * object
object (stored with pointer to save storage)
reference operator+=(const basic_json &val)
add an object to an array
value_type const & operator*() const
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
json_value(array_t &&value)
constructor for rvalue arrays
bool parse_error(std::size_t, const std::string &, const detail::exception &)
const_iterator find(KeyT &&key) const
find an element in a JSON object
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
reference value() const
return the value of an iterator
void update(const_iterator first, const_iterator last)
updates a JSON object from another object, overwriting existing keys
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
typename parser::parser_callback_t parser_callback_t
per-element parser callback type
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
iter_impl operator-(difference_type i) const
subtract from iterator
token_type
token types for the parser
typename T::pointer pointer_t
const int id
the id of the exception
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
parse_error(int id_, std::size_t byte_, const char *what_arg)
static void construct(BasicJsonType &j, const CompatibleStringType &str)
std::shared_ptr< input_adapter_protocol > input_adapter_t
a type to simplify interfaces
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
static constexpr CharType get_cbor_float_prefix(float)
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
size_type max_size() const noexcept
returns the maximum possible number of elements
static basic_json from_ubjson(detail::input_adapter &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
bool get_bson_string(const NumberType len, string_t &result)
Parses a zero-terminated string of length len from the BSON input.
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
error_handler_t
how to treat decoding errors
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
std::initializer_list< detail::json_ref< basic_json >> initializer_list_t
helper type for initializer lists of basic_json values
typename BasicJsonType::number_float_t number_float_t
static std::size_t calc_bson_string_size(const string_t &value)
basic_json(basic_json &&other) noexcept
move constructor
#define JSON_CATCH(exception)
bool unexpect_eof(const input_format_t format, const char *context) const
NumberFloatType number_float_t
a type for a number (floating-point)
constexpr auto get_ptr() const noexcept-> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
static basic_json from_bson(detail::input_adapter &&i, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
std::vector< BasicJsonType * > ref_stack
stack to model hierarchy of values
typename BasicJsonType::string_t string_t
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
iter_impl & operator+=(difference_type i)
add to iterator
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
value_t
the JSON type enumeration
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
primitive_iterator_t & operator+=(difference_type n) noexcept
iter_impl operator+(difference_type i) const
add to iterator
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
bool skip_bom()
skip the UTF-8 byte order mark
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
iter_impl(pointer object) noexcept
constructor for a given JSON instance
IteratorType erase(IteratorType pos)
remove element given an iterator
json_reverse_iterator const operator--(int)
post-decrement (it–)
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
void write_bson_object(const typename BasicJsonType::object_t &value)
~basic_json() noexcept
destructor
array_t * array
array (stored with pointer to save storage)
basic_json(CompatibleType &&val) noexcept(noexcept(JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value
string_t * string
string (stored with pointer to save storage)
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
static void strtof(long double &f, const char *str, char **endptr) noexcept
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
ReferenceType get_ref() const
get a reference value (implicit)
bool start_array(std::size_t len)
typename BasicJsonType::string_t string_t
std::ptrdiff_t difference_type
static basic_json from_cbor(detail::input_adapter &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in CBOR format
void destroy(value_t t) noexcept
primitive_iterator_t & operator++() noexcept
bool number_integer(number_integer_t val)
json_value(const string_t &value)
constructor for strings
typename BasicJsonType::string_t string_t
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
a signed integer – use get_number_integer() for actual value
std::vector< BasicJsonType * > ref_stack
stack to model hierarchy of values
array (ordered collection of values)
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
void write_bson_double(const string_t &name, const double value)
Writes a BSON element with key name and double value value.
std::numeric_limits< RealIntegerType > RealLimits
json_pointer(const std::string &s="")
create JSON pointer
primitive_iterator_t operator+(difference_type n) noexcept
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than or equal
static other_error create(int id_, const std::string &what_arg)
iter_impl & operator++()
pre-increment (++it)
static bool sax_parse(IteratorType first, IteratorType last, SAX *sax)
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
json_value(value_t t)
constructor for empty values of a given type
T const & operator+(T const &value, StreamEndStop)
static constexpr CharType to_char_type(InputCharType x) noexcept
static void replace_substring(std::string &s, const std::string &f, const std::string &t)
replace all occurrences of a substring by another string
NumberIntegerType number_integer_t
a type for a number (integer)
reference operator[](const typename object_t::key_type &key)
access specified object element
a template for a reverse iterator class
bool start_object(std::size_t=std::size_t(-1))
const char indent_char
the indentation character
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
constexpr bool is_primitive() const noexcept
return whether type is primitive
std::runtime_error m
an exception object as storage for error messages
a class to store JSON values
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
constexpr diyfp(uint64_t f_, int e_) noexcept
static void to_msgpack(const basic_json &j, detail::output_adapter< uint8_t > o)
bool operator==(const iteration_proxy_internal &o) const noexcept
equality operator (needed for InputIterator)
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
typename T::iterator iterator_t
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
bool get_ubjson_string(string_t &result, const bool get_char=true)
reads a UBJSON string
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
iterator insert(const_iterator pos, basic_json &&val)
inserts element
bool string(string_t &val)
typename BasicJsonType::number_unsigned_t number_unsigned_t
value_type moved_or_copied() const
typename BasicJsonType::string_t string_t
basic_json(const value_t v)
create an empty value with a given type
default JSONSerializer template argument
std::shared_ptr< output_adapter_protocol< CharType >> output_adapter_t
a type to simplify interfaces
void insert(const_iterator first, const_iterator last)
inserts elements
iter_impl const operator--(int)
post-decrement (it–)
std::ptrdiff_t difference_type
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
typename lexer_t::token_type token_type
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
constexpr bool is_structured() const noexcept
return whether type is structured
static std::string escape(std::string s)
escape "~" to "~0" and "/" to "~1"
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
type_error(int id_, const char *what_arg)
bool parse_error(std::size_t, const std::string &, const detail::exception &ex)
static allocator_type get_allocator()
returns the allocator associated with the container
void write_bson_object_entry(const string_t &name, const typename BasicJsonType::object_t &value)
Writes a BSON element with key name and object value.
StringType string_t
a type for a string
auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
void parse(const bool strict, BasicJsonType &result)
public parser interface
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
bool parse_bson_element_list(const bool is_array)
Read a BSON element list (as specified in the BSON-spec)
iterator end() noexcept
returns an iterator to one past the last element
typename BasicJsonType::template json_serializer< T, void > serializer
bool start_array(std::size_t len)
static std::string position_string(const position_t &pos)
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json >>> object_t
a type for an object
number value (signed integer)
char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
bool string(string_t &val)
typename BasicJsonType::number_integer_t number_integer_t
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
#define JSON_INTERNAL_CATCH(exception)
Target reinterpret_bits(const Source source)
bool operator!=(const iteration_proxy_internal &o) const noexcept
inequality operator (needed for range-based for)
difference_type operator-(const iter_impl &other) const
return difference
void dump_integer(NumberType x)
dump an integer
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value andstd::is_nothrow_move_assignable< value_t >::value andstd::is_nothrow_move_constructible< json_value >::value andstd::is_nothrow_move_assignable< json_value >::value)
exchanges the values
iterator begin() noexcept
returns an iterator to the first element
output_adapter(StringType &s)
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
auto operator()(const BasicJsonType &j, T &val) const noexcept(noexcept(from_json(j, val))) -> decltype(from_json(j, val), void())
json_reverse_iterator & operator+=(difference_type i)
add to iterator
difference_type operator-(const json_reverse_iterator &other) const
return difference
std::ptrdiff_t difference_type
a type to represent differences between iterators
static void unescape(std::string &s)
unescape "~1" to tilde and "~0" to slash (order is important!)
reference operator+=(const typename object_t::value_type &val)
add an object to an object
static constexpr CharType get_ubjson_float_prefix(double)
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
typename BasicJsonType::number_integer_t number_integer_t
friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
BasicJsonType & get_and_create(BasicJsonType &j) const
create and return a reference to the pointed to value
pointer m_object
associated JSON instance
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
iter_impl & operator-=(difference_type i)
subtract from iterator
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
number_unsigned_t number_unsigned
number (unsigned integer)
void set_end() noexcept
set the iterator past the last value
number_float_t number_float
number (floating-point)
bool start_object(std::size_t len)
pointer operator->() const
dereference the iterator
a template for a bidirectional iterator for the basic_json class
ignore invalid UTF-8 sequences
token_type get_token()
get next token from lexer
friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
comparison: equal
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
std::size_t chars_read_current_line
the number of characters read in the current line
::nlohmann::detail::output_adapter_t< CharType > output_adapter_t
bool parse_cbor_internal(const bool get_char=true)
std::bidirectional_iterator_tag iterator_category
constexpr bool is_object() const noexcept
return whether value is an object
output_adapter(std::basic_ostream< CharType > &s)
void write_character(CharType c) override
cached_power get_cached_power_for_binary_exponent(int e)
bool get_msgpack_object(const std::size_t len)
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
static std::vector< std::string > split(const std::string &reference_string)
split the string input to reference tokens
json_reverse_iterator operator+(difference_type i) const
add to iterator
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
void write_bson(const BasicJsonType &j)
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
reference operator[](difference_type n) const
access to successor
void set_end() noexcept
set iterator to a defined past the end
typename BasicJsonType::number_integer_t number_integer_t
int get_codepoint()
get codepoint from 4 hex characters following \u
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
void from_json(const BasicJsonType &j, std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > &m)
friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
void emplace_back(Args &&...args)
add an object to an array
serialization to CBOR and MessagePack values
static iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
output adapter for byte vectors
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
const std::size_t byte
byte index of the parse error
reference operator[](difference_type n) const
access to successor
std::vector< bool > key_keep_stack
stack to manage which object keys to keep
void write_characters(const CharType *s, std::size_t length) override
typename BasicJsonType::number_unsigned_t number_unsigned_t
type for unsigned integers
void unget()
unget current character (read it again on next get)
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than or equal
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
void to_json(BasicJsonType &j, T b) noexcept
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
static void strtof(double &f, const char *str, char **endptr) noexcept
throw a type_error exception in case of invalid UTF-8
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
bool number_float(number_float_t val, const string_t &)
exception indicating access out of the defined range
bool next_byte_in_range(std::initializer_list< int > ranges)
check if the next byte(s) are inside a given range
constexpr bool is_null() const noexcept
return whether value is null
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
typename BasicJsonType::number_unsigned_t number_unsigned_t
std::function< bool(int depth, parse_event_t event, BasicJsonType &parsed)> parser_callback_t
bool get_number(const input_format_t format, NumberType &result)
primitive_iterator_t & operator--() noexcept
JSONSerializer< T, SFINAE > json_serializer
iterator find(KeyT &&key)
find an element in a JSON object
const_reference operator[](size_type idx) const
access specified array element
void set_begin() noexcept
set iterator to a defined beginning
decltype(std::declval< T >().template get< U >()) get_template_function
void write_msgpack(const BasicJsonType &j)
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
reference at(size_type idx)
access specified array element with bounds checking
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
typename BasicJsonType::exception exception_t
primitive_iterator_t const operator++(int) noexcept
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
void add(int c)
add a character to token_buffer
typename T::difference_type difference_type_t
bool sax_parse(SAX *sax, const bool strict=true)
friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than
basic_json(const basic_json &other)
copy constructor
typename BasicJsonType::parser_callback_t parser_callback_t
bool operator>(const iter_impl &other) const
comparison: greater than
constexpr position_t get_position() const noexcept
return position of last read token
void write_bson_string(const string_t &name, const string_t &value)
Writes a BSON element with key name and string value value.
iter_impl const operator++(int)
post-increment (it++)
const_reference back() const
access the last element
decltype(std::declval< T & >().end_object()) end_object_function_t
static iteration_proxy< const_iterator > iterator_wrapper(const_reference ref) noexcept
wrapper to access iterator member functions in range-based for
std::iterator_traits< T > traits
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
const_reference front() const
access the first element
SAX implementation to create a JSON value from SAX events.
typename detector< nonesuch, void, Op, Args... >::type detected_t
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
bool is_root() const noexcept
return whether pointer points to the root document
void clear() noexcept
clears the contents
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
static T * create(Args &&...args)
helper for exception-safe object creation
reference operator+=(initializer_list_t init)
add an object to an object
typename BasicJsonType::number_unsigned_t number_unsigned_t
constexpr number_integer_t get_number_integer() const noexcept
return integer value
constexpr bool is_number() const noexcept
return whether value is a number
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
static basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
exception indicating a parse error
reference operator[](T *key)
access specified object element
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
#define JSON_THROW(exception)
constexpr number_float_t get_number_float() const noexcept
return floating-point value
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
std::input_iterator_tag iterator_category
const char * what() const noexceptoverride
returns the explanatory string
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
decltype(std::declval< T & >().parse_error(std::declval< std::size_t >(), std::declval< const std::string & >(), std::declval< const Exception & >())) parse_error_function_t
basic_json unflatten() const
unflatten a previously flattened JSON value
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
json_reverse_iterator const operator++(int)
post-increment (it++)
bool number_unsigned(number_unsigned_t val)
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
decltype(std::declval< T & >().end_array()) end_array_function_t
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
std::vector< CharType > & v
bool parse_ubjson_internal(const bool get_char=true)
typename Base::reference reference
the reference type for the pointed-to element
Grid< NDIM, T > operator*(Grid< NDIM, T > lhs, const Grid< NDIM, T > &rhs)
an unsigned integer – use get_number_unsigned() for actual value
void reset() noexcept
reset token_buffer; current character is beginning of token
primitive_iterator_t primitive_iterator
generic iterator for all other types
position_t position
the start position of the current token
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
abstract output adapter interface
static basic_json from_msgpack(detail::input_adapter &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
void write_character(CharType c) override
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
general exception of the basic_json class
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
IteratorType anchor
the iterator
basic_json(const detail::json_ref< basic_json > &ref)
IteratorType::reference container
the container to iterate
size_type size() const noexcept
returns the number of elements
typename BasicJsonType::template json_serializer< T, void > serializer
bool sax_parse_internal(SAX *sax)
static std::vector< uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
boundaries compute_boundaries(FloatType value)
out_of_range(int id_, const char *what_arg)
static basic_json from_cbor(A1 &&a1, A2 &&a2, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in CBOR format
bool get_cbor_object(const std::size_t len)
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
value_type const * operator->() const
void write_bson_null(const string_t &name)
Writes a BSON element with key name and null value.
char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
std::string pop_back()
remove and return last reference pointer
typename BasicJsonType::number_float_t number_float_t
const error_handler_t error_handler
error_handler how to react on decoding errors
reference back()
access the last element
static basic_json from_msgpack(A1 &&a1, A2 &&a2, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
void to_json(BasicJsonType &j, const std::tuple< Args... > &t)
bool parse_bson_array()
Reads an array from the BSON input and passes it to the SAX-parser.
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
comparison: equal
bool number_integer(number_integer_t val)
output_adapter(std::vector< CharType > &vec)
const char * type_name() const noexcept
return the type as string
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
BasicJsonType & get_checked(BasicJsonType *ptr) const
void dump_float(number_float_t x, std::false_type)
const_iterator begin() const noexcept
returns a const iterator to the first element
exception indicating errors with iterators
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
constexpr bool is_boolean() const noexcept
return whether value is a boolean
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
void from_json_tuple_impl(const BasicJsonType &j, Tuple &t, index_sequence< Idx... >)
static std::vector< uint8_t > to_bson(const basic_json &j)
Serializes the given JSON object j to BSON and returns a vector containing the corresponding BSON-rep...
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
namespace for Niels Lohmann
bool number_integer(number_integer_t)
bool number_float(number_float_t val, const string_t &)
json_ref(std::initializer_list< json_ref > init)
bool get_cbor_array(const std::size_t len)
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
constexpr bool is_string() const noexcept
return whether value is a string
bool parse_bson_internal()
Reads in a BSON-object and passes it to the SAX-parser.
constexpr difference_type get_value() const noexcept
an floating point number – use get_number_float() for actual value
typename BasicJsonType::number_integer_t number_integer_t
bool start_object(std::size_t len)
object (unordered set of name/value pairs)
void write_number(const NumberType n)
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
iteration_proxy_internal & operator++()
increment operator (needed for range-based for)
static CCL_BEGIN_DECLS double x[111][8]
void dump_float(number_float_t x, std::true_type)
ReferenceType get_ref()
get a reference value (implicit)
typename BasicJsonType::number_integer_t number_integer_t
static T max(const std::vector< T > &data)
parser(detail::input_adapter_t &&adapter, const parser_callback_t cb=nullptr, const bool allow_exceptions_=true)
a parser reading from an input adapter
typename std::enable_if< B, T >::type enable_if_t
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
#define NLOHMANN_BASIC_JSON_TPL
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
exception indicating executing a member function with a wrong type
value_t m_type
the type of the current element
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
#define NLOHMANN_JSON_VERSION_PATCH
static void flatten(const std::string &reference_string, const BasicJsonType &value, BasicJsonType &result)
void write_bson_entry_header(const string_t &name, const std::uint8_t element_type)
Writes the given element_type and name to the output adapter.
BasicJsonType * handle_value(Value &&v)
static constexpr CharType get_cbor_float_prefix(double)
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
void assert_invariant() const noexcept
checks the class invariants
typename BasicJsonType::number_float_t number_float_t
static void strtof(float &f, const char *str, char **endptr) noexcept
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
typename BasicJsonType::parse_event_t parse_event_t
bool parse_msgpack_internal()
typename BasicJsonType::number_unsigned_t number_unsigned_t
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
static basic_json from_ubjson(A1 &&a1, A2 &&a2, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
static auto from_json(BasicJsonType &&j, ValueType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
basic_json flatten() const
return flattened JSON value
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
typename parser::parse_event_t parse_event_t
parser event types
typename BasicJsonType::number_unsigned_t number_unsigned_t
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
void push_back(const basic_json &val)
add an object to an array
static bool sax_parse(detail::input_adapter &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true)
generate SAX events
iterator insert_iterator(const_iterator pos, Args &&...args)
typename T::value_type value_type_t
output_vector_adapter(std::vector< CharType > &vec) noexcept
void push_back(initializer_list_t init)
add an object to an object
bool get_ubjson_value(const int prefix)
void write_characters(const CharType *s, std::size_t length) override
bool parse_error(std::size_t, const std::string &, const detail::exception &ex)
bool start_array(std::size_t=std::size_t(-1))
Grid< NDIM, T > operator-(Grid< NDIM, T > lhs, const Grid< NDIM, T > &rhs)
static basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr, const bool allow_exceptions=true)
deserialize from an iterator range with contiguous storage
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t &value)
decltype(std::declval< T & >().null()) null_function_t
std::ptrdiff_t difference_type
typename BasicJsonType::number_float_t number_float_t
type for floating-point numbers
void merge_patch(const basic_json &patch)
applies a JSON Merge Patch
void write_bson_array(const string_t &name, const typename BasicJsonType::array_t &value)
Writes a BSON element with key name and array value.
static invalid_iterator create(int id_, const std::string &what_arg)
std::is_same< Expected, detected_t< Op, Args... >> is_detected_exact
ArrayType< basic_json, AllocatorType< basic_json >> array_t
a type for an array
typename BasicJsonType::exception exception_t
static int array_index(const std::string &s)
std::string get_token_string() const
BasicJsonType & root
the parsed JSON value
typename BasicJsonType::string_t string_t
auto operator+=(std::string &lhs, StringRef const &sr) -> std::string &
typename T::key_type key_type_t
constexpr bool is_discarded() const noexcept
return whether value is discarded
output adapter for basic_string
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
bool get_bson_cstr(string_t &result)
Parses a C-style string from the BSON input.
BooleanType boolean_t
a type for a boolean
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
constexpr const char * get_error_message() const noexcept
return syntax error message
typename BasicJsonType::number_float_t number_float_t
bool number_unsigned(number_unsigned_t)
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
bool accept(const bool strict=true)
public accept interface
static BasicJsonType unflatten(const BasicJsonType &value)
char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
output adapter for output streams
reference operator*() const
return a reference to the value pointed to by the iterator
static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t &value)
Calculates the size of the BSON serialization of the given JSON-object j.
#define NLOHMANN_JSON_VERSION_MINOR
reference operator+=(basic_json &&val)
add an object to an array
typename BasicJsonType::object_t object_t
void dump_float(number_float_t x)
dump a floating-point number
bool operator<(const iter_impl &other) const
comparison: smaller
bool get_string(const input_format_t format, const NumberType len, string_t &result)
create a string by reading characters from the input
json_ref(value_type &&value)
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
exception indicating other library errors
typename BasicJsonType::number_integer_t number_integer_t
type for (signed) integers
typename BasicJsonType::number_float_t number_float_t
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
invalid_iterator(int id_, const char *what_arg)
static std::size_t calc_bson_entry_header_size(const string_t &name)
static std::string name(const std::string &ename, int id_)
constexpr bool is_end() const noexcept
return whether the iterator is at end
typename BasicJsonType::string_t string_t
const_iterator cbegin() const noexcept
returns a const iterator to the first element
friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
void swap(array_t &other)
exchanges the values
std::pair< bool, BasicJsonType * > handle_value(Value &&v, const bool skip_callback=false)
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
auto range(T const &first, T const &last) -> Generator< T >
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
deserialization of CBOR, MessagePack, and UBJSON values
const std::string & key() const
return key of the iterator
static void to_bson(const basic_json &j, detail::output_adapter< uint8_t > o)
Serializes the given JSON object j to BSON and forwards the corresponding BSON-representation to the ...
const BasicJsonType & get_checked(const BasicJsonType *ptr) const
bool get_ubjson_size_value(std::size_t &result)
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
Serializes the given JSON object j to BSON and forwards the corresponding BSON-representation to the ...
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
static uint8_t decode(uint8_t &state, uint32_t &codep, const uint8_t byte) noexcept
check whether a string is UTF-8 encoded
std::size_t lines_read
the number of lines read
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
T min(const std::vector< T > &data)
typename BasicJsonType::number_float_t number_float_t
static std::size_t calc_bson_integer_size(const std::int64_t value)
bool get_msgpack_string(string_t &result)
reads a MessagePack string
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
constexpr bool is_errored() const
std::basic_ostream< CharType > & stream
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
typename BasicJsonType::object_t object_t
static constexpr CharType get_msgpack_float_prefix(float)
static void to_ubjson(const basic_json &j, detail::output_adapter< uint8_t > o, const bool use_size=false, const bool use_type=false)
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
iteration_proxy_internal begin() noexcept
return iterator begin (needed for range-based for)
static constexpr std::size_t size() noexcept
json_value(object_t &&value)
constructor for rvalue objects
void write_character(CharType c) override
void write_bson_integer(const string_t &name, const std::int64_t value)
Writes a BSON element with key name and integer value.
number_integer_t number_integer
number (integer)
static auto to_json(BasicJsonType &j, ValueType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< ValueType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< ValueType >(val)), void())
convert any value type to a JSON value
decltype(T::from_json(std::declval< Args >()...)) from_json_function
std::string to_string() const
return a string representation of the JSON pointer
static CharType to_char_type(std::uint8_t x) noexcept
void swap(string_t &other)
exchanges the values
std::vector< bool > keep_stack
stack to manage which values to keep
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
typename BasicJsonType::number_unsigned_t number_unsigned_t
static std::size_t calc_bson_element_size(const string_t &name, const BasicJsonType &j)
Calculates the size necessary to serialize the JSON value j with its name.
exception(int id_, const char *what_arg)
json_value(const array_t &value)
constructor for arrays
std::string exception_message(const input_format_t format, const std::string &detail, const std::string &context) const
void write_bson_boolean(const string_t &name, const bool value)
Writes a BSON element with key name and boolean value value.
IteratorType::reference value() const
return value of the iterator
string_t value(const json_pointer &ptr, const char *default_value) const
overload for a default value of type const char*
iter_impl & operator--()
pre-decrement (–it)
replace invalid UTF-8 sequences with U+FFFD
iterator insert(const_iterator pos, const basic_json &val)
inserts element
constexpr bool is_array() const noexcept
return whether value is an array
typename make_void< Ts... >::type void_t
binary_reader(input_adapter_t adapter)
create a binary reader
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
const_iterator end() const noexcept
returns a const iterator to one past the last element
std::less< StringType > object_comparator_t
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
typename BasicJsonType::string_t string_t
static constexpr CharType to_char_type(std::uint8_t x) noexcept
iteration_proxy_internal & operator*()
dereference operator (needed for range-based for)
typename BasicJsonType::string_t string_t
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
input_format_t
the supported input formats
typename BasicJsonType::number_integer_t number_integer_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
static out_of_range create(int id_, const std::string &what_arg)
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements
typename BasicJsonType::number_unsigned_t number_unsigned_t
static const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
typename BasicJsonType::string_t string_t
json_value(boolean_t v) noexcept
constructor for booleans
void dump_escaped(const string_t &s, const bool ensure_ascii)
dump escaped string
static basic_json from_bson(A1 &&a1, A2 &&a2, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
token_type scan_literal(const char *literal_text, const std::size_t length, token_type return_type)
static bool accept(detail::input_adapter &&i)
primitive_iterator_t const operator--(int) noexcept
typename detected_or< Default, Op, Args... >::type detected_or_t
reference operator[](size_type idx)
access specified array element
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
BasicJsonType & root
the parsed JSON value
const_reference at(size_type idx) const
access specified array element with bounds checking
void push_back(basic_json &&val)
add an object to an array
constexpr bool is_errored() const
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than
reference front()
access the first element
string_t dump(const int indent=-1, const char indent_char= ' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
token_type scan_number()
scan a number literal
bool get_ubjson_size_type(std::pair< std::size_t, int > &result)
determine the type and size for a container
struct to capture the start position of the current token
bool operator<=(const iter_impl &other) const
comparison: less than or equal
number value (unsigned integer)
std::size_t size_type
a type to represent container sizes
typename BasicJsonType::array_t array_t
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
CharType ubjson_prefix(const BasicJsonType &j) const noexcept
determine the type prefix of container values
static constexpr bool little_endianess(int num=1) noexcept
determine system byte order
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
typename BasicJsonType::template json_serializer< T, void > serializer
static bool accept(IteratorType first, IteratorType last)
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value andstd::is_nothrow_move_assignable< value_t >::value andstd::is_nothrow_move_constructible< json_value >::value andstd::is_nothrow_move_assignable< json_value >::value)
copy assignment
const BasicJsonType & get_unchecked(const BasicJsonType *ptr) const
return a const reference to the pointed to value
friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
comparison: not equal
static basic_json parse(detail::input_adapter &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true)
deserialize from a compatible input
typename T::iterator_category iterator_category_t
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
typename BasicJsonType::number_integer_t number_integer_t
const object_t::key_type & key() const
return the key of an object iterator
auto value(T const &val) -> Generator< T >
bool operator!=(const iter_impl &other) const
comparison: not equal
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
void swap(object_t &other)
exchanges the values
json_value(const object_t &value)
constructor for objects
decltype(T::to_json(std::declval< Args >()...)) to_json_function
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
typename BasicJsonType::number_integer_t number_integer_t
static char get_decimal_point() noexcept
return the locale-dependent decimal point
void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value)
typename T::reference reference_t
const_iterator cend() const noexcept
returns a const iterator to one past the last element
proxy class for the items() function
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
json_reverse_iterator & operator--()
pre-decrement (–it)
reference value() const
return the value of an iterator
bool operator==(const iter_impl &other) const
comparison: equal
bool number_unsigned(number_unsigned_t val)
typename BasicJsonType::number_float_t number_float_t
void push_back(const typename object_t::value_type &val)
add an object to an object
void write_bson_unsigned(const string_t &name, const std::uint64_t value)
Writes a BSON element with key name and unsigned value.
void write_characters(const CharType *s, std::size_t length) override
string_t indent_string
the indentation string
other_error(int id_, const char *what_arg)
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
lexer(detail::input_adapter_t &&adapter)
iteration_proxy_internal(IteratorType it) noexcept
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
static basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
number value (floating-point)
void erase(const size_type idx)
remove element from a JSON array given an index
token_type scan_string()
scan a string literal
typename BasicJsonType::number_unsigned_t number_unsigned_t
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
iteration_proxy_internal end() noexcept
return iterator end (needed for range-based for)
typename BasicJsonType::number_integer_t number_integer_t
std::vector< std::string > reference_tokens
the reference tokens
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
bool get_cbor_string(string_t &result)
reads a CBOR string
void write_cbor(const BasicJsonType &j)
typename BasicJsonType::number_float_t number_float_t
typename BasicJsonType::string_t string_t
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg)
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
std::pair< iterator, bool > emplace(Args &&...args)
add an object to an object if key does not exist
std::size_t chars_read_total
the total number of characters read
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
typename BasicJsonType::object_t object_t
static double w[2][28][111]
static type_error create(int id_, const std::string &what_arg)
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
bool parse_bson_element_internal(const int element_type, const std::size_t element_type_parse_position)
Read a BSON document element of the given element_type.
std::string exception_message(const token_type expected, const std::string &context)
void grisu2_round(char *buf, int len, uint64_t dist, uint64_t delta, uint64_t rest, uint64_t ten_k)
std::numeric_limits< CompatibleNumberIntegerType > CompatibleLimits
std::string get_token_string() const
AllocatorType< basic_json > allocator_type
the allocator type
json_ref(const value_type &value)
void write_bson_element(const string_t &name, const BasicJsonType &j)
Serializes the JSON value j to BSON and associates it with the key name.
helper class for iteration
json_reverse_iterator & operator++()
pre-increment (++it)
bool get_msgpack_array(const std::size_t len)
output_string_adapter(StringType &s) noexcept
static parse_error create(int id_, const position_t &pos, const std::string &what_arg)
create a parse error exception
primitive_iterator_t & operator-=(difference_type n) noexcept
auto get_ptr() noexcept-> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
static void to_cbor(const basic_json &j, detail::output_adapter< uint8_t > o)
int find_largest_pow10(const uint32_t n, uint32_t &pow10)
static constexpr CharType get_msgpack_float_prefix(double)
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true)
json_value m_value
the value of the current element
typename BasicJsonType::number_float_t number_float_t
const_reference operator[](T *key) const
read-only access specified object element
typename BasicJsonType::string_t string_t
type for strings
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
discarded by the the parser callback function
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
#define NLOHMANN_JSON_VERSION_MAJOR
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
bool empty() const noexcept
checks whether the container is empty.
typename T::mapped_type mapped_type_t
void set_begin() noexcept
set the iterator to the first value
bool number_float(number_float_t, const string_t &)
static basic_json meta()
returns version information on the library
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)