40#ifndef NLOHMANN_JSON_HPP
41#define NLOHMANN_JSON_HPP
43#define NLOHMANN_JSON_VERSION_MAJOR 3
44#define NLOHMANN_JSON_VERSION_MINOR 1
45#define NLOHMANN_JSON_VERSION_PATCH 2
52#include <initializer_list>
60#ifndef NLOHMANN_JSON_FWD_HPP
61#define NLOHMANN_JSON_FWD_HPP
83template <
typename =
void,
typename =
void>
86template <
template <
typename U,
typename V,
typename... Args>
class ObjectType =
88 template <
typename U,
typename... Args>
class ArrayType = std::vector,
89 class StringType = std::string,
class BooleanType = bool,
90 class NumberIntegerType = std::int64_t,
91 class NumberUnsignedType = std::uint64_t,
92 class NumberFloatType = double,
93 template <
typename U>
class AllocatorType = std::allocator,
94 template <
typename T,
typename SFINAE =
void>
class JSONSerializer =
109template <
typename BasicJsonType>
131#if defined(__clang__)
132#if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
133#error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
135#elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
136#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900
137#error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
142#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
143#pragma GCC diagnostic push
144#pragma GCC diagnostic ignored "-Wfloat-equal"
148#if defined(__clang__)
149#pragma GCC diagnostic push
150#pragma GCC diagnostic ignored "-Wdocumentation"
154#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
155#define JSON_DEPRECATED __attribute__((deprecated))
156#elif defined(_MSC_VER)
157#define JSON_DEPRECATED __declspec(deprecated)
159#define JSON_DEPRECATED
163#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
164#define JSON_THROW(exception) throw exception
166#define JSON_CATCH(exception) catch (exception)
168#define JSON_THROW(exception) std::abort()
169#define JSON_TRY if (true)
170#define JSON_CATCH(exception) if (false)
174#if defined(JSON_THROW_USER)
176#define JSON_THROW JSON_THROW_USER
178#if defined(JSON_TRY_USER)
180#define JSON_TRY JSON_TRY_USER
182#if defined(JSON_CATCH_USER)
184#define JSON_CATCH JSON_CATCH_USER
188#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
189#define JSON_LIKELY(x) __builtin_expect(!!(x), 1)
190#define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
192#define JSON_LIKELY(x) x
193#define JSON_UNLIKELY(x) x
197#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1)
198#define JSON_HAS_CPP_17
199#define JSON_HAS_CPP_14
200#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
201#define JSON_HAS_CPP_14
207#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
208 template <template <typename, typename, typename...> class ObjectType, \
209 template <typename, typename...> class ArrayType, \
210 class StringType, class BooleanType, class NumberIntegerType, \
211 class NumberUnsignedType, class NumberFloatType, \
212 template <typename> class AllocatorType, \
213 template <typename, typename = void> class JSONSerializer>
215#define NLOHMANN_BASIC_JSON_TPL \
216 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
217 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
218 AllocatorType, JSONSerializer>
230#define NLOHMANN_JSON_HAS_HELPER(type) \
231 template <typename T> \
232 struct has_##type { \
234 template <typename U, typename = typename U::type> \
235 static int detect(U&&); \
236 static void detect(...); \
239 static constexpr bool value = \
240 std::is_integral<decltype(detect(std::declval<T>()))>::value; \
248#include <type_traits>
280template <
bool B,
typename T =
void>
284using uncvref_t =
typename std::remove_cv<typename std::remove_reference<T>::type>
::type;
288template <std::size_t... Ints>
292 static constexpr std::size_t
size() noexcept
294 return sizeof...(Ints);
298template <
class Sequence1,
class Sequence2>
301template <std::size_t... I1, std::size_t... I2>
306template <std::
size_t N>
309 typename make_index_sequence<N - N / 2>::type> {
319template <
typename... Ts>
341template <
class B1,
class... Bn>
346struct negation : std::integral_constant<bool, not B::value> {
363template <
typename T,
typename =
void>
376template <
bool B,
class RealType,
class CompatibleObjectType>
380template <
class RealType,
class CompatibleObjectType>
383 std::is_constructible<typename RealType::key_type, typename CompatibleObjectType::key_type>::value and
384 std::is_constructible<typename RealType::mapped_type, typename CompatibleObjectType::mapped_type>::value;
387template <
class BasicJsonType,
class CompatibleObjectType>
391 has_mapped_type<CompatibleObjectType>,
392 has_key_type<CompatibleObjectType>>
::value,
393 typename BasicJsonType::object_t, CompatibleObjectType>
::value;
396template <
typename BasicJsonType,
typename T>
398 static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
399 std::is_same<T, typename BasicJsonType::const_iterator>::value or
400 std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
401 std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
404template <
class BasicJsonType,
class CompatibleArrayType>
409 BasicJsonType, CompatibleArrayType>>,
410 negation<std::is_constructible<
typename BasicJsonType::string_t,
411 CompatibleArrayType>>,
413 has_value_type<CompatibleArrayType>,
414 has_iterator<CompatibleArrayType>>
::value;
417template <
bool,
typename,
typename>
421template <
typename RealIntegerType,
typename CompatibleNumberIntegerType>
428 std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
429 CompatibleLimits::is_integer and
430 RealLimits::is_signed == CompatibleLimits::is_signed;
433template <
typename RealIntegerType,
typename CompatibleNumberIntegerType>
437 std::is_integral<CompatibleNumberIntegerType>::value and
438 not std::is_same<bool, CompatibleNumberIntegerType>::value,
439 RealIntegerType, CompatibleNumberIntegerType >
::value;
443template <
typename BasicJsonType,
typename T>
447 template <
typename U,
typename = enable_if_t<std::is_same<
void, decltype(uncvref_t<U>::from_json(
448 std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
449 static int detect(U&&);
450 static void detect(...);
453 static constexpr bool value = std::is_integral<
decltype(
454 detect(std::declval<
typename BasicJsonType::template json_serializer<T, void>>()))>
::value;
459template <
typename BasicJsonType,
typename T>
466 static int detect(U&&);
467 static void detect(...);
470 static constexpr bool value = std::is_integral<
decltype(detect(
471 std::declval<
typename BasicJsonType::template json_serializer<T, void>>()))>
::value;
475template <
typename BasicJsonType,
typename T>
478 template <
typename U,
typename = decltype(uncvref_t<U>::to_json(
479 std::declval<BasicJsonType&>(), std::declval<T>()))>
480 static int detect(U&&);
481 static void detect(...);
484 static constexpr bool value = std::is_integral<
decltype(detect(
485 std::declval<
typename BasicJsonType::template json_serializer<T, void>>()))>
::value;
488template <
typename BasicJsonType,
typename CompatibleCompleteType>
491 not std::is_base_of<std::istream, CompatibleCompleteType>::value and
497template <
typename BasicJsonType,
typename CompatibleType>
560 const char*
what() const noexcept
override
571 static std::string
name(
const std::string& ename,
int id_)
573 return "[json.exception." + ename +
"." +
std::to_string(id_) +
"] ";
578 std::runtime_error
m;
655 parse_error(
int id_, std::size_t byte_,
const char* what_arg)
884enum class value_t : std::uint8_t {
906inline bool operator<(
const value_t lhs,
const value_t rhs)
noexcept
908 static constexpr std::array<std::uint8_t, 8> order = {{
913 const auto l_index =
static_cast<std::size_t
>(
lhs);
914 const auto r_index =
static_cast<std::size_t
>(
rhs);
915 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
925#include <forward_list>
929#include <type_traits>
946template <
typename BasicJsonType,
typename ArithmeticType,
947 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
948 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
950void get_arithmetic_value(
const BasicJsonType&
j, ArithmeticType&
val)
952 switch (
static_cast<value_t
>(
j)) {
953 case value_t::number_unsigned: {
954 val =
static_cast<ArithmeticType
>(*
j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
957 case value_t::number_integer: {
958 val =
static_cast<ArithmeticType
>(*
j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
961 case value_t::number_float: {
962 val =
static_cast<ArithmeticType
>(*
j.template get_ptr<const typename BasicJsonType::number_float_t*>());
971template <
typename BasicJsonType>
972void from_json(
const BasicJsonType&
j,
typename BasicJsonType::boolean_t&
b)
977 b = *
j.template get_ptr<const typename BasicJsonType::boolean_t*>();
980template <
typename BasicJsonType>
981void from_json(
const BasicJsonType&
j,
typename BasicJsonType::string_t& s)
986 s = *
j.template get_ptr<const typename BasicJsonType::string_t*>();
989template <
typename BasicJsonType>
990void from_json(
const BasicJsonType&
j,
typename BasicJsonType::number_float_t&
val)
992 get_arithmetic_value(
j,
val);
995template <
typename BasicJsonType>
996void from_json(
const BasicJsonType&
j,
typename BasicJsonType::number_unsigned_t&
val)
998 get_arithmetic_value(
j,
val);
1001template <
typename BasicJsonType>
1002void from_json(
const BasicJsonType&
j,
typename BasicJsonType::number_integer_t&
val)
1004 get_arithmetic_value(
j,
val);
1007template <
typename BasicJsonType,
typename EnumType,
1008 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
1009void from_json(
const BasicJsonType&
j, EnumType& e)
1011 typename std::underlying_type<EnumType>::type
val;
1012 get_arithmetic_value(
j,
val);
1013 e =
static_cast<EnumType
>(
val);
1016template <
typename BasicJsonType>
1017void from_json(
const BasicJsonType&
j,
typename BasicJsonType::array_t& arr)
1022 arr = *
j.template get_ptr<const typename BasicJsonType::array_t*>();
1026template <
typename BasicJsonType,
typename T,
typename Allocator,
1027 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1028void from_json(
const BasicJsonType&
j, std::forward_list<T, Allocator>& l)
1033 std::transform(
j.rbegin(),
j.rend(),
1034 std::front_inserter(l), [](
const BasicJsonType&
i) {
1035 return i.template get<T>();
1040template <
typename BasicJsonType,
typename T,
1041 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1042void from_json(
const BasicJsonType&
j, std::valarray<T>& l)
1048 std::copy(
j.m_value.array->begin(),
j.m_value.array->end(), std::begin(l));
1051template <
typename BasicJsonType,
typename CompatibleArrayType>
1052void from_json_array_impl(
const BasicJsonType&
j, CompatibleArrayType& arr, priority_tag<0> )
1056 std::transform(
j.begin(),
j.end(),
1057 std::inserter(arr,
end(arr)), [](
const BasicJsonType&
i) {
1060 return i.template get<typename CompatibleArrayType::value_type>();
1064template <
typename BasicJsonType,
typename CompatibleArrayType>
1065auto from_json_array_impl(
const BasicJsonType&
j, CompatibleArrayType& arr, priority_tag<1> )
1067 arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
1072 arr.reserve(
j.size());
1073 std::transform(
j.begin(),
j.end(),
1074 std::inserter(arr,
end(arr)), [](
const BasicJsonType&
i) {
1077 return i.template get<typename CompatibleArrayType::value_type>();
1081template <
typename BasicJsonType,
typename T, std::
size_t N>
1082void from_json_array_impl(
const BasicJsonType&
j, std::array<T, N>& arr, priority_tag<2> )
1084 for (std::size_t
i = 0;
i < N; ++
i) {
1085 arr[
i] =
j.at(
i).template get<T>();
1090 typename BasicJsonType,
typename CompatibleArrayType,
1093 not std::is_same<
typename BasicJsonType::array_t,
1094 CompatibleArrayType>
::value and
1095 std::is_constructible<
1096 BasicJsonType,
typename CompatibleArrayType::value_type>
::value,
1098void from_json(
const BasicJsonType&
j, CompatibleArrayType& arr)
1102 std::string(
j.type_name())));
1105 from_json_array_impl(
j, arr, priority_tag<2>{});
1108template <
typename BasicJsonType,
typename CompatibleObjectType,
1109 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
int> = 0>
1110void from_json(
const BasicJsonType&
j, CompatibleObjectType& obj)
1116 auto inner_object =
j.template get_ptr<const typename BasicJsonType::object_t*>();
1117 using value_type =
typename CompatibleObjectType::value_type;
1119 inner_object->begin(), inner_object->end(),
1120 std::inserter(obj, obj.begin()),
1121 [](
typename BasicJsonType::object_t::value_type
const& p) {
1122 return value_type(p.first, p.second.template get<typename CompatibleObjectType::mapped_type>());
1130template <
typename BasicJsonType,
typename ArithmeticType,
1132 std::is_arithmetic<ArithmeticType>::value and
1133 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1134 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1135 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1136 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1138void from_json(
const BasicJsonType&
j, ArithmeticType&
val)
1140 switch (
static_cast<value_t
>(
j)) {
1141 case value_t::number_unsigned: {
1142 val =
static_cast<ArithmeticType
>(*
j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1145 case value_t::number_integer: {
1146 val =
static_cast<ArithmeticType
>(*
j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1149 case value_t::number_float: {
1150 val =
static_cast<ArithmeticType
>(*
j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1153 case value_t::boolean: {
1154 val =
static_cast<ArithmeticType
>(*
j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1163template <
typename BasicJsonType,
typename A1,
typename A2>
1164void from_json(
const BasicJsonType&
j, std::pair<A1, A2>& p)
1166 p = {
j.at(0).template get<A1>(),
j.at(1).template get<A2>()};
1169template <
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1170void from_json_tuple_impl(
const BasicJsonType&
j, Tuple& t, index_sequence<Idx...>)
1172 t = std::make_tuple(
j.at(Idx).template get<
typename std::tuple_element<Idx, Tuple>::type>()...);
1175template <
typename BasicJsonType,
typename... Args>
1176void from_json(
const BasicJsonType&
j, std::tuple<Args...>& t)
1178 from_json_tuple_impl(
j, t, index_sequence_for<Args...>{});
1181struct from_json_fn {
1183 template <
typename BasicJsonType,
typename T>
1184 auto call(
const BasicJsonType&
j, T&
val, priority_tag<1> )
const
1185 noexcept(
noexcept(from_json(
j,
val)))
1186 ->
decltype(from_json(
j,
val),
void())
1188 return from_json(
j,
val);
1191 template <
typename BasicJsonType,
typename T>
1192 void call(
const BasicJsonType& , T& , priority_tag<0> )
const noexcept
1194 static_assert(
sizeof(BasicJsonType) == 0,
1195 "could not find from_json() method in T's namespace");
1198 using decayed = uncvref_t<T>;
1199 static_assert(
sizeof(
typename decayed::force_msvc_stacktrace) == 0,
1200 "forcing MSVC stacktrace to show which T we're talking about.");
1205 template <
typename BasicJsonType,
typename T>
1206 void operator()(
const BasicJsonType&
j, T&
val)
const
1207 noexcept(
noexcept(std::declval<from_json_fn>().call(
j,
val, priority_tag<1>{})))
1209 return call(
j,
val, priority_tag<1>{});
1228#include <type_traits>
1246struct external_constructor;
1249struct external_constructor<value_t::boolean> {
1250 template <
typename BasicJsonType>
1251 static void construct(BasicJsonType&
j,
typename BasicJsonType::boolean_t
b)
noexcept
1253 j.m_type = value_t::boolean;
1255 j.assert_invariant();
1260struct external_constructor<value_t::
string> {
1261 template <
typename BasicJsonType>
1262 static void construct(BasicJsonType&
j,
const typename BasicJsonType::string_t& s)
1264 j.m_type = value_t::string;
1266 j.assert_invariant();
1269 template <
typename BasicJsonType>
1270 static void construct(BasicJsonType&
j,
typename BasicJsonType::string_t&& s)
1272 j.m_type = value_t::string;
1273 j.m_value = std::move(s);
1274 j.assert_invariant();
1279struct external_constructor<value_t::number_float> {
1280 template <
typename BasicJsonType>
1281 static void construct(BasicJsonType&
j,
typename BasicJsonType::number_float_t
val)
noexcept
1283 j.m_type = value_t::number_float;
1285 j.assert_invariant();
1290struct external_constructor<value_t::number_unsigned> {
1291 template <
typename BasicJsonType>
1292 static void construct(BasicJsonType&
j,
typename BasicJsonType::number_unsigned_t
val)
noexcept
1294 j.m_type = value_t::number_unsigned;
1296 j.assert_invariant();
1301struct external_constructor<value_t::number_integer> {
1302 template <
typename BasicJsonType>
1303 static void construct(BasicJsonType&
j,
typename BasicJsonType::number_integer_t
val)
noexcept
1305 j.m_type = value_t::number_integer;
1307 j.assert_invariant();
1312struct external_constructor<value_t::
array> {
1313 template <
typename BasicJsonType>
1314 static void construct(BasicJsonType&
j,
const typename BasicJsonType::array_t& arr)
1316 j.m_type = value_t::array;
1318 j.assert_invariant();
1321 template <
typename BasicJsonType>
1322 static void construct(BasicJsonType&
j,
typename BasicJsonType::array_t&& arr)
1324 j.m_type = value_t::array;
1325 j.m_value = std::move(arr);
1326 j.assert_invariant();
1329 template <
typename BasicJsonType,
typename CompatibleArrayType,
1330 enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
1332 static void construct(BasicJsonType&
j,
const CompatibleArrayType& arr)
1336 j.m_type = value_t::array;
1337 j.m_value.array =
j.template create<typename BasicJsonType::array_t>(
begin(arr),
end(arr));
1338 j.assert_invariant();
1341 template <
typename BasicJsonType>
1342 static void construct(BasicJsonType&
j,
const std::vector<bool>& arr)
1344 j.m_type = value_t::array;
1345 j.m_value = value_t::array;
1346 j.m_value.array->reserve(arr.size());
1347 for (
const bool x : arr) {
1348 j.m_value.array->push_back(
x);
1350 j.assert_invariant();
1353 template <
typename BasicJsonType,
typename T,
1354 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
1355 static void construct(BasicJsonType&
j,
const std::valarray<T>& arr)
1357 j.m_type = value_t::array;
1358 j.m_value = value_t::array;
1359 j.m_value.array->resize(arr.size());
1360 std::copy(std::begin(arr), std::end(arr),
j.m_value.array->begin());
1361 j.assert_invariant();
1366struct external_constructor<value_t::
object> {
1367 template <
typename BasicJsonType>
1368 static void construct(BasicJsonType&
j,
const typename BasicJsonType::object_t& obj)
1370 j.m_type = value_t::object;
1372 j.assert_invariant();
1375 template <
typename BasicJsonType>
1376 static void construct(BasicJsonType&
j,
typename BasicJsonType::object_t&& obj)
1378 j.m_type = value_t::object;
1379 j.m_value = std::move(obj);
1380 j.assert_invariant();
1383 template <
typename BasicJsonType,
typename CompatibleObjectType,
1384 enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value,
int> = 0>
1385 static void construct(BasicJsonType&
j,
const CompatibleObjectType& obj)
1390 j.m_type = value_t::object;
1391 j.m_value.object =
j.template create<typename BasicJsonType::object_t>(
begin(obj),
end(obj));
1392 j.assert_invariant();
1400template <
typename BasicJsonType,
typename T,
1401 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value,
int> = 0>
1402void to_json(BasicJsonType&
j, T
b)
noexcept
1404 external_constructor<value_t::boolean>::construct(
j,
b);
1407template <
typename BasicJsonType,
typename CompatibleString,
1408 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value,
int> = 0>
1409void to_json(BasicJsonType&
j,
const CompatibleString& s)
1411 external_constructor<value_t::string>::construct(
j, s);
1414template <
typename BasicJsonType>
1415void to_json(BasicJsonType&
j,
typename BasicJsonType::string_t&& s)
1417 external_constructor<value_t::string>::construct(
j, std::move(s));
1420template <
typename BasicJsonType,
typename FloatType,
1421 enable_if_t<std::is_floating_point<FloatType>::value,
int> = 0>
1422void to_json(BasicJsonType&
j, FloatType
val)
noexcept
1424 external_constructor<value_t::number_float>::construct(
j,
static_cast<typename BasicJsonType::number_float_t
>(
val));
1427template <
typename BasicJsonType,
typename CompatibleNumberUnsignedType,
1428 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value,
int> = 0>
1429void to_json(BasicJsonType&
j, CompatibleNumberUnsignedType
val)
noexcept
1431 external_constructor<value_t::number_unsigned>::construct(
j,
static_cast<typename BasicJsonType::number_unsigned_t
>(
val));
1434template <
typename BasicJsonType,
typename CompatibleNumberIntegerType,
1435 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value,
int> = 0>
1436void to_json(BasicJsonType&
j, CompatibleNumberIntegerType
val)
noexcept
1438 external_constructor<value_t::number_integer>::construct(
j,
static_cast<typename BasicJsonType::number_integer_t
>(
val));
1441template <
typename BasicJsonType,
typename EnumType,
1442 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
1443void to_json(BasicJsonType&
j, EnumType e)
noexcept
1445 using underlying_type =
typename std::underlying_type<EnumType>::type;
1446 external_constructor<value_t::number_integer>::construct(
j,
static_cast<underlying_type
>(e));
1449template <
typename BasicJsonType>
1450void to_json(BasicJsonType&
j,
const std::vector<bool>& e)
1452 external_constructor<value_t::array>::construct(
j, e);
1455template <
typename BasicJsonType,
typename CompatibleArrayType,
1456 enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value or
1457 std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
1459void to_json(BasicJsonType&
j,
const CompatibleArrayType& arr)
1461 external_constructor<value_t::array>::construct(
j, arr);
1464template <
typename BasicJsonType,
typename T,
1465 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
1466void to_json(BasicJsonType&
j, std::valarray<T> arr)
1468 external_constructor<value_t::array>::construct(
j, std::move(arr));
1471template <
typename BasicJsonType>
1472void to_json(BasicJsonType&
j,
typename BasicJsonType::array_t&& arr)
1474 external_constructor<value_t::array>::construct(
j, std::move(arr));
1477template <
typename BasicJsonType,
typename CompatibleObjectType,
1478 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
int> = 0>
1479void to_json(BasicJsonType&
j,
const CompatibleObjectType& obj)
1481 external_constructor<value_t::object>::construct(
j, obj);
1484template <
typename BasicJsonType>
1485void to_json(BasicJsonType&
j,
typename BasicJsonType::object_t&& obj)
1487 external_constructor<value_t::object>::construct(
j, std::move(obj));
1490template <
typename BasicJsonType,
typename T, std::size_t N,
1491 enable_if_t<not std::is_constructible<
typename BasicJsonType::string_t,
T (&)[N]>
::value,
int> = 0>
1492void to_json(BasicJsonType&
j, T (&arr)[N])
1494 external_constructor<value_t::array>::construct(
j, arr);
1497template <
typename BasicJsonType,
typename... Args>
1498void to_json(BasicJsonType&
j,
const std::pair<Args...>& p)
1500 j = {p.first, p.second};
1503template <
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1504void to_json_tuple_impl(BasicJsonType&
j,
const Tuple& t, index_sequence<Idx...>)
1506 j = {std::get<Idx>(t)...};
1509template <
typename BasicJsonType,
typename... Args>
1510void to_json(BasicJsonType&
j,
const std::tuple<Args...>& t)
1512 to_json_tuple_impl(
j, t, index_sequence_for<Args...>{});
1517 template <
typename BasicJsonType,
typename T>
1518 auto call(BasicJsonType&
j, T&&
val, priority_tag<1> )
const noexcept(
noexcept(to_json(
j, std::forward<T>(
val))))
1519 ->
decltype(to_json(
j, std::forward<T>(
val)),
void())
1521 return to_json(
j, std::forward<T>(
val));
1524 template <
typename BasicJsonType,
typename T>
1525 void call(BasicJsonType& , T&& , priority_tag<0> )
const noexcept
1527 static_assert(
sizeof(BasicJsonType) == 0,
1528 "could not find to_json() method in T's namespace");
1532 using decayed = uncvref_t<T>;
1533 static_assert(
sizeof(
typename decayed::force_msvc_stacktrace) == 0,
1534 "forcing MSVC stacktrace to show which T we're talking about.");
1539 template <
typename BasicJsonType,
typename T>
1540 void operator()(BasicJsonType&
j, T&&
val)
const
1541 noexcept(
noexcept(std::declval<to_json_fn>().call(
j, std::forward<T>(
val), priority_tag<1>{})))
1543 return call(
j, std::forward<T>(
val), priority_tag<1>{});
1568#include <type_traits>
1592struct input_adapter_protocol {
1594 virtual std::char_traits<char>::int_type get_character() = 0;
1596 virtual void unget_character() = 0;
1597 virtual ~input_adapter_protocol() =
default;
1601using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
1612class input_stream_adapter :
public input_adapter_protocol
1615 ~input_stream_adapter()
override
1622 explicit input_stream_adapter(std::istream&
i)
1623 : is(
i), sb(*
i.rdbuf())
1626 std::char_traits<char>::int_type
c;
1627 if ((
c = get_character()) == 0xEF) {
1628 if ((
c = get_character()) == 0xBB) {
1629 if ((
c = get_character()) == 0xBF) {
1631 }
else if (
c != std::char_traits<char>::eof()) {
1635 }
else if (
c != std::char_traits<char>::eof()) {
1639 }
else if (
c != std::char_traits<char>::eof()) {
1645 input_stream_adapter(
const input_stream_adapter&) =
delete;
1646 input_stream_adapter& operator=(input_stream_adapter&) =
delete;
1651 std::char_traits<char>::int_type get_character()
override
1656 void unget_character()
override
1668class input_buffer_adapter :
public input_adapter_protocol
1671 input_buffer_adapter(
const char*
b,
const std::size_t l)
1672 : cursor(
b), limit(
b + l),
start(
b)
1675 if (l >= 3 and
b[0] ==
'\xEF' and
b[1] ==
'\xBB' and
b[2] ==
'\xBF') {
1681 input_buffer_adapter(
const input_buffer_adapter&) =
delete;
1682 input_buffer_adapter& operator=(input_buffer_adapter&) =
delete;
1684 std::char_traits<char>::int_type get_character() noexcept
override
1687 return std::char_traits<char>::to_int_type(*(cursor++));
1690 return std::char_traits<char>::eof();
1693 void unget_character() noexcept
override
1715 input_adapter(std::istream&
i)
1716 : ia(
std::make_shared<input_stream_adapter>(
i)) {}
1719 input_adapter(std::istream&&
i)
1720 : ia(
std::make_shared<input_stream_adapter>(
i)) {}
1723 template <
typename CharT,
1724 typename std::enable_if<
1725 std::is_pointer<CharT>::value and
1726 std::is_integral<typename std::remove_pointer<CharT>::type>
::value and
1727 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
1729 input_adapter(CharT
b, std::size_t l)
1730 : ia(
std::make_shared<input_buffer_adapter>(reinterpret_cast<const
char*>(
b), l))
1737 template <
typename CharT,
1738 typename std::enable_if<
1739 std::is_pointer<CharT>::value and
1740 std::is_integral<typename std::remove_pointer<CharT>::type>
::value and
1741 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
1743 input_adapter(CharT
b)
1744 : input_adapter(reinterpret_cast<const
char*>(
b),
1745 std::strlen(reinterpret_cast<const
char*>(
b)))
1750 template <
class IteratorType,
1751 typename std::enable_if<
1752 std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>
::value,
1754 input_adapter(IteratorType
first, IteratorType last)
1758 assert(std::accumulate(
1759 first, last, std::pair<bool, int>(
true, 0),
1761 res.first &= (
val == *(std::next(std::addressof(*
first),
res.second++)));
1768 sizeof(
typename std::iterator_traits<IteratorType>::value_type) == 1,
1769 "each element in the iterator range must have the size of 1 byte");
1771 const auto len =
static_cast<size_t>(std::distance(
first, last));
1774 ia = std::make_shared<input_buffer_adapter>(
reinterpret_cast<const char*
>(&(*
first)),
len);
1777 ia = std::make_shared<input_buffer_adapter>(
nullptr,
len);
1782 template <
class T, std::
size_t N>
1783 input_adapter(T (&
array)[N])
1789 template <class ContiguousContainer, typename std::enable_if<not std::is_pointer<ContiguousContainer>::value and
1790 std::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>
::value,
1792 input_adapter(
const ContiguousContainer&
c)
1797 operator input_adapter_t()
1804 input_adapter_t ia =
nullptr;
1814#include <initializer_list>
1838template <
typename BasicJsonType>
1841 using number_integer_t =
typename BasicJsonType::number_integer_t;
1842 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
1843 using number_float_t =
typename BasicJsonType::number_float_t;
1844 using string_t =
typename BasicJsonType::string_t;
1848 enum class token_type {
1869 static const char* token_type_name(
const token_type t)
noexcept
1872 case token_type::uninitialized:
1873 return "<uninitialized>";
1874 case token_type::literal_true:
1875 return "true literal";
1876 case token_type::literal_false:
1877 return "false literal";
1878 case token_type::literal_null:
1879 return "null literal";
1880 case token_type::value_string:
1881 return "string literal";
1882 case lexer::token_type::value_unsigned:
1883 case lexer::token_type::value_integer:
1884 case lexer::token_type::value_float:
1885 return "number literal";
1886 case token_type::begin_array:
1888 case token_type::begin_object:
1890 case token_type::end_array:
1892 case token_type::end_object:
1894 case token_type::name_separator:
1896 case token_type::value_separator:
1898 case token_type::parse_error:
1899 return "<parse error>";
1900 case token_type::end_of_input:
1901 return "end of input";
1902 case token_type::literal_or_value:
1903 return "'[', '{', or a literal";
1905 return "unknown token";
1909 explicit lexer(detail::input_adapter_t adapter)
1910 : ia(
std::move(adapter)), decimal_point_char(get_decimal_point()) {}
1913 lexer(
const lexer&) =
delete;
1914 lexer& operator=(lexer&) =
delete;
1922 static char get_decimal_point() noexcept
1924 const auto loc = localeconv();
1925 assert(loc !=
nullptr);
1926 return (loc->decimal_point ==
nullptr) ?
'.' : *(loc->decimal_point);
1951 assert(current ==
'u');
1954 const auto factors = {12, 8, 4, 0};
1955 for (
const auto factor : factors) {
1958 if (current >=
'0' and current <=
'9') {
1959 codepoint += ((current - 0x30) << factor);
1960 }
else if (current >=
'A' and current <=
'F') {
1961 codepoint += ((current - 0x37) << factor);
1962 }
else if (current >=
'a' and current <=
'f') {
1963 codepoint += ((current - 0x57) << factor);
1969 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
1988 bool next_byte_in_range(std::initializer_list<int> ranges)
1990 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
1998 error_message =
"invalid string: ill-formed UTF-8 byte";
2021 token_type scan_string()
2027 assert(current ==
'\"');
2033 case std::char_traits<char>::eof(): {
2034 error_message =
"invalid string: missing closing quote";
2035 return token_type::parse_error;
2040 return token_type::value_string;
2081 const int codepoint1 = get_codepoint();
2082 int codepoint = codepoint1;
2085 error_message = R
"(invalid string: '\u' must be followed by 4 hex digits)";
2086 return token_type::parse_error;
2090 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF) {
2093 const int codepoint2 = get_codepoint();
2096 error_message = R
"(invalid string: '\u' must be followed by 4 hex digits)";
2097 return token_type::parse_error;
2101 if (
JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF)) {
2113 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2114 return token_type::parse_error;
2117 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2118 return token_type::parse_error;
2121 if (
JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF)) {
2122 error_message =
"invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
2123 return token_type::parse_error;
2128 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
2131 if (codepoint < 0x80) {
2134 }
else if (codepoint <= 0x7FF) {
2136 add(0xC0 | (codepoint >> 6));
2137 add(0x80 | (codepoint & 0x3F));
2138 }
else if (codepoint <= 0xFFFF) {
2140 add(0xE0 | (codepoint >> 12));
2141 add(0x80 | ((codepoint >> 6) & 0x3F));
2142 add(0x80 | (codepoint & 0x3F));
2145 add(0xF0 | (codepoint >> 18));
2146 add(0x80 | ((codepoint >> 12) & 0x3F));
2147 add(0x80 | ((codepoint >> 6) & 0x3F));
2148 add(0x80 | (codepoint & 0x3F));
2156 error_message =
"invalid string: forbidden character after backslash";
2157 return token_type::parse_error;
2196 error_message =
"invalid string: control character must be escaped";
2197 return token_type::parse_error;
2331 return token_type::parse_error;
2338 if (
JSON_UNLIKELY(not(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF})))) {
2339 return token_type::parse_error;
2360 if (
JSON_UNLIKELY(not(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF})))) {
2361 return token_type::parse_error;
2368 if (
JSON_UNLIKELY(not(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF})))) {
2369 return token_type::parse_error;
2376 if (
JSON_UNLIKELY(not(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) {
2377 return token_type::parse_error;
2386 if (
JSON_UNLIKELY(not(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) {
2387 return token_type::parse_error;
2394 if (
JSON_UNLIKELY(not(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF})))) {
2395 return token_type::parse_error;
2402 error_message =
"invalid string: ill-formed UTF-8 byte";
2403 return token_type::parse_error;
2409 static void strtof(
float&
f,
const char*
str,
char** endptr)
noexcept
2411 f = std::strtof(
str, endptr);
2414 static void strtof(
double&
f,
const char*
str,
char** endptr)
noexcept
2416 f = std::strtod(
str, endptr);
2419 static void strtof(
long double&
f,
const char*
str,
char** endptr)
noexcept
2421 f = std::strtold(
str, endptr);
2464 token_type scan_number()
2471 token_type number_type = token_type::value_unsigned;
2477 goto scan_number_minus;
2482 goto scan_number_zero;
2495 goto scan_number_any1;
2506 number_type = token_type::value_integer;
2510 goto scan_number_zero;
2523 goto scan_number_any1;
2527 error_message =
"invalid number; expected digit after '-'";
2528 return token_type::parse_error;
2536 add(decimal_point_char);
2537 goto scan_number_decimal1;
2543 goto scan_number_exponent;
2547 goto scan_number_done;
2564 goto scan_number_any1;
2568 add(decimal_point_char);
2569 goto scan_number_decimal1;
2575 goto scan_number_exponent;
2579 goto scan_number_done;
2582 scan_number_decimal1:
2584 number_type = token_type::value_float;
2597 goto scan_number_decimal2;
2601 error_message =
"invalid number; expected digit after '.'";
2602 return token_type::parse_error;
2606 scan_number_decimal2:
2620 goto scan_number_decimal2;
2626 goto scan_number_exponent;
2630 goto scan_number_done;
2633 scan_number_exponent:
2635 number_type = token_type::value_float;
2640 goto scan_number_sign;
2654 goto scan_number_any2;
2659 "invalid number; expected '+', '-', or digit after exponent";
2660 return token_type::parse_error;
2678 goto scan_number_any2;
2682 error_message =
"invalid number; expected digit after exponent sign";
2683 return token_type::parse_error;
2701 goto scan_number_any2;
2705 goto scan_number_done;
2713 char* endptr =
nullptr;
2717 if (number_type == token_type::value_unsigned) {
2718 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
2721 assert(endptr == token_buffer.data() + token_buffer.size());
2724 value_unsigned =
static_cast<number_unsigned_t
>(
x);
2725 if (value_unsigned ==
x) {
2726 return token_type::value_unsigned;
2729 }
else if (number_type == token_type::value_integer) {
2730 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
2733 assert(endptr == token_buffer.data() + token_buffer.size());
2736 value_integer =
static_cast<number_integer_t
>(
x);
2737 if (value_integer ==
x) {
2738 return token_type::value_integer;
2745 strtof(value_float, token_buffer.data(), &endptr);
2748 assert(endptr == token_buffer.data() + token_buffer.size());
2750 return token_type::value_float;
2758 token_type scan_literal(
const char* literal_text,
const std::size_t
length,
2759 token_type return_type)
2761 assert(current == literal_text[0]);
2762 for (std::size_t
i = 1;
i <
length; ++
i) {
2764 error_message =
"invalid literal";
2765 return token_type::parse_error;
2776 void reset() noexcept
2778 token_buffer.clear();
2779 token_string.clear();
2780 token_string.push_back(std::char_traits<char>::to_char_type(current));
2793 std::char_traits<char>::int_type
get()
2796 current = ia->get_character();
2797 if (
JSON_LIKELY(current != std::char_traits<char>::eof())) {
2798 token_string.push_back(std::char_traits<char>::to_char_type(current));
2807 if (
JSON_LIKELY(current != std::char_traits<char>::eof())) {
2808 ia->unget_character();
2809 assert(token_string.size() != 0);
2810 token_string.pop_back();
2817 token_buffer.push_back(std::char_traits<char>::to_char_type(
c));
2826 constexpr number_integer_t get_number_integer() const noexcept
2828 return value_integer;
2832 constexpr number_unsigned_t get_number_unsigned() const noexcept
2834 return value_unsigned;
2838 constexpr number_float_t get_number_float() const noexcept
2844 string_t&& move_string()
2846 return std::move(token_buffer);
2854 constexpr std::size_t get_position() const noexcept
2862 std::string get_token_string()
const
2866 for (
const auto c : token_string) {
2867 if (
'\x00' <=
c and
c <=
'\x1F') {
2869 std::stringstream ss;
2870 ss <<
"<U+" << std::setw(4) << std::uppercase << std::setfill(
'0')
2871 << std::hex << static_cast<int>(
c) <<
">";
2883 constexpr const char* get_error_message() const noexcept
2885 return error_message;
2897 }
while (current ==
' ' or current ==
'\t' or current ==
'\n' or current ==
'\r');
2902 return token_type::begin_array;
2904 return token_type::end_array;
2906 return token_type::begin_object;
2908 return token_type::end_object;
2910 return token_type::name_separator;
2912 return token_type::value_separator;
2916 return scan_literal(
"true", 4, token_type::literal_true);
2918 return scan_literal(
"false", 5, token_type::literal_false);
2920 return scan_literal(
"null", 4, token_type::literal_null);
2924 return scan_string();
2938 return scan_number();
2943 case std::char_traits<char>::eof():
2944 return token_type::end_of_input;
2948 error_message =
"invalid literal";
2949 return token_type::parse_error;
2955 detail::input_adapter_t ia =
nullptr;
2958 std::char_traits<char>::int_type current = std::char_traits<char>::eof();
2961 std::size_t chars_read = 0;
2964 std::vector<char> token_string{};
2967 string_t token_buffer{};
2970 const char* error_message =
"";
2973 number_integer_t value_integer = 0;
2974 number_unsigned_t value_unsigned = 0;
2975 number_float_t value_float = 0;
2978 const char decimal_point_char =
'.';
2988#include <functional>
3015template <
typename BasicJsonType>
3018 using number_integer_t =
typename BasicJsonType::number_integer_t;
3019 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
3020 using number_float_t =
typename BasicJsonType::number_float_t;
3021 using string_t =
typename BasicJsonType::string_t;
3022 using lexer_t = lexer<BasicJsonType>;
3023 using token_type =
typename lexer_t::token_type;
3045 explicit parser(detail::input_adapter_t adapter,
3047 const bool allow_exceptions_ =
true)
3048 : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_)
3067 parse_internal(
true,
result);
3068 result.assert_invariant();
3073 expect(token_type::end_of_input);
3078 result = value_t::discarded;
3084 if (
result.is_discarded()) {
3100 if (not accept_internal()) {
3105 return not strict or (get_token() == token_type::end_of_input);
3115 void parse_internal(
bool keep, BasicJsonType&
result)
3118 assert(not errored);
3121 if (not
result.is_discarded()) {
3123 result.m_type = value_t::discarded;
3126 switch (last_token) {
3127 case token_type::begin_object: {
3133 if (not callback or keep) {
3135 result.m_type = value_t::object;
3136 result.m_value = value_t::object;
3144 if (last_token == token_type::end_object) {
3147 result.m_type = value_t::discarded;
3154 BasicJsonType
value;
3157 if (not expect(token_type::value_string)) {
3160 key = m_lexer.move_string();
3162 bool keep_tag =
false;
3165 BasicJsonType k(
key);
3174 if (not expect(token_type::name_separator)) {
3181 value.m_type = value_t::discarded;
3182 parse_internal(keep,
value);
3188 if (keep and keep_tag and not
value.is_discarded()) {
3189 result.m_value.object->emplace(std::move(
key), std::move(
value));
3194 if (last_token == token_type::value_separator) {
3200 if (not expect(token_type::end_object)) {
3208 result.m_type = value_t::discarded;
3213 case token_type::begin_array: {
3219 if (not callback or keep) {
3221 result.m_type = value_t::array;
3222 result.m_value = value_t::array;
3230 if (last_token == token_type::end_array) {
3233 result.m_type = value_t::discarded;
3239 BasicJsonType
value;
3243 value.m_type = value_t::discarded;
3244 parse_internal(keep,
value);
3250 if (keep and not
value.is_discarded()) {
3251 result.m_value.array->push_back(std::move(
value));
3256 if (last_token == token_type::value_separator) {
3262 if (not expect(token_type::end_array)) {
3270 result.m_type = value_t::discarded;
3275 case token_type::literal_null: {
3276 result.m_type = value_t::null;
3280 case token_type::value_string: {
3281 result.m_type = value_t::string;
3282 result.m_value = m_lexer.move_string();
3286 case token_type::literal_true: {
3287 result.m_type = value_t::boolean;
3292 case token_type::literal_false: {
3293 result.m_type = value_t::boolean;
3298 case token_type::value_unsigned: {
3299 result.m_type = value_t::number_unsigned;
3300 result.m_value = m_lexer.get_number_unsigned();
3304 case token_type::value_integer: {
3305 result.m_type = value_t::number_integer;
3306 result.m_value = m_lexer.get_number_integer();
3310 case token_type::value_float: {
3311 result.m_type = value_t::number_float;
3312 result.m_value = m_lexer.get_number_float();
3316 if (allow_exceptions) {
3318 m_lexer.get_token_string() +
"'"));
3320 expect(token_type::uninitialized);
3325 case token_type::parse_error: {
3327 if (not expect(token_type::uninitialized)) {
3335 if (not expect(token_type::literal_or_value)) {
3344 result.m_type = value_t::discarded;
3358 bool accept_internal()
3360 switch (last_token) {
3361 case token_type::begin_object: {
3366 if (last_token == token_type::end_object) {
3373 if (last_token != token_type::value_string) {
3379 if (last_token != token_type::name_separator) {
3385 if (not accept_internal()) {
3391 if (last_token == token_type::value_separator) {
3397 return (last_token == token_type::end_object);
3401 case token_type::begin_array: {
3406 if (last_token == token_type::end_array) {
3413 if (not accept_internal()) {
3419 if (last_token == token_type::value_separator) {
3425 return (last_token == token_type::end_array);
3429 case token_type::value_float: {
3431 return std::isfinite(m_lexer.get_number_float());
3434 case token_type::literal_false:
3435 case token_type::literal_null:
3436 case token_type::literal_true:
3437 case token_type::value_integer:
3438 case token_type::value_string:
3439 case token_type::value_unsigned:
3448 token_type get_token()
3450 return (last_token = m_lexer.scan());
3456 bool expect(token_type t)
3461 if (allow_exceptions) {
3471 [[noreturn]]
void throw_exception()
const
3473 std::string error_msg =
"syntax error - ";
3474 if (last_token == token_type::parse_error) {
3475 error_msg += std::string(m_lexer.get_error_message()) +
"; last read: '" +
3476 m_lexer.get_token_string() +
"'";
3478 error_msg +=
"unexpected " + std::string(lexer_t::token_type_name(last_token));
3481 if (expected != token_type::uninitialized) {
3482 error_msg +=
"; expected " + std::string(lexer_t::token_type_name(expected));
3494 token_type last_token = token_type::uninitialized;
3498 bool errored =
false;
3500 token_type expected = token_type::uninitialized;
3502 const bool allow_exceptions =
true;
3528 using difference_type = std::ptrdiff_t;
3529 static constexpr difference_type begin_value = 0;
3530 static constexpr difference_type end_value = begin_value + 1;
3533 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
3556 return m_it == begin_value;
3562 return m_it == end_value;
3567 return lhs.m_it == rhs.m_it;
3572 return lhs.m_it < rhs.m_it;
3584 return lhs.m_it - rhs.m_it;
3642template <
typename BasicJsonType>
3658#include <type_traits>
3677template <
typename IteratorType>
3678class iteration_proxy;
3700template <
typename BasicJsonType>
3705 friend BasicJsonType;
3708 using object_t =
typename BasicJsonType::object_t;
3709 using array_t =
typename BasicJsonType::array_t;
3712 "iter_impl only accepts (const) basic_json");
3727 using pointer =
typename std::conditional<std::is_const<BasicJsonType>::value,
3728 typename BasicJsonType::const_pointer,
3729 typename BasicJsonType::pointer>
::type;
3732 typename std::conditional<std::is_const<BasicJsonType>::value,
3733 typename BasicJsonType::const_reference,
3734 typename BasicJsonType::reference>
::type;
3747 assert(m_object !=
nullptr);
3749 switch (m_object->m_type) {
3750 case value_t::object: {
3755 case value_t::array: {
3782 : m_object(
other.m_object), m_it(
other.m_it) {}
3792 m_object =
other.m_object;
3802 void set_begin() noexcept
3804 assert(m_object !=
nullptr);
3806 switch (m_object->m_type) {
3807 case value_t::object: {
3812 case value_t::array: {
3817 case value_t::null: {
3834 void set_end() noexcept
3836 assert(m_object !=
nullptr);
3838 switch (m_object->m_type) {
3839 case value_t::object: {
3844 case value_t::array: {
3863 assert(m_object !=
nullptr);
3865 switch (m_object->m_type) {
3866 case value_t::object: {
3871 case value_t::array: {
3895 assert(m_object !=
nullptr);
3897 switch (m_object->m_type) {
3898 case value_t::object: {
3903 case value_t::array: {
3935 assert(m_object !=
nullptr);
3937 switch (m_object->m_type) {
3938 case value_t::object: {
3943 case value_t::array: {
3974 assert(m_object !=
nullptr);
3976 switch (m_object->m_type) {
3977 case value_t::object: {
3982 case value_t::array: {
4007 assert(m_object !=
nullptr);
4009 switch (m_object->m_type) {
4010 case value_t::object:
4013 case value_t::array:
4041 assert(m_object !=
nullptr);
4043 switch (m_object->m_type) {
4044 case value_t::object:
4047 case value_t::array:
4061 return not
other.operator<(*this);
4088 assert(m_object !=
nullptr);
4090 switch (m_object->m_type) {
4091 case value_t::object:
4094 case value_t::array: {
4156 assert(m_object !=
nullptr);
4158 switch (m_object->m_type) {
4159 case value_t::object:
4162 case value_t::array:
4176 assert(m_object !=
nullptr);
4178 switch (m_object->m_type) {
4179 case value_t::object:
4182 case value_t::array:
4202 typename object_t::key_type
key()
const
4204 assert(m_object !=
nullptr);
4243template <
typename IteratorType>
4248 class iteration_proxy_internal
4252 IteratorType anchor;
4254 std::size_t array_index = 0;
4257 explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
4260 iteration_proxy_internal& operator*()
4266 iteration_proxy_internal& operator++()
4275 bool operator!=(
const iteration_proxy_internal&
o)
const noexcept
4277 return anchor !=
o.anchor;
4281 std::string
key()
const
4283 assert(anchor.m_object !=
nullptr);
4285 switch (anchor.m_object->type()) {
4287 case value_t::array:
4291 case value_t::object:
4292 return anchor.key();
4301 typename IteratorType::reference
value()
const
4303 return anchor.value();
4308 typename IteratorType::reference container;
4313 : container(cont) {}
4316 iteration_proxy_internal
begin() noexcept
4318 return iteration_proxy_internal(container.begin());
4322 iteration_proxy_internal
end() noexcept
4324 return iteration_proxy_internal(container.end());
4362template <
typename Base>
4436 auto it = --this->base();
4443 auto it = --this->base();
4444 return it.operator*();
4466template <
typename CharType>
4474template <
typename CharType>
4478template <
typename CharType>
4491 std::copy(s, s +
length, std::back_inserter(
v));
4495 std::vector<CharType>&
v;
4499template <
typename CharType>
4516 std::basic_ostream<CharType>&
stream;
4520template <
typename CharType,
typename StringType = std::basic_
string<CharType>>
4540template <
typename CharType,
typename StringType = std::basic_
string<CharType>>
4600template <
typename BasicJsonType>
4603 using number_integer_t =
typename BasicJsonType::number_integer_t;
4604 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
4605 using string_t =
typename BasicJsonType::string_t;
4613 explicit binary_reader(input_adapter_t adapter) : ia(
std::move(adapter))
4628 BasicJsonType parse_cbor(
const bool strict)
4630 const auto res = parse_cbor_internal();
4648 BasicJsonType parse_msgpack(
const bool strict)
4650 const auto res = parse_msgpack_internal();
4668 BasicJsonType parse_ubjson(
const bool strict)
4670 const auto res = parse_ubjson_internal();
4685 static constexpr bool little_endianess(
int num = 1) noexcept
4687 return (*
reinterpret_cast<char*
>(&
num) == 1);
4696 BasicJsonType parse_cbor_internal(
const bool get_char =
true)
4698 switch (get_char ?
get() : current) {
4700 case std::char_traits<char>::eof():
4701 JSON_THROW(parse_error::
create(110, chars_read,
"unexpected end of input"));
4728 return static_cast<number_unsigned_t
>(current);
4731 return get_number<uint8_t>();
4734 return get_number<uint16_t>();
4737 return get_number<uint32_t>();
4740 return get_number<uint64_t>();
4767 return static_cast<int8_t
>(0x20 - 1 - current);
4771 return static_cast<number_integer_t
>(-1) - get_number<uint8_t>();
4776 return static_cast<number_integer_t
>(-1) - get_number<uint16_t>();
4781 return static_cast<number_integer_t
>(-1) - get_number<uint32_t>();
4786 return static_cast<number_integer_t
>(-1) -
4787 static_cast<number_integer_t
>(get_number<uint64_t>());
4821 return get_cbor_string();
4849 return get_cbor_array(current & 0x1F);
4854 return get_cbor_array(get_number<uint8_t>());
4859 return get_cbor_array(get_number<uint16_t>());
4864 return get_cbor_array(get_number<uint32_t>());
4869 return get_cbor_array(get_number<uint64_t>());
4874 BasicJsonType
result = value_t::array;
4875 while (
get() != 0xFF) {
4876 result.push_back(parse_cbor_internal(
false));
4906 return get_cbor_object(current & 0x1F);
4911 return get_cbor_object(get_number<uint8_t>());
4916 return get_cbor_object(get_number<uint16_t>());
4921 return get_cbor_object(get_number<uint32_t>());
4926 return get_cbor_object(get_number<uint64_t>());
4931 BasicJsonType
result = value_t::object;
4932 while (
get() != 0xFF) {
4933 auto key = get_cbor_string();
4951 return value_t::null;
4956 const int byte1 =
get();
4958 const int byte2 =
get();
4969 const int half = (byte1 << 8) + byte2;
4970 const int exp = (half >> 10) & 0x1F;
4971 const int mant = half & 0x3FF;
4974 val = std::ldexp(mant, -24);
4975 }
else if (
exp != 31) {
4976 val = std::ldexp(mant + 1024,
exp - 25);
4978 val = (mant == 0) ? std::numeric_limits<double>::infinity()
4979 : std::numeric_limits<double>::quiet_NaN();
4981 return (half & 0x8000) != 0 ? -
val :
val;
4986 return get_number<float>();
4991 return get_number<double>();
4996 std::stringstream ss;
4997 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5003 BasicJsonType parse_msgpack_internal()
5007 case std::char_traits<char>::eof():
5008 JSON_THROW(parse_error::
create(110, chars_read,
"unexpected end of input"));
5139 return static_cast<number_unsigned_t
>(current);
5158 return get_msgpack_object(current & 0x0F);
5178 return get_msgpack_array(current & 0x0F);
5214 return get_msgpack_string();
5217 return value_t::null;
5226 return get_number<float>();
5229 return get_number<double>();
5232 return get_number<uint8_t>();
5235 return get_number<uint16_t>();
5238 return get_number<uint32_t>();
5241 return get_number<uint64_t>();
5244 return get_number<int8_t>();
5247 return get_number<int16_t>();
5250 return get_number<int32_t>();
5253 return get_number<int64_t>();
5258 return get_msgpack_string();
5262 return get_msgpack_array(get_number<uint16_t>());
5267 return get_msgpack_array(get_number<uint32_t>());
5272 return get_msgpack_object(get_number<uint16_t>());
5277 return get_msgpack_object(get_number<uint32_t>());
5313 return static_cast<int8_t
>(current);
5317 std::stringstream ss;
5318 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5320 "error reading MessagePack; last byte: 0x" + ss.str()));
5330 BasicJsonType parse_ubjson_internal(
const bool get_char =
true)
5332 return get_ubjson_value(get_char ? get_ignore_noop() : current);
5347 return (current = ia->get_character());
5353 int get_ignore_noop()
5357 }
while (current ==
'N');
5375 template <
typename NumberType>
5376 NumberType get_number()
5380 for (std::size_t
i = 0;
i <
sizeof(NumberType); ++
i) {
5385 if (is_little_endian) {
5386 vec[
sizeof(NumberType) -
i - 1] =
static_cast<uint8_t>(current);
5394 std::memcpy(&
result,
vec.data(),
sizeof(NumberType));
5411 template <
typename NumberType>
5412 string_t get_string(
const NumberType
len)
5415 std::generate_n(std::back_inserter(
result),
len, [
this]() {
5418 return static_cast<char>(current);
5435 string_t get_cbor_string()
5465 return get_string(current & 0x1F);
5470 return get_string(get_number<uint8_t>());
5475 return get_string(get_number<uint16_t>());
5480 return get_string(get_number<uint32_t>());
5485 return get_string(get_number<uint64_t>());
5491 while (
get() != 0xFF) {
5492 result.append(get_cbor_string());
5498 std::stringstream ss;
5499 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5505 template <
typename NumberType>
5506 BasicJsonType get_cbor_array(
const NumberType
len)
5508 BasicJsonType
result = value_t::array;
5509 std::generate_n(std::back_inserter(*
result.m_value.array),
len, [
this]() {
5510 return parse_cbor_internal();
5515 template <
typename NumberType>
5516 BasicJsonType get_cbor_object(
const NumberType
len)
5518 BasicJsonType
result = value_t::object;
5519 std::generate_n(std::inserter(*
result.m_value.object,
5520 result.m_value.object->end()),
5523 auto key = get_cbor_string();
5524 auto val = parse_cbor_internal();
5525 return std::make_pair(std::move(key), std::move(val));
5541 string_t get_msgpack_string()
5579 return get_string(current & 0x1F);
5584 return get_string(get_number<uint8_t>());
5589 return get_string(get_number<uint16_t>());
5594 return get_string(get_number<uint32_t>());
5598 std::stringstream ss;
5599 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5601 "expected a MessagePack string; last byte: 0x" + ss.str()));
5606 template <
typename NumberType>
5607 BasicJsonType get_msgpack_array(
const NumberType
len)
5609 BasicJsonType
result = value_t::array;
5610 std::generate_n(std::back_inserter(*
result.m_value.array),
len, [
this]() {
5611 return parse_msgpack_internal();
5616 template <
typename NumberType>
5617 BasicJsonType get_msgpack_object(
const NumberType
len)
5619 BasicJsonType
result = value_t::object;
5620 std::generate_n(std::inserter(*
result.m_value.object,
5621 result.m_value.object->end()),
5624 auto key = get_msgpack_string();
5625 auto val = parse_msgpack_internal();
5626 return std::make_pair(std::move(key), std::move(val));
5647 string_t get_ubjson_string(
const bool get_char =
true)
5657 return get_string(get_number<uint8_t>());
5659 return get_string(get_number<int8_t>());
5661 return get_string(get_number<int16_t>());
5663 return get_string(get_number<int32_t>());
5665 return get_string(get_number<int64_t>());
5667 std::stringstream ss;
5668 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5670 "expected a UBJSON string; last byte: 0x" + ss.str()));
5682 std::pair<std::size_t, int> get_ubjson_size_type()
5684 std::size_t sz = string_t::npos;
5689 if (current ==
'$') {
5694 if (current !=
'#') {
5695 std::stringstream ss;
5696 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5698 "expected '#' after UBJSON type information; last byte: 0x" + ss.str()));
5700 sz = parse_ubjson_internal();
5701 }
else if (current ==
'#') {
5702 sz = parse_ubjson_internal();
5705 return std::make_pair(sz, tc);
5708 BasicJsonType get_ubjson_value(
const int prefix)
5711 case std::char_traits<char>::eof():
5712 JSON_THROW(parse_error::
create(110, chars_read,
"unexpected end of input"));
5723 return get_number<uint8_t>();
5725 return get_number<int8_t>();
5727 return get_number<int16_t>();
5729 return get_number<int32_t>();
5731 return get_number<int64_t>();
5733 return get_number<float>();
5735 return get_number<double>();
5742 std::stringstream ss;
5743 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5745 "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + ss.str()));
5747 return string_t(1,
static_cast<char>(current));
5751 return get_ubjson_string();
5754 return get_ubjson_array();
5757 return get_ubjson_object();
5760 std::stringstream ss;
5761 ss << std::setw(2) << std::uppercase << std::setfill(
'0') << std::hex << current;
5763 "error reading UBJSON; last byte: 0x" + ss.str()));
5767 BasicJsonType get_ubjson_array()
5769 BasicJsonType
result = value_t::array;
5770 const auto size_and_type = get_ubjson_size_type();
5772 if (size_and_type.first != string_t::npos) {
5775 "excessive array size: " +
std::to_string(size_and_type.first)));
5778 if (size_and_type.second != 0) {
5779 if (size_and_type.second !=
'N') {
5780 std::generate_n(std::back_inserter(*
result.m_value.array),
5781 size_and_type.first, [
this, size_and_type]() {
5782 return get_ubjson_value(size_and_type.second);
5786 std::generate_n(std::back_inserter(*
result.m_value.array),
5787 size_and_type.first, [
this]() {
5788 return parse_ubjson_internal();
5792 while (current !=
']') {
5793 result.push_back(parse_ubjson_internal(
false));
5801 BasicJsonType get_ubjson_object()
5803 BasicJsonType
result = value_t::object;
5804 const auto size_and_type = get_ubjson_size_type();
5806 if (size_and_type.first != string_t::npos) {
5809 "excessive object size: " +
std::to_string(size_and_type.first)));
5812 if (size_and_type.second != 0) {
5813 std::generate_n(std::inserter(*
result.m_value.object,
5814 result.m_value.object->end()),
5815 size_and_type.first, [
this, size_and_type]() {
5816 auto key = get_ubjson_string();
5817 auto val = get_ubjson_value(size_and_type.second);
5818 return std::make_pair(std::move(key), std::move(val));
5821 std::generate_n(std::inserter(*
result.m_value.object,
5822 result.m_value.object->end()),
5823 size_and_type.first, [
this]() {
5824 auto key = get_ubjson_string();
5825 auto val = parse_ubjson_internal();
5826 return std::make_pair(std::move(key), std::move(val));
5830 while (current !=
'}') {
5831 auto key = get_ubjson_string(
false);
5832 result[std::move(
key)] = parse_ubjson_internal();
5844 void expect_eof()
const
5846 if (
JSON_UNLIKELY(current != std::char_traits<char>::eof())) {
5855 void unexpect_eof()
const
5857 if (
JSON_UNLIKELY(current == std::char_traits<char>::eof())) {
5864 input_adapter_t ia =
nullptr;
5867 int current = std::char_traits<char>::eof();
5870 std::size_t chars_read = 0;
5873 const bool is_little_endian = little_endianess();
5901template <
typename BasicJsonType,
typename CharType>
5910 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
5918 void write_cbor(
const BasicJsonType&
j)
5921 case value_t::null: {
5922 oa->write_character(
static_cast<CharType
>(0xF6));
5926 case value_t::boolean: {
5927 oa->write_character(
j.m_value.boolean
5928 ?
static_cast<CharType
>(0xF5)
5929 : static_cast<CharType>(0xF4));
5933 case value_t::number_integer: {
5934 if (
j.m_value.number_integer >= 0) {
5938 if (
j.m_value.number_integer <= 0x17) {
5939 write_number(
static_cast<uint8_t>(
j.m_value.number_integer));
5940 }
else if (
j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)()) {
5941 oa->write_character(
static_cast<CharType
>(0x18));
5942 write_number(
static_cast<uint8_t>(
j.m_value.number_integer));
5943 }
else if (
j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)()) {
5944 oa->write_character(
static_cast<CharType
>(0x19));
5945 write_number(
static_cast<uint16_t
>(
j.m_value.number_integer));
5946 }
else if (
j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)()) {
5947 oa->write_character(
static_cast<CharType
>(0x1A));
5948 write_number(
static_cast<uint32_t
>(
j.m_value.number_integer));
5950 oa->write_character(
static_cast<CharType
>(0x1B));
5951 write_number(
static_cast<uint64_t
>(
j.m_value.number_integer));
5956 const auto positive_number = -1 -
j.m_value.number_integer;
5957 if (
j.m_value.number_integer >= -24) {
5958 write_number(
static_cast<uint8_t>(0x20 + positive_number));
5959 }
else if (positive_number <= (std::numeric_limits<uint8_t>::max)()) {
5960 oa->write_character(
static_cast<CharType
>(0x38));
5961 write_number(
static_cast<uint8_t>(positive_number));
5962 }
else if (positive_number <= (std::numeric_limits<uint16_t>::max)()) {
5963 oa->write_character(
static_cast<CharType
>(0x39));
5964 write_number(
static_cast<uint16_t
>(positive_number));
5965 }
else if (positive_number <= (std::numeric_limits<uint32_t>::max)()) {
5966 oa->write_character(
static_cast<CharType
>(0x3A));
5967 write_number(
static_cast<uint32_t
>(positive_number));
5969 oa->write_character(
static_cast<CharType
>(0x3B));
5970 write_number(
static_cast<uint64_t
>(positive_number));
5976 case value_t::number_unsigned: {
5977 if (
j.m_value.number_unsigned <= 0x17) {
5978 write_number(
static_cast<uint8_t>(
j.m_value.number_unsigned));
5979 }
else if (
j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)()) {
5980 oa->write_character(
static_cast<CharType
>(0x18));
5981 write_number(
static_cast<uint8_t>(
j.m_value.number_unsigned));
5982 }
else if (
j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)()) {
5983 oa->write_character(
static_cast<CharType
>(0x19));
5984 write_number(
static_cast<uint16_t
>(
j.m_value.number_unsigned));
5985 }
else if (
j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)()) {
5986 oa->write_character(
static_cast<CharType
>(0x1A));
5987 write_number(
static_cast<uint32_t
>(
j.m_value.number_unsigned));
5989 oa->write_character(
static_cast<CharType
>(0x1B));
5990 write_number(
static_cast<uint64_t
>(
j.m_value.number_unsigned));
5995 case value_t::number_float:
5997 oa->write_character(
static_cast<CharType
>(0xFB));
5998 write_number(
j.m_value.number_float);
6002 case value_t::string: {
6004 const auto N =
j.m_value.string->size();
6006 write_number(
static_cast<uint8_t>(0x60 + N));
6007 }
else if (N <= (std::numeric_limits<uint8_t>::max)()) {
6008 oa->write_character(
static_cast<CharType
>(0x78));
6009 write_number(
static_cast<uint8_t>(N));
6010 }
else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6011 oa->write_character(
static_cast<CharType
>(0x79));
6012 write_number(
static_cast<uint16_t
>(N));
6013 }
else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6014 oa->write_character(
static_cast<CharType
>(0x7A));
6015 write_number(
static_cast<uint32_t
>(N));
6018 else if (N <= (std::numeric_limits<uint64_t>::max)()) {
6019 oa->write_character(
static_cast<CharType
>(0x7B));
6020 write_number(
static_cast<uint64_t
>(N));
6025 oa->write_characters(
6026 reinterpret_cast<const CharType*
>(
j.m_value.string->c_str()),
6027 j.m_value.string->size());
6031 case value_t::array: {
6033 const auto N =
j.m_value.array->size();
6035 write_number(
static_cast<uint8_t>(0x80 + N));
6036 }
else if (N <= (std::numeric_limits<uint8_t>::max)()) {
6037 oa->write_character(
static_cast<CharType
>(0x98));
6038 write_number(
static_cast<uint8_t>(N));
6039 }
else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6040 oa->write_character(
static_cast<CharType
>(0x99));
6041 write_number(
static_cast<uint16_t
>(N));
6042 }
else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6043 oa->write_character(
static_cast<CharType
>(0x9A));
6044 write_number(
static_cast<uint32_t
>(N));
6047 else if (N <= (std::numeric_limits<uint64_t>::max)()) {
6048 oa->write_character(
static_cast<CharType
>(0x9B));
6049 write_number(
static_cast<uint64_t
>(N));
6054 for (
const auto& el : *
j.m_value.
array) {
6060 case value_t::object: {
6062 const auto N =
j.m_value.object->size();
6064 write_number(
static_cast<uint8_t>(0xA0 + N));
6065 }
else if (N <= (std::numeric_limits<uint8_t>::max)()) {
6066 oa->write_character(
static_cast<CharType
>(0xB8));
6067 write_number(
static_cast<uint8_t>(N));
6068 }
else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6069 oa->write_character(
static_cast<CharType
>(0xB9));
6070 write_number(
static_cast<uint16_t
>(N));
6071 }
else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6072 oa->write_character(
static_cast<CharType
>(0xBA));
6073 write_number(
static_cast<uint32_t
>(N));
6076 else if (N <= (std::numeric_limits<uint64_t>::max)()) {
6077 oa->write_character(
static_cast<CharType
>(0xBB));
6078 write_number(
static_cast<uint64_t
>(N));
6083 for (
const auto& el : *
j.m_value.
object) {
6084 write_cbor(el.first);
6085 write_cbor(el.second);
6098 void write_msgpack(
const BasicJsonType&
j)
6103 oa->write_character(
static_cast<CharType
>(0xC0));
6107 case value_t::boolean:
6109 oa->write_character(
j.m_value.boolean
6110 ?
static_cast<CharType
>(0xC3)
6111 : static_cast<CharType>(0xC2));
6115 case value_t::number_integer: {
6116 if (
j.m_value.number_integer >= 0) {
6120 if (
j.m_value.number_unsigned < 128) {
6122 write_number(
static_cast<uint8_t>(
j.m_value.number_integer));
6123 }
else if (
j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)()) {
6125 oa->write_character(
static_cast<CharType
>(0xCC));
6126 write_number(
static_cast<uint8_t>(
j.m_value.number_integer));
6127 }
else if (
j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)()) {
6129 oa->write_character(
static_cast<CharType
>(0xCD));
6130 write_number(
static_cast<uint16_t
>(
j.m_value.number_integer));
6131 }
else if (
j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)()) {
6133 oa->write_character(
static_cast<CharType
>(0xCE));
6134 write_number(
static_cast<uint32_t
>(
j.m_value.number_integer));
6135 }
else if (
j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)()) {
6137 oa->write_character(
static_cast<CharType
>(0xCF));
6138 write_number(
static_cast<uint64_t
>(
j.m_value.number_integer));
6141 if (
j.m_value.number_integer >= -32) {
6143 write_number(
static_cast<int8_t
>(
j.m_value.number_integer));
6144 }
else if (
j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and
6145 j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)()) {
6147 oa->write_character(
static_cast<CharType
>(0xD0));
6148 write_number(
static_cast<int8_t
>(
j.m_value.number_integer));
6149 }
else if (
j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and
6150 j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)()) {
6152 oa->write_character(
static_cast<CharType
>(0xD1));
6153 write_number(
static_cast<int16_t
>(
j.m_value.number_integer));
6154 }
else if (
j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and
6155 j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)()) {
6157 oa->write_character(
static_cast<CharType
>(0xD2));
6158 write_number(
static_cast<int32_t
>(
j.m_value.number_integer));
6159 }
else if (
j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and
6160 j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)()) {
6162 oa->write_character(
static_cast<CharType
>(0xD3));
6163 write_number(
static_cast<int64_t
>(
j.m_value.number_integer));
6169 case value_t::number_unsigned: {
6170 if (
j.m_value.number_unsigned < 128) {
6172 write_number(
static_cast<uint8_t>(
j.m_value.number_integer));
6173 }
else if (
j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)()) {
6175 oa->write_character(
static_cast<CharType
>(0xCC));
6176 write_number(
static_cast<uint8_t>(
j.m_value.number_integer));
6177 }
else if (
j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)()) {
6179 oa->write_character(
static_cast<CharType
>(0xCD));
6180 write_number(
static_cast<uint16_t
>(
j.m_value.number_integer));
6181 }
else if (
j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)()) {
6183 oa->write_character(
static_cast<CharType
>(0xCE));
6184 write_number(
static_cast<uint32_t
>(
j.m_value.number_integer));
6185 }
else if (
j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)()) {
6187 oa->write_character(
static_cast<CharType
>(0xCF));
6188 write_number(
static_cast<uint64_t
>(
j.m_value.number_integer));
6193 case value_t::number_float:
6195 oa->write_character(
static_cast<CharType
>(0xCB));
6196 write_number(
j.m_value.number_float);
6200 case value_t::string: {
6202 const auto N =
j.m_value.string->size();
6205 write_number(
static_cast<uint8_t>(0xA0 | N));
6206 }
else if (N <= (std::numeric_limits<uint8_t>::max)()) {
6208 oa->write_character(
static_cast<CharType
>(0xD9));
6209 write_number(
static_cast<uint8_t>(N));
6210 }
else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6212 oa->write_character(
static_cast<CharType
>(0xDA));
6213 write_number(
static_cast<uint16_t
>(N));
6214 }
else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6216 oa->write_character(
static_cast<CharType
>(0xDB));
6217 write_number(
static_cast<uint32_t
>(N));
6221 oa->write_characters(
6222 reinterpret_cast<const CharType*
>(
j.m_value.string->c_str()),
6223 j.m_value.string->size());
6227 case value_t::array: {
6229 const auto N =
j.m_value.array->size();
6232 write_number(
static_cast<uint8_t>(0x90 | N));
6233 }
else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6235 oa->write_character(
static_cast<CharType
>(0xDC));
6236 write_number(
static_cast<uint16_t
>(N));
6237 }
else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6239 oa->write_character(
static_cast<CharType
>(0xDD));
6240 write_number(
static_cast<uint32_t
>(N));
6244 for (
const auto& el : *
j.m_value.
array) {
6250 case value_t::object: {
6252 const auto N =
j.m_value.object->size();
6255 write_number(
static_cast<uint8_t>(0x80 | (N & 0xF)));
6256 }
else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6258 oa->write_character(
static_cast<CharType
>(0xDE));
6259 write_number(
static_cast<uint16_t
>(N));
6260 }
else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6262 oa->write_character(
static_cast<CharType
>(0xDF));
6263 write_number(
static_cast<uint32_t
>(N));
6267 for (
const auto& el : *
j.m_value.
object) {
6268 write_msgpack(el.first);
6269 write_msgpack(el.second);
6285 void write_ubjson(
const BasicJsonType&
j,
const bool use_count,
6286 const bool use_type,
const bool add_prefix =
true)
6289 case value_t::null: {
6291 oa->write_character(
static_cast<CharType
>(
'Z'));
6296 case value_t::boolean: {
6298 oa->write_character(
j.m_value.boolean
6299 ?
static_cast<CharType
>(
'T')
6300 : static_cast<CharType>(
'F'));
6305 case value_t::number_integer: {
6306 write_number_with_ubjson_prefix(
j.m_value.number_integer, add_prefix);
6310 case value_t::number_unsigned: {
6311 write_number_with_ubjson_prefix(
j.m_value.number_unsigned, add_prefix);
6315 case value_t::number_float: {
6316 write_number_with_ubjson_prefix(
j.m_value.number_float, add_prefix);
6320 case value_t::string: {
6322 oa->write_character(
static_cast<CharType
>(
'S'));
6324 write_number_with_ubjson_prefix(
j.m_value.string->size(),
true);
6325 oa->write_characters(
6326 reinterpret_cast<const CharType*
>(
j.m_value.string->c_str()),
6327 j.m_value.string->size());
6331 case value_t::array: {
6333 oa->write_character(
static_cast<CharType
>(
'['));
6336 bool prefix_required =
true;
6337 if (use_type and not
j.m_value.array->empty()) {
6339 const char first_prefix = ubjson_prefix(
j.front());
6340 const bool same_prefix = std::all_of(
j.begin() + 1,
j.end(),
6341 [
this, first_prefix](
const BasicJsonType&
v) {
6342 return ubjson_prefix(v) == first_prefix;
6346 prefix_required =
false;
6347 oa->write_character(
static_cast<CharType
>(
'$'));
6348 oa->write_character(
static_cast<CharType
>(first_prefix));
6353 oa->write_character(
static_cast<CharType
>(
'#'));
6354 write_number_with_ubjson_prefix(
j.m_value.array->size(),
true);
6357 for (
const auto& el : *
j.m_value.
array) {
6358 write_ubjson(el, use_count, use_type, prefix_required);
6361 if (not use_count) {
6362 oa->write_character(
static_cast<CharType
>(
']'));
6368 case value_t::object: {
6370 oa->write_character(
static_cast<CharType
>(
'{'));
6373 bool prefix_required =
true;
6374 if (use_type and not
j.m_value.object->empty()) {
6376 const char first_prefix = ubjson_prefix(
j.front());
6377 const bool same_prefix = std::all_of(
j.begin(),
j.end(),
6378 [
this, first_prefix](
const BasicJsonType&
v) {
6379 return ubjson_prefix(v) == first_prefix;
6383 prefix_required =
false;
6384 oa->write_character(
static_cast<CharType
>(
'$'));
6385 oa->write_character(
static_cast<CharType
>(first_prefix));
6390 oa->write_character(
static_cast<CharType
>(
'#'));
6391 write_number_with_ubjson_prefix(
j.m_value.object->size(),
true);
6394 for (
const auto& el : *
j.m_value.
object) {
6395 write_number_with_ubjson_prefix(el.first.size(),
true);
6396 oa->write_characters(
6397 reinterpret_cast<const CharType*
>(el.first.c_str()),
6399 write_ubjson(el.second, use_count, use_type, prefix_required);
6402 if (not use_count) {
6403 oa->write_character(
static_cast<CharType
>(
'}'));
6425 template <
typename NumberType>
6426 void write_number(
const NumberType
n)
6429 std::array<CharType,
sizeof(NumberType)>
vec;
6430 std::memcpy(
vec.data(), &
n,
sizeof(NumberType));
6433 if (is_little_endian) {
6435 std::reverse(
vec.begin(),
vec.end());
6438 oa->write_characters(
vec.data(),
sizeof(NumberType));
6442 template <
typename NumberType,
typename std::enable_if<
6443 std::is_floating_point<NumberType>::value,
int>
::type = 0>
6444 void write_number_with_ubjson_prefix(
const NumberType
n,
6445 const bool add_prefix)
6448 oa->write_character(
static_cast<CharType
>(
'D'));
6454 template <
typename NumberType,
typename std::enable_if<
6455 std::is_unsigned<NumberType>::value,
int>
::type = 0>
6456 void write_number_with_ubjson_prefix(
const NumberType
n,
6457 const bool add_prefix)
6459 if (
n <=
static_cast<uint64_t
>((std::numeric_limits<int8_t>::max)())) {
6461 oa->write_character(
static_cast<CharType
>(
'i'));
6463 write_number(
static_cast<uint8_t>(
n));
6464 }
else if (
n <= (std::numeric_limits<uint8_t>::max)()) {
6466 oa->write_character(
static_cast<CharType
>(
'U'));
6468 write_number(
static_cast<uint8_t>(
n));
6469 }
else if (
n <=
static_cast<uint64_t
>((std::numeric_limits<int16_t>::max)())) {
6471 oa->write_character(
static_cast<CharType
>(
'I'));
6473 write_number(
static_cast<int16_t
>(
n));
6474 }
else if (
n <=
static_cast<uint64_t
>((std::numeric_limits<int32_t>::max)())) {
6476 oa->write_character(
static_cast<CharType
>(
'l'));
6478 write_number(
static_cast<int32_t
>(
n));
6479 }
else if (
n <=
static_cast<uint64_t
>((std::numeric_limits<int64_t>::max)())) {
6481 oa->write_character(
static_cast<CharType
>(
'L'));
6483 write_number(
static_cast<int64_t
>(
n));
6490 template <
typename NumberType,
typename std::enable_if<
6491 std::is_signed<NumberType>::value and
6492 not std::is_floating_point<NumberType>::value,
6494 void write_number_with_ubjson_prefix(
const NumberType
n,
6495 const bool add_prefix)
6497 if ((std::numeric_limits<int8_t>::min)() <=
n and
n <= (std::numeric_limits<int8_t>::max)()) {
6499 oa->write_character(
static_cast<CharType
>(
'i'));
6501 write_number(
static_cast<int8_t
>(
n));
6502 }
else if (
static_cast<int64_t
>((std::numeric_limits<uint8_t>::min)()) <=
n and
n <=
static_cast<int64_t
>((std::numeric_limits<uint8_t>::max)())) {
6504 oa->write_character(
static_cast<CharType
>(
'U'));
6506 write_number(
static_cast<uint8_t>(
n));
6507 }
else if ((std::numeric_limits<int16_t>::min)() <=
n and
n <= (std::numeric_limits<int16_t>::max)()) {
6509 oa->write_character(
static_cast<CharType
>(
'I'));
6511 write_number(
static_cast<int16_t
>(
n));
6512 }
else if ((std::numeric_limits<int32_t>::min)() <=
n and
n <= (std::numeric_limits<int32_t>::max)()) {
6514 oa->write_character(
static_cast<CharType
>(
'l'));
6516 write_number(
static_cast<int32_t
>(
n));
6517 }
else if ((std::numeric_limits<int64_t>::min)() <=
n and
n <= (std::numeric_limits<int64_t>::max)()) {
6519 oa->write_character(
static_cast<CharType
>(
'L'));
6521 write_number(
static_cast<int64_t
>(
n));
6539 char ubjson_prefix(
const BasicJsonType&
j)
const noexcept
6545 case value_t::boolean:
6546 return j.m_value.boolean ?
'T' :
'F';
6548 case value_t::number_integer: {
6549 if ((std::numeric_limits<int8_t>::min)() <=
j.m_value.number_integer and
j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)()) {
6551 }
else if ((std::numeric_limits<uint8_t>::min)() <=
j.m_value.number_integer and
j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)()) {
6553 }
else if ((std::numeric_limits<int16_t>::min)() <=
j.m_value.number_integer and
j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)()) {
6555 }
else if ((std::numeric_limits<int32_t>::min)() <=
j.m_value.number_integer and
j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)()) {
6563 case value_t::number_unsigned: {
6564 if (
j.m_value.number_unsigned <= (std::numeric_limits<int8_t>::max)()) {
6566 }
else if (
j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)()) {
6568 }
else if (
j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max)()) {
6570 }
else if (
j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max)()) {
6578 case value_t::number_float:
6581 case value_t::string:
6584 case value_t::array:
6587 case value_t::object:
6597 const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
6600 output_adapter_t<CharType> oa =
nullptr;
6621#include <type_traits>
6660template <
typename Target,
typename Source>
6661Target reinterpret_bits(
const Source
source)
6663 static_assert(
sizeof(Target) ==
sizeof(Source),
"size mismatch");
6672 static constexpr int kPrecision = 64;
6677 constexpr diyfp() noexcept :
f(0), e(0) {}
6678 constexpr diyfp(uint64_t f_,
int e_) noexcept :
f(f_), e(e_) {}
6684 static diyfp sub(
const diyfp&
x,
const diyfp&
y)
noexcept
6689 return diyfp(
x.f -
y.f,
x.e);
6696 static diyfp mul(
const diyfp&
x,
const diyfp&
y)
noexcept
6698 static_assert(kPrecision == 64,
"internal error");
6723 const uint64_t u_lo =
x.f & 0xFFFFFFFF;
6724 const uint64_t u_hi =
x.f >> 32;
6725 const uint64_t v_lo =
y.f & 0xFFFFFFFF;
6726 const uint64_t v_hi =
y.f >> 32;
6728 const uint64_t p0 = u_lo * v_lo;
6729 const uint64_t
p1 = u_lo * v_hi;
6730 const uint64_t
p2 = u_hi * v_lo;
6731 const uint64_t p3 = u_hi * v_hi;
6733 const uint64_t p0_hi = p0 >> 32;
6734 const uint64_t p1_lo =
p1 & 0xFFFFFFFF;
6735 const uint64_t p1_hi =
p1 >> 32;
6736 const uint64_t p2_lo =
p2 & 0xFFFFFFFF;
6737 const uint64_t p2_hi =
p2 >> 32;
6739 uint64_t Q = p0_hi + p1_lo + p2_lo;
6750 Q += uint64_t{1} << (64 - 32 - 1);
6752 const uint64_t
h = p3 + p2_hi + p1_hi + (Q >> 32);
6754 return diyfp(
h,
x.e +
y.e + 64);
6761 static diyfp normalize(diyfp
x)
noexcept
6765 while ((
x.f >> 63) == 0) {
6777 static diyfp normalize_to(
const diyfp&
x,
const int target_exponent)
noexcept
6779 const int delta =
x.e - target_exponent;
6782 assert(((
x.f << delta) >> delta) ==
x.f);
6784 return diyfp(
x.f << delta, target_exponent);
6800template <
typename FloatType>
6801boundaries compute_boundaries(FloatType
value)
6803 assert(std::isfinite(
value));
6813 static_assert(std::numeric_limits<FloatType>::is_iec559,
6814 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
6816 constexpr int kPrecision = std::numeric_limits<FloatType>::digits;
6817 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
6818 constexpr int kMinExp = 1 - kBias;
6819 constexpr uint64_t kHiddenBit = uint64_t{1} << (kPrecision - 1);
6821 using bits_type =
typename std::conditional<kPrecision == 24, uint32_t, uint64_t>::type;
6823 const uint64_t
bits = reinterpret_bits<bits_type>(
value);
6824 const uint64_t E =
bits >> (kPrecision - 1);
6825 const uint64_t F =
bits & (kHiddenBit - 1);
6827 const bool is_denormal = (E == 0);
6828 const diyfp
v = is_denormal
6830 : diyfp(F + kHiddenBit,
static_cast<int>(E) - kBias);
6853 const bool lower_boundary_is_closer = (F == 0 and E > 1);
6854 const diyfp m_plus = diyfp(2 *
v.f + 1,
v.e - 1);
6855 const diyfp m_minus = lower_boundary_is_closer
6856 ? diyfp(4 *
v.f - 1,
v.e - 2)
6857 : diyfp(2 *
v.f - 1,
v.e - 1);
6860 const diyfp w_plus = diyfp::normalize(m_plus);
6863 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
6865 return {diyfp::normalize(
v), w_minus, w_plus};
6923constexpr int kAlpha = -60;
6924constexpr int kGamma = -32;
6940inline cached_power get_cached_power_for_binary_exponent(
int e)
6992 constexpr int kCachedPowersSize = 79;
6993 constexpr int kCachedPowersMinDecExp = -300;
6994 constexpr int kCachedPowersDecStep = 8;
6996 static constexpr cached_power kCachedPowers[] =
6998 {0xAB70FE17C79AC6CA, -1060, -300},
6999 {0xFF77B1FCBEBCDC4F, -1034, -292},
7000 {0xBE5691EF416BD60C, -1007, -284},
7001 {0x8DD01FAD907FFC3C, -980, -276},
7002 {0xD3515C2831559A83, -954, -268},
7003 {0x9D71AC8FADA6C9B5, -927, -260},
7004 {0xEA9C227723EE8BCB, -901, -252},
7005 {0xAECC49914078536D, -874, -244},
7006 {0x823C12795DB6CE57, -847, -236},
7007 {0xC21094364DFB5637, -821, -228},
7008 {0x9096EA6F3848984F, -794, -220},
7009 {0xD77485CB25823AC7, -768, -212},
7010 {0xA086CFCD97BF97F4, -741, -204},
7011 {0xEF340A98172AACE5, -715, -196},
7012 {0xB23867FB2A35B28E, -688, -188},
7013 {0x84C8D4DFD2C63F3B, -661, -180},
7014 {0xC5DD44271AD3CDBA, -635, -172},
7015 {0x936B9FCEBB25C996, -608, -164},
7016 {0xDBAC6C247D62A584, -582, -156},
7017 {0xA3AB66580D5FDAF6, -555, -148},
7018 {0xF3E2F893DEC3F126, -529, -140},
7019 {0xB5B5ADA8AAFF80B8, -502, -132},
7020 {0x87625F056C7C4A8B, -475, -124},
7021 {0xC9BCFF6034C13053, -449, -116},
7022 {0x964E858C91BA2655, -422, -108},
7023 {0xDFF9772470297EBD, -396, -100},
7024 {0xA6DFBD9FB8E5B88F, -369, -92},
7025 {0xF8A95FCF88747D94, -343, -84},
7026 {0xB94470938FA89BCF, -316, -76},
7027 {0x8A08F0F8BF0F156B, -289, -68},
7028 {0xCDB02555653131B6, -263, -60},
7029 {0x993FE2C6D07B7FAC, -236, -52},
7030 {0xE45C10C42A2B3B06, -210, -44},
7031 {0xAA242499697392D3, -183, -36},
7032 {0xFD87B5F28300CA0E, -157, -28},
7033 {0xBCE5086492111AEB, -130, -20},
7034 {0x8CBCCC096F5088CC, -103, -12},
7035 {0xD1B71758E219652C, -77, -4},
7036 {0x9C40000000000000, -50, 4},
7037 {0xE8D4A51000000000, -24, 12},
7038 {0xAD78EBC5AC620000, 3, 20},
7039 {0x813F3978F8940984, 30, 28},
7040 {0xC097CE7BC90715B3, 56, 36},
7041 {0x8F7E32CE7BEA5C70, 83, 44},
7042 {0xD5D238A4ABE98068, 109, 52},
7043 {0x9F4F2726179A2245, 136, 60},
7044 {0xED63A231D4C4FB27, 162, 68},
7045 {0xB0DE65388CC8ADA8, 189, 76},
7046 {0x83C7088E1AAB65DB, 216, 84},
7047 {0xC45D1DF942711D9A, 242, 92},
7048 {0x924D692CA61BE758, 269, 100},
7049 {0xDA01EE641A708DEA, 295, 108},
7050 {0xA26DA3999AEF774A, 322, 116},
7051 {0xF209787BB47D6B85, 348, 124},
7052 {0xB454E4A179DD1877, 375, 132},
7053 {0x865B86925B9BC5C2, 402, 140},
7054 {0xC83553C5C8965D3D, 428, 148},
7055 {0x952AB45CFA97A0B3, 455, 156},
7056 {0xDE469FBD99A05FE3, 481, 164},
7057 {0xA59BC234DB398C25, 508, 172},
7058 {0xF6C69A72A3989F5C, 534, 180},
7059 {0xB7DCBF5354E9BECE, 561, 188},
7060 {0x88FCF317F22241E2, 588, 196},
7061 {0xCC20CE9BD35C78A5, 614, 204},
7062 {0x98165AF37B2153DF, 641, 212},
7063 {0xE2A0B5DC971F303A, 667, 220},
7064 {0xA8D9D1535CE3B396, 694, 228},
7065 {0xFB9B7CD9A4A7443C, 720, 236},
7066 {0xBB764C4CA7A44410, 747, 244},
7067 {0x8BAB8EEFB6409C1A, 774, 252},
7068 {0xD01FEF10A657842C, 800, 260},
7069 {0x9B10A4E5E9913129, 827, 268},
7070 {0xE7109BFBA19C0C9D, 853, 276},
7071 {0xAC2820D9623BF429, 880, 284},
7072 {0x80444B5E7AA7CF85, 907, 292},
7073 {0xBF21E44003ACDD2D, 933, 300},
7074 {0x8E679C2F5E44FF8F, 960, 308},
7075 {0xD433179D9C8CB841, 986, 316},
7076 {0x9E19DB92B4E31BA9, 1013, 324},
7085 const int f = kAlpha - e - 1;
7086 const int k = (
f * 78913) / (1 << 18) + (
f > 0);
7088 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
7090 assert(
index < kCachedPowersSize);
7091 static_cast<void>(kCachedPowersSize);
7093 const cached_power cached = kCachedPowers[
index];
7094 assert(kAlpha <= cached.e + e + 64);
7095 assert(kGamma >= cached.e + e + 64);
7104inline int find_largest_pow10(
const uint32_t
n, uint32_t& pow10)
7107 if (
n >= 1000000000) {
7112 else if (
n >= 100000000) {
7115 }
else if (
n >= 10000000) {
7118 }
else if (
n >= 1000000) {
7121 }
else if (
n >= 100000) {
7124 }
else if (
n >= 10000) {
7127 }
else if (
n >= 1000) {
7130 }
else if (
n >= 100) {
7133 }
else if (
n >= 10) {
7142inline void grisu2_round(
char*
buf,
int len, uint64_t dist, uint64_t delta,
7143 uint64_t rest, uint64_t ten_k)
7146 assert(dist <= delta);
7147 assert(rest <= delta);
7169 while (rest < dist and delta - rest >= ten_k and (rest + ten_k < dist or dist - rest > rest + ten_k - dist)) {
7170 assert(
buf[
len - 1] !=
'0');
7180inline void grisu2_digit_gen(
char*
buffer,
int&
length,
int& decimal_exponent,
7181 diyfp M_minus, diyfp
w, diyfp M_plus)
7183 static_assert(kAlpha >= -60,
"internal error");
7184 static_assert(kGamma <= -32,
"internal error");
7198 assert(M_plus.e >= kAlpha);
7199 assert(M_plus.e <= kGamma);
7201 uint64_t delta = diyfp::sub(M_plus, M_minus).f;
7202 uint64_t dist = diyfp::sub(M_plus,
w).f;
7211 const diyfp
one(uint64_t{1} << -M_plus.e, M_plus.e);
7213 uint32_t
p1 =
static_cast<uint32_t
>(M_plus.f >> -
one.e);
7214 uint64_t
p2 = M_plus.f & (
one.f - 1);
7223 const int k = find_largest_pow10(
p1, pow10);
7249 const uint32_t d =
p1 / pow10;
7250 const uint32_t
r =
p1 % pow10;
7275 const uint64_t rest = (uint64_t{
p1} << -
one.e) +
p2;
7276 if (rest <= delta) {
7279 decimal_exponent +=
n;
7290 const uint64_t ten_n = uint64_t{pow10} << -
one.e;
7291 grisu2_round(
buffer,
length, dist, delta, rest, ten_n);
7351 assert(
p2 <= UINT64_MAX / 10);
7353 const uint64_t d =
p2 >> -
one.e;
7354 const uint64_t
r =
p2 & (
one.f - 1);
7385 decimal_exponent -=
m;
7393 const uint64_t ten_m =
one.f;
7416inline void grisu2(
char*
buf,
int&
len,
int& decimal_exponent,
7417 diyfp m_minus, diyfp
v, diyfp m_plus)
7419 assert(m_plus.e == m_minus.e);
7420 assert(m_plus.e ==
v.e);
7431 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
7433 const diyfp c_minus_k(cached.f, cached.e);
7436 const diyfp
w = diyfp::mul(
v, c_minus_k);
7437 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
7438 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
7461 const diyfp M_minus(w_minus.f + 1, w_minus.e);
7462 const diyfp M_plus(w_plus.f - 1, w_plus.e);
7464 decimal_exponent = -cached.k;
7466 grisu2_digit_gen(
buf,
len, decimal_exponent, M_minus,
w, M_plus);
7474template <
typename FloatType>
7475void grisu2(
char*
buf,
int&
len,
int& decimal_exponent, FloatType
value)
7477 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
7478 "internal error: not enough precision");
7480 assert(std::isfinite(
value));
7500 const boundaries
w = compute_boundaries(
static_cast<double>(
value));
7502 const boundaries
w = compute_boundaries(
value);
7505 grisu2(
buf,
len, decimal_exponent,
w.minus,
w.w,
w.plus);
7513inline char* append_exponent(
char*
buf,
int e)
7525 uint32_t k =
static_cast<uint32_t
>(e);
7530 *
buf++ =
static_cast<char>(
'0' + k);
7531 }
else if (k < 100) {
7532 *
buf++ =
static_cast<char>(
'0' + k / 10);
7534 *
buf++ =
static_cast<char>(
'0' + k);
7536 *
buf++ =
static_cast<char>(
'0' + k / 100);
7538 *
buf++ =
static_cast<char>(
'0' + k / 10);
7540 *
buf++ =
static_cast<char>(
'0' + k);
7555inline char* format_buffer(
char*
buf,
int len,
int decimal_exponent,
7556 int min_exp,
int max_exp)
7558 assert(min_exp < 0);
7559 assert(max_exp > 0);
7562 const int n =
len + decimal_exponent;
7568 if (k <=
n and
n <= max_exp) {
7572 std::memset(
buf + k,
'0',
static_cast<size_t>(
n - k));
7576 return buf + (
n + 2);
7579 if (0 <
n and
n <= max_exp) {
7585 std::memmove(
buf + (
n + 1),
buf +
n,
static_cast<size_t>(k -
n));
7587 return buf + (k + 1);
7590 if (min_exp <
n and
n <= 0) {
7594 std::memmove(
buf + (2 + -
n),
buf,
static_cast<size_t>(k));
7597 std::memset(
buf + 2,
'0',
static_cast<size_t>(-
n));
7598 return buf + (2 + (-
n) + k);
7610 std::memmove(
buf + 2,
buf + 1,
static_cast<size_t>(k - 1));
7616 return append_exponent(
buf,
n - 1);
7631template <
typename FloatType>
7632char* to_chars(
char*
first,
char* last, FloatType
value)
7634 static_cast<void>(last);
7635 assert(std::isfinite(
value));
7638 if (std::signbit(
value)) {
7652 assert(last -
first >= std::numeric_limits<FloatType>::max_digits10);
7659 int decimal_exponent = 0;
7662 assert(
len <= std::numeric_limits<FloatType>::max_digits10);
7665 constexpr int kMinExp = -4;
7667 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
7669 assert(last -
first >= kMaxExp + 2);
7670 assert(last -
first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
7671 assert(last -
first >= std::numeric_limits<FloatType>::max_digits10 + 6);
7673 return dtoa_impl::format_buffer(
first,
len, decimal_exponent, kMinExp, kMaxExp);
7695template <
typename BasicJsonType>
7698 using string_t =
typename BasicJsonType::string_t;
7699 using number_float_t =
typename BasicJsonType::number_float_t;
7700 using number_integer_t =
typename BasicJsonType::number_integer_t;
7701 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
7702 static constexpr uint8_t UTF8_ACCEPT = 0;
7703 static constexpr uint8_t UTF8_REJECT = 1;
7710 serializer(output_adapter_t<char> s,
const char ichar)
7711 :
o(
std::move(
s)), loc(
std::localeconv()), thousands_sep(loc->thousands_sep == nullptr ?
'\0' : *(loc->thousands_sep)), decimal_point(loc->decimal_point == nullptr ?
'\0' : *(loc->decimal_point)), indent_char(ichar), indent_string(512, indent_char)
7716 serializer(
const serializer&) =
delete;
7717 serializer& operator=(
const serializer&) =
delete;
7736 void dump(
const BasicJsonType&
val,
const bool pretty_print,
7737 const bool ensure_ascii,
7738 const unsigned int indent_step,
7739 const unsigned int current_indent = 0)
7741 switch (
val.m_type) {
7742 case value_t::object: {
7743 if (
val.m_value.object->empty()) {
7744 o->write_characters(
"{}", 2);
7749 o->write_characters(
"{\n", 2);
7752 const auto new_indent = current_indent + indent_step;
7754 indent_string.resize(indent_string.size() * 2,
' ');
7758 auto i =
val.m_value.object->cbegin();
7759 for (std::size_t cnt = 0; cnt <
val.m_value.object->size() - 1; ++cnt, ++
i) {
7760 o->write_characters(indent_string.c_str(), new_indent);
7761 o->write_character(
'\"');
7762 dump_escaped(
i->first, ensure_ascii);
7763 o->write_characters(R
"(": )", 3);
7764 dump(i->second, true, ensure_ascii, indent_step, new_indent);
7765 o->write_characters(
",\n", 2);
7769 assert(
i !=
val.m_value.object->cend());
7770 assert(std::next(
i) ==
val.m_value.object->cend());
7771 o->write_characters(indent_string.c_str(), new_indent);
7772 o->write_character(
'\"');
7773 dump_escaped(
i->first, ensure_ascii);
7774 o->write_characters(R
"(": )", 3);
7775 dump(i->second, true, ensure_ascii, indent_step, new_indent);
7777 o->write_character(
'\n');
7778 o->write_characters(indent_string.c_str(), current_indent);
7779 o->write_character(
'}');
7781 o->write_character(
'{');
7784 auto i =
val.m_value.object->cbegin();
7785 for (std::size_t cnt = 0; cnt <
val.m_value.object->size() - 1; ++cnt, ++
i) {
7786 o->write_character(
'\"');
7787 dump_escaped(
i->first, ensure_ascii);
7788 o->write_characters(R
"(":)", 2);
7789 dump(i->second, false, ensure_ascii, indent_step, current_indent);
7790 o->write_character(
',');
7794 assert(
i !=
val.m_value.object->cend());
7795 assert(std::next(
i) ==
val.m_value.object->cend());
7796 o->write_character(
'\"');
7797 dump_escaped(
i->first, ensure_ascii);
7798 o->write_characters(R
"(":)", 2);
7799 dump(i->second, false, ensure_ascii, indent_step, current_indent);
7801 o->write_character(
'}');
7807 case value_t::array: {
7808 if (
val.m_value.array->empty()) {
7809 o->write_characters(
"[]", 2);
7814 o->write_characters(
"[\n", 2);
7817 const auto new_indent = current_indent + indent_step;
7819 indent_string.resize(indent_string.size() * 2,
' ');
7823 for (
auto i =
val.m_value.array->cbegin();
7824 i !=
val.m_value.array->cend() - 1; ++
i) {
7825 o->write_characters(indent_string.c_str(), new_indent);
7826 dump(*
i,
true, ensure_ascii, indent_step, new_indent);
7827 o->write_characters(
",\n", 2);
7831 assert(not
val.m_value.array->empty());
7832 o->write_characters(indent_string.c_str(), new_indent);
7833 dump(
val.m_value.array->back(),
true, ensure_ascii, indent_step, new_indent);
7835 o->write_character(
'\n');
7836 o->write_characters(indent_string.c_str(), current_indent);
7837 o->write_character(
']');
7839 o->write_character(
'[');
7842 for (
auto i =
val.m_value.array->cbegin();
7843 i !=
val.m_value.array->cend() - 1; ++
i) {
7844 dump(*
i,
false, ensure_ascii, indent_step, current_indent);
7845 o->write_character(
',');
7849 assert(not
val.m_value.array->empty());
7850 dump(
val.m_value.array->back(),
false, ensure_ascii, indent_step, current_indent);
7852 o->write_character(
']');
7858 case value_t::string: {
7859 o->write_character(
'\"');
7860 dump_escaped(*
val.m_value.string, ensure_ascii);
7861 o->write_character(
'\"');
7865 case value_t::boolean: {
7866 if (
val.m_value.boolean) {
7867 o->write_characters(
"true", 4);
7869 o->write_characters(
"false", 5);
7874 case value_t::number_integer: {
7875 dump_integer(
val.m_value.number_integer);
7879 case value_t::number_unsigned: {
7880 dump_integer(
val.m_value.number_unsigned);
7884 case value_t::number_float: {
7885 dump_float(
val.m_value.number_float);
7889 case value_t::discarded: {
7890 o->write_characters(
"<discarded>", 11);
7894 case value_t::null: {
7895 o->write_characters(
"null", 4);
7916 void dump_escaped(
const string_t& s,
const bool ensure_ascii)
7920 std::size_t bytes = 0;
7922 for (std::size_t
i = 0;
i <
s.size(); ++
i) {
7923 const auto byte =
static_cast<uint8_t>(
s[
i]);
7928 switch (codepoint) {
7931 string_buffer[bytes++] =
'\\';
7932 string_buffer[bytes++] =
'b';
7938 string_buffer[bytes++] =
'\\';
7939 string_buffer[bytes++] =
't';
7945 string_buffer[bytes++] =
'\\';
7946 string_buffer[bytes++] =
'n';
7952 string_buffer[bytes++] =
'\\';
7953 string_buffer[bytes++] =
'f';
7959 string_buffer[bytes++] =
'\\';
7960 string_buffer[bytes++] =
'r';
7966 string_buffer[bytes++] =
'\\';
7967 string_buffer[bytes++] =
'\"';
7973 string_buffer[bytes++] =
'\\';
7974 string_buffer[bytes++] =
'\\';
7981 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F))) {
7982 if (codepoint <= 0xFFFF) {
7983 std::snprintf(string_buffer.data() + bytes, 7, R
"(\u%04x)",
7984 static_cast<uint16_t
>(codepoint));
7987 std::snprintf(string_buffer.data() + bytes, 13, R
"(\u%04x\u%04x)",
7988 static_cast<uint16_t
>(0xD7C0 + (codepoint >> 10)),
7989 static_cast<uint16_t
>(0xDC00 + (codepoint & 0x3FF)));
7995 string_buffer[bytes++] =
s[
i];
8004 if (string_buffer.size() - bytes < 13) {
8005 o->write_characters(string_buffer.data(), bytes);
8013 std::stringstream ss;
8014 ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << static_cast<int>(
byte);
8020 if (not ensure_ascii) {
8022 string_buffer[bytes++] =
s[
i];
8032 o->write_characters(string_buffer.data(), bytes);
8036 std::stringstream ss;
8037 ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << static_cast<int>(
static_cast<uint8_t>(
s.back()));
8038 JSON_THROW(type_error::create(316,
"incomplete UTF-8 string; last byte: 0x" + ss.str()));
8051 template <
typename NumberType, detail::enable_if_t<
8052 std::is_same<NumberType, number_unsigned_t>::value or
8053 std::is_same<NumberType, number_integer_t>::value,
8055 void dump_integer(NumberType
x)
8059 o->write_character(
'0');
8063 const bool is_negative = (
x <= 0) and (
x != 0);
8068 assert(
i < number_buffer.size() - 1);
8070 const auto digit = std::labs(
static_cast<long>(
x % 10));
8071 number_buffer[
i++] =
static_cast<char>(
'0' + digit);
8077 assert(
i < number_buffer.size() - 2);
8078 number_buffer[
i++] =
'-';
8081 std::reverse(number_buffer.begin(), number_buffer.begin() +
i);
8082 o->write_characters(number_buffer.data(),
i);
8093 void dump_float(number_float_t
x)
8096 if (not std::isfinite(
x)) {
8097 o->write_characters(
"null", 4);
8106 static constexpr bool is_ieee_single_or_double = (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
8107 (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);
8109 dump_float(
x, std::integral_constant<bool, is_ieee_single_or_double>());
8112 void dump_float(number_float_t
x, std::true_type )
8114 char*
begin = number_buffer.data();
8115 char*
end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(),
x);
8117 o->write_characters(begin,
static_cast<size_t>(
end - begin));
8120 void dump_float(number_float_t
x, std::false_type )
8123 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
8126 std::ptrdiff_t
len = snprintf(number_buffer.data(), number_buffer.size(),
"%.*g", d,
x);
8131 assert(
static_cast<std::size_t
>(
len) < number_buffer.size());
8134 if (thousands_sep !=
'\0') {
8135 const auto end = std::remove(number_buffer.begin(),
8136 number_buffer.begin() +
len, thousands_sep);
8137 std::fill(
end, number_buffer.end(),
'\0');
8138 assert((
end - number_buffer.begin()) <=
len);
8139 len = (
end - number_buffer.begin());
8143 if (decimal_point !=
'\0' and decimal_point !=
'.') {
8144 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
8145 if (dec_pos != number_buffer.end()) {
8150 o->write_characters(number_buffer.data(),
static_cast<std::size_t
>(
len));
8153 const bool value_is_int_like =
8154 std::none_of(number_buffer.begin(), number_buffer.begin() +
len + 1,
8156 return (c ==
'.' or c ==
'e');
8159 if (value_is_int_like) {
8160 o->write_characters(
".0", 2);
8187 static const std::array<uint8_t, 400> utf8d =
8190 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,
8191 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,
8192 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,
8193 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,
8194 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,
8195 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,
8196 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,
8197 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
8198 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
8199 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
8200 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,
8201 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,
8202 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,
8203 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
8208 codep = (
state != UTF8_ACCEPT)
8209 ? (
byte & 0x3fu) | (codep << 6)
8210 : static_cast<uint32_t>(0xff >>
type) & (byte);
8218 output_adapter_t<char>
o =
nullptr;
8221 std::array<char, 64> number_buffer{{}};
8224 const std::lconv* loc =
nullptr;
8226 const char thousands_sep =
'\0';
8228 const char decimal_point =
'\0';
8231 std::array<char, 512> string_buffer{{}};
8234 const char indent_char;
8236 string_t indent_string;
8243#include <initializer_list>
8250template <
typename BasicJsonType>
8254 using value_type = BasicJsonType;
8256 json_ref(value_type&&
value)
8257 : owned_value(
std::move(
value)), value_ref(&owned_value), is_rvalue(true)
8261 json_ref(
const value_type&
value)
8262 : value_ref(const_cast<value_type*>(&
value)), is_rvalue(false)
8266 json_ref(std::initializer_list<json_ref> init)
8267 : owned_value(init), value_ref(&owned_value), is_rvalue(true)
8271 template <
class... Args>
8272 json_ref(Args&&... args)
8273 : owned_value(
std::forward<Args>(args)...), value_ref(&owned_value), is_rvalue(true)
8278 json_ref(json_ref&&) =
default;
8279 json_ref(
const json_ref&) =
delete;
8280 json_ref& operator=(
const json_ref&) =
delete;
8282 value_type moved_or_copied()
const
8285 return std::move(*value_ref);
8292 return *
static_cast<value_type const*
>(value_ref);
8295 value_type
const* operator->()
const
8297 return static_cast<value_type const*
>(value_ref);
8301 mutable value_type owned_value =
nullptr;
8302 value_type* value_ref =
nullptr;
8303 const bool is_rvalue;
8323template <
typename BasicJsonType>
8328 friend class basic_json;
8352 explicit json_pointer(
const std::string& s =
"")
8353 : reference_tokens(
split(
s))
8374 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
8376 [](
const std::string&
a,
const std::string&
b) {
8377 return a +
"/" + escape(b);
8382 operator std::string()
const
8394 static int array_index(
const std::string& s)
8396 std::size_t processed_chars = 0;
8397 const int res = std::stoi(s, &processed_chars);
8412 std::string pop_back()
8418 auto last = reference_tokens.back();
8419 reference_tokens.pop_back();
8424 bool is_root()
const
8426 return reference_tokens.empty();
8429 json_pointer
top()
const
8435 json_pointer
result = *
this;
8436 result.reference_tokens = {reference_tokens[0]};
8448 BasicJsonType& get_and_create(BasicJsonType&
j)
const
8450 using size_type =
typename BasicJsonType::size_type;
8455 for (
const auto& reference_token : reference_tokens) {
8456 switch (
result->m_type) {
8457 case detail::value_t::null: {
8458 if (reference_token ==
"0") {
8468 case detail::value_t::object: {
8474 case detail::value_t::array: {
8478 result = &
result->operator[](
static_cast<size_type
>(array_index(reference_token)));
8520 BasicJsonType& get_unchecked(BasicJsonType*
ptr)
const
8522 using size_type =
typename BasicJsonType::size_type;
8523 for (
const auto& reference_token : reference_tokens) {
8525 if (
ptr->m_type == detail::value_t::null) {
8528 std::all_of(reference_token.begin(), reference_token.end(),
8530 return (x >=
'0' and x <=
'9');
8534 *
ptr = (nums or reference_token ==
"-")
8535 ? detail::value_t::array
8536 : detail::value_t::
object;
8539 switch (
ptr->m_type) {
8540 case detail::value_t::object: {
8542 ptr = &
ptr->operator[](reference_token);
8546 case detail::value_t::array: {
8548 if (
JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0')) {
8550 "array index '" + reference_token +
8551 "' must not begin with '0'"));
8554 if (reference_token ==
"-") {
8556 ptr = &
ptr->operator[](
ptr->m_value.array->size());
8562 static_cast<size_type
>(array_index(reference_token)));
8586 BasicJsonType& get_checked(BasicJsonType*
ptr)
const
8588 using size_type =
typename BasicJsonType::size_type;
8589 for (
const auto& reference_token : reference_tokens) {
8590 switch (
ptr->m_type) {
8591 case detail::value_t::object: {
8593 ptr = &
ptr->at(reference_token);
8597 case detail::value_t::array: {
8602 ") is out of range"));
8606 if (
JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0')) {
8608 "array index '" + reference_token +
8609 "' must not begin with '0'"));
8615 ptr = &
ptr->at(
static_cast<size_type
>(array_index(reference_token)));
8645 const BasicJsonType& get_unchecked(
const BasicJsonType*
ptr)
const
8647 using size_type =
typename BasicJsonType::size_type;
8648 for (
const auto& reference_token : reference_tokens) {
8649 switch (
ptr->m_type) {
8650 case detail::value_t::object: {
8652 ptr = &
ptr->operator[](reference_token);
8656 case detail::value_t::array: {
8661 ") is out of range"));
8665 if (
JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0')) {
8667 "array index '" + reference_token +
8668 "' must not begin with '0'"));
8675 static_cast<size_type
>(array_index(reference_token)));
8698 const BasicJsonType& get_checked(
const BasicJsonType*
ptr)
const
8700 using size_type =
typename BasicJsonType::size_type;
8701 for (
const auto& reference_token : reference_tokens) {
8702 switch (
ptr->m_type) {
8703 case detail::value_t::object: {
8705 ptr = &
ptr->at(reference_token);
8709 case detail::value_t::array: {
8714 ") is out of range"));
8718 if (
JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0')) {
8720 "array index '" + reference_token +
8721 "' must not begin with '0'"));
8727 ptr = &
ptr->at(
static_cast<size_type
>(array_index(reference_token)));
8753 static std::vector<std::string>
split(
const std::string& reference_string)
8755 std::vector<std::string>
result;
8758 if (reference_string.empty()) {
8765 "JSON pointer must be empty or begin with '/' - was: '" +
8766 reference_string +
"'"));
8774 std::size_t slash = reference_string.find_first_of(
'/', 1),
8783 slash = reference_string.find_first_of(
'/',
start)) {
8786 auto reference_token = reference_string.substr(
start, slash -
start);
8789 for (std::size_t
pos = reference_token.find_first_of(
'~');
8790 pos != std::string::npos;
8791 pos = reference_token.find_first_of(
'~',
pos + 1)) {
8792 assert(reference_token[
pos] ==
'~');
8796 (reference_token[
pos + 1] !=
'0' and
8797 reference_token[
pos + 1] !=
'1'))) {
8803 unescape(reference_token);
8804 result.push_back(reference_token);
8823 static void replace_substring(std::string& s,
const std::string&
f,
8824 const std::string& t)
8826 assert(not
f.empty());
8827 for (
auto pos =
s.find(
f);
8828 pos != std::string::npos;
8829 s.replace(
pos,
f.size(), t),
8836 static std::string escape(std::string s)
8838 replace_substring(s,
"~",
"~0");
8839 replace_substring(s,
"/",
"~1");
8844 static void unescape(std::string& s)
8846 replace_substring(s,
"~1",
"/");
8847 replace_substring(s,
"~0",
"~");
8857 static void flatten(
const std::string& reference_string,
8858 const BasicJsonType&
value,
8861 switch (
value.m_type) {
8862 case detail::value_t::array: {
8863 if (
value.m_value.array->empty()) {
8865 result[reference_string] =
nullptr;
8868 for (std::size_t
i = 0;
i <
value.m_value.array->size(); ++
i) {
8876 case detail::value_t::object: {
8877 if (
value.m_value.object->empty()) {
8879 result[reference_string] =
nullptr;
8882 for (
const auto& element : *
value.m_value.
object) {
8883 flatten(reference_string +
"/" + escape(element.first), element.second,
result);
8907 static BasicJsonType
8908 unflatten(
const BasicJsonType&
value)
8917 for (
const auto& element : *
value.m_value.
object) {
8926 json_pointer(element.first).get_and_create(
result) = element.second;
8932 friend bool operator==(json_pointer
const& lhs,
8933 json_pointer
const& rhs)
noexcept
8935 return (
lhs.reference_tokens ==
rhs.reference_tokens);
8938 friend bool operator!=(json_pointer
const& lhs,
8939 json_pointer
const& rhs)
noexcept
8941 return not(lhs == rhs);
8945 std::vector<std::string> reference_tokens;
8959template <
typename,
typename>
8960struct adl_serializer {
8970 template <
typename BasicJsonType,
typename ValueType>
8971 static void from_json(BasicJsonType&&
j, ValueType&
val)
noexcept(
8972 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(
j),
val)))
8974 ::nlohmann::from_json(std::forward<BasicJsonType>(
j),
val);
8986 template <
typename BasicJsonType,
typename ValueType>
8987 static void to_json(BasicJsonType&
j, ValueType&&
val)
noexcept(
8988 noexcept(::nlohmann::to_json(
j, std::forward<ValueType>(
val))))
8990 ::nlohmann::to_json(
j, std::forward<ValueType>(
val));
9088 template <detail::value_t>
9089 friend struct detail::external_constructor;
9090 friend ::nlohmann::json_pointer<basic_json>;
9091 friend ::nlohmann::detail::parser<basic_json>;
9092 friend ::nlohmann::detail::serializer<basic_json>;
9093 template <
typename BasicJsonType>
9094 friend class ::nlohmann::detail::iter_impl;
9095 template <
typename BasicJsonType,
typename CharType>
9096 friend class ::nlohmann::detail::binary_writer;
9097 template <
typename BasicJsonType>
9098 friend class ::nlohmann::detail::binary_reader;
9104 using lexer = ::nlohmann::detail::lexer<basic_json>;
9108 template <
typename BasicJsonType>
9110 template <
typename BasicJsonType>
9112 template <
typename Iterator>
9114 template <
typename Base>
9117 template <
typename CharType>
9120 using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
9121 template <
typename CharType>
9122 using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
9124 using serializer = ::nlohmann::detail::serializer<basic_json>;
9127 using value_t = detail::value_t;
9130 template <
typename T,
typename SFINAE>
9131 using json_serializer = JSONSerializer<T, SFINAE>;
9133 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
9144 using exception = detail::exception;
9146 using parse_error = detail::parse_error;
9148 using invalid_iterator = detail::invalid_iterator;
9150 using type_error = detail::type_error;
9152 using out_of_range = detail::out_of_range;
9154 using other_error = detail::other_error;
9168 using value_type = basic_json;
9173 using const_reference =
const value_type&;
9176 using difference_type = std::ptrdiff_t;
9178 using size_type = std::size_t;
9181 using allocator_type = AllocatorType<basic_json>;
9184 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
9186 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
9189 using iterator = iter_impl<basic_json>;
9191 using const_iterator = iter_impl<const basic_json>;
9193 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
9195 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
9202 static allocator_type get_allocator()
9204 return allocator_type();
9233 static basic_json meta()
9237 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
9238 result[
"name"] =
"JSON for Modern C++";
9239 result[
"url"] =
"https://github.com/nlohmann/json";
9240 result[
"version"][
"string"] =
9249 result[
"platform"] =
"win32";
9250#elif defined __linux__
9251 result[
"platform"] =
"linux";
9252#elif defined __APPLE__
9253 result[
"platform"] =
"apple";
9254#elif defined __unix__
9255 result[
"platform"] =
"unix";
9257 result[
"platform"] =
"unknown";
9260#if defined(__ICC) || defined(__INTEL_COMPILER)
9261 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
9262#elif defined(__clang__)
9263 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
9264#elif defined(__GNUC__) || defined(__GNUG__)
9266#elif defined(__HP_cc) || defined(__HP_aCC)
9267 result[
"compiler"] =
"hp"
9268#elif defined(__IBMCPP__)
9269 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
9270#elif defined(_MSC_VER)
9271 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
9273 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
9274#elif defined(__SUNPRO_CC)
9275 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
9277 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
9283 result[
"compiler"][
"c++"] =
"unknown";
9297#if defined(JSON_HAS_CPP_14)
9300 using object_comparator_t = std::less<>;
9302 using object_comparator_t = std::less<StringType>;
9388 using object_t = ObjectType<StringType,
9390 object_comparator_t,
9391 AllocatorType<std::pair<
const StringType,
9438 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
9491 using string_t = StringType;
9517 using boolean_t = BooleanType;
9589 using number_integer_t = NumberIntegerType;
9660 using number_unsigned_t = NumberUnsignedType;
9728 using number_float_t = NumberFloatType;
9734 template <
typename T,
typename... Args>
9735 static T*
create(Args&&... args)
9737 AllocatorType<T>
alloc;
9738 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
9740 auto deleter = [&](
T*
object) {
9741 AllocatorTraits::deallocate(alloc,
object, 1);
9743 std::unique_ptr<
T,
decltype(deleter)>
object(AllocatorTraits::allocate(alloc, 1), deleter);
9744 AllocatorTraits::construct(alloc,
object.
get(), std::forward<Args>(args)...);
9745 assert(
object !=
nullptr);
9746 return object.release();
9787 number_integer_t number_integer;
9789 number_unsigned_t number_unsigned;
9791 number_float_t number_float;
9794 json_value() =
default;
9796 json_value(boolean_t
v) noexcept : boolean(
v) {}
9798 json_value(number_integer_t
v) noexcept : number_integer(
v) {}
9800 json_value(number_unsigned_t
v) noexcept : number_unsigned(
v) {}
9802 json_value(number_float_t
v) noexcept : number_float(
v) {}
9804 json_value(value_t t)
9807 case value_t::object: {
9808 object = create<object_t>();
9812 case value_t::array: {
9813 array = create<array_t>();
9817 case value_t::string: {
9818 string = create<string_t>(
"");
9822 case value_t::boolean: {
9823 boolean = boolean_t(
false);
9827 case value_t::number_integer: {
9828 number_integer = number_integer_t(0);
9832 case value_t::number_unsigned: {
9833 number_unsigned = number_unsigned_t(0);
9837 case value_t::number_float: {
9838 number_float = number_float_t(0.0);
9842 case value_t::null: {
9850 JSON_THROW(other_error::create(500,
"961c151d2e87f2686a955a9be24d316f1362bf21 3.1.2"));
9858 json_value(
const string_t&
value)
9860 string = create<string_t>(
value);
9864 json_value(string_t&&
value)
9866 string = create<string_t>(std::move(
value));
9870 json_value(
const object_t&
value)
9872 object = create<object_t>(
value);
9876 json_value(object_t&&
value)
9878 object = create<object_t>(std::move(
value));
9882 json_value(
const array_t&
value)
9888 json_value(array_t&&
value)
9893 void destroy(value_t t)
noexcept
9896 case value_t::object: {
9897 AllocatorType<object_t>
alloc;
9898 std::allocator_traits<
decltype(
alloc)>::destroy(alloc,
object);
9899 std::allocator_traits<
decltype(
alloc)>::deallocate(alloc,
object, 1);
9903 case value_t::array: {
9904 AllocatorType<array_t>
alloc;
9905 std::allocator_traits<
decltype(
alloc)>::destroy(alloc,
array);
9906 std::allocator_traits<
decltype(
alloc)>::deallocate(alloc,
array, 1);
9910 case value_t::string: {
9911 AllocatorType<string_t>
alloc;
9912 std::allocator_traits<
decltype(
alloc)>::destroy(alloc,
string);
9913 std::allocator_traits<
decltype(
alloc)>::deallocate(alloc,
string, 1);
9933 void assert_invariant() const noexcept
9935 assert(m_type != value_t::object or m_value.object !=
nullptr);
9936 assert(m_type != value_t::array or m_value.array !=
nullptr);
9937 assert(m_type != value_t::string or m_value.string !=
nullptr);
9960 using parse_event_t =
typename parser::parse_event_t;
10011 using parser_callback_t =
typename parser::parser_callback_t;
10051 basic_json(
const value_t
v)
10052 : m_type(
v), m_value(
v)
10054 assert_invariant();
10075 basic_json(std::nullptr_t =
nullptr) noexcept
10076 : basic_json(value_t::null)
10078 assert_invariant();
10138 template <
typename CompatibleType,
10139 typename U = detail::uncvref_t<CompatibleType>,
10141 detail::is_compatible_type<basic_json_t, U>::value,
int> = 0>
10142 basic_json(CompatibleType&&
val)
noexcept(
noexcept(
10143 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
10144 std::forward<CompatibleType>(
val))))
10146 JSONSerializer<U>::to_json(*
this, std::forward<CompatibleType>(
val));
10147 assert_invariant();
10176 template <
typename BasicJsonType,
10178 detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value,
int> = 0>
10179 basic_json(
const BasicJsonType&
val)
10181 using other_boolean_t =
typename BasicJsonType::boolean_t;
10182 using other_number_float_t =
typename BasicJsonType::number_float_t;
10183 using other_number_integer_t =
typename BasicJsonType::number_integer_t;
10184 using other_number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
10185 using other_string_t =
typename BasicJsonType::string_t;
10186 using other_object_t =
typename BasicJsonType::object_t;
10187 using other_array_t =
typename BasicJsonType::array_t;
10189 switch (
val.type()) {
10190 case value_t::boolean:
10191 JSONSerializer<other_boolean_t>::to_json(*
this,
val.template get<other_boolean_t>());
10193 case value_t::number_float:
10194 JSONSerializer<other_number_float_t>::to_json(*
this,
val.template get<other_number_float_t>());
10196 case value_t::number_integer:
10197 JSONSerializer<other_number_integer_t>::to_json(*
this,
val.template get<other_number_integer_t>());
10199 case value_t::number_unsigned:
10200 JSONSerializer<other_number_unsigned_t>::to_json(*
this,
val.template get<other_number_unsigned_t>());
10202 case value_t::string:
10203 JSONSerializer<other_string_t>::to_json(*
this,
val.template get_ref<const other_string_t&>());
10205 case value_t::object:
10206 JSONSerializer<other_object_t>::to_json(*
this,
val.template get_ref<const other_object_t&>());
10208 case value_t::array:
10209 JSONSerializer<other_array_t>::to_json(*
this,
val.template get_ref<const other_array_t&>());
10211 case value_t::null:
10214 case value_t::discarded:
10215 m_type = value_t::discarded;
10218 assert_invariant();
10295 basic_json(initializer_list_t init,
10296 bool type_deduction =
true,
10297 value_t manual_type = value_t::array)
10301 bool is_an_object = std::all_of(init.begin(), init.end(),
10302 [](
const detail::json_ref<basic_json>& element_ref) {
10303 return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
10307 if (not type_deduction) {
10309 if (manual_type == value_t::array) {
10310 is_an_object =
false;
10314 if (
JSON_UNLIKELY(manual_type == value_t::object and not is_an_object)) {
10315 JSON_THROW(type_error::create(301,
"cannot create object from initializer list"));
10319 if (is_an_object) {
10321 m_type = value_t::object;
10322 m_value = value_t::object;
10324 std::for_each(init.begin(), init.end(), [
this](
const detail::json_ref<basic_json>& element_ref) {
10325 auto element = element_ref.moved_or_copied();
10326 m_value.object->emplace(
10327 std::move(*((*element.m_value.array)[0].m_value.string)),
10328 std::move((*element.m_value.array)[1]));
10332 m_type = value_t::array;
10333 m_value.array = create<array_t>(init.begin(), init.end());
10336 assert_invariant();
10376 static basic_json
array(initializer_list_t init = {})
10378 return basic_json(init,
false, value_t::array);
10419 static basic_json
object(initializer_list_t init = {})
10421 return basic_json(init,
false, value_t::object);
10446 basic_json(size_type cnt,
const basic_json&
val)
10447 : m_type(value_t::
array)
10449 m_value.array = create<array_t>(cnt,
val);
10450 assert_invariant();
10508 template <
class InputIT,
typename std::enable_if<
10509 std::is_same<InputIT, typename basic_json_t::iterator>::value or
10510 std::is_same<InputIT, typename basic_json_t::const_iterator>::value,
10512 basic_json(InputIT
first, InputIT last)
10514 assert(
first.m_object !=
nullptr);
10515 assert(
last.m_object !=
nullptr);
10519 JSON_THROW(invalid_iterator::create(201,
"iterators are not compatible"));
10523 m_type =
first.m_object->m_type;
10527 case value_t::boolean:
10528 case value_t::number_float:
10529 case value_t::number_integer:
10530 case value_t::number_unsigned:
10531 case value_t::string: {
10532 if (
JSON_UNLIKELY(not
first.m_it.primitive_iterator.is_begin() or not
last.m_it.primitive_iterator.is_end())) {
10533 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
10543 case value_t::number_integer: {
10544 m_value.number_integer =
first.m_object->m_value.number_integer;
10548 case value_t::number_unsigned: {
10549 m_value.number_unsigned =
first.m_object->m_value.number_unsigned;
10553 case value_t::number_float: {
10554 m_value.number_float =
first.m_object->m_value.number_float;
10558 case value_t::boolean: {
10559 m_value.boolean =
first.m_object->m_value.boolean;
10563 case value_t::string: {
10564 m_value = *
first.m_object->m_value.string;
10568 case value_t::object: {
10569 m_value.object = create<object_t>(
first.m_it.object_iterator,
10570 last.m_it.object_iterator);
10574 case value_t::array: {
10575 m_value.array = create<array_t>(
first.m_it.array_iterator,
10576 last.m_it.array_iterator);
10581 JSON_THROW(invalid_iterator::create(206,
"cannot construct with iterators from " +
10582 std::string(
first.m_object->type_name())));
10585 assert_invariant();
10593 basic_json(
const detail::json_ref<basic_json>&
ref)
10594 : basic_json(
ref.moved_or_copied())
10623 basic_json(
const basic_json&
other)
10624 : m_type(
other.m_type)
10627 other.assert_invariant();
10630 case value_t::object: {
10631 m_value = *
other.m_value.object;
10635 case value_t::array: {
10636 m_value = *
other.m_value.array;
10640 case value_t::string: {
10641 m_value = *
other.m_value.string;
10645 case value_t::boolean: {
10646 m_value =
other.m_value.boolean;
10650 case value_t::number_integer: {
10651 m_value =
other.m_value.number_integer;
10655 case value_t::number_unsigned: {
10656 m_value =
other.m_value.number_unsigned;
10660 case value_t::number_float: {
10661 m_value =
other.m_value.number_float;
10669 assert_invariant();
10698 basic_json(basic_json&&
other) noexcept
10699 : m_type(std::move(
other.m_type)),
10700 m_value(std::move(
other.m_value))
10703 other.assert_invariant();
10706 other.m_type = value_t::null;
10707 other.m_value = {};
10709 assert_invariant();
10736 std::is_nothrow_move_constructible<value_t>::value and
10737 std::is_nothrow_move_assignable<value_t>::value and
10738 std::is_nothrow_move_constructible<json_value>::value and
10739 std::is_nothrow_move_assignable<json_value>::value)
10742 other.assert_invariant();
10745 swap(m_type,
other.m_type);
10746 swap(m_value,
other.m_value);
10748 assert_invariant();
10767 ~basic_json() noexcept
10769 assert_invariant();
10770 m_value.destroy(m_type);
10820 string_t
dump(
const int indent = -1,
const char indent_char =
' ',
10821 const bool ensure_ascii =
false)
const
10824 serializer
s(detail::output_adapter<char, string_t>(
result), indent_char);
10827 s.dump(*
this,
true, ensure_ascii,
static_cast<unsigned int>(indent));
10829 s.dump(*
this,
false, ensure_ascii, 0);
10867 constexpr value_t
type() const noexcept
10897 constexpr bool is_primitive() const noexcept
10899 return is_null() or is_string() or is_boolean() or is_number();
10924 constexpr
bool is_structured() const noexcept
10926 return is_array() or is_object();
10946 constexpr
bool is_null() const noexcept
10948 return (m_type == value_t::null);
10968 constexpr bool is_boolean() const noexcept
10970 return (m_type == value_t::boolean);
10998 constexpr bool is_number() const noexcept
11000 return is_number_integer() or is_number_float();
11027 constexpr
bool is_number_integer() const noexcept
11029 return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
11055 constexpr bool is_number_unsigned() const noexcept
11057 return (m_type == value_t::number_unsigned);
11083 constexpr bool is_number_float() const noexcept
11085 return (m_type == value_t::number_float);
11105 constexpr bool is_object() const noexcept
11107 return (m_type == value_t::object);
11127 constexpr bool is_array() const noexcept
11129 return (m_type == value_t::array);
11149 constexpr bool is_string() const noexcept
11151 return (m_type == value_t::string);
11176 constexpr bool is_discarded() const noexcept
11178 return (m_type == value_t::discarded);
11202 constexpr operator value_t() const noexcept
11215 boolean_t get_impl(boolean_t* )
const
11218 return m_value.boolean;
11221 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(type_name())));
11225 object_t* get_impl_ptr(object_t* )
noexcept
11227 return is_object() ? m_value.object :
nullptr;
11231 constexpr const object_t* get_impl_ptr(
const object_t* )
const noexcept
11233 return is_object() ? m_value.object :
nullptr;
11237 array_t* get_impl_ptr(array_t* )
noexcept
11239 return is_array() ? m_value.array :
nullptr;
11243 constexpr const array_t* get_impl_ptr(
const array_t* )
const noexcept
11245 return is_array() ? m_value.array :
nullptr;
11249 string_t* get_impl_ptr(string_t* )
noexcept
11251 return is_string() ? m_value.string :
nullptr;
11255 constexpr const string_t* get_impl_ptr(
const string_t* )
const noexcept
11257 return is_string() ? m_value.string :
nullptr;
11261 boolean_t* get_impl_ptr(boolean_t* )
noexcept
11263 return is_boolean() ? &m_value.boolean :
nullptr;
11267 constexpr const boolean_t* get_impl_ptr(
const boolean_t* )
const noexcept
11269 return is_boolean() ? &m_value.boolean :
nullptr;
11273 number_integer_t* get_impl_ptr(number_integer_t* )
noexcept
11275 return is_number_integer() ? &m_value.number_integer :
nullptr;
11279 constexpr const number_integer_t* get_impl_ptr(
const number_integer_t* )
const noexcept
11281 return is_number_integer() ? &m_value.number_integer :
nullptr;
11285 number_unsigned_t* get_impl_ptr(number_unsigned_t* )
noexcept
11287 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
11291 constexpr const number_unsigned_t* get_impl_ptr(
const number_unsigned_t* )
const noexcept
11293 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
11297 number_float_t* get_impl_ptr(number_float_t* )
noexcept
11299 return is_number_float() ? &m_value.number_float :
nullptr;
11303 constexpr const number_float_t* get_impl_ptr(
const number_float_t* )
const noexcept
11305 return is_number_float() ? &m_value.number_float :
nullptr;
11319 template <
typename ReferenceType,
typename ThisType>
11320 static ReferenceType get_ref_impl(ThisType& obj)
11323 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
11329 JSON_THROW(type_error::create(303,
"incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
11352 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>
::value,
11354 basic_json
get()
const
11375 not std::is_same<BasicJsonType, basic_json>::value and
11376 detail::is_basic_json<BasicJsonType>::value,
11378 BasicJsonType
get()
const
11422 template <
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
11423 detail::enable_if_t<
11424 not detail::is_basic_json<ValueType>::value and
11425 detail::has_from_json<basic_json_t, ValueType>::value and
11426 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
11428 ValueType
get() const noexcept(noexcept(
11429 JSONSerializer<ValueType>::from_json(
std::declval<const basic_json_t&>(),
std::declval<ValueType&>())))
11434 static_assert(not std::is_reference<ValueTypeCV>::value,
11435 "get() cannot be used with reference types, you might want to use get_ref()");
11436 static_assert(std::is_default_constructible<ValueType>::value,
11437 "types must be DefaultConstructible when used with get()");
11440 JSONSerializer<ValueType>::from_json(*
this, ret);
11475 template <
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
11476 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
11477 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
11479 ValueType
get() const noexcept(noexcept(
11480 JSONSerializer<ValueTypeCV>::from_json(
std::declval<const basic_json_t&>())))
11482 static_assert(not std::is_reference<ValueTypeCV>::value,
11483 "get() cannot be used with reference types, you might want to use get_ref()");
11484 return JSONSerializer<ValueTypeCV>::from_json(*
this);
11514 template <
typename PointerType,
typename std::enable_if<
11515 std::is_pointer<PointerType>::value,
int>
::type = 0>
11516 PointerType
get() noexcept
11519 return get_ptr<PointerType>();
11526 template <
typename PointerType,
typename std::enable_if<
11527 std::is_pointer<PointerType>::value,
int>
::type = 0>
11528 constexpr const PointerType
get() const noexcept
11531 return get_ptr<PointerType>();
11560 template <
typename PointerType,
typename std::enable_if<
11561 std::is_pointer<PointerType>::value,
int>
::type = 0>
11562 PointerType get_ptr() noexcept
11565 using pointee_t =
typename std::remove_const<typename std::remove_pointer<typename std::remove_const<PointerType>::type>
::type>
::type;
11568 std::is_same<object_t, pointee_t>::value or std::is_same<array_t, pointee_t>::value or std::is_same<string_t, pointee_t>::value or std::is_same<boolean_t, pointee_t>::value or std::is_same<number_integer_t, pointee_t>::value or std::is_same<number_unsigned_t, pointee_t>::value or std::is_same<number_float_t, pointee_t>::value,
"incompatible pointer type");
11571 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
11578 template <
typename PointerType,
typename std::enable_if<
11579 std::is_pointer<PointerType>::value and
11580 std::is_const<typename std::remove_pointer<PointerType>::type>
::value,
11582 constexpr const PointerType get_ptr() const noexcept
11585 using pointee_t =
typename std::remove_const<typename std::remove_pointer<typename std::remove_const<PointerType>::type>
::type>
::type;
11588 std::is_same<object_t, pointee_t>::value or std::is_same<array_t, pointee_t>::value or std::is_same<string_t, pointee_t>::value or std::is_same<boolean_t, pointee_t>::value or std::is_same<number_integer_t, pointee_t>::value or std::is_same<number_unsigned_t, pointee_t>::value or std::is_same<number_float_t, pointee_t>::value,
"incompatible pointer type");
11591 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
11620 template <
typename ReferenceType,
typename std::enable_if<
11621 std::is_reference<ReferenceType>::value,
int>
::type = 0>
11622 ReferenceType get_ref()
11625 return get_ref_impl<ReferenceType>(*
this);
11632 template <
typename ReferenceType,
typename std::enable_if<
11633 std::is_reference<ReferenceType>::value and
11634 std::is_const<typename std::remove_reference<ReferenceType>::type>
::value,
11636 ReferenceType get_ref()
const
11639 return get_ref_impl<ReferenceType>(*
this);
11671 template <
typename ValueType,
typename std::enable_if<
11672 not std::is_pointer<ValueType>::value and
11673 not std::is_same<ValueType, detail::json_ref<basic_json>>
::value and
11674 not std::is_same<ValueType, typename string_t::value_type>::value and
11675 not detail::is_basic_json<ValueType>::value
11677 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>
::value
11679#if defined(JSON_HAS_CPP_17)
11680 and not std::is_same<ValueType, typename std::string_view>::value
11684 operator ValueType()
const
11687 return get<ValueType>();
11732 return m_value.array->at(idx);
11740 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
11770 const_reference at(size_type idx)
const
11776 return m_value.array->at(idx);
11784 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
11824 return m_value.object->at(
key);
11829 JSON_THROW(out_of_range::create(403,
"key '" +
key +
"' not found"));
11832 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
11866 const_reference at(
const typename object_t::key_type&
key)
const
11872 return m_value.object->at(
key);
11877 JSON_THROW(out_of_range::create(403,
"key '" +
key +
"' not found"));
11880 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
11913 m_type = value_t::array;
11914 m_value.array = create<array_t>();
11915 assert_invariant();
11921 if (idx >= m_value.array->size()) {
11922 m_value.array->insert(m_value.array->end(),
11923 idx - m_value.array->size() + 1,
11927 return m_value.array->operator[](
idx);
11930 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
11952 const_reference operator[](size_type idx)
const
11956 return m_value.array->operator[](
idx);
11959 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
11989 reference operator[](
const typename object_t::key_type&
key)
11993 m_type = value_t::object;
11994 m_value.object = create<object_t>();
11995 assert_invariant();
12000 return m_value.object->operator[](
key);
12003 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
12036 const_reference operator[](
const typename object_t::key_type&
key)
const
12040 assert(m_value.object->find(
key) != m_value.object->end());
12041 return m_value.object->find(
key)->second;
12044 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
12074 template <
typename T>
12079 m_type = value_t::object;
12080 m_value = value_t::object;
12081 assert_invariant();
12086 return m_value.object->operator[](
key);
12089 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
12122 template <
typename T>
12123 const_reference operator[](T*
key)
const
12127 assert(m_value.object->find(
key) != m_value.object->end());
12128 return m_value.object->find(
key)->second;
12131 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + std::string(type_name())));
12182 template <
class ValueType,
typename std::enable_if<
12183 std::is_convertible<basic_json_t, ValueType>::value,
int>
::type = 0>
12184 ValueType
value(
const typename object_t::key_type&
key,
const ValueType& default_value)
const
12189 const auto it = find(
key);
12194 return default_value;
12197 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
12204 string_t
value(
const typename object_t::key_type&
key,
const char* default_value)
const
12206 return value(
key, string_t(default_value));
12250 template <
class ValueType,
typename std::enable_if<
12251 std::is_convertible<basic_json_t, ValueType>::value,
int>
::type = 0>
12252 ValueType
value(
const json_pointer&
ptr,
const ValueType& default_value)
const
12259 return ptr.get_checked(
this);
12263 return default_value;
12267 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
12274 string_t
value(
const json_pointer&
ptr,
const char* default_value)
const
12276 return value(
ptr, string_t(default_value));
12312 const_reference front()
const
12358 const_reference back()
const
12411 template <
class IteratorType,
typename std::enable_if<
12412 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
12413 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
12415 IteratorType erase(IteratorType
pos)
12419 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
12425 case value_t::boolean:
12426 case value_t::number_float:
12427 case value_t::number_integer:
12428 case value_t::number_unsigned:
12429 case value_t::string: {
12431 JSON_THROW(invalid_iterator::create(205,
"iterator out of range"));
12435 AllocatorType<string_t>
alloc;
12436 std::allocator_traits<
decltype(
alloc)>::destroy(alloc, m_value.string);
12437 std::allocator_traits<
decltype(
alloc)>::deallocate(alloc, m_value.string, 1);
12438 m_value.string =
nullptr;
12441 m_type = value_t::null;
12442 assert_invariant();
12446 case value_t::object: {
12447 result.m_it.object_iterator = m_value.object->erase(
pos.m_it.object_iterator);
12451 case value_t::array: {
12452 result.m_it.array_iterator = m_value.array->erase(
pos.m_it.array_iterator);
12457 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
12509 template <
class IteratorType,
typename std::enable_if<
12510 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
12511 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
12513 IteratorType erase(IteratorType
first, IteratorType last)
12517 JSON_THROW(invalid_iterator::create(203,
"iterators do not fit current value"));
12523 case value_t::boolean:
12524 case value_t::number_float:
12525 case value_t::number_integer:
12526 case value_t::number_unsigned:
12527 case value_t::string: {
12528 if (
JSON_LIKELY(not
first.m_it.primitive_iterator.is_begin() or not
last.m_it.primitive_iterator.is_end())) {
12529 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
12533 AllocatorType<string_t>
alloc;
12534 std::allocator_traits<
decltype(
alloc)>::destroy(alloc, m_value.string);
12535 std::allocator_traits<
decltype(
alloc)>::deallocate(alloc, m_value.string, 1);
12536 m_value.string =
nullptr;
12539 m_type = value_t::null;
12540 assert_invariant();
12544 case value_t::object: {
12545 result.m_it.object_iterator = m_value.object->erase(
first.m_it.object_iterator,
12546 last.m_it.object_iterator);
12550 case value_t::array: {
12551 result.m_it.array_iterator = m_value.array->erase(
first.m_it.array_iterator,
12552 last.m_it.array_iterator);
12557 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
12592 size_type erase(
const typename object_t::key_type&
key)
12596 return m_value.object->erase(
key);
12599 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
12626 void erase(
const size_type idx)
12634 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type
>(idx));
12636 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
12671 template <
typename KeyT>
12672 iterator find(KeyT&&
key)
12677 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(
key));
12687 template <
typename KeyT>
12688 const_iterator find(KeyT&&
key)
const
12693 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(
key));
12720 template <
typename KeyT>
12724 return is_object() ? m_value.object->count(std::forward<KeyT>(
key)) : 0;
12760 iterator
begin() noexcept
12770 const_iterator
begin() const noexcept
12800 const_iterator cbegin() const noexcept
12802 const_iterator
result(
this);
12831 iterator
end() noexcept
12841 const_iterator
end() const noexcept
12871 const_iterator cend() const noexcept
12873 const_iterator
result(
this);
12901 reverse_iterator rbegin() noexcept
12903 return reverse_iterator(
end());
12909 const_reverse_iterator rbegin() const noexcept
12938 reverse_iterator rend() noexcept
12940 return reverse_iterator(
begin());
12946 const_reverse_iterator rend() const noexcept
12975 const_reverse_iterator crbegin() const noexcept
12977 return const_reverse_iterator(cend());
13004 const_reverse_iterator crend() const noexcept
13006 return const_reverse_iterator(cbegin());
13068 static iteration_proxy<iterator> iterator_wrapper(
reference ref)
noexcept
13070 return ref.items();
13077 static iteration_proxy<const_iterator> iterator_wrapper(const_reference
ref)
noexcept
13079 return ref.items();
13134 iteration_proxy<iterator> items() noexcept
13136 return iteration_proxy<iterator>(*
this);
13142 iteration_proxy<const_iterator> items() const noexcept
13144 return iteration_proxy<const_iterator>(*
this);
13197 bool empty() const noexcept
13200 case value_t::null: {
13205 case value_t::array: {
13207 return m_value.array->empty();
13210 case value_t::object: {
13212 return m_value.object->empty();
13264 size_type
size() const noexcept
13267 case value_t::null: {
13272 case value_t::array: {
13274 return m_value.array->size();
13277 case value_t::object: {
13279 return m_value.object->size();
13329 size_type max_size() const noexcept
13332 case value_t::array: {
13334 return m_value.array->max_size();
13337 case value_t::object: {
13339 return m_value.object->max_size();
13394 void clear() noexcept
13397 case value_t::number_integer: {
13398 m_value.number_integer = 0;
13402 case value_t::number_unsigned: {
13403 m_value.number_unsigned = 0;
13407 case value_t::number_float: {
13408 m_value.number_float = 0.0;
13412 case value_t::boolean: {
13413 m_value.boolean =
false;
13417 case value_t::string: {
13418 m_value.string->clear();
13422 case value_t::array: {
13423 m_value.array->clear();
13427 case value_t::object: {
13428 m_value.object->clear();
13457 void push_back(basic_json&&
val)
13461 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
13466 m_type = value_t::array;
13467 m_value = value_t::array;
13468 assert_invariant();
13472 m_value.array->push_back(std::move(
val));
13474 val.m_type = value_t::null;
13483 push_back(std::move(
val));
13491 void push_back(
const basic_json&
val)
13495 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
13500 m_type = value_t::array;
13501 m_value = value_t::array;
13502 assert_invariant();
13506 m_value.array->push_back(
val);
13539 void push_back(
const typename object_t::value_type&
val)
13543 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
13548 m_type = value_t::object;
13549 m_value = value_t::object;
13550 assert_invariant();
13554 m_value.object->insert(
val);
13592 void push_back(initializer_list_t init)
13594 if (is_object() and init.size() == 2 and (*init.begin())->is_string()) {
13595 basic_json&&
key = init.begin()->moved_or_copied();
13596 push_back(
typename object_t::value_type(
13597 std::move(
key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
13599 push_back(basic_json(init));
13634 template <
class... Args>
13635 void emplace_back(Args&&... args)
13639 JSON_THROW(type_error::create(311,
"cannot use emplace_back() with " + std::string(type_name())));
13644 m_type = value_t::array;
13645 m_value = value_t::array;
13646 assert_invariant();
13650 m_value.array->emplace_back(std::forward<Args>(args)...);
13680 template <
class... Args>
13681 std::pair<iterator, bool> emplace(Args&&... args)
13685 JSON_THROW(type_error::create(311,
"cannot use emplace() with " + std::string(type_name())));
13690 m_type = value_t::object;
13691 m_value = value_t::object;
13692 assert_invariant();
13696 auto res = m_value.object->emplace(std::forward<Args>(args)...);
13699 it.m_it.object_iterator =
res.first;
13702 return {it,
res.second};
13727 iterator insert(const_iterator
pos,
const basic_json&
val)
13733 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
13738 result.m_it.array_iterator = m_value.array->insert(
pos.m_it.array_iterator,
val);
13742 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
13749 iterator insert(const_iterator
pos, basic_json&&
val)
13751 return insert(
pos,
val);
13778 iterator insert(const_iterator
pos, size_type cnt,
const basic_json&
val)
13784 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
13789 result.m_it.array_iterator = m_value.array->insert(
pos.m_it.array_iterator, cnt,
val);
13793 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
13826 iterator insert(const_iterator
pos, const_iterator
first, const_iterator last)
13830 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
13835 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
13840 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
13844 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container"));
13849 result.m_it.array_iterator = m_value.array->insert(
13850 pos.m_it.array_iterator,
13851 first.m_it.array_iterator,
13852 last.m_it.array_iterator);
13880 iterator insert(const_iterator
pos, initializer_list_t ilist)
13884 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
13889 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
13894 result.m_it.array_iterator = m_value.array->insert(
pos.m_it.array_iterator, ilist.begin(), ilist.end());
13921 void insert(const_iterator
first, const_iterator last)
13925 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
13930 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
13935 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
13938 m_value.object->insert(
first.m_it.object_iterator,
last.m_it.object_iterator);
13960 void update(const_reference
j)
13964 m_type = value_t::object;
13965 m_value.object = create<object_t>();
13966 assert_invariant();
13970 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
13973 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(
j.type_name())));
13976 for (
auto it =
j.cbegin(); it !=
j.cend(); ++it) {
13977 m_value.object->operator[](it.key()) = it.value();
14007 void update(const_iterator
first, const_iterator last)
14011 m_type = value_t::object;
14012 m_value.object = create<object_t>();
14013 assert_invariant();
14017 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
14022 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
14027 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
14030 for (
auto it =
first; it !=
last; ++it) {
14031 m_value.object->operator[](it.key()) = it.value();
14053 std::is_nothrow_move_constructible<value_t>::value and
14054 std::is_nothrow_move_assignable<value_t>::value and
14055 std::is_nothrow_move_constructible<json_value>::value and
14056 std::is_nothrow_move_assignable<json_value>::value)
14058 std::swap(m_type,
other.m_type);
14059 std::swap(m_value,
other.m_value);
14060 assert_invariant();
14083 void swap(array_t&
other)
14087 std::swap(*(m_value.array),
other);
14089 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
14113 void swap(object_t&
other)
14117 std::swap(*(m_value.object),
other);
14119 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
14143 void swap(string_t&
other)
14147 std::swap(*(m_value.string),
other);
14149 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
14202 friend bool operator==(const_reference lhs, const_reference rhs)
noexcept
14204 const auto lhs_type =
lhs.type();
14205 const auto rhs_type =
rhs.type();
14207 if (lhs_type == rhs_type) {
14208 switch (lhs_type) {
14209 case value_t::array:
14210 return (*
lhs.m_value.array == *
rhs.m_value.array);
14212 case value_t::object:
14213 return (*
lhs.m_value.object == *
rhs.m_value.object);
14215 case value_t::null:
14218 case value_t::string:
14219 return (*
lhs.m_value.string == *
rhs.m_value.string);
14221 case value_t::boolean:
14222 return (
lhs.m_value.boolean ==
rhs.m_value.boolean);
14224 case value_t::number_integer:
14225 return (
lhs.m_value.number_integer ==
rhs.m_value.number_integer);
14227 case value_t::number_unsigned:
14228 return (
lhs.m_value.number_unsigned ==
rhs.m_value.number_unsigned);
14230 case value_t::number_float:
14231 return (
lhs.m_value.number_float ==
rhs.m_value.number_float);
14236 }
else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float) {
14237 return (
static_cast<number_float_t
>(
lhs.m_value.number_integer) ==
rhs.m_value.number_float);
14238 }
else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer) {
14239 return (
lhs.m_value.number_float ==
static_cast<number_float_t
>(
rhs.m_value.number_integer));
14240 }
else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float) {
14241 return (
static_cast<number_float_t
>(
lhs.m_value.number_unsigned) ==
rhs.m_value.number_float);
14242 }
else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned) {
14243 return (
lhs.m_value.number_float ==
static_cast<number_float_t
>(
rhs.m_value.number_unsigned));
14244 }
else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer) {
14245 return (
static_cast<number_integer_t
>(
lhs.m_value.number_unsigned) ==
rhs.m_value.number_integer);
14246 }
else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned) {
14247 return (
lhs.m_value.number_integer ==
static_cast<number_integer_t
>(
rhs.m_value.number_unsigned));
14257 template <
typename ScalarType,
typename std::enable_if<
14258 std::is_scalar<ScalarType>::value,
int>
::type = 0>
14259 friend bool operator==(const_reference lhs,
const ScalarType rhs)
noexcept
14261 return (lhs == basic_json(rhs));
14268 template <
typename ScalarType,
typename std::enable_if<
14269 std::is_scalar<ScalarType>::value,
int>
::type = 0>
14270 friend bool operator==(
const ScalarType lhs, const_reference rhs)
noexcept
14272 return (basic_json(lhs) == rhs);
14293 friend bool operator!=(const_reference lhs, const_reference rhs)
noexcept
14295 return not(lhs == rhs);
14302 template <
typename ScalarType,
typename std::enable_if<
14303 std::is_scalar<ScalarType>::value,
int>
::type = 0>
14304 friend bool operator!=(const_reference lhs,
const ScalarType rhs)
noexcept
14306 return (lhs != basic_json(rhs));
14313 template <
typename ScalarType,
typename std::enable_if<
14314 std::is_scalar<ScalarType>::value,
int>
::type = 0>
14315 friend bool operator!=(
const ScalarType lhs, const_reference rhs)
noexcept
14317 return (basic_json(lhs) != rhs);
14346 friend bool operator<(const_reference lhs, const_reference rhs)
noexcept
14348 const auto lhs_type =
lhs.type();
14349 const auto rhs_type =
rhs.type();
14351 if (lhs_type == rhs_type) {
14352 switch (lhs_type) {
14353 case value_t::array:
14354 return (*
lhs.m_value.array) < (*
rhs.m_value.array);
14356 case value_t::object:
14357 return *
lhs.m_value.object < *
rhs.m_value.object;
14359 case value_t::null:
14362 case value_t::string:
14363 return *
lhs.m_value.string < *
rhs.m_value.string;
14365 case value_t::boolean:
14366 return lhs.m_value.boolean <
rhs.m_value.boolean;
14368 case value_t::number_integer:
14369 return lhs.m_value.number_integer <
rhs.m_value.number_integer;
14371 case value_t::number_unsigned:
14372 return lhs.m_value.number_unsigned <
rhs.m_value.number_unsigned;
14374 case value_t::number_float:
14375 return lhs.m_value.number_float <
rhs.m_value.number_float;
14380 }
else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float) {
14381 return static_cast<number_float_t
>(
lhs.m_value.number_integer) <
rhs.m_value.number_float;
14382 }
else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer) {
14383 return lhs.m_value.number_float <
static_cast<number_float_t
>(
rhs.m_value.number_integer);
14384 }
else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float) {
14385 return static_cast<number_float_t
>(
lhs.m_value.number_unsigned) <
rhs.m_value.number_float;
14386 }
else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned) {
14387 return lhs.m_value.number_float <
static_cast<number_float_t
>(
rhs.m_value.number_unsigned);
14388 }
else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned) {
14389 return lhs.m_value.number_integer <
static_cast<number_integer_t
>(
rhs.m_value.number_unsigned);
14390 }
else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer) {
14391 return static_cast<number_integer_t
>(
lhs.m_value.number_unsigned) <
rhs.m_value.number_integer;
14404 template <
typename ScalarType,
typename std::enable_if<
14405 std::is_scalar<ScalarType>::value,
int>
::type = 0>
14406 friend bool operator<(const_reference lhs,
const ScalarType rhs)
noexcept
14408 return (lhs < basic_json(rhs));
14415 template <
typename ScalarType,
typename std::enable_if<
14416 std::is_scalar<ScalarType>::value,
int>
::type = 0>
14417 friend bool operator<(
const ScalarType lhs, const_reference rhs)
noexcept
14419 return (basic_json(lhs) < rhs);
14441 friend bool operator<=(const_reference lhs, const_reference rhs)
noexcept
14443 return not(rhs < lhs);
14450 template <
typename ScalarType,
typename std::enable_if<
14451 std::is_scalar<ScalarType>::value,
int>
::type = 0>
14452 friend bool operator<=(const_reference lhs,
const ScalarType rhs)
noexcept
14454 return (lhs <= basic_json(rhs));
14461 template <
typename ScalarType,
typename std::enable_if<
14462 std::is_scalar<ScalarType>::value,
int>
::type = 0>
14463 friend bool operator<=(
const ScalarType lhs, const_reference rhs)
noexcept
14465 return (basic_json(lhs) <= rhs);
14487 friend bool operator>(const_reference lhs, const_reference rhs)
noexcept
14489 return not(lhs <= rhs);
14496 template <
typename ScalarType,
typename std::enable_if<
14497 std::is_scalar<ScalarType>::value,
int>
::type = 0>
14498 friend bool operator>(const_reference lhs,
const ScalarType rhs)
noexcept
14500 return (lhs > basic_json(rhs));
14507 template <
typename ScalarType,
typename std::enable_if<
14508 std::is_scalar<ScalarType>::value,
int>
::type = 0>
14509 friend bool operator>(
const ScalarType lhs, const_reference rhs)
noexcept
14511 return (basic_json(lhs) > rhs);
14533 friend bool operator>=(const_reference lhs, const_reference rhs)
noexcept
14535 return not(lhs < rhs);
14542 template <
typename ScalarType,
typename std::enable_if<
14543 std::is_scalar<ScalarType>::value,
int>
::type = 0>
14544 friend bool operator>=(const_reference lhs,
const ScalarType rhs)
noexcept
14546 return (lhs >= basic_json(rhs));
14553 template <
typename ScalarType,
typename std::enable_if<
14554 std::is_scalar<ScalarType>::value,
int>
::type = 0>
14555 friend bool operator>=(
const ScalarType lhs, const_reference rhs)
noexcept
14557 return (basic_json(lhs) >= rhs);
14600 friend std::ostream&
operator<<(std::ostream&
o,
const basic_json&
j)
14603 const bool pretty_print = (
o.width() > 0);
14604 const auto indentation = (pretty_print ?
o.width() : 0);
14610 serializer
s(detail::output_adapter<char>(
o),
o.fill());
14611 s.dump(
j, pretty_print,
false,
static_cast<unsigned int>(indentation));
14624 friend std::ostream&
operator>>(
const basic_json&
j, std::ostream&
o)
14700 static basic_json parse(detail::input_adapter
i,
14701 const parser_callback_t cb =
nullptr,
14702 const bool allow_exceptions =
true)
14705 parser(
i, cb, allow_exceptions).parse(
true,
result);
14712 static basic_json parse(detail::input_adapter&
i,
14713 const parser_callback_t cb =
nullptr,
14714 const bool allow_exceptions =
true)
14717 parser(
i, cb, allow_exceptions).parse(
true,
result);
14721 static bool accept(detail::input_adapter
i)
14723 return parser(
i).accept(
true);
14726 static bool accept(detail::input_adapter&
i)
14728 return parser(
i).accept(
true);
14778 template <
class IteratorType,
typename std::enable_if<
14780 std::random_access_iterator_tag,
14781 typename std::iterator_traits<IteratorType>::iterator_category>
::value,
14783 static basic_json parse(IteratorType
first, IteratorType last,
14784 const parser_callback_t cb =
nullptr,
14785 const bool allow_exceptions =
true)
14788 parser(detail::input_adapter(
first, last), cb, allow_exceptions).parse(
true,
result);
14792 template <
class IteratorType,
typename std::enable_if<
14794 std::random_access_iterator_tag,
14795 typename std::iterator_traits<IteratorType>::iterator_category>
::value,
14797 static bool accept(IteratorType
first, IteratorType last)
14799 return parser(detail::input_adapter(
first, last)).accept(
true);
14811 friend std::istream&
operator<<(basic_json&
j, std::istream&
i)
14841 friend std::istream&
operator>>(std::istream&
i, basic_json&
j)
14843 parser(detail::input_adapter(
i)).parse(
false,
j);
14883 const char* type_name() const noexcept
14887 case value_t::null:
14889 case value_t::object:
14891 case value_t::array:
14893 case value_t::string:
14895 case value_t::boolean:
14897 case value_t::discarded:
14898 return "discarded";
14911 value_t m_type = value_t::null;
14914 json_value m_value = {};
15012 static std::vector<uint8_t> to_cbor(
const basic_json&
j)
15014 std::vector<uint8_t>
result;
15019 static void to_cbor(
const basic_json&
j, detail::output_adapter<uint8_t>
o)
15021 binary_writer<uint8_t>(
o).write_cbor(
j);
15024 static void to_cbor(
const basic_json&
j, detail::output_adapter<char>
o)
15026 binary_writer<char>(
o).write_cbor(
j);
15109 static std::vector<uint8_t> to_msgpack(
const basic_json&
j)
15111 std::vector<uint8_t>
result;
15116 static void to_msgpack(
const basic_json&
j, detail::output_adapter<uint8_t>
o)
15118 binary_writer<uint8_t>(
o).write_msgpack(
j);
15121 static void to_msgpack(
const basic_json&
j, detail::output_adapter<char>
o)
15123 binary_writer<char>(
o).write_msgpack(
j);
15206 static std::vector<uint8_t> to_ubjson(
const basic_json&
j,
15207 const bool use_size =
false,
15208 const bool use_type =
false)
15210 std::vector<uint8_t>
result;
15211 to_ubjson(
j,
result, use_size, use_type);
15215 static void to_ubjson(
const basic_json&
j, detail::output_adapter<uint8_t>
o,
15216 const bool use_size =
false,
const bool use_type =
false)
15218 binary_writer<uint8_t>(
o).write_ubjson(
j, use_size, use_type);
15221 static void to_ubjson(
const basic_json&
j, detail::output_adapter<char>
o,
15222 const bool use_size =
false,
const bool use_type =
false)
15224 binary_writer<char>(
o).write_ubjson(
j, use_size, use_type);
15320 static basic_json from_cbor(detail::input_adapter
i,
15321 const bool strict =
true)
15323 return binary_reader(
i).parse_cbor(strict);
15329 template <
typename A1,
typename A2,
15330 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
15331 static basic_json from_cbor(A1&&
a1, A2&& a2,
const bool strict =
true)
15333 return binary_reader(detail::input_adapter(std::forward<A1>(
a1), std::forward<A2>(a2))).parse_cbor(strict);
15409 static basic_json from_msgpack(detail::input_adapter
i,
15410 const bool strict =
true)
15412 return binary_reader(
i).parse_msgpack(strict);
15418 template <
typename A1,
typename A2,
15419 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
15420 static basic_json from_msgpack(A1&&
a1, A2&& a2,
const bool strict =
true)
15422 return binary_reader(detail::input_adapter(std::forward<A1>(
a1), std::forward<A2>(a2))).parse_msgpack(strict);
15478 static basic_json from_ubjson(detail::input_adapter
i,
15479 const bool strict =
true)
15481 return binary_reader(
i).parse_ubjson(strict);
15484 template <
typename A1,
typename A2,
15485 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
15486 static basic_json from_ubjson(A1&&
a1, A2&& a2,
const bool strict =
true)
15488 return binary_reader(detail::input_adapter(std::forward<A1>(
a1), std::forward<A2>(a2))).parse_ubjson(strict);
15535 return ptr.get_unchecked(
this);
15561 const_reference operator[](
const json_pointer&
ptr)
const
15563 return ptr.get_unchecked(
this);
15606 return ptr.get_checked(
this);
15647 const_reference at(
const json_pointer&
ptr)
const
15649 return ptr.get_checked(
this);
15676 basic_json
result(value_t::object);
15677 json_pointer::flatten(
"", *
this,
result);
15711 basic_json unflatten()
const
15713 return json_pointer::unflatten(*
this);
15772 basic_json patch(
const basic_json& json_patch)
const
15775 basic_json
result = *
this;
15778 enum class patch_operations { add,
15786 const auto get_op = [](
const std::string&
op) {
15788 return patch_operations::add;
15790 if (
op ==
"remove") {
15791 return patch_operations::remove;
15793 if (
op ==
"replace") {
15794 return patch_operations::replace;
15796 if (
op ==
"move") {
15797 return patch_operations::move;
15799 if (
op ==
"copy") {
15800 return patch_operations::copy;
15802 if (
op ==
"test") {
15803 return patch_operations::test;
15806 return patch_operations::invalid;
15810 const auto operation_add = [&
result](json_pointer&
ptr, basic_json
val) {
15812 if (
ptr.is_root()) {
15816 json_pointer top_pointer =
ptr.top();
15817 if (top_pointer !=
ptr) {
15822 const auto last_path =
ptr.pop_back();
15825 switch (parent.m_type) {
15826 case value_t::null:
15827 case value_t::object: {
15829 parent[last_path] =
val;
15833 case value_t::array: {
15834 if (last_path ==
"-") {
15836 parent.push_back(
val);
15838 const auto idx = json_pointer::array_index(last_path);
15839 if (
JSON_UNLIKELY(
static_cast<size_type
>(idx) > parent.size())) {
15844 parent.insert(parent.begin() +
static_cast<difference_type
>(idx),
val);
15859 const auto operation_remove = [&
result](json_pointer&
ptr) {
15861 const auto last_path =
ptr.pop_back();
15865 if (parent.is_object()) {
15867 auto it = parent.find(last_path);
15871 JSON_THROW(out_of_range::create(403,
"key '" + last_path +
"' not found"));
15873 }
else if (parent.is_array()) {
15875 parent.erase(
static_cast<size_type
>(json_pointer::array_index(last_path)));
15881 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
15885 for (
const auto&
val : json_patch) {
15887 const auto get_value = [&
val](
const std::string&
op,
15888 const std::string& member,
15889 bool string_type) -> basic_json& {
15891 auto it =
val.m_value.object->find(member);
15894 const auto error_msg = (
op ==
"op") ?
"operation" :
"operation '" +
op +
"'";
15898 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have member '" + member +
"'"));
15902 if (
JSON_UNLIKELY(string_type and not it->second.is_string())) {
15903 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have string member '" + member +
"'"));
15912 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
15916 const std::string
op = get_value(
"op",
"op",
true);
15917 const std::string
path = get_value(
op,
"path",
true);
15920 switch (get_op(
op)) {
15921 case patch_operations::add: {
15922 operation_add(
ptr, get_value(
"add",
"value",
false));
15926 case patch_operations::remove: {
15927 operation_remove(
ptr);
15931 case patch_operations::replace: {
15933 result.at(
ptr) = get_value(
"replace",
"value",
false);
15937 case patch_operations::move: {
15938 const std::string from_path = get_value(
"move",
"from",
true);
15939 json_pointer from_ptr(from_path);
15942 basic_json
v =
result.at(from_ptr);
15948 operation_remove(from_ptr);
15949 operation_add(
ptr,
v);
15953 case patch_operations::copy: {
15954 const std::string from_path = get_value(
"copy",
"from",
true);
15955 const json_pointer from_ptr(from_path);
15958 basic_json
v =
result.at(from_ptr);
15963 operation_add(
ptr,
v);
15967 case patch_operations::test: {
15968 bool success =
false;
15973 success = (
result.at(
ptr) == get_value(
"test",
"value",
false));
15982 JSON_THROW(other_error::create(501,
"unsuccessful: " +
val.dump()));
15988 case patch_operations::invalid: {
15991 JSON_THROW(parse_error::create(105, 0,
"operation value '" +
op +
"' is invalid"));
16032 static basic_json diff(
const basic_json&
source,
const basic_json&
target,
16033 const std::string&
path =
"")
16036 basic_json
result(value_t::array);
16046 {{
"op",
"replace"}, {
"path",
path}, {
"value",
target}});
16048 switch (
source.type()) {
16049 case value_t::array: {
16055 result.insert(
result.end(), temp_diff.begin(), temp_diff.end());
16063 const auto end_index =
static_cast<difference_type
>(
result.size());
16085 case value_t::object: {
16087 for (
auto it =
source.cbegin(); it !=
source.cend(); ++it) {
16089 const auto key = json_pointer::escape(it.key());
16093 auto temp_diff = diff(it.value(),
target[it.key()],
path +
"/" +
key);
16094 result.insert(
result.end(), temp_diff.begin(), temp_diff.end());
16097 result.push_back(
object(
16098 {{
"op",
"remove"}, {
"path",
path +
"/" +
key}}));
16103 for (
auto it =
target.cbegin(); it !=
target.cend(); ++it) {
16106 const auto key = json_pointer::escape(it.key());
16108 {{
"op",
"add"}, {
"path",
path +
"/" +
key}, {
"value", it.value()}});
16118 {{
"op",
"replace"}, {
"path",
path}, {
"value",
target}});
16178 void merge_patch(
const basic_json& patch)
16180 if (patch.is_object()) {
16181 if (not is_object()) {
16184 for (
auto it = patch.begin(); it != patch.end(); ++it) {
16185 if (it.value().is_null()) {
16188 operator[](it.key()).merge_patch(it.value());
16214 nlohmann::json& j2)
noexcept(is_nothrow_move_constructible<nlohmann::json>::value and
16215 is_nothrow_move_assignable<nlohmann::json>::value)
16231 const auto&
h = hash<nlohmann::json::string_t>();
16232 return h(
j.dump());
16240struct less<::nlohmann::detail::value_t> {
16245 bool operator()(nlohmann::detail::value_t lhs,
16246 nlohmann::detail::value_t rhs)
const noexcept
16248 return nlohmann::detail::operator<(lhs, rhs);
16269 return nlohmann::json::parse(s, s +
n);
16285inline nlohmann::json::json_pointer
operator"" _json_pointer(
const char* s, std::size_t
n)
16287 return nlohmann::json::json_pointer(std::string(s,
n));
16293#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
16294#pragma GCC diagnostic pop
16296#if defined(__clang__)
16297#pragma GCC diagnostic pop
16305#undef JSON_UNLIKELY
16306#undef JSON_DEPRECATED
16307#undef JSON_HAS_CPP_14
16308#undef JSON_HAS_CPP_17
16309#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
16310#undef NLOHMANN_BASIC_JSON_TPL
16311#undef NLOHMANN_JSON_HAS_HELPER
std::ostream & operator<<(std::ostream &os, const o2::math_utils::Rotation2Df_t &t)
uint64_t exp(uint64_t base, uint8_t exp) noexcept
const GPUTPCGMMerger::trackCluster & a1
constexpr int p1()
constexpr to accelerate the coordinates changing
std::istream & operator>>(std::istream &input, DataType &data)
Class for time synchronization of RawReader instances.
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_)
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)
a template for a bidirectional iterator for the basic_json class
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–)
bool operator==(const iter_impl &other) const
comparison: equal
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
object_t::key_type key() const
return the key of an object iterator
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
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
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
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
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
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
iter_impl & operator-=(difference_type i)
subtract from iterator
proxy class for the items() function
iteration_proxy_internal end() noexcept
return iterator end (needed for range-based for)
iteration_proxy_internal begin() noexcept
return iterator begin (needed for range-based for)
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
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)
exception indicating other library errors
static other_error create(int id_, const std::string &what_arg)
exception indicating access out of the defined range
static out_of_range create(int id_, const std::string &what_arg)
output_adapter(std::vector< CharType > &vec)
output_adapter(std::basic_ostream< CharType > &s)
output_adapter(StringType &s)
output adapter for output streams
output_stream_adapter(std::basic_ostream< CharType > &s)
void write_character(CharType c) override
void write_characters(const CharType *s, std::size_t length) override
output adapter for basic_string
output_string_adapter(StringType &s)
void write_character(CharType c) override
void write_characters(const CharType *s, std::size_t length) override
output adapter for byte vectors
output_vector_adapter(std::vector< CharType > &vec)
void write_characters(const CharType *s, std::size_t length) override
void write_character(CharType c) override
exception indicating a parse error
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)
create a parse error exception
void parse(const bool strict, BasicJsonType &result)
public parser interface
bool accept(const bool strict=true)
public accept interface
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
parser(detail::input_adapter_t adapter, const parser_callback_t cb=nullptr, const bool allow_exceptions_=true)
a parser reading from an input adapter
std::function< bool(int depth, parse_event_t event, BasicJsonType &parsed)> parser_callback_t
primitive_iterator_t operator+(difference_type n) noexcept
primitive_iterator_t & operator++() noexcept
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
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
primitive_iterator_t & operator+=(difference_type n) noexcept
exception indicating executing a member function with a wrong type
static type_error create(int id_, const std::string &what_arg)
void dump(const std::string what, DPMAP m, int verbose)
GLsizei const GLchar *const * string
GLdouble GLdouble GLdouble GLdouble top
GLboolean GLboolean GLboolean b
GLsizei GLsizei GLchar * source
GLsizei const GLfloat * value
GLint GLint GLsizei GLint GLenum GLenum type
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
GLuint GLsizei GLsizei * length
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLint GLint GLsizei GLsizei GLsizei depth
GLsizei const GLchar *const * path
GLenum GLenum GLsizei len
GLboolean GLboolean GLboolean GLboolean a
GLenum GLuint GLenum GLsizei const GLchar * buf
GLubyte GLubyte GLubyte GLubyte w
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
#define NLOHMANN_JSON_VERSION_PATCH
#define JSON_CATCH(exception)
#define JSON_THROW(exception)
#define NLOHMANN_JSON_VERSION_MAJOR
#define NLOHMANN_BASIC_JSON_TPL
#define NLOHMANN_JSON_VERSION_MINOR
#define NLOHMANN_JSON_HAS_HELPER(type)
Helper to determine whether there's a key_type for T.
auto operator+=(std::string &lhs, StringRef rhs) -> std::string &
typename std::enable_if< B, T >::type enable_if_t
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
namespace for Niels Lohmann
uint8_t itsSharedClusterMap uint8_t
bool operator<(EntryPM const &entryPM1, EntryPM const &entryPM2)
ConcreteParserVariants< PageSize, BOUNDS_CHECKS > create(T const *buffer, size_t size)
create a raw parser depending on version of RAWDataHeader found at beginning of data
D const SVectorGPU< T, D > & rhs
MultPolicyGPU< T, R1, R2 >::RepType operator*(const SMatrixGPU< T, D1, D, R1 > &lhs, const SMatrixGPU< T, D, D2, R2 > &rhs)
Enum< T >::Iterator begin(Enum< T >)
return(kp2 - aa - bb) *kp1/aa
bool operator!=(const observer_ptr< W1 > &p1, const observer_ptr< W2 > &p2)
bool operator<=(const observer_ptr< W1 > &p1, const observer_ptr< W2 > &p2)
bool operator>=(const observer_ptr< W1 > &p1, const observer_ptr< W2 > &p2)
bool operator>(const observer_ptr< W1 > &p1, const observer_ptr< W2 > &p2)
Defining DataPointCompositeObject explicitly as copiable.
std::string to_string(gsl::span< T, Size > span)
FIXME: do not use data model tables.
std::vector< std::string > split(const std::string &str, char delimiter=',')
default JSONSerializer template argument
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
static auto constexpr value
std::numeric_limits< RealIntegerType > RealLimits
std::numeric_limits< CompatibleNumberIntegerType > CompatibleLimits
static constexpr auto value
static auto constexpr value
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
VectorOfTObjectPtrs other
std::vector< o2::ctf::BufferType > vec
coder decode(ctfImage, triggersD, clustersD)