30#ifndef INCLUDE_NLOHMANN_JSON_HPP_
31#define INCLUDE_NLOHMANN_JSON_HPP_
33#define NLOHMANN_JSON_VERSION_MAJOR 3
34#define NLOHMANN_JSON_VERSION_MINOR 6
35#define NLOHMANN_JSON_VERSION_PATCH 1
42#include <initializer_list>
62#include <forward_list>
68#include <unordered_map>
99 constexpr operator size_t()
const
149 const char*
what() const noexcept
override
160 static std::string
name(
const std::string& ename,
int id_)
162 return "[json.exception." + ename +
"." + std::to_string(id_) +
"] ";
167 std::runtime_error
m;
236 (byte_ != 0 ? (
" at byte " + std::to_string(byte_)) :
"") +
258 return " at line " + std::to_string(
pos.lines_read + 1) +
259 ", column " + std::to_string(
pos.chars_read_current_line);
460#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
461#if defined(__clang__)
462#if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
463 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
465#elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
466#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
467#error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
473#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
474#pragma GCC diagnostic push
475#pragma GCC diagnostic ignored "-Wfloat-equal"
479#if defined(__clang__)
480#pragma GCC diagnostic push
481 #pragma GCC diagnostic ignored "-Wdocumentation"
485#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
486#define JSON_DEPRECATED __attribute__((deprecated))
487#elif defined(_MSC_VER)
488#define JSON_DEPRECATED __declspec(deprecated)
490 #define JSON_DEPRECATED
494#if defined(__has_cpp_attribute)
495#if __has_cpp_attribute(nodiscard)
496 #define JSON_NODISCARD [[nodiscard]]
497 #elif __has_cpp_attribute(gnu::warn_unused_result)
498 #define JSON_NODISCARD [[gnu::warn_unused_result]]
500 #define JSON_NODISCARD
503#define JSON_NODISCARD
507#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
508#define JSON_THROW(exception) throw exception
510#define JSON_CATCH(exception) catch(exception)
511#define JSON_INTERNAL_CATCH(exception) catch(exception)
514 #define JSON_THROW(exception) std::abort()
515 #define JSON_TRY if(true)
516 #define JSON_CATCH(exception) if(false)
517 #define JSON_INTERNAL_CATCH(exception) if(false)
521#if defined(JSON_THROW_USER)
523 #define JSON_THROW JSON_THROW_USER
525#if defined(JSON_TRY_USER)
527 #define JSON_TRY JSON_TRY_USER
529#if defined(JSON_CATCH_USER)
531 #define JSON_CATCH JSON_CATCH_USER
532 #undef JSON_INTERNAL_CATCH
533 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
535#if defined(JSON_INTERNAL_CATCH_USER)
536#undef JSON_INTERNAL_CATCH
537 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
541#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
542#define JSON_LIKELY(x) __builtin_expect(x, 1)
543#define JSON_UNLIKELY(x) __builtin_expect(x, 0)
545#define JSON_LIKELY(x) x
546 #define JSON_UNLIKELY(x) x
550#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1)
551#define JSON_HAS_CPP_17
552#define JSON_HAS_CPP_14
553#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
554#define JSON_HAS_CPP_14
562#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
563 template<typename BasicJsonType> \
564 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
566 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
567 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
568 auto it = std::find_if(std::begin(m), std::end(m), \
569 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
571 return ej_pair.first == e; \
573 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
575 template<typename BasicJsonType> \
576 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
578 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
579 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
580 auto it = std::find_if(std::begin(m), std::end(m), \
581 [j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
583 return ej_pair.second == j; \
585 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
591#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
592 template<template<typename, typename, typename...> class ObjectType, \
593 template<typename, typename...> class ArrayType, \
594 class StringType, class BooleanType, class NumberIntegerType, \
595 class NumberUnsignedType, class NumberFloatType, \
596 template<typename> class AllocatorType, \
597 template<typename, typename = void> class JSONSerializer>
599#define NLOHMANN_BASIC_JSON_TPL \
600 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
601 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
602 AllocatorType, JSONSerializer>
609#include <type_traits>
616 template<
bool B,
typename T =
void>
620 using uncvref_t =
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
624 template<std::size_t... Ints>
629 static constexpr std::size_t
size() noexcept
631 return sizeof...(Ints);
635 template<
class Sequence1,
class Sequence2>
638 template<std::size_t... I1, std::size_t... I2>
642 template<std::
size_t N>
645 typename make_index_sequence < N - N / 2 >::type > {};
650 template<
typename... Ts>
674#include <type_traits>
704 template <
typename It,
typename =
void>
707 template <
typename It>
711 typename It::reference, typename It::iterator_category >>
722 template <
typename T,
typename =
void>
727 template <
typename T>
733 template <
typename T>
752#include <type_traits>
772 template <
class Default,
774 template <
class...>
class Op,
782 template <
class Default,
template <
class...>
class Op,
class... Args>
789 template <
template <
class...>
class Op,
class... Args>
792 template <
template <
class...>
class Op,
class... Args>
795 template <
class Default,
template <
class...>
class Op,
class... Args>
798 template <
class Default,
template <
class...>
class Op,
class... Args>
801 template <
class Expected,
template <
class...>
class Op,
class... Args>
804 template <
class To,
template <
class...>
class Op,
class... Args>
806 std::is_convertible<
detected_t<Op, Args...>, To>;
811#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
812#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
834 template<
typename T =
void,
typename SFINAE =
void>
835 struct adl_serializer;
837 template<
template<
typename U,
typename V,
typename... Args>
class ObjectType =
839 template<
typename U,
typename... Args>
class ArrayType =
std::vector,
840 class StringType = std::string,
class BooleanType = bool,
841 class NumberIntegerType = std::int64_t,
842 class NumberUnsignedType = std::uint64_t,
843 class NumberFloatType = double,
844 template<
typename U>
class AllocatorType = std::allocator,
845 template<
typename T,
typename SFINAE =
void>
class JSONSerializer =
860 template<
typename BasicJsonType>
911 template <
typename T>
914 template <
typename T>
917 template <
typename T>
920 template <
typename T>
923 template <
typename T>
926 template <
typename T>
929 template <
typename T>
932 template <
typename T>
935 template <
typename T,
typename... Args>
938 template <
typename T,
typename... Args>
941 template <
typename T,
typename U>
945 template <
typename BasicJsonType,
typename T,
typename =
void>
948 template <
typename BasicJsonType,
typename T>
952 using serializer =
typename BasicJsonType::template json_serializer<T, void>;
954 static constexpr bool value =
956 const BasicJsonType&, T&>::value;
961 template <
typename BasicJsonType,
typename T,
typename =
void>
964 template<
typename BasicJsonType,
typename T>
967 using serializer =
typename BasicJsonType::template json_serializer<T, void>;
969 static constexpr bool value =
971 const BasicJsonType&>::value;
976 template <
typename BasicJsonType,
typename T,
typename =
void>
979 template <
typename BasicJsonType,
typename T>
982 using serializer =
typename BasicJsonType::template json_serializer<T, void>;
984 static constexpr bool value =
994 template <
typename T,
typename =
void>
997 template <
typename T>
1004 static constexpr auto value =
1014 template <
typename T,
typename =
void>
1017 template <
typename T>
1020 template <
typename BasicJsonType,
typename CompatibleObjectType,
1024 template <
typename BasicJsonType,
typename CompatibleObjectType>
1026 BasicJsonType, CompatibleObjectType,
1028 is_detected<key_type_t, CompatibleObjectType>::value >>
1034 static constexpr bool value =
1035 std::is_constructible<
typename object_t::key_type,
1036 typename CompatibleObjectType::key_type>::value and
1037 std::is_constructible<
typename object_t::mapped_type,
1038 typename CompatibleObjectType::mapped_type>::value;
1041 template <
typename BasicJsonType,
typename CompatibleObjectType>
1045 template <
typename BasicJsonType,
typename ConstructibleObjectType,
1049 template <
typename BasicJsonType,
typename ConstructibleObjectType>
1051 BasicJsonType, ConstructibleObjectType,
1053 is_detected<key_type_t, ConstructibleObjectType>::value >>
1057 static constexpr bool value =
1058 (std::is_constructible<typename ConstructibleObjectType::key_type, typename object_t::key_type>::value and
1059 std::is_same<typename object_t::mapped_type, typename ConstructibleObjectType::mapped_type>::value) or
1064 template <
typename BasicJsonType,
typename ConstructibleObjectType>
1067 ConstructibleObjectType> {};
1069 template <
typename BasicJsonType,
typename CompatibleStringType,
1073 template <
typename BasicJsonType,
typename CompatibleStringType>
1075 BasicJsonType, CompatibleStringType,
1079 static constexpr auto value =
1080 std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
1083 template <
typename BasicJsonType,
typename ConstructibleStringType>
1087 template <
typename BasicJsonType,
typename ConstructibleStringType,
1091 template <
typename BasicJsonType,
typename ConstructibleStringType>
1093 BasicJsonType, ConstructibleStringType,
1097 static constexpr auto value =
1098 std::is_constructible<ConstructibleStringType,
1099 typename BasicJsonType::string_t>::value;
1102 template <
typename BasicJsonType,
typename ConstructibleStringType>
1106 template <
typename BasicJsonType,
typename CompatibleArrayType,
typename =
void>
1109 template <
typename BasicJsonType,
typename CompatibleArrayType>
1111 BasicJsonType, CompatibleArrayType,
1113 is_detected<iterator_t, CompatibleArrayType>::value and
1118 iterator_traits<CompatibleArrayType>>::value >>
1120 static constexpr bool value =
1121 std::is_constructible<BasicJsonType,
1122 typename CompatibleArrayType::value_type>::value;
1125 template <
typename BasicJsonType,
typename CompatibleArrayType>
1129 template <
typename BasicJsonType,
typename ConstructibleArrayType,
typename =
void>
1132 template <
typename BasicJsonType,
typename ConstructibleArrayType>
1134 BasicJsonType, ConstructibleArrayType,
1136 typename BasicJsonType::value_type>::value >>
1137 : std::true_type {};
1139 template <
typename BasicJsonType,
typename ConstructibleArrayType>
1141 BasicJsonType, ConstructibleArrayType,
1143 typename BasicJsonType::value_type>::value and
1144 is_detected<value_type_t, ConstructibleArrayType>::value and
1145 is_detected<iterator_t, ConstructibleArrayType>::value and
1147 detected_t<value_type_t, ConstructibleArrayType>>::value >>
1149 static constexpr bool value =
1157 (std::is_same<typename ConstructibleArrayType::value_type, typename BasicJsonType::array_t::value_type>::value or
1159 typename ConstructibleArrayType::value_type>::value or
1161 BasicJsonType,
typename ConstructibleArrayType::value_type >::value);
1164 template <
typename BasicJsonType,
typename ConstructibleArrayType>
1168 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType,
1172 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType>
1174 RealIntegerType, CompatibleNumberIntegerType,
1176 std::is_integral<CompatibleNumberIntegerType>::value and
1177 not std::is_same<bool, CompatibleNumberIntegerType>::value >>
1183 static constexpr auto value =
1184 std::is_constructible<RealIntegerType,
1185 CompatibleNumberIntegerType>::value and
1186 CompatibleLimits::is_integer and
1187 RealLimits::is_signed == CompatibleLimits::is_signed;
1190 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType>
1193 CompatibleNumberIntegerType> {};
1195 template <
typename BasicJsonType,
typename CompatibleType,
typename =
void>
1198 template <
typename BasicJsonType,
typename CompatibleType>
1200 BasicJsonType, CompatibleType,
1203 static constexpr bool value =
1207 template <
typename BasicJsonType,
typename CompatibleType>
1279 static constexpr std::array<std::uint8_t, 8> order = {{
1285 const auto l_index =
static_cast<std::size_t
>(lhs);
1286 const auto r_index =
static_cast<std::size_t
>(rhs);
1287 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
1297 template<
typename BasicJsonType>
1298 void from_json(
const BasicJsonType& j,
typename std::nullptr_t& n)
1308 template<
typename BasicJsonType,
typename ArithmeticType,
1309 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
1310 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1314 switch (
static_cast<value_t>(j))
1318 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1323 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1328 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1337 template<
typename BasicJsonType>
1338 void from_json(
const BasicJsonType& j,
typename BasicJsonType::boolean_t& b)
1344 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
1347 template<
typename BasicJsonType>
1348 void from_json(
const BasicJsonType& j,
typename BasicJsonType::string_t& s)
1354 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1358 typename BasicJsonType,
typename ConstructibleStringType,
1360 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value and
1361 not std::is_same<
typename BasicJsonType::string_t,
1362 ConstructibleStringType>::value,
1364 void from_json(
const BasicJsonType& j, ConstructibleStringType& s)
1371 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1374 template<
typename BasicJsonType>
1375 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_float_t& val)
1380 template<
typename BasicJsonType>
1381 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_unsigned_t& val)
1386 template<
typename BasicJsonType>
1387 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_integer_t& val)
1392 template<
typename BasicJsonType,
typename EnumType,
1393 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
1396 typename std::underlying_type<EnumType>::type val;
1398 e =
static_cast<EnumType
>(val);
1402 template<
typename BasicJsonType,
typename T,
typename Allocator,
1403 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1404 void from_json(
const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1410 std::transform(j.rbegin(), j.rend(),
1411 std::front_inserter(l), [](
const BasicJsonType & i)
1413 return i.template get<T>();
1418 template<
typename BasicJsonType,
typename T,
1419 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1427 std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1430 template<
typename BasicJsonType>
1433 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
1436 template <
typename BasicJsonType,
typename T, std::
size_t N>
1439 ->
decltype(j.template get<T>(), void())
1441 for (std::size_t i = 0; i < N; ++i)
1443 arr[i] = j.at(i).template get<T>();
1447 template<
typename BasicJsonType,
typename ConstructibleArrayType>
1450 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
1451 j.template get<typename ConstructibleArrayType::value_type>(),
1456 arr.reserve(j.size());
1457 std::transform(j.begin(), j.end(),
1458 std::inserter(arr, end(arr)), [](
const BasicJsonType & i)
1462 return i.template get<typename ConstructibleArrayType::value_type>();
1466 template <
typename BasicJsonType,
typename ConstructibleArrayType>
1473 j.begin(), j.end(), std::inserter(arr, end(arr)),
1474 [](
const BasicJsonType & i)
1478 return i.template get<typename ConstructibleArrayType::value_type>();
1482 template <
typename BasicJsonType,
typename ConstructibleArrayType,
1484 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
1485 not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
1486 not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
1487 not is_basic_json<ConstructibleArrayType>::value,
1490 auto from_json(
const BasicJsonType& j, ConstructibleArrayType& arr)
1492 j.template get<typename ConstructibleArrayType::value_type>(),
1498 std::string(j.type_name())));
1504 template<
typename BasicJsonType,
typename ConstructibleObjectType,
1505 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value,
int> = 0>
1506 void from_json(
const BasicJsonType& j, ConstructibleObjectType& obj)
1513 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1514 using value_type =
typename ConstructibleObjectType::value_type;
1516 inner_object->begin(), inner_object->end(),
1517 std::inserter(obj, obj.begin()),
1518 [](
typename BasicJsonType::object_t::value_type
const & p)
1520 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
1528 template<
typename BasicJsonType,
typename ArithmeticType,
1530 std::is_arithmetic<ArithmeticType>::value and
1531 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1532 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1533 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1534 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1538 switch (
static_cast<value_t>(j))
1542 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1547 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1552 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1557 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1566 template<
typename BasicJsonType,
typename A1,
typename A2>
1567 void from_json(
const BasicJsonType& j, std::pair<A1, A2>& p)
1569 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
1572 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1575 t = std::make_tuple(j.at(Idx).template
get<
typename std::tuple_element<Idx, Tuple>::type>()...);
1578 template<
typename BasicJsonType,
typename... Args>
1579 void from_json(
const BasicJsonType& j, std::tuple<Args...>& t)
1584 template <
typename BasicJsonType,
typename Key,
typename Value,
typename Compare,
typename Allocator,
1586 typename BasicJsonType::string_t, Key>::value>>
1587 void from_json(
const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
1593 for (
const auto& p : j)
1599 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1603 template <
typename BasicJsonType,
typename Key,
typename Value,
typename Hash,
typename KeyEqual,
typename Allocator,
1605 typename BasicJsonType::string_t, Key>::value>>
1606 void from_json(
const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
1612 for (
const auto& p : j)
1618 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1624 template<
typename BasicJsonType,
typename T>
1651#include <type_traits>
1725 const std::string&
key()
const
1727 assert(
anchor.m_object !=
nullptr);
1729 switch (
anchor.m_object->type())
1753 typename IteratorType::reference
value()
const
1786 template <std::
size_t N,
typename IteratorType, enable_if_t<N == 0,
int> = 0>
1794 template <std::
size_t N,
typename IteratorType, enable_if_t<N == 1,
int> = 0>
1808#if defined(__clang__)
1810 #pragma clang diagnostic push
1811 #pragma clang diagnostic ignored "-Wmismatched-tags"
1813 template <
typename IteratorType>
1815 :
public std::integral_constant<std::size_t, 2> {};
1817 template <std::
size_t N,
typename IteratorType>
1822 get<N>(std::declval <
1825#if defined(__clang__)
1826#pragma clang diagnostic pop
1850 template<
typename BasicJsonType>
1851 static void construct(BasicJsonType& j,
typename BasicJsonType::boolean_t b)
noexcept
1855 j.assert_invariant();
1862 template<
typename BasicJsonType>
1863 static void construct(BasicJsonType& j,
const typename BasicJsonType::string_t& s)
1867 j.assert_invariant();
1870 template<
typename BasicJsonType>
1871 static void construct(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
1874 j.m_value = std::move(s);
1875 j.assert_invariant();
1878 template<
typename BasicJsonType,
typename CompatibleStringType,
1881 static void construct(BasicJsonType& j,
const CompatibleStringType& str)
1884 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
1885 j.assert_invariant();
1892 template<
typename BasicJsonType>
1893 static void construct(BasicJsonType& j,
typename BasicJsonType::number_float_t val)
noexcept
1897 j.assert_invariant();
1904 template<
typename BasicJsonType>
1905 static void construct(BasicJsonType& j,
typename BasicJsonType::number_unsigned_t val)
noexcept
1909 j.assert_invariant();
1916 template<
typename BasicJsonType>
1917 static void construct(BasicJsonType& j,
typename BasicJsonType::number_integer_t val)
noexcept
1921 j.assert_invariant();
1928 template<
typename BasicJsonType>
1929 static void construct(BasicJsonType& j,
const typename BasicJsonType::array_t& arr)
1933 j.assert_invariant();
1936 template<
typename BasicJsonType>
1937 static void construct(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
1940 j.m_value = std::move(arr);
1941 j.assert_invariant();
1944 template<
typename BasicJsonType,
typename CompatibleArrayType,
1947 static void construct(BasicJsonType& j,
const CompatibleArrayType& arr)
1952 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
1953 j.assert_invariant();
1956 template<
typename BasicJsonType>
1961 j.m_value.array->reserve(arr.
size());
1962 for (
const bool x : arr)
1964 j.m_value.array->push_back(x);
1966 j.assert_invariant();
1969 template<
typename BasicJsonType,
typename T,
1971 static void construct(BasicJsonType& j,
const std::valarray<T>& arr)
1975 j.m_value.array->resize(arr.size());
1976 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
1977 j.assert_invariant();
1984 template<
typename BasicJsonType>
1985 static void construct(BasicJsonType& j,
const typename BasicJsonType::object_t& obj)
1989 j.assert_invariant();
1992 template<
typename BasicJsonType>
1993 static void construct(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
1996 j.m_value = std::move(obj);
1997 j.assert_invariant();
2000 template<
typename BasicJsonType,
typename CompatibleObjectType,
2002 static void construct(BasicJsonType& j,
const CompatibleObjectType& obj)
2008 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
2009 j.assert_invariant();
2017 template<
typename BasicJsonType,
typename T,
2018 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value,
int> = 0>
2024 template<
typename BasicJsonType,
typename CompatibleString,
2025 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value,
int> = 0>
2026 void to_json(BasicJsonType& j,
const CompatibleString& s)
2031 template<
typename BasicJsonType>
2032 void to_json(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
2037 template<
typename BasicJsonType,
typename FloatType,
2038 enable_if_t<std::is_floating_point<FloatType>::value,
int> = 0>
2039 void to_json(BasicJsonType& j, FloatType val)
noexcept
2044 template<
typename BasicJsonType,
typename CompatibleNumberUnsignedType,
2045 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value,
int> = 0>
2046 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val)
noexcept
2051 template<
typename BasicJsonType,
typename CompatibleNumberIntegerType,
2052 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value,
int> = 0>
2053 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val)
noexcept
2058 template<
typename BasicJsonType,
typename EnumType,
2059 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
2060 void to_json(BasicJsonType& j, EnumType e)
noexcept
2062 using underlying_type =
typename std::underlying_type<EnumType>::type;
2066 template<
typename BasicJsonType>
2072 template <
typename BasicJsonType,
typename CompatibleArrayType,
2073 enable_if_t<is_compatible_array_type<BasicJsonType,
2074 CompatibleArrayType>::value and
2075 not is_compatible_object_type<
2076 BasicJsonType, CompatibleArrayType>::value and
2077 not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
2078 not is_basic_json<CompatibleArrayType>::value,
2080 void to_json(BasicJsonType& j,
const CompatibleArrayType& arr)
2085 template<
typename BasicJsonType,
typename T,
2086 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
2087 void to_json(BasicJsonType& j,
const std::valarray<T>& arr)
2092 template<
typename BasicJsonType>
2093 void to_json(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
2098 template<
typename BasicJsonType,
typename CompatibleObjectType,
2099 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value and not is_basic_json<CompatibleObjectType>::value,
int> = 0>
2100 void to_json(BasicJsonType& j,
const CompatibleObjectType& obj)
2105 template<
typename BasicJsonType>
2106 void to_json(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
2112 typename BasicJsonType,
typename T, std::size_t N,
2113 enable_if_t<not std::is_constructible<
typename BasicJsonType::string_t,
2114 const T(&)[N]>::value,
2121 template<
typename BasicJsonType,
typename... Args>
2122 void to_json(BasicJsonType& j,
const std::pair<Args...>& p)
2124 j = { p.first, p.second };
2128 template <
typename BasicJsonType,
typename T,
2129 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value,
int> = 0>
2132 j = { {b.key(), b.value()} };
2135 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
2138 j = { std::get<Idx>(t)... };
2141 template<
typename BasicJsonType,
typename... Args>
2142 void to_json(BasicJsonType& j,
const std::tuple<Args...>& t)
2149 template<
typename BasicJsonType,
typename T>
2150 auto operator()(BasicJsonType& j, T&& val)
const noexcept(
noexcept(
to_json(j, std::forward<T>(val))))
2151 ->
decltype(
to_json(j, std::forward<T>(val)), void())
2153 return to_json(j, std::forward<T>(val));
2169 template<
typename,
typename>
2181 template<
typename BasicJsonType,
typename ValueType>
2182 static auto from_json(BasicJsonType&& j, ValueType& val)
noexcept(
2198 template <
typename BasicJsonType,
typename ValueType>
2199 static auto to_json(BasicJsonType& j, ValueType&& val)
noexcept(
2246#include <type_traits>
2306 return std::fgetc(
m_file);
2331 is.clear(
is.rdstate() & std::ios::eofbit);
2335 :
is(i),
sb(*i.rdbuf())
2349 auto res =
sb.sbumpc();
2353 is.clear(
is.rdstate() | std::ios::eofbit);
2383 return std::char_traits<char>::to_int_type(*(
cursor++));
2386 return std::char_traits<char>::eof();
2396 template<
typename W
ideStringType,
size_t T>
2401 size_t& current_wchar,
2402 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
2403 size_t& utf8_bytes_index,
2404 size_t& utf8_bytes_filled)
2406 utf8_bytes_index = 0;
2408 if (current_wchar == str.size())
2410 utf8_bytes[0] = std::char_traits<char>::eof();
2411 utf8_bytes_filled = 1;
2416 const auto wc =
static_cast<unsigned int>(str[current_wchar++]);
2421 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
2422 utf8_bytes_filled = 1;
2424 else if (wc <= 0x7FF)
2426 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xC0u | ((wc >> 6u) & 0x1Fu));
2427 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (wc & 0x3Fu));
2428 utf8_bytes_filled = 2;
2430 else if (wc <= 0xFFFF)
2432 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xE0u | ((wc >> 12u) & 0x0Fu));
2433 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((wc >> 6u) & 0x3Fu));
2434 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (wc & 0x3Fu));
2435 utf8_bytes_filled = 3;
2437 else if (wc <= 0x10FFFF)
2439 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xF0u | ((wc >> 18u) & 0x07u));
2440 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((wc >> 12u) & 0x3Fu));
2441 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((wc >> 6u) & 0x3Fu));
2442 utf8_bytes[3] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (wc & 0x3Fu));
2443 utf8_bytes_filled = 4;
2448 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
2449 utf8_bytes_filled = 1;
2455 template<
typename W
ideStringType>
2460 size_t& current_wchar,
2461 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
2462 size_t& utf8_bytes_index,
2463 size_t& utf8_bytes_filled)
2465 utf8_bytes_index = 0;
2467 if (current_wchar == str.size())
2469 utf8_bytes[0] = std::char_traits<char>::eof();
2470 utf8_bytes_filled = 1;
2475 const auto wc =
static_cast<unsigned int>(str[current_wchar++]);
2480 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
2481 utf8_bytes_filled = 1;
2483 else if (wc <= 0x7FF)
2485 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xC0u | ((wc >> 6u)));
2486 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (wc & 0x3Fu));
2487 utf8_bytes_filled = 2;
2489 else if (0xD800 > wc or wc >= 0xE000)
2491 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xE0u | ((wc >> 12u)));
2492 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((wc >> 6u) & 0x3Fu));
2493 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (wc & 0x3Fu));
2494 utf8_bytes_filled = 3;
2498 if (current_wchar < str.size())
2500 const auto wc2 =
static_cast<unsigned int>(str[current_wchar++]);
2501 const auto charcode = 0x10000u + (((wc & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
2502 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xF0u | (charcode >> 18u));
2503 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((charcode >> 12u) & 0x3Fu));
2504 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((charcode >> 6u) & 0x3Fu));
2505 utf8_bytes[3] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (charcode & 0x3Fu));
2506 utf8_bytes_filled = 4;
2512 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
2513 utf8_bytes_filled = 1;
2520 template<
typename W
ideStringType>
2533 fill_buffer<sizeof(typename WideStringType::value_type)>();
2559 std::array<std::char_traits<char>::int_type, 4>
utf8_bytes = {{0, 0, 0, 0}};
2591 template<
typename CharT,
2592 typename std::enable_if<
2593 std::is_pointer<CharT>::value and
2594 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2595 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
2598 :
ia(std::make_shared<input_buffer_adapter>(
reinterpret_cast<const char*
>(b), l)) {}
2603 template<
typename CharT,
2604 typename std::enable_if<
2605 std::is_pointer<CharT>::value and
2606 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2607 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
2611 std::strlen(
reinterpret_cast<const char*
>(b))) {}
2614 template<
class IteratorType,
2615 typename std::enable_if<
2616 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
2623 const auto is_contiguous = std::accumulate(
2624 first, last, std::pair<bool, int>(
true, 0),
2625 [&first](std::pair<bool, int> res,
decltype(*first) val)
2627 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
2630 assert(is_contiguous);
2636 "each element in the iterator range must have the size of 1 byte");
2638 const auto len =
static_cast<size_t>(std::distance(first, last));
2642 ia = std::make_shared<input_buffer_adapter>(
reinterpret_cast<const char*
>(&(*first)), len);
2647 ia = std::make_shared<input_buffer_adapter>(
nullptr, len);
2652 template<
class T, std::
size_t N>
2657 template<
class ContiguousContainer,
typename
2658 std::enable_if<not std::is_pointer<ContiguousContainer>::value and
2659 std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
2701 template<
typename BasicJsonType>
2800 const std::string& last_token,
2822 template<
typename BasicJsonType>
2890 "excessive object size: " + std::to_string(len)));
2916 "excessive array size: " + std::to_string(len)));
2935 switch ((ex.
id / 100) % 100)
2968 template<
typename Value>
2973 root = BasicJsonType(std::forward<Value>(v));
2981 ref_stack.
back()->m_value.array->emplace_back(std::forward<Value>(v));
3003 template<
typename BasicJsonType>
3016 const bool allow_exceptions_ =
true)
3071 auto val =
handle_value(BasicJsonType::value_t::object,
true);
3085 BasicJsonType k = BasicJsonType(val);
3118 if (it->is_discarded())
3134 auto val =
handle_value(BasicJsonType::value_t::array,
true);
3181 switch ((ex.
id / 100) % 100)
3223 template<
typename Value>
3224 std::pair<bool, BasicJsonType*>
handle_value(Value&& v,
const bool skip_callback =
false)
3232 return {
false,
nullptr};
3236 auto value = BasicJsonType(std::forward<Value>(v));
3239 const bool keep = skip_callback or
callback(
static_cast<int>(
ref_stack.
size()), parse_event_t::value, value);
3244 return {
false,
nullptr};
3249 root = std::move(value);
3250 return {
true, &
root};
3257 return {
false,
nullptr};
3266 ref_stack.
back()->m_value.array->push_back(std::move(value));
3277 if (not store_element)
3279 return {
false,
nullptr};
3304 BasicJsonType
discarded = BasicJsonType::value_t::discarded;
3307 template<
typename BasicJsonType>
3398 template <
typename T>
3401 template <
typename T>
3403 decltype(std::declval<T&>().boolean(std::declval<bool>()));
3405 template <
typename T,
typename Integer>
3407 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
3409 template <
typename T,
typename Un
signed>
3411 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
3413 template <
typename T,
typename Float,
typename String>
3415 std::declval<Float>(), std::declval<const String&>()));
3417 template <
typename T,
typename String>
3419 decltype(std::declval<T&>().string(std::declval<String&>()));
3421 template <
typename T>
3423 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
3425 template <
typename T,
typename String>
3427 decltype(std::declval<T&>().key(std::declval<String&>()));
3429 template <
typename T>
3432 template <
typename T>
3434 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
3436 template <
typename T>
3439 template <
typename T,
typename Exception>
3441 std::declval<std::size_t>(), std::declval<const std::string&>(),
3442 std::declval<const Exception&>()));
3444 template <
typename SAX,
typename BasicJsonType>
3449 "BasicJsonType must be of type basic_json<...>");
3476 template <
typename SAX,
typename BasicJsonType>
3481 "BasicJsonType must be of type basic_json<...>");
3491 "Missing/invalid function: bool null()");
3493 "Missing/invalid function: bool boolean(bool)");
3495 "Missing/invalid function: bool boolean(bool)");
3499 "Missing/invalid function: bool number_integer(number_integer_t)");
3503 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
3506 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
3509 "Missing/invalid function: bool string(string_t&)");
3511 "Missing/invalid function: bool start_object(std::size_t)");
3513 "Missing/invalid function: bool key(string_t&)");
3515 "Missing/invalid function: bool end_object()");
3517 "Missing/invalid function: bool start_array(std::size_t)");
3519 "Missing/invalid function: bool end_array()");
3522 "Missing/invalid function: bool parse_error(std::size_t, const "
3523 "std::string&, const exception&)");
3542 template<
typename BasicJsonType,
typename SAX = json_sax_dom_parser<BasicJsonType>>
3579 const bool strict =
true)
3582 bool result =
false;
3637 return *
reinterpret_cast<char*
>(&num) == 1;
3651 std::int32_t document_size;
3664 return sax->end_object();
3676 auto out = std::back_inserter(result);
3688 *out++ =
static_cast<char>(
current);
3705 template<
typename NumberType>
3728 const std::size_t element_type_parse_position)
3730 switch (element_type)
3757 return sax->boolean(
get() != 0);
3779 std::array<char, 3> cr{{}};
3780 (std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<unsigned char>(element_type));
3781 return sax->parse_error(element_type_parse_position, std::string(cr.data()),
parse_error::create(114, element_type_parse_position,
"Unsupported BSON record type 0x" + std::string(cr.data())));
3801 while (
int element_type =
get())
3808 const std::size_t element_type_parse_position =
chars_read;
3814 if (not is_array and not
sax->key(key))
3837 std::int32_t document_size;
3850 return sax->end_array();
3869 case std::char_traits<char>::eof():
3901 std::uint8_t number;
3907 std::uint16_t number;
3913 std::uint32_t number;
3919 std::uint64_t number;
3948 return sax->number_integer(
static_cast<std::int8_t
>(0x20 - 1 -
current));
3952 std::uint8_t number;
3958 std::uint16_t number;
3964 std::uint32_t number;
3970 std::uint64_t number;
4119 return sax->boolean(
false);
4122 return sax->boolean(
true);
4129 const int byte1_raw =
get();
4134 const int byte2_raw =
get();
4140 const auto byte1 =
static_cast<unsigned char>(byte1_raw);
4141 const auto byte2 =
static_cast<unsigned char>(byte2_raw);
4151 const auto half =
static_cast<unsigned int>((byte1 << 8u) + byte2);
4152 const double val = [&half]
4154 const int exp = (half >> 10u) & 0x1Fu;
4155 const unsigned int mant = half & 0x3FFu;
4156 assert(0 <=
exp and
exp <= 32);
4157 assert(0 <= mant and mant <= 1024);
4161 return std::ldexp(mant, -24);
4164 ? std::numeric_limits<double>::infinity()
4165 : std::numeric_limits<double>::quiet_NaN();
4167 return std::ldexp(mant + 1024,
exp - 25);
4170 return sax->number_float((half & 0x8000u) != 0
4270 while (
get() != 0xFF)
4277 result.append(chunk);
4302 if (len != std::size_t(-1))
4304 for (std::size_t i = 0; i < len; ++i)
4314 while (
get() != 0xFF)
4323 return sax->end_array();
4339 if (len != std::size_t(-1))
4341 for (std::size_t i = 0; i < len; ++i)
4358 while (
get() != 0xFF)
4373 return sax->end_object();
4388 case std::char_traits<char>::eof():
4602 return sax->boolean(
false);
4605 return sax->boolean(
true);
4621 std::uint8_t number;
4627 std::uint16_t number;
4633 std::uint32_t number;
4639 std::uint64_t number;
4651 std::int16_t number;
4657 std::int32_t number;
4663 std::int64_t number;
4732 return sax->number_integer(
static_cast<std::int8_t
>(
current));
4835 for (std::size_t i = 0; i < len; ++i)
4843 return sax->end_array();
4858 for (std::size_t i = 0; i < len; ++i)
4873 return sax->end_object();
4952 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")));
4966 std::uint8_t number;
4971 result =
static_cast<std::size_t
>(number);
4982 result =
static_cast<std::size_t
>(number);
4988 std::int16_t number;
4993 result =
static_cast<std::size_t
>(number);
4999 std::int32_t number;
5004 result =
static_cast<std::size_t
>(number);
5010 std::int64_t number;
5015 result =
static_cast<std::size_t
>(number);
5022 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")));
5039 result.first = string_t::npos;
5046 result.second =
get();
5082 case std::char_traits<char>::eof():
5086 return sax->boolean(
true);
5088 return sax->boolean(
false);
5095 std::uint8_t number;
5107 std::int16_t number;
5113 std::int32_t number;
5119 std::int64_t number;
5148 return sax->string(s);
5176 std::pair<std::size_t, int> size_and_type;
5182 if (size_and_type.first != string_t::npos)
5189 if (size_and_type.second != 0)
5191 if (size_and_type.second !=
'N')
5193 for (std::size_t i = 0; i < size_and_type.first; ++i)
5204 for (std::size_t i = 0; i < size_and_type.first; ++i)
5230 return sax->end_array();
5238 std::pair<std::size_t, int> size_and_type;
5245 if (size_and_type.first != string_t::npos)
5252 if (size_and_type.second != 0)
5254 for (std::size_t i = 0; i < size_and_type.first; ++i)
5269 for (std::size_t i = 0; i < size_and_type.first; ++i)
5305 return sax->end_object();
5354 template<
typename NumberType,
bool InputIsLittleEndian = false>
5358 std::array<std::uint8_t,
sizeof(NumberType)> vec;
5359 for (std::size_t i = 0; i <
sizeof(NumberType); ++i)
5370 vec[
sizeof(NumberType) - i - 1] =
static_cast<std::uint8_t
>(
current);
5374 vec[i] =
static_cast<std::uint8_t
>(
current);
5379 std::memcpy(&result, vec.data(),
sizeof(NumberType));
5397 template<
typename NumberType>
5399 const NumberType len,
5402 bool success =
true;
5403 std::generate_n(std::back_inserter(result), len, [
this, &success, &format]()
5410 return static_cast<char>(
current);
5435 std::array<char, 3> cr{{}};
5436 (std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<unsigned char>(
current));
5437 return std::string{cr.data()};
5447 const std::string& detail,
5448 const std::string& context)
const
5450 std::string error_msg =
"syntax error while parsing ";
5455 error_msg +=
"CBOR";
5459 error_msg +=
"MessagePack";
5463 error_msg +=
"UBJSON";
5467 error_msg +=
"BSON";
5474 return error_msg +
" " + context +
": " + detail;
5506#include <initializer_list>
5531 template<
typename BasicJsonType>
5568 return "<uninitialized>";
5570 return "true literal";
5572 return "false literal";
5574 return "null literal";
5576 return "string literal";
5580 return "number literal";
5594 return "<parse error>";
5596 return "end of input";
5598 return "'[', '{', or a literal";
5601 return "unknown token";
5624 const auto loc = localeconv();
5625 assert(loc !=
nullptr);
5626 return (loc->decimal_point ==
nullptr) ?
'.' : *(loc->decimal_point);
5654 const auto factors = { 12u, 8u, 4u, 0u };
5655 for (
const auto factor : factors)
5661 codepoint +=
static_cast<int>((
static_cast<unsigned int>(
current) - 0x30u) << factor);
5665 codepoint +=
static_cast<int>((
static_cast<unsigned int>(
current) - 0x37u) << factor);
5669 codepoint +=
static_cast<int>((
static_cast<unsigned int>(
current) - 0x57u) << factor);
5677 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
5698 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
5701 for (
auto range = ranges.begin(); range != ranges.end(); ++range)
5747 case std::char_traits<char>::eof():
5801 int codepoint = codepoint1;
5805 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
5810 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
5819 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
5824 if (
JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
5827 codepoint =
static_cast<int>(
5829 (
static_cast<unsigned int>(codepoint1) << 10u)
5831 +
static_cast<unsigned int>(codepoint2)
5839 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
5845 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
5851 if (
JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
5853 error_message =
"invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
5859 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
5862 if (codepoint < 0x80)
5867 else if (codepoint <= 0x7FF)
5870 add(
static_cast<int>(0xC0u | (
static_cast<unsigned int>(codepoint) >> 6u)));
5871 add(
static_cast<int>(0x80u | (
static_cast<unsigned int>(codepoint) & 0x3Fu)));
5873 else if (codepoint <= 0xFFFF)
5876 add(
static_cast<int>(0xE0u | (
static_cast<unsigned int>(codepoint) >> 12u)));
5877 add(
static_cast<int>(0x80u | ((
static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
5878 add(
static_cast<int>(0x80u | (
static_cast<unsigned int>(codepoint) & 0x3Fu)));
5883 add(
static_cast<int>(0xF0u | (
static_cast<unsigned int>(codepoint) >> 18u)));
5884 add(
static_cast<int>(0x80u | ((
static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
5885 add(
static_cast<int>(0x80u | ((
static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
5886 add(
static_cast<int>(0x80u | (
static_cast<unsigned int>(codepoint) & 0x3Fu)));
5894 error_message =
"invalid string: forbidden character after backslash";
5904 error_message =
"invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
5910 error_message =
"invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
5916 error_message =
"invalid string: control character U+0002 (STX) must be escaped to \\u0002";
5922 error_message =
"invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
5928 error_message =
"invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
5934 error_message =
"invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
5940 error_message =
"invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
5946 error_message =
"invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
5952 error_message =
"invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
5958 error_message =
"invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
5964 error_message =
"invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
5970 error_message =
"invalid string: control character U+000B (VT) must be escaped to \\u000B";
5976 error_message =
"invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
5982 error_message =
"invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
5988 error_message =
"invalid string: control character U+000E (SO) must be escaped to \\u000E";
5994 error_message =
"invalid string: control character U+000F (SI) must be escaped to \\u000F";
6000 error_message =
"invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
6006 error_message =
"invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
6012 error_message =
"invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
6018 error_message =
"invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
6024 error_message =
"invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
6030 error_message =
"invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
6036 error_message =
"invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
6042 error_message =
"invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
6048 error_message =
"invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
6054 error_message =
"invalid string: control character U+0019 (EM) must be escaped to \\u0019";
6060 error_message =
"invalid string: control character U+001A (SUB) must be escaped to \\u001A";
6066 error_message =
"invalid string: control character U+001B (ESC) must be escaped to \\u001B";
6072 error_message =
"invalid string: control character U+001C (FS) must be escaped to \\u001C";
6078 error_message =
"invalid string: control character U+001D (GS) must be escaped to \\u001D";
6084 error_message =
"invalid string: control character U+001E (RS) must be escaped to \\u001E";
6090 error_message =
"invalid string: control character U+001F (US) must be escaped to \\u001F";
6319 static void strtof(
float& f,
const char* str,
char** endptr)
noexcept
6321 f = std::strtof(str, endptr);
6324 static void strtof(
double& f,
const char* str,
char** endptr)
noexcept
6326 f = std::strtod(str, endptr);
6329 static void strtof(
long double& f,
const char* str,
char** endptr)
noexcept
6331 f = std::strtold(str, endptr);
6389 goto scan_number_minus;
6395 goto scan_number_zero;
6409 goto scan_number_any1;
6425 goto scan_number_zero;
6439 goto scan_number_any1;
6456 goto scan_number_decimal1;
6463 goto scan_number_exponent;
6467 goto scan_number_done;
6486 goto scan_number_any1;
6492 goto scan_number_decimal1;
6499 goto scan_number_exponent;
6503 goto scan_number_done;
6506 scan_number_decimal1:
6523 goto scan_number_decimal2;
6533 scan_number_decimal2:
6549 goto scan_number_decimal2;
6556 goto scan_number_exponent;
6560 goto scan_number_done;
6563 scan_number_exponent:
6572 goto scan_number_sign;
6587 goto scan_number_any2;
6593 "invalid number; expected '+', '-', or digit after exponent";
6614 goto scan_number_any2;
6619 error_message =
"invalid number; expected digit after exponent sign";
6640 goto scan_number_any2;
6644 goto scan_number_done;
6652 char* endptr =
nullptr;
6658 const auto x = std::strtoull(
token_buffer.data(), &endptr, 10);
6674 const auto x = std::strtoll(
token_buffer.data(), &endptr, 10);
6707 assert(
current == literal_text[0]);
6708 for (std::size_t i = 1; i < length; ++i)
6741 std::char_traits<char>::int_type
get()
6807 token_buffer.push_back(std::char_traits<char>::to_char_type(c));
6858 if (
'\x00' <= c and c <=
'\x1F')
6861 std::array<char, 9> cs{{}};
6862 (std::snprintf)(cs.data(), cs.size(),
"<U+%.4X>",
static_cast<unsigned char>(c));
6863 result += cs.data();
6868 result.push_back(c);
6894 return get() == 0xBB and
get() == 0xBF;
6908 error_message =
"invalid BOM; must be 0xEF 0xBB 0xBF if given";
6964 case std::char_traits<char>::eof():
6979 std::char_traits<char>::int_type
current = std::char_traits<char>::eof();
7013#include <functional>
7046 template<
typename BasicJsonType>
7074 std::function<bool(
int depth,
parse_event_t event, BasicJsonType& parsed)>;
7079 const bool allow_exceptions_ =
true)
7096 void parse(
const bool strict, BasicJsonType& result)
7102 result.assert_invariant();
7122 if (result.is_discarded())
7131 result.assert_invariant();
7163 template <
typename SAX>
7182 template <
typename SAX>
7189 bool skip_to_state_evaluation =
false;
7193 if (not skip_to_state_evaluation)
7198 case token_type::begin_object:
7206 if (
get_token() == token_type::end_object)
7245 case token_type::begin_array:
7253 if (
get_token() == token_type::end_array)
7269 case token_type::value_float:
7288 case token_type::literal_false:
7297 case token_type::literal_null:
7306 case token_type::literal_true:
7315 case token_type::value_integer:
7324 case token_type::value_string:
7333 case token_type::value_unsigned:
7342 case token_type::parse_error:
7362 skip_to_state_evaluation =
false;
7375 if (
get_token() == token_type::value_separator)
7394 assert(not states.
empty());
7396 skip_to_state_evaluation =
true;
7408 if (
get_token() == token_type::value_separator)
7450 assert(not states.
empty());
7452 skip_to_state_evaluation =
true;
7472 std::string error_msg =
"syntax error ";
7474 if (not context.empty())
7476 error_msg +=
"while parsing " + context +
" ";
7491 if (expected != token_type::uninitialized)
7576 return lhs.m_it == rhs.m_it;
7581 return lhs.m_it < rhs.m_it;
7586 auto result = *
this;
7593 return lhs.m_it - rhs.m_it;
7604 auto result = *
this;
7617 auto result = *
this;
7665#include <type_traits>
7687 template<
typename IteratorType>
class iteration_proxy;
7688 template<
typename IteratorType>
class iteration_proxy_value;
7706 template<
typename BasicJsonType>
7719 "iter_impl only accepts (const) basic_json");
7735 using pointer =
typename std::conditional<std::is_const<BasicJsonType>::value,
7736 typename BasicJsonType::const_pointer,
7737 typename BasicJsonType::pointer>::type;
7740 typename std::conditional<std::is_const<BasicJsonType>::value,
7741 typename BasicJsonType::const_reference,
7742 typename BasicJsonType::reference>::type;
7955 auto result = *
this;
7998 auto result = *
this;
8104 return not other.operator < (*this);
8169 auto result = *
this;
8191 auto result = *
this;
8252 const typename object_t::key_type&
key()
const
8317 template<
typename Base>
8391 auto it = --this->base();
8398 auto it = --this->base();
8399 return it.operator * ();
8426 template<
typename BasicJsonType>
8477 [](
const std::string & a,
const std::string & b)
8479 return a +
"/" + escape(b);
8484 operator std::string()
const
8508 ptr.reference_tokens.begin(),
8509 ptr.reference_tokens.end());
8741 std::size_t processed_chars = 0;
8742 const int res = std::stoi(s, &processed_chars);
8775 using size_type =
typename BasicJsonType::size_type;
8782 switch (result->m_type)
8786 if (reference_token ==
"0")
8789 result = &result->operator[](0);
8794 result = &result->operator[](reference_token);
8802 result = &result->operator[](reference_token);
8811 result = &result->operator[](
static_cast<size_type
>(
array_index(reference_token)));
8855 using size_type =
typename BasicJsonType::size_type;
8863 std::all_of(reference_token.begin(), reference_token.end(),
8866 return x >=
'0' and x <=
'9';
8870 *
ptr = (nums or reference_token ==
"-")
8875 switch (
ptr->m_type)
8880 ptr = &
ptr->operator[](reference_token);
8887 if (
JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0'))
8890 "array index '" + reference_token +
8891 "' must not begin with '0'"));
8894 if (reference_token ==
"-")
8897 ptr = &
ptr->operator[](
ptr->m_value.array->size());
8905 static_cast<size_type
>(
array_index(reference_token)));
8931 using size_type =
typename BasicJsonType::size_type;
8934 switch (
ptr->m_type)
8939 ptr = &
ptr->at(reference_token);
8949 "array index '-' (" + std::to_string(
ptr->m_value.array->size()) +
8950 ") is out of range"));
8954 if (
JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0'))
8957 "array index '" + reference_token +
8958 "' must not begin with '0'"));
8996 using size_type =
typename BasicJsonType::size_type;
8999 switch (
ptr->m_type)
9004 ptr = &
ptr->operator[](reference_token);
9014 "array index '-' (" + std::to_string(
ptr->m_value.array->size()) +
9015 ") is out of range"));
9019 if (
JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0'))
9022 "array index '" + reference_token +
9023 "' must not begin with '0'"));
9030 static_cast<size_type
>(
array_index(reference_token)));
9055 using size_type =
typename BasicJsonType::size_type;
9058 switch (
ptr->m_type)
9063 ptr = &
ptr->at(reference_token);
9073 "array index '-' (" + std::to_string(
ptr->m_value.array->size()) +
9074 ") is out of range"));
9078 if (
JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0'))
9081 "array index '" + reference_token +
9082 "' must not begin with '0'"));
9119 if (reference_string.empty())
9128 "JSON pointer must be empty or begin with '/' - was: '" +
9129 reference_string +
"'"));
9137 std::size_t slash = reference_string.find_first_of(
'/', 1),
9144 start = (slash == std::string::npos) ? 0 : slash + 1,
9146 slash = reference_string.find_first_of(
'/', start))
9150 auto reference_token = reference_string.substr(start, slash - start);
9153 for (std::size_t
pos = reference_token.find_first_of(
'~');
9154 pos != std::string::npos;
9155 pos = reference_token.find_first_of(
'~',
pos + 1))
9157 assert(reference_token[
pos] ==
'~');
9161 (reference_token[
pos + 1] !=
'0' and
9162 reference_token[
pos + 1] !=
'1')))
9190 const std::string& t)
9192 assert(not f.empty());
9193 for (
auto pos = s.find(f);
9194 pos != std::string::npos;
9195 s.replace(
pos, f.size(), t),
9196 pos = s.find(f,
pos + t.size()))
9222 static void flatten(
const std::string& reference_string,
9223 const BasicJsonType& value,
9224 BasicJsonType& result)
9226 switch (value.m_type)
9230 if (value.m_value.array->empty())
9233 result[reference_string] =
nullptr;
9238 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
9240 flatten(reference_string +
"/" + std::to_string(i),
9241 value.m_value.array->operator[](i), result);
9249 if (value.m_value.object->empty())
9252 result[reference_string] =
nullptr;
9257 for (
const auto& element : *value.m_value.object)
9259 flatten(reference_string +
"/" +
escape(element.first), element.second, result);
9268 result[reference_string] = value;
9284 static BasicJsonType
9292 BasicJsonType result;
9295 for (
const auto& element : *value.m_value.object)
9306 json_pointer(element.first).get_and_create(result) = element.second;
9326 return lhs.reference_tokens == rhs.reference_tokens;
9343 return not (lhs == rhs);
9354#include <initializer_list>
9364 template<
typename BasicJsonType>
9466 template<
typename CharType>
9470 template<
typename CharType>
9485 std::copy(s, s + length, std::back_inserter(v));
9493 template<
typename CharType>
9508 stream.write(s,
static_cast<std::streamsize
>(length));
9516 template<
typename CharType,
typename StringType = std::basic_
string<CharType>>
9531 str.append(s, length);
9538 template<
typename CharType,
typename StringType = std::basic_
string<CharType>>
9574 template<
typename BasicJsonType,
typename CharType>
9626 oa->write_character(j.m_value.boolean
9634 if (j.m_value.number_integer >= 0)
9639 if (j.m_value.number_integer <= 0x17)
9641 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
9643 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
9646 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
9648 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
9651 write_number(
static_cast<std::uint16_t
>(j.m_value.number_integer));
9653 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
9656 write_number(
static_cast<std::uint32_t
>(j.m_value.number_integer));
9661 write_number(
static_cast<std::uint64_t
>(j.m_value.number_integer));
9668 const auto positive_number = -1 - j.m_value.number_integer;
9669 if (j.m_value.number_integer >= -24)
9671 write_number(
static_cast<std::uint8_t
>(0x20 + positive_number));
9673 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
9676 write_number(
static_cast<std::uint8_t
>(positive_number));
9678 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
9681 write_number(
static_cast<std::uint16_t
>(positive_number));
9683 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
9686 write_number(
static_cast<std::uint32_t
>(positive_number));
9691 write_number(
static_cast<std::uint64_t
>(positive_number));
9699 if (j.m_value.number_unsigned <= 0x17)
9701 write_number(
static_cast<std::uint8_t
>(j.m_value.number_unsigned));
9703 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
9706 write_number(
static_cast<std::uint8_t
>(j.m_value.number_unsigned));
9708 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
9711 write_number(
static_cast<std::uint16_t
>(j.m_value.number_unsigned));
9713 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
9716 write_number(
static_cast<std::uint32_t
>(j.m_value.number_unsigned));
9721 write_number(
static_cast<std::uint64_t
>(j.m_value.number_unsigned));
9736 const auto N = j.m_value.string->size();
9741 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
9746 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
9751 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
9757 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
9765 oa->write_characters(
9766 reinterpret_cast<const CharType*
>(j.m_value.string->c_str()),
9767 j.m_value.string->size());
9774 const auto N = j.m_value.array->size();
9779 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
9784 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
9789 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
9795 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
9803 for (
const auto& el : *j.m_value.array)
9813 const auto N = j.m_value.object->size();
9818 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
9823 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
9828 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
9834 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
9842 for (
const auto& el : *j.m_value.object)
9870 oa->write_character(j.m_value.boolean
9878 if (j.m_value.number_integer >= 0)
9883 if (j.m_value.number_unsigned < 128)
9886 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
9888 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
9892 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
9894 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
9898 write_number(
static_cast<std::uint16_t
>(j.m_value.number_integer));
9900 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
9904 write_number(
static_cast<std::uint32_t
>(j.m_value.number_integer));
9906 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
9910 write_number(
static_cast<std::uint64_t
>(j.m_value.number_integer));
9915 if (j.m_value.number_integer >= -32)
9918 write_number(
static_cast<std::int8_t
>(j.m_value.number_integer));
9920 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() and
9921 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
9925 write_number(
static_cast<std::int8_t
>(j.m_value.number_integer));
9927 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() and
9928 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
9932 write_number(
static_cast<std::int16_t
>(j.m_value.number_integer));
9934 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() and
9935 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
9939 write_number(
static_cast<std::int32_t
>(j.m_value.number_integer));
9941 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() and
9942 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
9946 write_number(
static_cast<std::int64_t
>(j.m_value.number_integer));
9954 if (j.m_value.number_unsigned < 128)
9957 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
9959 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
9963 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
9965 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
9969 write_number(
static_cast<std::uint16_t
>(j.m_value.number_integer));
9971 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
9975 write_number(
static_cast<std::uint32_t
>(j.m_value.number_integer));
9977 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
9981 write_number(
static_cast<std::uint64_t
>(j.m_value.number_integer));
9996 const auto N = j.m_value.string->size();
10002 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
10008 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
10014 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
10022 oa->write_characters(
10023 reinterpret_cast<const CharType*
>(j.m_value.string->c_str()),
10024 j.m_value.string->size());
10031 const auto N = j.m_value.array->size();
10037 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
10043 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
10051 for (
const auto& el : *j.m_value.array)
10061 const auto N = j.m_value.object->size();
10065 write_number(
static_cast<std::uint8_t
>(0x80 | (N & 0xF)));
10067 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
10073 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
10081 for (
const auto& el : *j.m_value.object)
10101 const bool use_type,
const bool add_prefix =
true)
10118 oa->write_character(j.m_value.boolean
10150 oa->write_characters(
10151 reinterpret_cast<const CharType*
>(j.m_value.string->c_str()),
10152 j.m_value.string->size());
10163 bool prefix_required =
true;
10164 if (use_type and not j.m_value.array->empty())
10168 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
10169 [
this, first_prefix](
const BasicJsonType & v)
10171 return ubjson_prefix(v) == first_prefix;
10176 prefix_required =
false;
10178 oa->write_character(first_prefix);
10188 for (
const auto& el : *j.m_value.array)
10190 write_ubjson(el, use_count, use_type, prefix_required);
10208 bool prefix_required =
true;
10209 if (use_type and not j.m_value.object->empty())
10213 const bool same_prefix = std::all_of(j.begin(), j.end(),
10214 [
this, first_prefix](
const BasicJsonType & v)
10216 return ubjson_prefix(v) == first_prefix;
10221 prefix_required =
false;
10223 oa->write_character(first_prefix);
10233 for (
const auto& el : *j.m_value.object)
10236 oa->write_characters(
10237 reinterpret_cast<const CharType*
>(el.first.c_str()),
10239 write_ubjson(el.second, use_count, use_type, prefix_required);
10266 const auto it = name.find(
static_cast<typename string_t::value_type
>(0));
10270 "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) +
")"));
10273 return 1ul + name.size() + 1u;
10280 const std::uint8_t element_type)
10283 oa->write_characters(
10284 reinterpret_cast<const CharType*
>(name.c_str()),
10302 const double value)
10305 write_number<double, true>(value);
10313 return sizeof(std::int32_t) + value.size() + 1ul;
10324 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(value.size() + 1ul));
10325 oa->write_characters(
10326 reinterpret_cast<const CharType*
>(value.c_str()),
10343 return (std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)()
10344 ?
sizeof(std::int32_t)
10345 :
sizeof(std::int64_t);
10352 const std::int64_t value)
10354 if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)())
10357 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(value));
10362 write_number<std::int64_t, true>(
static_cast<std::int64_t
>(value));
10371 return (value <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int32_t>::max)()))
10372 ?
sizeof(std::int32_t)
10373 :
sizeof(std::int64_t);
10380 const std::uint64_t value)
10382 if (value <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int32_t>::max)()))
10385 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(value));
10387 else if (value <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int64_t>::max)()))
10390 write_number<std::int64_t, true>(
static_cast<std::int64_t
>(value));
10402 const typename BasicJsonType::object_t& value)
10413 std::size_t embedded_document_size = 0ul;
10414 std::size_t array_index = 0ul;
10416 for (
const auto& el : value)
10421 return sizeof(std::int32_t) + embedded_document_size + 1ul;
10428 const typename BasicJsonType::array_t& value)
10433 std::size_t array_index = 0ul;
10435 for (
const auto& el : value)
10448 const BasicJsonType& j)
10460 return header_size + 1ul;
10463 return header_size + 8ul;
10475 return header_size + 0ul;
10493 const BasicJsonType& j)
10537 std::size_t document_size = std::accumulate(value.begin(), value.end(), 0ul,
10538 [](
size_t result,
const typename BasicJsonType::object_t::value_type & el)
10540 return result += calc_bson_element_size(el.first, el.second);
10543 return sizeof(std::int32_t) + document_size + 1ul;
10554 for (
const auto& el : value)
10595 template<
typename NumberType,
typename std::enable_if<
10596 std::is_floating_point<NumberType>::value,
int>::type = 0>
10598 const bool add_prefix)
10608 template<
typename NumberType,
typename std::enable_if<
10609 std::is_unsigned<NumberType>::value,
int>::type = 0>
10611 const bool add_prefix)
10613 if (n <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int8_t>::max)()))
10621 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
10629 else if (n <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int16_t>::max)()))
10637 else if (n <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int32_t>::max)()))
10645 else if (n <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int64_t>::max)()))
10660 template<
typename NumberType,
typename std::enable_if<
10661 std::is_signed<NumberType>::value and
10662 not std::is_floating_point<NumberType>::value,
int>::type = 0>
10664 const bool add_prefix)
10666 if ((std::numeric_limits<std::int8_t>::min)() <= n and n <= (std::numeric_limits<std::int8_t>::max)())
10674 else if (
static_cast<std::int64_t
>((std::numeric_limits<std::uint8_t>::min)()) <= n and n <=
static_cast<std::int64_t
>((std::numeric_limits<std::uint8_t>::max)()))
10682 else if ((std::numeric_limits<std::int16_t>::min)() <= n and n <= (std::numeric_limits<std::int16_t>::max)())
10690 else if ((std::numeric_limits<std::int32_t>::min)() <= n and n <= (std::numeric_limits<std::int32_t>::max)())
10698 else if ((std::numeric_limits<std::int64_t>::min)() <= n and n <= (std::numeric_limits<std::int64_t>::max)())
10731 return j.m_value.boolean ?
'T' :
'F';
10735 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
10739 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
10743 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
10747 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
10757 if (j.m_value.number_unsigned <= (std::numeric_limits<std::int8_t>::max)())
10761 if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
10765 if (j.m_value.number_unsigned <= (std::numeric_limits<std::int16_t>::max)())
10769 if (j.m_value.number_unsigned <= (std::numeric_limits<std::int32_t>::max)())
10819 template<
typename NumberType,
bool OutputIsLittleEndian = false>
10823 std::array<CharType,
sizeof(NumberType)> vec;
10824 std::memcpy(vec.data(), &n,
sizeof(NumberType));
10830 std::reverse(vec.begin(), vec.end());
10833 oa->write_characters(vec.data(),
sizeof(NumberType));
10841 template <
typename C = CharType,
10845 return *
reinterpret_cast<char*
>(&x);
10848 template <
typename C = CharType,
10852 static_assert(
sizeof(std::uint8_t) ==
sizeof(CharType),
"size of CharType must be equal to std::uint8_t");
10853 static_assert(std::is_pod<CharType>::value,
"CharType must be POD");
10855 std::memcpy(&result, &x,
sizeof(x));
10859 template<
typename C = CharType,
10866 template <
typename InputCharType,
typename C = CharType,
10868 std::is_signed<C>::value and
10869 std::is_signed<char>::value and
10870 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
10892#include <algorithm>
10903#include <type_traits>
10916#include <type_traits>
10942 namespace dtoa_impl
10945 template <
typename Target,
typename Source>
10948 static_assert(
sizeof(Target) ==
sizeof(Source),
"size mismatch");
10951 std::memcpy(&target, &source,
sizeof(Source));
10962 constexpr diyfp(std::uint64_t f_,
int e_) noexcept :
f(f_),
e(e_) {}
10970 assert(x.e == y.e);
10971 assert(x.f >= y.f);
10973 return {x.f - y.f, x.e};
10982 static_assert(
kPrecision == 64,
"internal error");
11007 const std::uint64_t u_lo = x.
f & 0xFFFFFFFFu;
11008 const std::uint64_t u_hi = x.f >> 32u;
11009 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
11010 const std::uint64_t v_hi = y.f >> 32u;
11012 const std::uint64_t p0 = u_lo * v_lo;
11013 const std::uint64_t p1 = u_lo * v_hi;
11014 const std::uint64_t p2 = u_hi * v_lo;
11015 const std::uint64_t p3 = u_hi * v_hi;
11017 const std::uint64_t p0_hi = p0 >> 32u;
11018 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
11019 const std::uint64_t p1_hi = p1 >> 32u;
11020 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
11021 const std::uint64_t p2_hi = p2 >> 32u;
11023 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
11034 Q += std::uint64_t{1} << (64u - 32u - 1u);
11036 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
11038 return {h, x.e + y.e + 64};
11049 while ((x.f >> 63u) == 0)
11064 const int delta = x.
e - target_exponent;
11066 assert(delta >= 0);
11067 assert(((x.f << delta) >> delta) == x.f);
11069 return {x.f << delta, target_exponent};
11086 template <
typename FloatType>
11089 assert(std::isfinite(value));
11099 static_assert(std::numeric_limits<FloatType>::is_iec559,
11100 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
11102 constexpr int kPrecision = std::numeric_limits<FloatType>::digits;
11103 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
11104 constexpr int kMinExp = 1 - kBias;
11105 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1);
11107 using bits_type =
typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
11109 const std::uint64_t bits = reinterpret_bits<bits_type>(value);
11110 const std::uint64_t E = bits >> (kPrecision - 1);
11111 const std::uint64_t F = bits & (kHiddenBit - 1);
11113 const bool is_denormal = E == 0;
11114 const diyfp v = is_denormal
11115 ?
diyfp(F, kMinExp)
11116 :
diyfp(F + kHiddenBit,
static_cast<int>(E) - kBias);
11139 const bool lower_boundary_is_closer = F == 0 and E > 1;
11141 const diyfp m_minus = lower_boundary_is_closer
11142 ?
diyfp(4 * v.
f - 1, v.
e - 2)
11143 :
diyfp(2 * v.
f - 1, v.
e - 1);
11278 constexpr int kCachedPowersMinDecExp = -300;
11279 constexpr int kCachedPowersDecStep = 8;
11281 static constexpr std::array<cached_power, 79> kCachedPowers =
11284 { 0xAB70FE17C79AC6CA, -1060, -300 },
11285 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
11286 { 0xBE5691EF416BD60C, -1007, -284 },
11287 { 0x8DD01FAD907FFC3C, -980, -276 },
11288 { 0xD3515C2831559A83, -954, -268 },
11289 { 0x9D71AC8FADA6C9B5, -927, -260 },
11290 { 0xEA9C227723EE8BCB, -901, -252 },
11291 { 0xAECC49914078536D, -874, -244 },
11292 { 0x823C12795DB6CE57, -847, -236 },
11293 { 0xC21094364DFB5637, -821, -228 },
11294 { 0x9096EA6F3848984F, -794, -220 },
11295 { 0xD77485CB25823AC7, -768, -212 },
11296 { 0xA086CFCD97BF97F4, -741, -204 },
11297 { 0xEF340A98172AACE5, -715, -196 },
11298 { 0xB23867FB2A35B28E, -688, -188 },
11299 { 0x84C8D4DFD2C63F3B, -661, -180 },
11300 { 0xC5DD44271AD3CDBA, -635, -172 },
11301 { 0x936B9FCEBB25C996, -608, -164 },
11302 { 0xDBAC6C247D62A584, -582, -156 },
11303 { 0xA3AB66580D5FDAF6, -555, -148 },
11304 { 0xF3E2F893DEC3F126, -529, -140 },
11305 { 0xB5B5ADA8AAFF80B8, -502, -132 },
11306 { 0x87625F056C7C4A8B, -475, -124 },
11307 { 0xC9BCFF6034C13053, -449, -116 },
11308 { 0x964E858C91BA2655, -422, -108 },
11309 { 0xDFF9772470297EBD, -396, -100 },
11310 { 0xA6DFBD9FB8E5B88F, -369, -92 },
11311 { 0xF8A95FCF88747D94, -343, -84 },
11312 { 0xB94470938FA89BCF, -316, -76 },
11313 { 0x8A08F0F8BF0F156B, -289, -68 },
11314 { 0xCDB02555653131B6, -263, -60 },
11315 { 0x993FE2C6D07B7FAC, -236, -52 },
11316 { 0xE45C10C42A2B3B06, -210, -44 },
11317 { 0xAA242499697392D3, -183, -36 },
11318 { 0xFD87B5F28300CA0E, -157, -28 },
11319 { 0xBCE5086492111AEB, -130, -20 },
11320 { 0x8CBCCC096F5088CC, -103, -12 },
11321 { 0xD1B71758E219652C, -77, -4 },
11322 { 0x9C40000000000000, -50, 4 },
11323 { 0xE8D4A51000000000, -24, 12 },
11324 { 0xAD78EBC5AC620000, 3, 20 },
11325 { 0x813F3978F8940984, 30, 28 },
11326 { 0xC097CE7BC90715B3, 56, 36 },
11327 { 0x8F7E32CE7BEA5C70, 83, 44 },
11328 { 0xD5D238A4ABE98068, 109, 52 },
11329 { 0x9F4F2726179A2245, 136, 60 },
11330 { 0xED63A231D4C4FB27, 162, 68 },
11331 { 0xB0DE65388CC8ADA8, 189, 76 },
11332 { 0x83C7088E1AAB65DB, 216, 84 },
11333 { 0xC45D1DF942711D9A, 242, 92 },
11334 { 0x924D692CA61BE758, 269, 100 },
11335 { 0xDA01EE641A708DEA, 295, 108 },
11336 { 0xA26DA3999AEF774A, 322, 116 },
11337 { 0xF209787BB47D6B85, 348, 124 },
11338 { 0xB454E4A179DD1877, 375, 132 },
11339 { 0x865B86925B9BC5C2, 402, 140 },
11340 { 0xC83553C5C8965D3D, 428, 148 },
11341 { 0x952AB45CFA97A0B3, 455, 156 },
11342 { 0xDE469FBD99A05FE3, 481, 164 },
11343 { 0xA59BC234DB398C25, 508, 172 },
11344 { 0xF6C69A72A3989F5C, 534, 180 },
11345 { 0xB7DCBF5354E9BECE, 561, 188 },
11346 { 0x88FCF317F22241E2, 588, 196 },
11347 { 0xCC20CE9BD35C78A5, 614, 204 },
11348 { 0x98165AF37B2153DF, 641, 212 },
11349 { 0xE2A0B5DC971F303A, 667, 220 },
11350 { 0xA8D9D1535CE3B396, 694, 228 },
11351 { 0xFB9B7CD9A4A7443C, 720, 236 },
11352 { 0xBB764C4CA7A44410, 747, 244 },
11353 { 0x8BAB8EEFB6409C1A, 774, 252 },
11354 { 0xD01FEF10A657842C, 800, 260 },
11355 { 0x9B10A4E5E9913129, 827, 268 },
11356 { 0xE7109BFBA19C0C9D, 853, 276 },
11357 { 0xAC2820D9623BF429, 880, 284 },
11358 { 0x80444B5E7AA7CF85, 907, 292 },
11359 { 0xBF21E44003ACDD2D, 933, 300 },
11360 { 0x8E679C2F5E44FF8F, 960, 308 },
11361 { 0xD433179D9C8CB841, 986, 316 },
11362 { 0x9E19DB92B4E31BA9, 1013, 324 },
11370 assert(e >= -1500);
11372 const int f =
kAlpha - e - 1;
11373 const int k = (f * 78913) / (1 << 18) +
static_cast<int>(f > 0);
11375 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
11376 assert(index >= 0);
11377 assert(
static_cast<std::size_t
>(index) < kCachedPowers.size());
11379 const cached_power cached = kCachedPowers[
static_cast<std::size_t
>(index)];
11380 assert(
kAlpha <= cached.
e + e + 64);
11381 assert(
kGamma >= cached.
e + e + 64);
11393 if (n >= 1000000000)
11395 pow10 = 1000000000;
11399 else if (n >= 100000000)
11404 else if (n >= 10000000)
11409 else if (n >= 1000000)
11414 else if (n >= 100000)
11419 else if (n >= 10000)
11424 else if (n >= 1000)
11446 inline void grisu2_round(
char* buf,
int len, std::uint64_t dist, std::uint64_t delta,
11447 std::uint64_t rest, std::uint64_t ten_k)
11450 assert(dist <= delta);
11451 assert(rest <= delta);
11474 and delta - rest >= ten_k
11475 and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
11477 assert(buf[len - 1] !=
'0');
11490 static_assert(
kAlpha >= -60,
"internal error");
11491 static_assert(
kGamma <= -32,
"internal error");
11508 std::uint64_t delta =
diyfp::sub(M_plus, M_minus).
f;
11518 const diyfp one(std::uint64_t{1} << -M_plus.
e, M_plus.
e);
11520 auto p1 =
static_cast<std::uint32_t
>(M_plus.
f >> -one.e);
11521 std::uint64_t p2 = M_plus.
f & (one.f - 1);
11529 std::uint32_t pow10;
11557 const std::uint32_t d = p1 / pow10;
11558 const std::uint32_t r = p1 % pow10;
11564 buffer[length++] =
static_cast<char>(
'0' + d);
11583 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
11588 decimal_exponent += n;
11599 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
11600 grisu2_round(buffer, length, dist, delta, rest, ten_n);
11650 assert(p2 > delta);
11661 assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
11663 const std::uint64_t d = p2 >> -one.e;
11664 const std::uint64_t r = p2 & (one.f - 1);
11671 buffer[length++] =
static_cast<char>(
'0' + d);
11696 decimal_exponent -= m;
11704 const std::uint64_t ten_m = one.f;
11727 inline void grisu2(
char* buf,
int& len,
int& decimal_exponent,
11730 assert(m_plus.
e == m_minus.
e);
11731 assert(m_plus.
e == v.
e);
11744 const diyfp c_minus_k(cached.
f, cached.
e);
11772 const diyfp M_minus(w_minus.
f + 1, w_minus.
e);
11773 const diyfp M_plus (w_plus.
f - 1, w_plus.
e );
11775 decimal_exponent = -cached.
k;
11785 template <
typename FloatType>
11786 void grisu2(
char* buf,
int& len,
int& decimal_exponent, FloatType value)
11789 "internal error: not enough precision");
11791 assert(std::isfinite(value));
11839 auto k =
static_cast<std::uint32_t
>(e);
11845 *buf++ =
static_cast<char>(
'0' + k);
11849 *buf++ =
static_cast<char>(
'0' + k / 10);
11851 *buf++ =
static_cast<char>(
'0' + k);
11855 *buf++ =
static_cast<char>(
'0' + k / 100);
11857 *buf++ =
static_cast<char>(
'0' + k / 10);
11859 *buf++ =
static_cast<char>(
'0' + k);
11875 int min_exp,
int max_exp)
11877 assert(min_exp < 0);
11878 assert(max_exp > 0);
11881 const int n = len + decimal_exponent;
11887 if (k <= n and n <= max_exp)
11892 std::memset(buf + k,
'0',
static_cast<size_t>(n - k));
11896 return buf + (n + 2);
11899 if (0 < n and n <= max_exp)
11906 std::memmove(buf + (n + 1), buf + n,
static_cast<size_t>(k - n));
11908 return buf + (k + 1);
11911 if (min_exp < n and n <= 0)
11916 std::memmove(buf + (2 + -n), buf,
static_cast<size_t>(k));
11919 std::memset(buf + 2,
'0',
static_cast<size_t>(-n));
11920 return buf + (2 + (-n) + k);
11935 std::memmove(buf + 2, buf + 1,
static_cast<size_t>(k - 1));
11956 template <
typename FloatType>
11957 char*
to_chars(
char* first,
const char* last, FloatType value)
11959 static_cast<void>(last);
11960 assert(std::isfinite(value));
11963 if (std::signbit(value))
11978 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
11985 int decimal_exponent = 0;
11988 assert(len <= std::numeric_limits<FloatType>::max_digits10);
11991 constexpr int kMinExp = -4;
11993 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
11995 assert(last - first >= kMaxExp + 2);
11996 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
11997 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
12034 template<
typename BasicJsonType>
12053 ,
loc(
std::localeconv())
12085 void dump(
const BasicJsonType& val,
const bool pretty_print,
12086 const bool ensure_ascii,
12087 const unsigned int indent_step,
12088 const unsigned int current_indent = 0)
12090 switch (val.m_type)
12094 if (val.m_value.object->empty())
12096 o->write_characters(
"{}", 2);
12102 o->write_characters(
"{\n", 2);
12105 const auto new_indent = current_indent + indent_step;
12112 auto i = val.m_value.object->cbegin();
12113 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
12116 o->write_character(
'\"');
12118 o->write_characters(
"\": ", 3);
12119 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
12120 o->write_characters(
",\n", 2);
12124 assert(i != val.m_value.object->cend());
12125 assert(std::next(i) == val.m_value.object->cend());
12127 o->write_character(
'\"');
12129 o->write_characters(
"\": ", 3);
12130 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
12132 o->write_character(
'\n');
12134 o->write_character(
'}');
12138 o->write_character(
'{');
12141 auto i = val.m_value.object->cbegin();
12142 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
12144 o->write_character(
'\"');
12146 o->write_characters(
"\":", 2);
12147 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
12148 o->write_character(
',');
12152 assert(i != val.m_value.object->cend());
12153 assert(std::next(i) == val.m_value.object->cend());
12154 o->write_character(
'\"');
12156 o->write_characters(
"\":", 2);
12157 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
12159 o->write_character(
'}');
12167 if (val.m_value.array->empty())
12169 o->write_characters(
"[]", 2);
12175 o->write_characters(
"[\n", 2);
12178 const auto new_indent = current_indent + indent_step;
12185 for (
auto i = val.m_value.array->cbegin();
12186 i != val.m_value.array->cend() - 1; ++i)
12189 dump(*i,
true, ensure_ascii, indent_step, new_indent);
12190 o->write_characters(
",\n", 2);
12194 assert(not val.m_value.array->empty());
12196 dump(val.m_value.array->back(),
true, ensure_ascii, indent_step, new_indent);
12198 o->write_character(
'\n');
12200 o->write_character(
']');
12204 o->write_character(
'[');
12207 for (
auto i = val.m_value.array->cbegin();
12208 i != val.m_value.array->cend() - 1; ++i)
12210 dump(*i,
false, ensure_ascii, indent_step, current_indent);
12211 o->write_character(
',');
12215 assert(not val.m_value.array->empty());
12216 dump(val.m_value.array->back(),
false, ensure_ascii, indent_step, current_indent);
12218 o->write_character(
']');
12226 o->write_character(
'\"');
12228 o->write_character(
'\"');
12234 if (val.m_value.boolean)
12236 o->write_characters(
"true", 4);
12240 o->write_characters(
"false", 5);
12265 o->write_characters(
"<discarded>", 11);
12271 o->write_characters(
"null", 4);
12297 std::uint32_t codepoint;
12299 std::size_t bytes = 0;
12302 std::size_t bytes_after_last_accept = 0;
12303 std::size_t undumped_chars = 0;
12305 for (std::size_t i = 0; i < s.size(); ++i)
12307 const auto byte =
static_cast<uint8_t
>(s[i]);
12309 switch (
decode(state, codepoint,
byte))
12368 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
12370 if (codepoint <= 0xFFFF)
12372 (std::snprintf)(
string_buffer.data() + bytes, 7,
"\\u%04x",
12373 static_cast<std::uint16_t
>(codepoint));
12378 (std::snprintf)(
string_buffer.data() + bytes, 13,
"\\u%04x\\u%04x",
12379 static_cast<std::uint16_t
>(0xD7C0u + (codepoint >> 10u)),
12380 static_cast<std::uint16_t
>(0xDC00u + (codepoint & 0x3FFu)));
12404 bytes_after_last_accept = bytes;
12405 undumped_chars = 0;
12415 std::string sn(3,
'\0');
12416 (std::snprintf)(&sn[0], sn.size(),
"%.2X", byte);
12427 if (undumped_chars > 0)
12434 bytes = bytes_after_last_accept;
12464 bytes_after_last_accept = bytes;
12467 undumped_chars = 0;
12482 if (not ensure_ascii)
12509 std::string sn(3,
'\0');
12510 (std::snprintf)(&sn[0], sn.size(),
"%.2X",
static_cast<std::uint8_t
>(s.back()));
12517 o->write_characters(
string_buffer.data(), bytes_after_last_accept);
12524 o->write_characters(
string_buffer.data(), bytes_after_last_accept);
12528 o->write_characters(
"\\ufffd", 6);
12532 o->write_characters(
"\xEF\xBF\xBD", 3);
12553 unsigned int n_digits = 1;
12562 return n_digits + 1;
12566 return n_digits + 2;
12570 return n_digits + 3;
12587 std::is_same<NumberType, number_unsigned_t>::value or
12588 std::is_same<NumberType, number_integer_t>::value,
12592 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
12595 {{
'0',
'0'}}, {{
'0',
'1'}}, {{
'0',
'2'}}, {{
'0',
'3'}}, {{
'0',
'4'}}, {{
'0',
'5'}}, {{
'0',
'6'}}, {{
'0',
'7'}}, {{
'0',
'8'}}, {{
'0',
'9'}},
12596 {{
'1',
'0'}}, {{
'1',
'1'}}, {{
'1',
'2'}}, {{
'1',
'3'}}, {{
'1',
'4'}}, {{
'1',
'5'}}, {{
'1',
'6'}}, {{
'1',
'7'}}, {{
'1',
'8'}}, {{
'1',
'9'}},
12597 {{
'2',
'0'}}, {{
'2',
'1'}}, {{
'2',
'2'}}, {{
'2',
'3'}}, {{
'2',
'4'}}, {{
'2',
'5'}}, {{
'2',
'6'}}, {{
'2',
'7'}}, {{
'2',
'8'}}, {{
'2',
'9'}},
12598 {{
'3',
'0'}}, {{
'3',
'1'}}, {{
'3',
'2'}}, {{
'3',
'3'}}, {{
'3',
'4'}}, {{
'3',
'5'}}, {{
'3',
'6'}}, {{
'3',
'7'}}, {{
'3',
'8'}}, {{
'3',
'9'}},
12599 {{
'4',
'0'}}, {{
'4',
'1'}}, {{
'4',
'2'}}, {{
'4',
'3'}}, {{
'4',
'4'}}, {{
'4',
'5'}}, {{
'4',
'6'}}, {{
'4',
'7'}}, {{
'4',
'8'}}, {{
'4',
'9'}},
12600 {{
'5',
'0'}}, {{
'5',
'1'}}, {{
'5',
'2'}}, {{
'5',
'3'}}, {{
'5',
'4'}}, {{
'5',
'5'}}, {{
'5',
'6'}}, {{
'5',
'7'}}, {{
'5',
'8'}}, {{
'5',
'9'}},
12601 {{
'6',
'0'}}, {{
'6',
'1'}}, {{
'6',
'2'}}, {{
'6',
'3'}}, {{
'6',
'4'}}, {{
'6',
'5'}}, {{
'6',
'6'}}, {{
'6',
'7'}}, {{
'6',
'8'}}, {{
'6',
'9'}},
12602 {{
'7',
'0'}}, {{
'7',
'1'}}, {{
'7',
'2'}}, {{
'7',
'3'}}, {{
'7',
'4'}}, {{
'7',
'5'}}, {{
'7',
'6'}}, {{
'7',
'7'}}, {{
'7',
'8'}}, {{
'7',
'9'}},
12603 {{
'8',
'0'}}, {{
'8',
'1'}}, {{
'8',
'2'}}, {{
'8',
'3'}}, {{
'8',
'4'}}, {{
'8',
'5'}}, {{
'8',
'6'}}, {{
'8',
'7'}}, {{
'8',
'8'}}, {{
'8',
'9'}},
12604 {{
'9',
'0'}}, {{
'9',
'1'}}, {{
'9',
'2'}}, {{
'9',
'3'}}, {{
'9',
'4'}}, {{
'9',
'5'}}, {{
'9',
'6'}}, {{
'9',
'7'}}, {{
'9',
'8'}}, {{
'9',
'9'}},
12611 o->write_character(
'0');
12618 const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not(x >= 0);
12621 unsigned int n_chars;
12642 buffer_ptr += n_chars;
12646 while (abs_value >= 100)
12648 const auto digits_index =
static_cast<unsigned>((abs_value % 100));
12650 *(--buffer_ptr) = digits_to_99[digits_index][1];
12651 *(--buffer_ptr) = digits_to_99[digits_index][0];
12654 if (abs_value >= 10)
12656 const auto digits_index =
static_cast<unsigned>(abs_value);
12657 *(--buffer_ptr) = digits_to_99[digits_index][1];
12658 *(--buffer_ptr) = digits_to_99[digits_index][0];
12662 *(--buffer_ptr) =
static_cast<char>(
'0' + abs_value);
12679 if (not std::isfinite(x))
12681 o->write_characters(
"null", 4);
12690 static constexpr bool is_ieee_single_or_double
12691 = (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
12692 (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);
12694 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
12702 o->write_characters(begin,
static_cast<size_t>(end - begin));
12708 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
12716 assert(
static_cast<std::size_t
>(len) <
number_buffer.size());
12738 o->write_characters(
number_buffer.data(),
static_cast<std::size_t
>(len));
12741 const bool value_is_int_like =
12745 return c ==
'.' or c ==
'e';
12748 if (value_is_int_like)
12750 o->write_characters(
".0", 2);
12775 static std::uint8_t
decode(std::uint8_t& state, std::uint32_t& codep,
const std::uint8_t
byte)
noexcept
12777 static const std::array<std::uint8_t, 400> utf8d =
12780 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,
12781 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,
12782 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,
12783 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,
12784 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,
12785 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,
12786 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,
12787 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
12788 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
12789 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
12790 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,
12791 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,
12792 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,
12793 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
12797 const std::uint8_t type = utf8d[byte];
12800 ? (
byte & 0x3fu) | (codep << 6u)
12801 : (0xFFu >> type) & (byte);
12803 state = utf8d[256u + state * 16u + type];
12934 friend ::nlohmann::json_pointer<basic_json>;
12935 friend ::nlohmann::detail::parser<basic_json>;
12936 friend ::nlohmann::detail::serializer<basic_json>;
12937 template<
typename BasicJsonType>
12938 friend class ::nlohmann::detail::iter_impl;
12939 template<
typename BasicJsonType,
typename CharType>
12940 friend class ::nlohmann::detail::binary_writer;
12941 template<
typename BasicJsonType,
typename SAX>
12942 friend class ::nlohmann::detail::binary_reader;
12943 template<
typename BasicJsonType>
12944 friend class ::nlohmann::detail::json_sax_dom_parser;
12945 template<
typename BasicJsonType>
12946 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
12956 template<
typename BasicJsonType>
12958 template<
typename BasicJsonType>
12960 template<
typename Iterator>
12964 template<
typename CharType>
12976 template<
typename T,
typename SFINAE>
13037 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
13039 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
13092 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
13093 result[
"name"] =
"JSON for Modern C++";
13094 result[
"url"] =
"https://github.com/nlohmann/json";
13095 result[
"version"][
"string"] =
13104 result[
"platform"] =
"win32";
13105#elif defined __linux__
13106 result[
"platform"] =
"linux";
13107#elif defined __APPLE__
13108 result[
"platform"] =
"apple";
13109#elif defined __unix__
13110 result[
"platform"] =
"unix";
13112 result[
"platform"] =
"unknown";
13115#if defined(__ICC) || defined(__INTEL_COMPILER)
13116 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
13117#elif defined(__clang__)
13118 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
13119#elif defined(__GNUC__) || defined(__GNUG__)
13120 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(__GNUC_PATCHLEVEL__)}};
13121#elif defined(__HP_cc) || defined(__HP_aCC)
13122 result[
"compiler"] =
"hp"
13123#elif defined(__IBMCPP__)
13124 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
13125#elif defined(_MSC_VER)
13126 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
13127#elif defined(__PGI)
13128 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
13129#elif defined(__SUNPRO_CC)
13130 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
13132 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
13136 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
13138 result[
"compiler"][
"c++"] =
"unknown";
13153#if defined(JSON_HAS_CPP_14)
13247 AllocatorType<std::pair<
const StringType,
13294 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
13591 template<
typename T,
typename... Args>
13594 AllocatorType<T> alloc;
13595 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
13597 auto deleter = [&](T *
object)
13599 AllocatorTraits::deallocate(alloc,
object, 1);
13601 std::unique_ptr<T,
decltype(deleter)>
object(AllocatorTraits::allocate(alloc, 1), deleter);
13602 AllocatorTraits::construct(alloc,
object.
get(), std::forward<Args>(args)...);
13603 assert(
object !=
nullptr);
13604 return object.release();
13669 object = create<object_t>();
13675 array = create<array_t>();
13681 string = create<string_t>(
"");
13730 string = create<string_t>(
value);
13736 string = create<string_t>(std::move(
value));
13742 object = create<object_t>(
value);
13748 object = create<object_t>(std::move(
value));
13769 AllocatorType<object_t> alloc;
13770 std::allocator_traits<
decltype(alloc)>
::destroy(alloc,
object);
13771 std::allocator_traits<
decltype(alloc)>::deallocate(alloc,
object, 1);
13777 AllocatorType<array_t> alloc;
13779 std::allocator_traits<
decltype(alloc)>::deallocate(alloc,
array, 1);
13785 AllocatorType<string_t> alloc;
13786 std::allocator_traits<
decltype(alloc)>
::destroy(alloc,
string);
13787 std::allocator_traits<
decltype(alloc)>::deallocate(alloc,
string, 1);
14013 template <
typename CompatibleType,
14019 std::forward<CompatibleType>(val))))
14051 template <
typename BasicJsonType,
14056 using other_boolean_t =
typename BasicJsonType::boolean_t;
14057 using other_number_float_t =
typename BasicJsonType::number_float_t;
14058 using other_number_integer_t =
typename BasicJsonType::number_integer_t;
14059 using other_number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
14060 using other_string_t =
typename BasicJsonType::string_t;
14061 using other_object_t =
typename BasicJsonType::object_t;
14062 using other_array_t =
typename BasicJsonType::array_t;
14064 switch (val.type())
14174 bool type_deduction =
true,
14179 bool is_an_object = std::all_of(init.begin(), init.end(),
14182 return element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string();
14186 if (not type_deduction)
14191 is_an_object =
false;
14209 auto element = element_ref.moved_or_copied();
14210 m_value.object->emplace(
14211 std::move(*((*element.m_value.array)[0].m_value.string)),
14212 std::move((*element.m_value.array)[1]));
14219 m_value.
array = create<array_t>(init.begin(), init.end());
14396 template<
class InputIT,
typename std::enable_if<
14397 std::is_same<InputIT, typename basic_json_t::iterator>::value or
14398 std::is_same<InputIT, typename basic_json_t::const_iterator>::value,
int>
::type = 0>
14401 assert(first.m_object !=
nullptr);
14402 assert(last.m_object !=
nullptr);
14411 m_type = first.m_object->m_type;
14422 if (
JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
14423 or not last.m_it.primitive_iterator.is_end()))
14468 m_value.
object = create<object_t>(first.m_it.object_iterator,
14469 last.m_it.object_iterator);
14475 m_value.
array = create<array_t>(first.m_it.array_iterator,
14476 last.m_it.array_iterator);
14482 std::string(first.m_object->type_name())));
14607 :
m_type(std::move(other.m_type)),
14608 m_value(std::move(other.m_value))
14611 other.assert_invariant();
14615 other.m_value = {};
14644 std::is_nothrow_move_constructible<value_t>::value and
14645 std::is_nothrow_move_assignable<value_t>::value and
14646 std::is_nothrow_move_constructible<json_value>::value and
14647 std::is_nothrow_move_assignable<json_value>::value
14735 const char indent_char =
' ',
14736 const bool ensure_ascii =
false,
14744 s.
dump(*
this,
true, ensure_ascii,
static_cast<unsigned int>(indent));
14748 s.
dump(*
this,
false, ensure_ascii, 0);
15239 template<
typename ReferenceType,
typename ThisType>
15243 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
15296 not std::is_same<BasicJsonType, basic_json>::value and
15342 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
15343 detail::enable_if_t <
15344 not detail::is_basic_json<ValueType>::value and
15345 detail::has_from_json<basic_json_t, ValueType>::value and
15346 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
15348 ValueType
get() const noexcept(noexcept(
15354 static_assert(not std::is_reference<ValueTypeCV>::value,
15355 "get() cannot be used with reference types, you might want to use get_ref()");
15356 static_assert(std::is_default_constructible<ValueType>::value,
15357 "types must be DefaultConstructible when used with get()");
15395 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
15396 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
15397 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
15399 ValueType
get() const noexcept(noexcept(
15402 static_assert(not std::is_reference<ValueTypeCV>::value,
15403 "get() cannot be used with reference types, you might want to use get_ref()");
15440 template<
typename ValueType,
15445 ValueType &
get_to(ValueType& v)
const noexcept(
noexcept(
15479 template<
typename PointerType,
typename std::enable_if<
15480 std::is_pointer<PointerType>::value,
int>
::type = 0>
15484 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
15491 template<
typename PointerType,
typename std::enable_if<
15492 std::is_pointer<PointerType>::value and
15493 std::is_const<typename std::remove_pointer<PointerType>::type>
::value,
int>
::type = 0>
15497 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
15527 template<
typename PointerType,
typename std::enable_if<
15528 std::is_pointer<PointerType>::value,
int>
::type = 0>
15532 return get_ptr<PointerType>();
15539 template<
typename PointerType,
typename std::enable_if<
15540 std::is_pointer<PointerType>::value,
int>
::type = 0>
15544 return get_ptr<PointerType>();
15573 template<
typename ReferenceType,
typename std::enable_if<
15574 std::is_reference<ReferenceType>::value,
int>
::type = 0>
15578 return get_ref_impl<ReferenceType>(*
this);
15585 template<
typename ReferenceType,
typename std::enable_if<
15586 std::is_reference<ReferenceType>::value and
15587 std::is_const<typename std::remove_reference<ReferenceType>::type>
::value,
int>
::type = 0>
15591 return get_ref_impl<ReferenceType>(*
this);
15623 template <
typename ValueType,
typename std::enable_if <
15624 not std::is_pointer<ValueType>::value and
15625 not std::is_same<ValueType, detail::json_ref<basic_json>>
::value and
15626 not std::is_same<ValueType, typename string_t::value_type>::value and
15630 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>
::value
15631 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) and _MSC_VER <= 1914))
15632 and not std::is_same<ValueType, typename std::string_view>::value
15637 operator ValueType()
const
15640 return get<ValueType>();
16047 template<
typename T>
16097 template<
typename T>
16158 template<
class ValueType,
typename std::enable_if<
16159 std::is_convertible<basic_json_t, ValueType>::value,
int>
::type = 0>
16160 ValueType
value(
const typename object_t::key_type& key,
const ValueType& default_value)
const
16166 const auto it =
find(key);
16172 return default_value;
16182 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const
16228 template<
class ValueType,
typename std::enable_if<
16229 std::is_convertible<basic_json_t, ValueType>::value,
int>
::type = 0>
16238 return ptr.get_checked(
this);
16242 return default_value;
16390 template<
class IteratorType,
typename std::enable_if<
16391 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
16392 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>
::type
16402 IteratorType result =
end();
16419 AllocatorType<string_t> alloc;
16420 std::allocator_traits<
decltype(alloc)>::destroy(alloc,
m_value.
string);
16421 std::allocator_traits<
decltype(alloc)>::deallocate(alloc,
m_value.
string, 1);
16432 result.m_it.object_iterator =
m_value.
object->erase(
pos.m_it.object_iterator);
16438 result.m_it.array_iterator =
m_value.
array->erase(
pos.m_it.array_iterator);
16495 template<
class IteratorType,
typename std::enable_if<
16496 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
16497 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>
::type
16499 IteratorType
erase(IteratorType first, IteratorType last)
16502 if (
JSON_UNLIKELY(
this != first.m_object or
this != last.m_object))
16507 IteratorType result =
end();
16517 if (
JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
16518 or not last.m_it.primitive_iterator.is_end()))
16525 AllocatorType<string_t> alloc;
16526 std::allocator_traits<
decltype(alloc)>::destroy(alloc,
m_value.
string);
16527 std::allocator_traits<
decltype(alloc)>::deallocate(alloc,
m_value.
string, 1);
16538 result.m_it.object_iterator =
m_value.
object->erase(first.m_it.object_iterator,
16539 last.m_it.object_iterator);
16545 result.m_it.array_iterator =
m_value.
array->erase(first.m_it.array_iterator,
16546 last.m_it.array_iterator);
16673 template<
typename KeyT>
16676 auto result =
end();
16680 result.m_it.object_iterator =
m_value.
object->find(std::forward<KeyT>(key));
16690 template<
typename KeyT>
16693 auto result =
cend();
16697 result.m_it.object_iterator =
m_value.
object->find(std::forward<KeyT>(key));
16724 template<
typename KeyT>
16755 template<
typename KeyT>
17105 return ref.items();
17114 return ref.items();
17671 if (
is_object() and init.size() == 2 and (*init.begin())->is_string())
17674 push_back(
typename object_t::value_type(
17675 std::move(key.
get_ref<
string_t&>()), (init.begin() + 1)->moved_or_copied()));
17714 template<
class... Args>
17732 m_value.
array->emplace_back(std::forward<Args>(args)...);
17762 template<
class... Args>
17780 auto res =
m_value.
object->emplace(std::forward<Args>(args)...);
17783 it.m_it.object_iterator = res.first;
17786 return {it, res.second};
17792 template<
typename... Args>
17798 auto insert_pos = std::distance(
m_value.
array->begin(),
pos.m_it.array_iterator);
17799 m_value.
array->insert(
pos.m_it.array_iterator, std::forward<Args>(args)...);
18085 for (
auto it = j.
cbegin(); it != j.
cend(); ++it)
18140 or not last.
m_object->is_object()))
18145 for (
auto it = first; it != last; ++it)
18169 std::is_nothrow_move_constructible<value_t>::value and
18170 std::is_nothrow_move_assignable<value_t>::value and
18171 std::is_nothrow_move_constructible<json_value>::value and
18172 std::is_nothrow_move_assignable<json_value>::value
18330 const auto lhs_type = lhs.type();
18331 const auto rhs_type = rhs.type();
18333 if (lhs_type == rhs_type)
18338 return *lhs.m_value.array == *rhs.m_value.array;
18341 return *lhs.m_value.object == *rhs.m_value.object;
18347 return *lhs.m_value.string == *rhs.m_value.string;
18350 return lhs.m_value.boolean == rhs.m_value.boolean;
18353 return lhs.m_value.number_integer == rhs.m_value.number_integer;
18356 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
18359 return lhs.m_value.number_float == rhs.m_value.number_float;
18367 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
18371 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
18375 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
18379 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
18383 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
18387 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
18397 template<
typename ScalarType,
typename std::enable_if<
18398 std::is_scalar<ScalarType>::value,
int>
::type = 0>
18408 template<
typename ScalarType,
typename std::enable_if<
18409 std::is_scalar<ScalarType>::value,
int>
::type = 0>
18435 return not (lhs == rhs);
18442 template<
typename ScalarType,
typename std::enable_if<
18443 std::is_scalar<ScalarType>::value,
int>
::type = 0>
18453 template<
typename ScalarType,
typename std::enable_if<
18454 std::is_scalar<ScalarType>::value,
int>
::type = 0>
18488 const auto lhs_type = lhs.type();
18489 const auto rhs_type = rhs.type();
18491 if (lhs_type == rhs_type)
18498 return (*lhs.m_value.array) < (*rhs.m_value.array);
18501 return *lhs.m_value.object < *rhs.m_value.object;
18507 return *lhs.m_value.string < *rhs.m_value.string;
18510 return lhs.m_value.boolean < rhs.m_value.boolean;
18513 return lhs.m_value.number_integer < rhs.m_value.number_integer;
18516 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
18519 return lhs.m_value.number_float < rhs.m_value.number_float;
18527 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
18531 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
18535 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
18539 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
18543 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
18547 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
18560 template<
typename ScalarType,
typename std::enable_if<
18561 std::is_scalar<ScalarType>::value,
int>
::type = 0>
18571 template<
typename ScalarType,
typename std::enable_if<
18572 std::is_scalar<ScalarType>::value,
int>
::type = 0>
18599 return not (rhs < lhs);
18606 template<
typename ScalarType,
typename std::enable_if<
18607 std::is_scalar<ScalarType>::value,
int>
::type = 0>
18617 template<
typename ScalarType,
typename std::enable_if<
18618 std::is_scalar<ScalarType>::value,
int>
::type = 0>
18645 return not (lhs <= rhs);
18652 template<
typename ScalarType,
typename std::enable_if<
18653 std::is_scalar<ScalarType>::value,
int>
::type = 0>
18663 template<
typename ScalarType,
typename std::enable_if<
18664 std::is_scalar<ScalarType>::value,
int>
::type = 0>
18691 return not (lhs < rhs);
18698 template<
typename ScalarType,
typename std::enable_if<
18699 std::is_scalar<ScalarType>::value,
int>
::type = 0>
18709 template<
typename ScalarType,
typename std::enable_if<
18710 std::is_scalar<ScalarType>::value,
int>
::type = 0>
18759 const bool pretty_print = o.width() > 0;
18760 const auto indentation = pretty_print ? o.width() : 0;
18767 s.
dump(j, pretty_print,
false,
static_cast<unsigned int>(indentation));
18861 const bool allow_exceptions =
true)
18864 parser(i, cb, allow_exceptions).parse(
true, result);
18870 return parser(i).accept(
true);
18926 template <
typename SAX>
18929 const bool strict =
true)
18933 ?
parser(std::move(i)).sax_parse(sax, strict)
18986 template<
class IteratorType,
typename std::enable_if<
18988 std::random_access_iterator_tag,
18989 typename std::iterator_traits<IteratorType>::iterator_category>
::value,
int>
::type = 0>
18992 const bool allow_exceptions =
true)
18999 template<
class IteratorType,
typename std::enable_if<
19001 std::random_access_iterator_tag,
19002 typename std::iterator_traits<IteratorType>::iterator_category>
::value,
int>
::type = 0>
19003 static bool accept(IteratorType first, IteratorType last)
19008 template<
class IteratorType,
class SAX,
typename std::enable_if<
19010 std::random_access_iterator_tag,
19011 typename std::iterator_traits<IteratorType>::iterator_category>
::value,
int>
::type = 0>
19012 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
19114 return "discarded";
19423 const bool use_size =
false,
19424 const bool use_type =
false)
19427 to_ubjson(j, result, use_size, use_type);
19432 const bool use_size =
false,
const bool use_type =
false)
19438 const bool use_size =
false,
const bool use_type =
false)
19629 const bool strict =
true,
19630 const bool allow_exceptions =
true)
19641 template<
typename A1,
typename A2,
19645 const bool strict =
true,
19646 const bool allow_exceptions =
true)
19738 const bool strict =
true,
19739 const bool allow_exceptions =
true)
19750 template<
typename A1,
typename A2,
19754 const bool strict =
true,
19755 const bool allow_exceptions =
true)
19826 const bool strict =
true,
19827 const bool allow_exceptions =
true)
19838 template<
typename A1,
typename A2,
19842 const bool strict =
true,
19843 const bool allow_exceptions =
true)
19913 const bool strict =
true,
19914 const bool allow_exceptions =
true)
19925 template<
typename A1,
typename A2,
19929 const bool strict =
true,
19930 const bool allow_exceptions =
true)
19984 return ptr.get_unchecked(
this);
20012 return ptr.get_unchecked(
this);
20055 return ptr.get_checked(
this);
20098 return ptr.get_checked(
this);
20227 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
20229 const auto get_op = [](
const std::string & op)
20233 return patch_operations::add;
20235 if (op ==
"remove")
20237 return patch_operations::remove;
20239 if (op ==
"replace")
20241 return patch_operations::replace;
20245 return patch_operations::move;
20249 return patch_operations::copy;
20253 return patch_operations::test;
20256 return patch_operations::invalid;
20271 if (top_pointer !=
ptr)
20273 result.
at(top_pointer);
20277 const auto last_path =
ptr.back();
20287 parent[last_path] = val;
20293 if (last_path ==
"-")
20323 const auto last_path =
ptr.back();
20331 auto it = parent.
find(last_path);
20355 for (
const auto& val : json_patch)
20358 const auto get_value = [&val](
const std::string & op,
20359 const std::string & member,
20366 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
20375 if (
JSON_UNLIKELY(string_type and not it->second.is_string()))
20391 const std::string op = get_value(
"op",
"op",
true);
20392 const std::string path = get_value(op,
"path",
true);
20395 switch (get_op(op))
20397 case patch_operations::add:
20399 operation_add(
ptr, get_value(
"add",
"value",
false));
20403 case patch_operations::remove:
20405 operation_remove(
ptr);
20409 case patch_operations::replace:
20412 result.
at(
ptr) = get_value(
"replace",
"value",
false);
20416 case patch_operations::move:
20418 const std::string from_path = get_value(
"move",
"from",
true);
20428 operation_remove(from_ptr);
20429 operation_add(
ptr, v);
20433 case patch_operations::copy:
20435 const std::string from_path = get_value(
"copy",
"from",
true);
20444 operation_add(
ptr, v);
20448 case patch_operations::test:
20450 bool success =
false;
20455 success = (result.
at(
ptr) == get_value(
"test",
"value",
false));
20518 const std::string& path =
"")
20524 if (source == target)
20529 if (source.
type() != target.
type())
20534 {
"op",
"replace"}, {
"path", path}, {
"value", target}
20539 switch (source.
type())
20545 while (i < source.
size() and i < target.
size())
20548 auto temp_diff =
diff(source[i], target[i], path +
"/" + std::to_string(i));
20549 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
20558 while (i < source.
size())
20565 {
"path", path +
"/" + std::to_string(i)}
20571 while (i < target.
size())
20576 {
"path", path +
"/" + std::to_string(i)},
20577 {
"value", target[i]}
20588 for (
auto it = source.
cbegin(); it != source.
cend(); ++it)
20593 if (target.
find(it.key()) != target.
end())
20596 auto temp_diff =
diff(it.value(), target[it.key()], path +
"/" + key);
20597 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
20604 {
"op",
"remove"}, {
"path", path +
"/" + key}
20610 for (
auto it = target.
cbegin(); it != target.
cend(); ++it)
20612 if (source.
find(it.key()) == source.
end())
20618 {
"op",
"add"}, {
"path", path +
"/" + key},
20619 {
"value", it.value()}
20632 {
"op",
"replace"}, {
"path", path}, {
"value", target}
20700 for (
auto it = apply_patch.
begin(); it != apply_patch.
end(); ++it)
20702 if (it.value().is_null())
20714 *
this = apply_patch;
20742 const auto& h = hash<nlohmann::json::string_t>();
20743 return h(j.
dump());
20771 is_nothrow_move_constructible<nlohmann::json>::value and
20772 is_nothrow_move_assignable<nlohmann::json>::value
20820#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
20821#pragma GCC diagnostic pop
20823#if defined(__clang__)
20824#pragma GCC diagnostic pop
20828#undef JSON_INTERNAL_CATCH
20833#undef JSON_UNLIKELY
20834#undef JSON_DEPRECATED
20835#undef JSON_NODISCARD
20836#undef JSON_HAS_CPP_14
20837#undef JSON_HAS_CPP_17
20838#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
20839#undef NLOHMANN_BASIC_JSON_TPL
a class to store JSON values
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
reference back()
access the last element
iterator insert(const_iterator pos, const basic_json &val)
inserts element
static T * create(Args &&... args)
helper for exception-safe object creation
static JSON_NODISCARD 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
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
static JSON_DEPRECATED iteration_proxy< const_iterator > iterator_wrapper(const_reference ref) noexcept
wrapper to access iterator member functions in range-based for
IteratorType erase(IteratorType pos)
remove element given an iterator
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
iterator begin() noexcept
returns an iterator to the first element
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
iterator end() noexcept
returns an iterator to one past the last element
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
static JSON_DEPRECATED iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
bool empty() const noexcept
checks whether the container is empty.
void insert(const_iterator first, const_iterator last)
inserts elements
void push_back(initializer_list_t init)
add an object to an object
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
const_iterator end() const noexcept
returns a const iterator to one past the last element
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
iterator insert(const_iterator pos, basic_json &&val)
inserts element
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
reference operator[](const typename object_t::key_type &key)
access specified object element
static JSON_NODISCARD 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
size_type size() const noexcept
returns the number of elements
const_reference operator[](T *key) const
read-only access specified object element
void update(const_iterator first, const_iterator last)
updates a JSON object from another object, overwriting existing keys
static JSON_NODISCARD 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
static JSON_NODISCARD 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.
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
constexpr bool is_number() const noexcept
return whether value is a number
basic_json(const detail::json_ref< basic_json > &ref)
size_type max_size() const noexcept
returns the maximum possible number of elements
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
BasicJsonType get() const
get special-case overload
iterator insert_iterator(const_iterator pos, Args &&... args)
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
std::size_t size_type
a type to represent container sizes
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
reference front()
access the first element
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than
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
static JSON_NODISCARD basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
static void to_ubjson(const basic_json &j, detail::output_adapter< uint8_t > o, const bool use_size=false, const bool use_type=false)
void assert_invariant() const noexcept
checks the class invariants
const_reference front() const
access the first element
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
BooleanType boolean_t
a type for a boolean
static void to_msgpack(const basic_json &j, detail::output_adapter< uint8_t > o)
const_iterator begin() const noexcept
returns a const iterator to the first element
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
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
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
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 char * type_name() const noexcept
return the type as string
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
static JSON_NODISCARD basic_json meta()
returns version information on the library
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
ValueType get() const noexcept(noexcept(JSONSerializer< ValueTypeCV >::from_json(std::declval< const basic_json_t & >())))
get a value (explicit); special case
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
JSON_DEPRECATED friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
static void to_cbor(const basic_json &j, detail::output_adapter< uint8_t > o)
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > > > object_t
a type for an object
friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
::nlohmann::detail::output_adapter_t< CharType > output_adapter_t
StringType string_t
a type for a string
constexpr bool is_primitive() const noexcept
return whether type is primitive
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
void swap(array_t &other)
exchanges the values
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than or equal
constexpr bool is_string() const noexcept
return whether value is a string
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
basic_json get() const
get special-case overload
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
reference at(size_type idx)
access specified array element with bounds checking
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
basic_json unflatten() const
unflatten a previously flattened JSON value
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
basic_json(CompatibleType &&val) noexcept(noexcept(JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value
JSONSerializer< T, SFINAE > json_serializer
friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
::nlohmann::detail::binary_reader< basic_json > binary_reader
friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than or equal
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
const_reference back() const
access the last element
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
string_t value(const json_pointer &ptr, const char *default_value) const
overload for a default value of type const char*
AllocatorType< basic_json > allocator_type
the allocator type
static bool accept(detail::input_adapter &&i)
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
JSON_DEPRECATED friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
void erase(const size_type idx)
remove element from a JSON array given an index
NumberFloatType number_float_t
a type for a number (floating-point)
static JSON_NODISCARD 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.
iterator find(KeyT &&key)
find an element in a JSON object
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
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
const_iterator cend() const noexcept
returns a const iterator to one past the last element
constexpr bool is_null() const noexcept
return whether value is null
value_t m_type
the type of the current element
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
constexpr bool is_boolean() const noexcept
return whether value is a boolean
NumberIntegerType number_integer_t
a type for a number (integer)
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
copy assignment
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
basic_json(basic_json &&other) noexcept
move constructor
static JSON_NODISCARD basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
const_reference operator[](size_type idx) const
access specified array element
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
constexpr bool is_structured() const noexcept
return whether type is structured
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements
ValueType get() const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), std::declval< ValueType & >())))
get a value (explicit)
static bool sax_parse(IteratorType first, IteratorType last, SAX *sax)
constexpr bool is_discarded() const noexcept
return whether value is discarded
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
typename parser::parse_event_t parse_event_t
parser event types
void emplace_back(Args &&... args)
add an object to an array
static JSON_NODISCARD basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
const_reference at(size_type idx) const
access specified array element with bounds checking
static JSON_NODISCARD 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
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
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
void push_back(const basic_json &val)
add an object to an array
typename parser::parser_callback_t parser_callback_t
per-element parser callback type
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
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
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
basic_json flatten() const
return flattened JSON value
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
~basic_json() noexcept
destructor
friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
comparison: equal
::nlohmann::detail::parser< basic_json > parser
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
reference operator[](T *key)
access specified object element
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than
std::less< StringType > object_comparator_t
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
reference operator+=(const typename object_t::value_type &val)
add an object to an object
void clear() noexcept
clears the contents
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
void swap(object_t &other)
exchanges the values
ReferenceType get_ref() const
get a reference value (implicit)
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
reference operator[](size_type idx)
access specified array element
void push_back(basic_json &&val)
add an object to an array
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
constexpr auto get() const noexcept -> decltype(std::declval< const basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
const_iterator cbegin() const noexcept
returns a const iterator to the first element
void swap(string_t &other)
exchanges the values
reference operator+=(const basic_json &val)
add an object to an array
static JSON_NODISCARD 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
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
void push_back(const typename object_t::value_type &val)
add an object to an object
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
const_iterator find(KeyT &&key) const
find an element in a JSON object
static bool accept(IteratorType first, IteratorType last)
static JSON_NODISCARD 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
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
reference operator+=(basic_json &&val)
add an object to an array
json_value m_value
the value of the current element
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...
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 ...
basic_json(const value_t v)
create an empty value with a given type
friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
comparison: equal
constexpr bool is_array() const noexcept
return whether value is an array
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
reference operator+=(initializer_list_t init)
add an object to an object
static allocator_type get_allocator()
returns the allocator associated with the container
basic_json(const basic_json &other)
copy constructor
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
constexpr bool is_object() const noexcept
return whether value is an object
ReferenceType get_ref()
get a reference value (implicit)
static JSON_NODISCARD basic_json parse(detail::input_adapter &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true)
deserialize from a compatible input
std::ptrdiff_t difference_type
a type to represent differences between iterators
friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
comparison: not equal
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
NLOHMANN_BASIC_JSON_TPL basic_json_t
workaround type for MSVC
deserialization of CBOR, MessagePack, and UBJSON values
bool get_bson_cstr(string_t &result)
Parses a C-style string from the BSON input.
bool get_msgpack_array(const std::size_t len)
binary_reader & operator=(const binary_reader &)=delete
typename BasicJsonType::number_unsigned_t number_unsigned_t
bool get_number(const input_format_t format, NumberType &result)
static constexpr bool little_endianess(int num=1) noexcept
determine system byte order
bool get_string(const input_format_t format, const NumberType len, string_t &result)
create a string by reading characters from the input
input_adapter_t ia
input adapter
binary_reader(binary_reader &&)=default
std::size_t chars_read
the number of characters read
bool get_ubjson_string(string_t &result, const bool get_char=true)
reads a UBJSON string
bool parse_cbor_internal(const bool get_char=true)
bool get_cbor_object(const std::size_t len)
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.
bool get_ubjson_size_value(std::size_t &result)
bool get_bson_string(const NumberType len, string_t &result)
Parses a zero-terminated string of length len from the BSON input.
bool get_ubjson_size_type(std::pair< std::size_t, int > &result)
determine the type and size for a container
bool get_msgpack_string(string_t &result)
reads a MessagePack string
binary_reader & operator=(binary_reader &&)=default
bool get_ubjson_value(const int prefix)
bool parse_bson_array()
Reads an array from the BSON input and passes it to the SAX-parser.
bool parse_bson_element_list(const bool is_array)
Read a BSON element list (as specified in the BSON-spec)
bool parse_msgpack_internal()
std::string exception_message(const input_format_t format, const std::string &detail, const std::string &context) const
bool unexpect_eof(const input_format_t format, const char *context) const
bool parse_bson_internal()
Reads in a BSON-object and passes it to the SAX-parser.
typename BasicJsonType::number_integer_t number_integer_t
typename BasicJsonType::string_t string_t
const bool is_little_endian
whether we can assume little endianess
binary_reader(const binary_reader &)=delete
int current
the current character
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true)
bool get_cbor_array(const std::size_t len)
json_sax_t * sax
the SAX parser
bool get_cbor_string(string_t &result)
reads a CBOR string
std::string get_token_string() const
bool get_msgpack_object(const std::size_t len)
binary_reader(input_adapter_t adapter)
create a binary reader
typename BasicJsonType::number_float_t number_float_t
bool parse_ubjson_internal(const bool get_char=true)
int get()
get next character from the input
serialization to CBOR and MessagePack values
void write_bson_array(const string_t &name, const typename BasicJsonType::array_t &value)
Writes a BSON element with key name and array value.
const bool is_little_endian
whether we can assume little endianess
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix)
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
static constexpr CharType get_ubjson_float_prefix(double)
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.
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.
void write_bson_double(const string_t &name, const double value)
Writes a BSON element with key name and double value value.
void write_bson_object(const typename BasicJsonType::object_t &value)
typename BasicJsonType::string_t string_t
static constexpr CharType get_cbor_float_prefix(float)
static constexpr CharType to_char_type(InputCharType x) noexcept
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
static constexpr CharType get_msgpack_float_prefix(double)
CharType ubjson_prefix(const BasicJsonType &j) const noexcept
determine the type prefix of container values
void write_bson_integer(const string_t &name, const std::int64_t value)
Writes a BSON element with key name and integer value.
static std::size_t calc_bson_entry_header_size(const string_t &name)
void write_bson_unsigned(const string_t &name, const std::uint64_t value)
Writes a BSON element with key name and unsigned value.
static CharType to_char_type(std::uint8_t x) noexcept
void write_bson_string(const string_t &name, const string_t &value)
Writes a BSON element with key name and string value value.
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.
static constexpr CharType get_ubjson_float_prefix(float)
void write_number(const NumberType n)
output_adapter_t< CharType > oa
the output
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.
void write_bson_null(const string_t &name)
Writes a BSON element with key name and null value.
void write_bson(const BasicJsonType &j)
void write_cbor(const BasicJsonType &j)
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
static constexpr CharType to_char_type(std::uint8_t x) noexcept
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.
static constexpr CharType get_msgpack_float_prefix(float)
void write_bson_boolean(const string_t &name, const bool value)
Writes a BSON element with key name and boolean value value.
void write_msgpack(const BasicJsonType &j)
static std::size_t calc_bson_string_size(const string_t &value)
static std::size_t calc_bson_integer_size(const std::int64_t value)
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t &value)
static constexpr CharType get_cbor_float_prefix(double)
general exception of the basic_json class
const int id
the id of the exception
static std::string name(const std::string &ename, int id_)
std::runtime_error m
an exception object as storage for error messages
const char * what() const noexcept override
returns the explanatory string
exception(int id_, const char *what_arg)
exception indicating errors with iterators
static invalid_iterator create(int id_, const std::string &what_arg)
invalid_iterator(int id_, const char *what_arg)
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
bool operator<(const iter_impl &other) const
comparison: smaller
iter_impl operator-(difference_type i) const
subtract from iterator
iter_impl()=default
default constructor
iter_impl const operator--(int)
post-decrement (it–)
void set_end() noexcept
set the iterator past the last value
bool operator==(const iter_impl &other) const
comparison: equal
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
iter_impl & operator--()
pre-decrement (–it)
difference_type operator-(const iter_impl &other) const
return difference
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)
reference operator*() const
return a reference to the value pointed to by the iterator
void set_begin() noexcept
set the iterator to the first value
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
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)
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
pointer operator->() const
dereference the iterator
iter_impl const operator++(int)
post-increment (it++)
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
iter_impl(pointer object) noexcept
constructor for a given JSON instance
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
iter_impl operator+(difference_type i) const
add to iterator
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
const object_t::key_type & key() const
return the key of an object iterator
bool operator>(const iter_impl &other) const
comparison: greater than
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
reference value() const
return the value of an iterator
typename BasicJsonType::object_t object_t
iter_impl & operator++()
pre-increment (++it)
reference operator[](difference_type n) const
access to successor
bool operator<=(const iter_impl &other) const
comparison: less than or equal
pointer m_object
associated JSON instance
std::bidirectional_iterator_tag iterator_category
iter_impl & operator+=(difference_type i)
add to iterator
bool operator!=(const iter_impl &other) const
comparison: not equal
typename BasicJsonType::array_t array_t
iter_impl & operator-=(difference_type i)
subtract from iterator
IteratorType anchor
the iterator
std::input_iterator_tag iterator_category
std::string array_index_str
a string representation of the array index
iteration_proxy_value(IteratorType it) noexcept
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
const std::string & key() const
return key of the iterator
std::size_t array_index_last
last stringified array index
IteratorType::reference value() const
return value of the iterator
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
std::size_t array_index
an index for arrays (used to create key names)
iteration_proxy_value & operator*()
dereference operator (needed for range-based for)
std::ptrdiff_t difference_type
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
const std::string empty_str
an empty string (to return a reference for primitive values)
proxy class for the items() function
iteration_proxy_value< IteratorType > begin() noexcept
return iterator begin (needed for range-based for)
iteration_proxy_value< IteratorType > end() noexcept
return iterator end (needed for range-based for)
IteratorType::reference container
the container to iterate
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
json_ref & operator=(const json_ref &)=delete
json_ref(const json_ref &)=delete
json_ref(json_ref &&)=default
value_type const & operator*() const
json_ref(Args &&... args)
json_ref(const value_type &value)
value_type const * operator->() const
json_ref & operator=(json_ref &&)=delete
json_ref(std::initializer_list< json_ref > init)
json_ref(value_type &&value)
value_type moved_or_copied() const
a template for a reverse iterator class
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
json_reverse_iterator const operator--(int)
post-decrement (it–)
typename Base::reference reference
the reference type for the pointed-to element
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
json_reverse_iterator & operator+=(difference_type i)
add to iterator
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
reference operator[](difference_type n) const
access to successor
std::ptrdiff_t difference_type
difference_type operator-(const json_reverse_iterator &other) const
return difference
json_reverse_iterator operator+(difference_type i) const
add to iterator
json_reverse_iterator const operator++(int)
post-increment (it++)
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
json_reverse_iterator & operator--()
pre-decrement (–it)
reference value() const
return the value of an iterator
json_reverse_iterator & operator++()
pre-increment (++it)
typename BasicJsonType::string_t string_t
typename BasicJsonType::number_integer_t number_integer_t
typename BasicJsonType::number_float_t number_float_t
bool start_object(std::size_t=std::size_t(-1))
bool start_array(std::size_t=std::size_t(-1))
bool parse_error(std::size_t, const std::string &, const detail::exception &)
bool number_integer(number_integer_t)
bool number_unsigned(number_unsigned_t)
typename BasicJsonType::number_unsigned_t number_unsigned_t
bool number_float(number_float_t, const string_t &)
typename BasicJsonType::string_t string_t
json_sax_dom_callback_parser & operator=(const json_sax_dom_callback_parser &)=delete
bool start_object(std::size_t len)
const bool allow_exceptions
whether to throw exceptions in case of errors
constexpr bool is_errored() const
typename BasicJsonType::number_unsigned_t number_unsigned_t
BasicJsonType * object_element
helper to hold the reference for the next object element
typename BasicJsonType::number_integer_t number_integer_t
std::pair< bool, BasicJsonType * > handle_value(Value &&v, const bool skip_callback=false)
const parser_callback_t callback
callback function
typename BasicJsonType::parser_callback_t parser_callback_t
bool start_array(std::size_t len)
~json_sax_dom_callback_parser()=default
json_sax_dom_callback_parser(const json_sax_dom_callback_parser &)=delete
bool number_integer(number_integer_t val)
BasicJsonType & root
the parsed JSON value
std::vector< BasicJsonType * > ref_stack
stack to model hierarchy of values
BasicJsonType discarded
a discarded value for the callback
std::vector< bool > key_keep_stack
stack to manage which object keys to keep
typename BasicJsonType::number_float_t number_float_t
typename BasicJsonType::parse_event_t parse_event_t
bool parse_error(std::size_t, const std::string &, const detail::exception &ex)
bool errored
whether a syntax error occurred
std::vector< bool > keep_stack
stack to manage which values to keep
bool number_unsigned(number_unsigned_t val)
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
bool string(string_t &val)
bool number_float(number_float_t val, const string_t &)
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
SAX implementation to create a JSON value from SAX events.
bool start_array(std::size_t len)
json_sax_dom_parser(const json_sax_dom_parser &)=delete
json_sax_dom_parser & operator=(json_sax_dom_parser &&)=default
bool number_unsigned(number_unsigned_t val)
bool errored
whether a syntax error occurred
typename BasicJsonType::number_integer_t number_integer_t
~json_sax_dom_parser()=default
bool parse_error(std::size_t, const std::string &, const detail::exception &ex)
bool string(string_t &val)
typename BasicJsonType::number_unsigned_t number_unsigned_t
bool start_object(std::size_t len)
BasicJsonType * object_element
helper to hold the reference for the next object element
std::vector< BasicJsonType * > ref_stack
stack to model hierarchy of values
const bool allow_exceptions
whether to throw exceptions in case of errors
constexpr bool is_errored() const
json_sax_dom_parser(json_sax_dom_parser &&)=default
BasicJsonType * handle_value(Value &&v)
typename BasicJsonType::number_float_t number_float_t
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
BasicJsonType & root
the parsed JSON value
bool number_float(number_float_t val, const string_t &)
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
typename BasicJsonType::string_t string_t
bool number_integer(number_integer_t val)
static void strtof(long double &f, const char *str, char **endptr) noexcept
typename BasicJsonType::number_unsigned_t number_unsigned_t
const char decimal_point_char
the decimal point
static void strtof(float &f, const char *str, char **endptr) noexcept
lexer & operator=(lexer &&)=delete
lexer(const lexer &)=delete
constexpr const char * get_error_message() const noexcept
return syntax error message
bool next_byte_in_range(std::initializer_list< int > ranges)
check if the next byte(s) are inside a given range
lexer & operator=(lexer &)=delete
number_integer_t value_integer
token_type
token types for the parser
@ value_float
an floating point number – use get_number_float() for actual value
@ begin_array
the character for array begin [
@ value_string
a string – use get_string() for actual value
@ end_array
the character for array end ]
@ uninitialized
indicating the scanner is uninitialized
@ parse_error
indicating a parse error
@ value_integer
a signed integer – use get_number_integer() for actual value
@ value_separator
the value separator ,
@ end_object
the character for object end }
@ literal_true
the true literal
@ begin_object
the character for object begin {
@ value_unsigned
an unsigned integer – use get_number_unsigned() for actual value
@ literal_null
the null literal
@ end_of_input
indicating the end of the input buffer
@ name_separator
the name separator :
@ literal_or_value
a literal or the begin of a value (only for diagnostics)
@ literal_false
the false literal
std::char_traits< char >::int_type get()
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
std::char_traits< char >::int_type current
the current character
std::string get_token_string() const
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
void unget()
unget current character (read it again on next get)
token_type scan_number()
scan a number literal
token_type scan_literal(const char *literal_text, const std::size_t length, token_type return_type)
bool skip_bom()
skip the UTF-8 byte order mark
int get_codepoint()
get codepoint from 4 hex characters following \u
number_float_t value_float
static void strtof(double &f, const char *str, char **endptr) noexcept
string_t token_buffer
buffer for variable-length tokens (numbers, strings)
position_t position
the start position of the current token
typename BasicJsonType::number_integer_t number_integer_t
static const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
detail::input_adapter_t ia
input adapter
typename BasicJsonType::number_float_t number_float_t
typename BasicJsonType::string_t string_t
lexer(detail::input_adapter_t &&adapter)
constexpr position_t get_position() const noexcept
return position of last read token
constexpr number_float_t get_number_float() const noexcept
return floating-point value
void reset() noexcept
reset token_buffer; current character is beginning of token
void add(int c)
add a character to token_buffer
token_type scan_string()
scan a string literal
std::vector< char > token_string
raw input token string (for error messages)
const char * error_message
a description of occurred lexer errors
static char get_decimal_point() noexcept
return the locale-dependent decimal point
bool next_unget
whether the next get() call should just return current
number_unsigned_t value_unsigned
constexpr number_integer_t get_number_integer() const noexcept
return integer value
exception indicating other library errors
static other_error create(int id_, const std::string &what_arg)
other_error(int id_, const char *what_arg)
exception indicating access out of the defined range
static out_of_range create(int id_, const std::string &what_arg)
out_of_range(int id_, const char *what_arg)
output_adapter(std::vector< CharType > &vec)
output_adapter(std::basic_ostream< CharType > &s)
output_adapter(StringType &s)
output adapter for output streams
void write_character(CharType c) override
std::basic_ostream< CharType > & stream
void write_characters(const CharType *s, std::size_t length) override
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
output adapter for basic_string
void write_character(CharType c) override
void write_characters(const CharType *s, std::size_t length) override
output_string_adapter(StringType &s) noexcept
output adapter for byte vectors
std::vector< CharType > & v
output_vector_adapter(std::vector< CharType > &vec) noexcept
void write_characters(const CharType *s, std::size_t length) override
void write_character(CharType c) override
exception indicating a parse error
parse_error(int id_, std::size_t byte_, const char *what_arg)
static parse_error create(int id_, const position_t &pos, const std::string &what_arg)
create a parse error exception
const std::size_t byte
byte index of the parse error
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg)
static std::string position_string(const position_t &pos)
std::string exception_message(const token_type expected, const std::string &context)
void parse(const bool strict, BasicJsonType &result)
public parser interface
bool sax_parse(SAX *sax, const bool strict=true)
parser(detail::input_adapter_t &&adapter, const parser_callback_t cb=nullptr, const bool allow_exceptions_=true)
a parser reading from an input adapter
bool accept(const bool strict=true)
public accept interface
typename lexer_t::token_type token_type
token_type get_token()
get next token from lexer
typename BasicJsonType::number_unsigned_t number_unsigned_t
const bool allow_exceptions
whether to throw exceptions in case of errors
const parser_callback_t callback
callback function
typename BasicJsonType::number_float_t number_float_t
token_type last_token
the type of the last read token
typename BasicJsonType::number_integer_t number_integer_t
std::function< bool(int depth, parse_event_t event, BasicJsonType &parsed)> parser_callback_t
bool sax_parse_internal(SAX *sax)
typename BasicJsonType::string_t string_t
primitive_iterator_t operator+(difference_type n) noexcept
primitive_iterator_t & operator++() noexcept
difference_type m_it
iterator as signed integer type
constexpr bool is_end() const noexcept
return whether the iterator is at end
primitive_iterator_t & operator-=(difference_type n) noexcept
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
void set_begin() noexcept
set iterator to a defined beginning
primitive_iterator_t const operator++(int) noexcept
static constexpr difference_type end_value
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
primitive_iterator_t & operator--() noexcept
void set_end() noexcept
set iterator to a defined past the end
constexpr difference_type get_value() const noexcept
primitive_iterator_t const operator--(int) noexcept
std::ptrdiff_t difference_type
primitive_iterator_t & operator+=(difference_type n) noexcept
static constexpr difference_type begin_value
const error_handler_t error_handler
error_handler how to react on decoding errors
unsigned int count_digits(number_unsigned_t x) noexcept
count digits
typename BasicJsonType::number_unsigned_t number_unsigned_t
const std::lconv * loc
the locale
std::array< char, 64 > number_buffer
a (hopefully) large enough character buffer
static constexpr std::uint8_t UTF8_ACCEPT
void dump_float(number_float_t x, std::true_type)
serializer(serializer &&)=delete
serializer & operator=(serializer &&)=delete
const char decimal_point
the locale's decimal point character
void dump_float(number_float_t x, std::false_type)
typename BasicJsonType::number_float_t number_float_t
void dump_float(number_float_t x)
dump a floating-point number
const char thousands_sep
the locale's thousand separator character
serializer & operator=(const serializer &)=delete
static constexpr std::uint8_t UTF8_REJECT
void dump_integer(NumberType x)
dump an integer
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
const char indent_char
the indentation character
std::array< char, 512 > string_buffer
string buffer
static std::uint8_t decode(std::uint8_t &state, std::uint32_t &codep, const std::uint8_t byte) noexcept
check whether a string is UTF-8 encoded
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
void dump_escaped(const string_t &s, const bool ensure_ascii)
dump escaped string
output_adapter_t< char > o
the output of the serializer
typename BasicJsonType::string_t string_t
serializer(const serializer &)=delete
typename BasicJsonType::number_integer_t number_integer_t
string_t indent_string
the indentation string
exception indicating executing a member function with a wrong type
type_error(int id_, const char *what_arg)
static type_error create(int id_, const std::string &what_arg)
std::vector< std::string > reference_tokens
the reference tokens
json_pointer & operator/=(std::string token)
append an unescaped reference token at the end of this JSON pointer
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
std::string to_string() const
return a string representation of the JSON pointer
const BasicJsonType & get_unchecked(const BasicJsonType *ptr) const
return a const reference to the pointed to value
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for equality
void pop_back()
remove last reference token
const BasicJsonType & get_checked(const BasicJsonType *ptr) const
bool empty() const noexcept
return whether pointer points to the root document
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for inequality
void push_back(const std::string &token)
append an unescaped token at the end of the reference pointer
json_pointer(const std::string &s="")
create JSON pointer
static std::string escape(std::string s)
escape "~" to "~0" and "/" to "~1"
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
static BasicJsonType unflatten(const BasicJsonType &value)
friend json_pointer operator/(const json_pointer &ptr, std::string token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
friend json_pointer operator/(const json_pointer &ptr, std::size_t array_index)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
const std::string & back()
return last reference token
BasicJsonType & get_and_create(BasicJsonType &j) const
create and return a reference to the pointed to value
static void replace_substring(std::string &s, const std::string &f, const std::string &t)
replace all occurrences of a substring by another string
static void flatten(const std::string &reference_string, const BasicJsonType &value, BasicJsonType &result)
static void unescape(std::string &s)
unescape "~1" to tilde and "~0" to slash (order is important!)
void push_back(std::string &&token)
append an unescaped token at the end of the reference pointer
static int array_index(const std::string &s)
BasicJsonType & get_checked(BasicJsonType *ptr) const
json_pointer & operator/=(std::size_t array_index)
append an array index at the end of this JSON pointer
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
json_pointer parent_pointer() const
returns the parent of this JSON pointer
static std::vector< std::string > split(const std::string &reference_string)
split the string input to reference tokens
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
A simple vector class template.
void pop_back()
Removes the last element of the vector.
void push_back(const T &value)
Adds an element to the end of the vector.
iterator begin()
Returns an iterator to the first element.
void clear()
Clears the contents of the vector.
iterator end()
Returns an iterator to the last element.
size_t size() const
Returns the number of elements in the vector.
T & back()
Returns a reference to the last element.
void insert(iterator position, const T &value)
Inserts an element at the specified position.
bool empty() const
Checks if the vector is empty.
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
#define NLOHMANN_JSON_VERSION_PATCH
#define JSON_INTERNAL_CATCH(exception)
#define JSON_CATCH(exception)
#define JSON_THROW(exception)
#define NLOHMANN_JSON_VERSION_MAJOR
#define NLOHMANN_BASIC_JSON_TPL
#define NLOHMANN_JSON_VERSION_MINOR
T * ptr(T &obj)
returns a pointer (transforms reference into pointer)
Vector3D operator-(const Vector3D &v1, const Vector3D &v2)
Vector3D operator+(const Vector3D &v1, const Vector3D &v2)
void swap(shared_lock< Mutex > &lhs, shared_lock< Mutex > &rhs) noexcept
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Target reinterpret_bits(const Source source)
boundaries compute_boundaries(FloatType value)
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
cached_power get_cached_power_for_binary_exponent(int e)
typename std::enable_if< B, T >::type enable_if_t
typename T::reference reference_t
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
decltype(T::from_json(std::declval< Args >()...)) from_json_function
void to_json(BasicJsonType &j, T b) noexcept
value_t
the JSON type enumeration
@ number_integer
number value (signed integer)
@ discarded
discarded by the the parser callback function
@ object
object (unordered set of name/value pairs)
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
decltype(std::declval< T & >().parse_error(std::declval< std::size_t >(), std::declval< const std::string & >(), std::declval< const Exception & >())) parse_error_function_t
typename T::pointer pointer_t
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
void from_json_tuple_impl(const BasicJsonType &j, Tuple &t, index_sequence< Idx... >)
typename T::difference_type difference_type_t
typename detector< nonesuch, void, Op, Args... >::type detected_t
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
error_handler_t
how to treat decoding errors
@ strict
throw a type_error exception in case of invalid UTF-8
@ ignore
ignore invalid UTF-8 sequences
@ replace
replace invalid UTF-8 sequences with U+FFFD
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
typename T::key_type key_type_t
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
typename detected_or< Default, Op, Args... >::type detected_or_t
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
typename make_void< Ts... >::type void_t
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
typename T::mapped_type mapped_type_t
typename T::iterator iterator_t
input_format_t
the supported input formats
void to_json(BasicJsonType &j, const std::tuple< Args... > &t)
decltype(std::declval< T >().template get< U >()) get_template_function
decltype(std::declval< T & >().null()) null_function_t
char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
typename T::iterator_category iterator_category_t
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
std::shared_ptr< input_adapter_protocol > input_adapter_t
a type to simplify interfaces
decltype(std::declval< T & >().end_array()) end_array_function_t
void from_json(const BasicJsonType &j, std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > &m)
decltype(std::declval< T & >().end_object()) end_object_function_t
decltype(T::to_json(std::declval< Args >()...)) to_json_function
typename T::value_type value_type_t
namespace for Niels Lohmann
basic_json<> json
default JSON class
Provides common mathematical functions and vector operations.
int abs(int x)
Computes the absolute value of an integer.
double exp(double x)
Computes the exponential function of a number.
default JSONSerializer template argument
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
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
static constexpr int kPrecision
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
constexpr diyfp(std::uint64_t f_, int e_) noexcept
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
static void construct(BasicJsonType &j, const CompatibleStringType &str)
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
auto operator()(const BasicJsonType &j, T &val) const noexcept(noexcept(from_json(j, val))) -> decltype(from_json(j, val), void())
typename BasicJsonType::template json_serializer< T, void > serializer
typename BasicJsonType::template json_serializer< T, void > serializer
typename BasicJsonType::template json_serializer< T, void > serializer
static constexpr std::size_t size() noexcept
primitive_iterator_t primitive_iterator
generic iterator for all other types
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
std::numeric_limits< CompatibleNumberIntegerType > CompatibleLimits
std::numeric_limits< RealIntegerType > RealLimits
typename BasicJsonType::object_t object_t
typename BasicJsonType::object_t object_t
typename BasicJsonType::string_t string_t
typename BasicJsonType::exception exception_t
typename BasicJsonType::number_integer_t number_integer_t
typename BasicJsonType::number_float_t number_float_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
typename BasicJsonType::number_float_t number_float_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
typename BasicJsonType::exception exception_t
static constexpr bool value
typename BasicJsonType::number_integer_t number_integer_t
typename BasicJsonType::string_t string_t
std::random_access_iterator_tag iterator_category
ptrdiff_t difference_type
typename It::difference_type difference_type
typename It::reference reference
typename It::iterator_category iterator_category
typename It::pointer pointer
typename It::value_type value_type
nonesuch(nonesuch const &)=delete
void operator=(nonesuch &&)=delete
nonesuch(nonesuch const &&)=delete
void operator=(nonesuch const &)=delete
abstract output adapter interface
virtual void write_characters(const CharType *s, std::size_t length)=0
virtual void write_character(CharType c)=0
virtual ~output_adapter_protocol()=default
struct to capture the start position of the current token
std::size_t lines_read
the number of lines read
std::size_t chars_read_current_line
the number of characters read in the current line
std::size_t chars_read_total
the total number of characters read
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())
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
virtual bool string(string_t &val)=0
a string was read
virtual bool null()=0
a null value was read
typename BasicJsonType::number_integer_t number_integer_t
type for (signed) integers
virtual bool end_array()=0
the end of an array was read
virtual bool key(string_t &val)=0
an object key was read
typename BasicJsonType::number_unsigned_t number_unsigned_t
type for unsigned integers
typename BasicJsonType::number_float_t number_float_t
type for floating-point numbers
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
virtual bool boolean(bool val)=0
a boolean value was read
virtual bool end_object()=0
the end of an object was read
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
typename BasicJsonType::string_t string_t
type for strings
virtual bool number_float(number_float_t val, const string_t &s)=0
an floating-point number was read
virtual ~json_sax()=default
virtual bool number_integer(number_integer_t val)=0
an integer number was read
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
number_unsigned_t number_unsigned
number (unsigned integer)
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
json_value(const array_t &value)
constructor for arrays
json_value(boolean_t v) noexcept
constructor for booleans
json_value(value_t t)
constructor for empty values of a given type
json_value()=default
default constructor (for null values)
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
object_t * object
object (stored with pointer to save storage)
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
json_value(array_t &&value)
constructor for rvalue arrays
json_value(const object_t &value)
constructor for objects
array_t * array
array (stored with pointer to save storage)
json_value(object_t &&value)
constructor for rvalue objects
json_value(const string_t &value)
constructor for strings
string_t * string
string (stored with pointer to save storage)
json_value(string_t &&value)
constructor for rvalue strings
number_float_t number_float
number (floating-point)
void destroy(value_t t) noexcept
number_integer_t number_integer
number (integer)