30 #ifndef NLOHMANN_JSON_HPP 31 #define NLOHMANN_JSON_HPP 33 #define NLOHMANN_JSON_VERSION_MAJOR 3 34 #define NLOHMANN_JSON_VERSION_MINOR 5 35 #define NLOHMANN_JSON_VERSION_PATCH 0 42 #include <initializer_list> 50 #ifndef NLOHMANN_JSON_FWD_HPP 51 #define NLOHMANN_JSON_FWD_HPP 73 template<
typename T =
void,
typename SFINAE =
void>
76 template<
template<
typename U,
typename V,
typename... Args>
class ObjectType =
78 template<
typename U,
typename... Args>
class ArrayType = std::vector,
79 class StringType = std::string,
class BooleanType = bool,
80 class NumberIntegerType = std::int64_t,
81 class NumberUnsignedType = std::uint64_t,
82 class NumberFloatType = double,
83 template<
typename U>
class AllocatorType = std::allocator,
84 template<
typename T,
typename SFINAE =
void>
class JSONSerializer =
99 template<
typename BasicJsonType>
122 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) 123 #if defined(__clang__) 124 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 125 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" 127 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) 128 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 129 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" 135 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 136 #pragma GCC diagnostic push 137 #pragma GCC diagnostic ignored "-Wfloat-equal" 141 #if defined(__clang__) 142 #pragma GCC diagnostic push 143 #pragma GCC diagnostic ignored "-Wdocumentation" 147 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 148 #define JSON_DEPRECATED __attribute__((deprecated)) 149 #elif defined(_MSC_VER) 150 #define JSON_DEPRECATED __declspec(deprecated) 152 #define JSON_DEPRECATED 156 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) 157 #define JSON_THROW(exception) throw exception 159 #define JSON_CATCH(exception) catch(exception) 160 #define JSON_INTERNAL_CATCH(exception) catch(exception) 162 #define JSON_THROW(exception) std::abort() 163 #define JSON_TRY if(true) 164 #define JSON_CATCH(exception) if(false) 165 #define JSON_INTERNAL_CATCH(exception) if(false) 169 #if defined(JSON_THROW_USER) 171 #define JSON_THROW JSON_THROW_USER 173 #if defined(JSON_TRY_USER) 175 #define JSON_TRY JSON_TRY_USER 177 #if defined(JSON_CATCH_USER) 179 #define JSON_CATCH JSON_CATCH_USER 180 #undef JSON_INTERNAL_CATCH 181 #define JSON_INTERNAL_CATCH JSON_CATCH_USER 183 #if defined(JSON_INTERNAL_CATCH_USER) 184 #undef JSON_INTERNAL_CATCH 185 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER 189 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 190 #define JSON_LIKELY(x) __builtin_expect(!!(x), 1) 191 #define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0) 193 #define JSON_LIKELY(x) x 194 #define JSON_UNLIKELY(x) x 198 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 199 #define JSON_HAS_CPP_17 200 #define JSON_HAS_CPP_14 201 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) 202 #define JSON_HAS_CPP_14 210 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ 211 template<typename BasicJsonType> \ 212 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ 214 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \ 215 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \ 216 auto it = std::find_if(std::begin(m), std::end(m), \ 217 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \ 219 return ej_pair.first == e; \ 221 j = ((it != std::end(m)) ? it : std::begin(m))->second; \ 223 template<typename BasicJsonType> \ 224 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ 226 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \ 227 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \ 228 auto it = std::find_if(std::begin(m), std::end(m), \ 229 [j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \ 231 return ej_pair.second == j; \ 233 e = ((it != std::end(m)) ? it : std::begin(m))->first; \ 239 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ 240 template<template<typename, typename, typename...> class ObjectType, \ 241 template<typename, typename...> class ArrayType, \ 242 class StringType, class BooleanType, class NumberIntegerType, \ 243 class NumberUnsignedType, class NumberFloatType, \ 244 template<typename> class AllocatorType, \ 245 template<typename, typename = void> class JSONSerializer> 247 #define NLOHMANN_BASIC_JSON_TPL \ 248 basic_json<ObjectType, ArrayType, StringType, BooleanType, \ 249 NumberIntegerType, NumberUnsignedType, NumberFloatType, \ 250 AllocatorType, JSONSerializer> 257 #include <type_traits> 264 template<
bool B,
typename T =
void>
265 using enable_if_t =
typename std::enable_if<B, T>::type;
268 using uncvref_t =
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
272 template<std::size_t... Ints>
273 struct index_sequence
275 using type = index_sequence;
276 using value_type = std::size_t;
277 static constexpr std::size_t size() noexcept
279 return sizeof...(Ints);
283 template<
class Sequence1,
class Sequence2>
284 struct merge_and_renumber;
286 template<std::size_t... I1, std::size_t... I2>
287 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
288 : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
290 template<std::
size_t N>
291 struct make_index_sequence
292 : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
293 typename make_index_sequence < N - N / 2 >::type > {};
295 template<>
struct make_index_sequence<0> : index_sequence<> {};
296 template<>
struct make_index_sequence<1> : index_sequence<0> {};
298 template<
typename... Ts>
299 using index_sequence_for = make_index_sequence<
sizeof...(Ts)>;
302 template<
unsigned N>
struct priority_tag : priority_tag < N - 1 > {};
303 template<>
struct priority_tag<0> {};
309 static constexpr T value{};
313 constexpr T static_const<T>::value;
322 #include <type_traits> 339 template <
typename ...Ts>
struct make_void
343 template <
typename ...Ts>
using void_t =
typename make_void<Ts...>::type;
354 template <
typename It,
typename =
void>
355 struct iterator_types {};
357 template <
typename It>
358 struct iterator_types <
360 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
361 typename It::reference, typename It::iterator_category >>
363 using difference_type =
typename It::difference_type;
364 using value_type =
typename It::value_type;
365 using pointer =
typename It::pointer;
366 using reference =
typename It::reference;
367 using iterator_category =
typename It::iterator_category;
372 template <
typename T,
typename =
void>
373 struct iterator_traits
377 template <
typename T>
378 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
383 template <
typename T>
384 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
386 using iterator_category = std::random_access_iterator_tag;
387 using value_type = T;
388 using difference_type = ptrdiff_t;
390 using reference = T&;
400 #include <type_traits> 413 ~nonesuch() =
delete;
414 nonesuch(nonesuch
const&) =
delete;
415 void operator=(nonesuch
const&) =
delete;
418 template <
class Default,
420 template <
class...>
class Op,
424 using value_t = std::false_type;
425 using type = Default;
428 template <
class Default,
template <
class...>
class Op,
class... Args>
429 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
431 using value_t = std::true_type;
432 using type = Op<Args...>;
435 template <
template <
class...>
class Op,
class... Args>
436 using is_detected =
typename detector<nonesuch, void, Op, Args...>::value_t;
438 template <
template <
class...>
class Op,
class... Args>
439 using detected_t =
typename detector<nonesuch, void, Op, Args...>::type;
441 template <
class Default,
template <
class...>
class Op,
class... Args>
442 using detected_or = detector<Default, void, Op, Args...>;
444 template <
class Default,
template <
class...>
class Op,
class... Args>
445 using detected_or_t =
typename detected_or<Default, Op, Args...>::type;
447 template <
class Expected,
template <
class...>
class Op,
class... Args>
448 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
450 template <
class To,
template <
class...>
class Op,
class... Args>
451 using is_detected_convertible =
452 std::is_convertible<detected_t<Op, Args...>, To>;
484 template<
typename>
struct is_basic_json : std::false_type {};
486 NLOHMANN_BASIC_JSON_TPL_DECLARATION
487 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
493 template <
typename T>
494 using mapped_type_t =
typename T::mapped_type;
496 template <
typename T>
497 using key_type_t =
typename T::key_type;
499 template <
typename T>
500 using value_type_t =
typename T::value_type;
502 template <
typename T>
503 using difference_type_t =
typename T::difference_type;
505 template <
typename T>
506 using pointer_t =
typename T::pointer;
508 template <
typename T>
509 using reference_t =
typename T::reference;
511 template <
typename T>
512 using iterator_category_t =
typename T::iterator_category;
514 template <
typename T>
515 using iterator_t =
typename T::iterator;
517 template <
typename T,
typename... Args>
518 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
520 template <
typename T,
typename... Args>
521 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
523 template <
typename T,
typename U>
524 using get_template_function = decltype(std::declval<T>().
template get<U>());
527 template <
typename BasicJsonType,
typename T,
typename =
void>
528 struct has_from_json : std::false_type {};
530 template <
typename BasicJsonType,
typename T>
531 struct has_from_json<BasicJsonType, T,
532 enable_if_t<not is_basic_json<T>::value>>
534 using serializer =
typename BasicJsonType::template json_serializer<T, void>;
536 static constexpr
bool value =
537 is_detected_exact<void, from_json_function, serializer,
538 const BasicJsonType&, T&>::value;
543 template <
typename BasicJsonType,
typename T,
typename =
void>
544 struct has_non_default_from_json : std::false_type {};
546 template<
typename BasicJsonType,
typename T>
547 struct has_non_default_from_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
549 using serializer =
typename BasicJsonType::template json_serializer<T, void>;
551 static constexpr
bool value =
552 is_detected_exact<T, from_json_function, serializer,
553 const BasicJsonType&>::value;
558 template <
typename BasicJsonType,
typename T,
typename =
void>
559 struct has_to_json : std::false_type {};
561 template <
typename BasicJsonType,
typename T>
562 struct has_to_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
564 using serializer =
typename BasicJsonType::template json_serializer<T, void>;
566 static constexpr
bool value =
567 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
576 template <
typename T,
typename =
void>
577 struct is_iterator_traits : std::false_type {};
579 template <
typename T>
580 struct is_iterator_traits<iterator_traits<T>>
583 using traits = iterator_traits<T>;
586 static constexpr
auto value =
587 is_detected<value_type_t, traits>::value &&
588 is_detected<difference_type_t, traits>::value &&
589 is_detected<pointer_t, traits>::value &&
590 is_detected<iterator_category_t, traits>::value &&
591 is_detected<reference_t, traits>::value;
596 template <
typename T,
typename =
void>
597 struct is_complete_type : std::false_type {};
599 template <
typename T>
600 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
602 template <
typename BasicJsonType,
typename CompatibleObjectType,
604 struct is_compatible_object_type_impl : std::false_type {};
606 template <
typename BasicJsonType,
typename CompatibleObjectType>
607 struct is_compatible_object_type_impl <
608 BasicJsonType, CompatibleObjectType,
609 enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value and
610 is_detected<key_type_t, CompatibleObjectType>::value >>
613 using object_t =
typename BasicJsonType::object_t;
616 static constexpr
bool value =
617 std::is_constructible<
typename object_t::key_type,
618 typename CompatibleObjectType::key_type>::value and
619 std::is_constructible<
typename object_t::mapped_type,
620 typename CompatibleObjectType::mapped_type>::value;
623 template <
typename BasicJsonType,
typename CompatibleObjectType>
624 struct is_compatible_object_type
625 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
627 template <
typename BasicJsonType,
typename ConstructibleObjectType,
629 struct is_constructible_object_type_impl : std::false_type {};
631 template <
typename BasicJsonType,
typename ConstructibleObjectType>
632 struct is_constructible_object_type_impl <
633 BasicJsonType, ConstructibleObjectType,
634 enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value and
635 is_detected<key_type_t, ConstructibleObjectType>::value >>
637 using object_t =
typename BasicJsonType::object_t;
639 static constexpr
bool value =
640 (std::is_constructible<typename ConstructibleObjectType::key_type, typename object_t::key_type>::value and
641 std::is_same<typename object_t::mapped_type, typename ConstructibleObjectType::mapped_type>::value) or
642 (has_from_json<BasicJsonType, typename ConstructibleObjectType::mapped_type>::value or
643 has_non_default_from_json<BasicJsonType, typename ConstructibleObjectType::mapped_type >::value);
646 template <
typename BasicJsonType,
typename ConstructibleObjectType>
647 struct is_constructible_object_type
648 : is_constructible_object_type_impl<BasicJsonType,
649 ConstructibleObjectType> {};
651 template <
typename BasicJsonType,
typename CompatibleStringType,
653 struct is_compatible_string_type_impl : std::false_type {};
655 template <
typename BasicJsonType,
typename CompatibleStringType>
656 struct is_compatible_string_type_impl <
657 BasicJsonType, CompatibleStringType,
658 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
659 value_type_t, CompatibleStringType>::value >>
661 static constexpr
auto value =
662 std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
665 template <
typename BasicJsonType,
typename ConstructibleStringType>
666 struct is_compatible_string_type
667 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
669 template <
typename BasicJsonType,
typename ConstructibleStringType,
671 struct is_constructible_string_type_impl : std::false_type {};
673 template <
typename BasicJsonType,
typename ConstructibleStringType>
674 struct is_constructible_string_type_impl <
675 BasicJsonType, ConstructibleStringType,
676 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
677 value_type_t, ConstructibleStringType>::value >>
679 static constexpr
auto value =
680 std::is_constructible<ConstructibleStringType,
681 typename BasicJsonType::string_t>::value;
684 template <
typename BasicJsonType,
typename ConstructibleStringType>
685 struct is_constructible_string_type
686 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
688 template <
typename BasicJsonType,
typename CompatibleArrayType,
typename =
void>
689 struct is_compatible_array_type_impl : std::false_type {};
691 template <
typename BasicJsonType,
typename CompatibleArrayType>
692 struct is_compatible_array_type_impl <
693 BasicJsonType, CompatibleArrayType,
694 enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
695 is_detected<iterator_t, CompatibleArrayType>::value and
699 not is_iterator_traits<
700 iterator_traits<CompatibleArrayType>>::value >>
702 static constexpr
bool value =
703 std::is_constructible<BasicJsonType,
704 typename CompatibleArrayType::value_type>::value;
707 template <
typename BasicJsonType,
typename CompatibleArrayType>
708 struct is_compatible_array_type
709 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
711 template <
typename BasicJsonType,
typename ConstructibleArrayType,
typename =
void>
712 struct is_constructible_array_type_impl : std::false_type {};
714 template <
typename BasicJsonType,
typename ConstructibleArrayType>
715 struct is_constructible_array_type_impl <
716 BasicJsonType, ConstructibleArrayType,
717 enable_if_t<std::is_same<ConstructibleArrayType,
718 typename BasicJsonType::value_type>::value >>
721 template <
typename BasicJsonType,
typename ConstructibleArrayType>
722 struct is_constructible_array_type_impl <
723 BasicJsonType, ConstructibleArrayType,
724 enable_if_t<not std::is_same<ConstructibleArrayType,
725 typename BasicJsonType::value_type>::value and
726 is_detected<value_type_t, ConstructibleArrayType>::value and
727 is_detected<iterator_t, ConstructibleArrayType>::value and
729 detected_t<value_type_t, ConstructibleArrayType>>::value >>
731 static constexpr
bool value =
736 not is_iterator_traits <
737 iterator_traits<ConstructibleArrayType >>::value and
739 (std::is_same<typename ConstructibleArrayType::value_type, typename BasicJsonType::array_t::value_type>::value or
740 has_from_json<BasicJsonType,
741 typename ConstructibleArrayType::value_type>::value or
742 has_non_default_from_json <
743 BasicJsonType,
typename ConstructibleArrayType::value_type >::value);
746 template <
typename BasicJsonType,
typename ConstructibleArrayType>
747 struct is_constructible_array_type
748 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
750 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType,
752 struct is_compatible_integer_type_impl : std::false_type {};
754 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType>
755 struct is_compatible_integer_type_impl <
756 RealIntegerType, CompatibleNumberIntegerType,
757 enable_if_t<std::is_integral<RealIntegerType>::value and
758 std::is_integral<CompatibleNumberIntegerType>::value and
759 not std::is_same<bool, CompatibleNumberIntegerType>::value >>
762 using RealLimits = std::numeric_limits<RealIntegerType>;
763 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
765 static constexpr
auto value =
766 std::is_constructible<RealIntegerType,
767 CompatibleNumberIntegerType>::value and
768 CompatibleLimits::is_integer and
769 RealLimits::is_signed == CompatibleLimits::is_signed;
772 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType>
773 struct is_compatible_integer_type
774 : is_compatible_integer_type_impl<RealIntegerType,
775 CompatibleNumberIntegerType> {};
777 template <
typename BasicJsonType,
typename CompatibleType,
typename =
void>
778 struct is_compatible_type_impl: std::false_type {};
780 template <
typename BasicJsonType,
typename CompatibleType>
781 struct is_compatible_type_impl <
782 BasicJsonType, CompatibleType,
783 enable_if_t<is_complete_type<CompatibleType>::value >>
785 static constexpr
bool value =
786 has_to_json<BasicJsonType, CompatibleType>::value;
789 template <
typename BasicJsonType,
typename CompatibleType>
790 struct is_compatible_type
791 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
815 std::size_t chars_read_total = 0;
817 std::size_t chars_read_current_line = 0;
819 std::size_t lines_read = 0;
822 constexpr
operator size_t()
const 824 return chars_read_total;
868 class exception :
public std::exception
872 const char* what()
const noexcept
override 881 exception(
int id_,
const char* what_arg) : id(id_), m(what_arg) {}
883 static std::string name(
const std::string& ename,
int id_)
885 return "[json.exception." + ename +
"." + std::to_string(id_) +
"] ";
890 std::runtime_error m;
937 class parse_error :
public exception
949 static parse_error create(
int id_,
const position_t& pos,
const std::string& what_arg)
951 std::string w = exception::name(
"parse_error", id_) +
"parse error" +
952 position_string(pos) +
": " + what_arg;
953 return parse_error(id_, pos.chars_read_total, w.c_str());
956 static parse_error create(
int id_, std::size_t byte_,
const std::string& what_arg)
958 std::string w = exception::name(
"parse_error", id_) +
"parse error" +
959 (byte_ != 0 ? (
" at byte " + std::to_string(byte_)) :
"") +
961 return parse_error(id_, byte_, w.c_str());
973 const std::size_t byte;
976 parse_error(
int id_, std::size_t byte_,
const char* what_arg)
977 : exception(id_, what_arg), byte(byte_) {}
979 static std::string position_string(
const position_t& pos)
981 return " at line " + std::to_string(pos.lines_read + 1) +
982 ", column " + std::to_string(pos.chars_read_current_line);
1023 class invalid_iterator :
public exception
1026 static invalid_iterator create(
int id_,
const std::string& what_arg)
1028 std::string w = exception::name(
"invalid_iterator", id_) + what_arg;
1029 return invalid_iterator(id_, w.c_str());
1033 invalid_iterator(
int id_,
const char* what_arg)
1034 : exception(id_, what_arg) {}
1076 class type_error :
public exception
1079 static type_error create(
int id_,
const std::string& what_arg)
1081 std::string w = exception::name(
"type_error", id_) + what_arg;
1082 return type_error(id_, w.c_str());
1086 type_error(
int id_,
const char* what_arg) : exception(id_, what_arg) {}
1122 class out_of_range :
public exception
1125 static out_of_range create(
int id_,
const std::string& what_arg)
1127 std::string w = exception::name(
"out_of_range", id_) + what_arg;
1128 return out_of_range(id_, w.c_str());
1132 out_of_range(
int id_,
const char* what_arg) : exception(id_, what_arg) {}
1159 class other_error :
public exception
1162 static other_error create(
int id_,
const std::string& what_arg)
1164 std::string w = exception::name(
"other_error", id_) + what_arg;
1165 return other_error(id_, w.c_str());
1169 other_error(
int id_,
const char* what_arg) : exception(id_, what_arg) {}
1214 enum class value_t : std::uint8_t
1237 inline bool operator<(
const value_t lhs,
const value_t rhs) noexcept
1239 static constexpr std::array<std::uint8_t, 8> order = {{
1245 const auto l_index =
static_cast<std::size_t
>(lhs);
1246 const auto r_index =
static_cast<std::size_t
>(rhs);
1247 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
1255 #include <algorithm> 1258 #include <forward_list> 1263 #include <type_traits> 1264 #include <unordered_map> 1283 template<
typename BasicJsonType>
1284 void from_json(
const BasicJsonType& j,
typename std::nullptr_t& n)
1286 if (JSON_UNLIKELY(not j.is_null()))
1288 JSON_THROW(type_error::create(302,
"type must be null, but is " + std::string(j.type_name())));
1294 template<
typename BasicJsonType,
typename ArithmeticType,
1295 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
1296 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1298 void get_arithmetic_value(
const BasicJsonType& j, ArithmeticType& val)
1300 switch (static_cast<value_t>(j))
1302 case value_t::number_unsigned:
1304 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1307 case value_t::number_integer:
1309 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1312 case value_t::number_float:
1314 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1319 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
1323 template<
typename BasicJsonType>
1324 void from_json(
const BasicJsonType& j,
typename BasicJsonType::boolean_t& b)
1326 if (JSON_UNLIKELY(not j.is_boolean()))
1328 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(j.type_name())));
1330 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
1333 template<
typename BasicJsonType>
1334 void from_json(
const BasicJsonType& j,
typename BasicJsonType::string_t& s)
1336 if (JSON_UNLIKELY(not j.is_string()))
1338 JSON_THROW(type_error::create(302,
"type must be string, but is " + std::string(j.type_name())));
1340 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1344 typename BasicJsonType,
typename ConstructibleStringType,
1346 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value and
1347 not std::is_same<
typename BasicJsonType::string_t,
1348 ConstructibleStringType>::value,
1350 void from_json(
const BasicJsonType& j, ConstructibleStringType& s)
1352 if (JSON_UNLIKELY(not j.is_string()))
1354 JSON_THROW(type_error::create(302,
"type must be string, but is " + std::string(j.type_name())));
1357 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1360 template<
typename BasicJsonType>
1361 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_float_t& val)
1363 get_arithmetic_value(j, val);
1366 template<
typename BasicJsonType>
1367 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_unsigned_t& val)
1369 get_arithmetic_value(j, val);
1372 template<
typename BasicJsonType>
1373 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_integer_t& val)
1375 get_arithmetic_value(j, val);
1378 template<
typename BasicJsonType,
typename EnumType,
1379 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
1380 void from_json(
const BasicJsonType& j, EnumType& e)
1382 typename std::underlying_type<EnumType>::type val;
1383 get_arithmetic_value(j, val);
1384 e =
static_cast<EnumType
>(val);
1388 template<
typename BasicJsonType,
typename T,
typename Allocator,
1389 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1390 void from_json(
const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1392 if (JSON_UNLIKELY(not j.is_array()))
1394 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1396 std::transform(j.rbegin(), j.rend(),
1397 std::front_inserter(l), [](
const BasicJsonType & i)
1399 return i.template get<T>();
1404 template<
typename BasicJsonType,
typename T,
1405 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
1406 void from_json(
const BasicJsonType& j, std::valarray<T>& l)
1408 if (JSON_UNLIKELY(not j.is_array()))
1410 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1413 std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1416 template<
typename BasicJsonType>
1417 void from_json_array_impl(
const BasicJsonType& j,
typename BasicJsonType::array_t& arr, priority_tag<3> )
1419 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
1422 template <
typename BasicJsonType,
typename T, std::
size_t N>
1423 auto from_json_array_impl(
const BasicJsonType& j, std::array<T, N>& arr,
1425 -> decltype(j.template get<T>(),
void())
1427 for (std::size_t i = 0; i < N; ++i)
1429 arr[i] = j.at(i).template get<T>();
1433 template<
typename BasicJsonType,
typename ConstructibleArrayType>
1434 auto from_json_array_impl(
const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> )
1436 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
1437 j.template get<typename ConstructibleArrayType::value_type>(),
1442 arr.reserve(j.size());
1443 std::transform(j.begin(), j.end(),
1444 std::inserter(arr, end(arr)), [](
const BasicJsonType & i)
1448 return i.template get<typename ConstructibleArrayType::value_type>();
1452 template <
typename BasicJsonType,
typename ConstructibleArrayType>
1453 void from_json_array_impl(
const BasicJsonType& j, ConstructibleArrayType& arr,
1459 j.begin(), j.end(), std::inserter(arr, end(arr)),
1460 [](
const BasicJsonType & i)
1464 return i.template get<typename ConstructibleArrayType::value_type>();
1468 template <
typename BasicJsonType,
typename ConstructibleArrayType,
1470 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
1471 not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
1472 not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
1473 not is_basic_json<ConstructibleArrayType>::value,
1476 auto from_json(
const BasicJsonType& j, ConstructibleArrayType& arr)
1477 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
1478 j.template get<typename ConstructibleArrayType::value_type>(),
1481 if (JSON_UNLIKELY(not j.is_array()))
1483 JSON_THROW(type_error::create(302,
"type must be array, but is " +
1484 std::string(j.type_name())));
1487 from_json_array_impl(j, arr, priority_tag<3> {});
1490 template<
typename BasicJsonType,
typename ConstructibleObjectType,
1491 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value,
int> = 0>
1492 void from_json(
const BasicJsonType& j, ConstructibleObjectType& obj)
1494 if (JSON_UNLIKELY(not j.is_object()))
1496 JSON_THROW(type_error::create(302,
"type must be object, but is " + std::string(j.type_name())));
1499 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1500 using value_type =
typename ConstructibleObjectType::value_type;
1502 inner_object->begin(), inner_object->end(),
1503 std::inserter(obj, obj.begin()),
1504 [](
typename BasicJsonType::object_t::value_type
const & p)
1506 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
1514 template<
typename BasicJsonType,
typename ArithmeticType,
1516 std::is_arithmetic<ArithmeticType>::value and
1517 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1518 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1519 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1520 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1522 void from_json(
const BasicJsonType& j, ArithmeticType& val)
1524 switch (static_cast<value_t>(j))
1526 case value_t::number_unsigned:
1528 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1531 case value_t::number_integer:
1533 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1536 case value_t::number_float:
1538 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1541 case value_t::boolean:
1543 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1548 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
1552 template<
typename BasicJsonType,
typename A1,
typename A2>
1553 void from_json(
const BasicJsonType& j, std::pair<A1, A2>& p)
1555 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
1558 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
1559 void from_json_tuple_impl(
const BasicJsonType& j, Tuple& t, index_sequence<Idx...> )
1561 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
1564 template<
typename BasicJsonType,
typename... Args>
1565 void from_json(
const BasicJsonType& j, std::tuple<Args...>& t)
1567 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1570 template <
typename BasicJsonType,
typename Key,
typename Value,
typename Compare,
typename Allocator,
1571 typename = enable_if_t<not std::is_constructible<
1572 typename BasicJsonType::string_t, Key>::value>>
1573 void from_json(
const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
1575 if (JSON_UNLIKELY(not j.is_array()))
1577 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1579 for (
const auto& p : j)
1581 if (JSON_UNLIKELY(not p.is_array()))
1583 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(p.type_name())));
1585 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1589 template <
typename BasicJsonType,
typename Key,
typename Value,
typename Hash,
typename KeyEqual,
typename Allocator,
1590 typename = enable_if_t<not std::is_constructible<
1591 typename BasicJsonType::string_t, Key>::value>>
1592 void from_json(
const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
1594 if (JSON_UNLIKELY(not j.is_array()))
1596 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
1598 for (
const auto& p : j)
1600 if (JSON_UNLIKELY(not p.is_array()))
1602 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(p.type_name())));
1604 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1610 template<
typename BasicJsonType,
typename T>
1611 auto operator()(
const BasicJsonType& j, T& val)
const 1612 noexcept(noexcept(from_json(j, val)))
1613 -> decltype(from_json(j, val),
void())
1615 return from_json(j, val);
1625 constexpr
const auto&
from_json = detail::static_const<detail::from_json_fn>::value;
1635 #include <type_traits> 1663 template <
typename IteratorType>
class iteration_proxy_value
1666 using difference_type = std::ptrdiff_t;
1667 using value_type = iteration_proxy_value;
1668 using pointer = value_type * ;
1669 using reference = value_type & ;
1670 using iterator_category = std::input_iterator_tag;
1674 IteratorType anchor;
1676 std::size_t array_index = 0;
1678 mutable std::size_t array_index_last = 0;
1680 mutable std::string array_index_str =
"0";
1682 const std::string empty_str =
"";
1685 explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
1688 iteration_proxy_value& operator*()
1694 iteration_proxy_value& operator++()
1703 bool operator==(
const iteration_proxy_value& o)
const noexcept
1705 return anchor == o.anchor;
1709 bool operator!=(
const iteration_proxy_value& o)
const noexcept
1711 return anchor != o.anchor;
1715 const std::string& key()
const 1717 assert(anchor.m_object !=
nullptr);
1719 switch (anchor.m_object->type())
1722 case value_t::array:
1724 if (array_index != array_index_last)
1726 array_index_str = std::to_string(array_index);
1727 array_index_last = array_index;
1729 return array_index_str;
1733 case value_t::object:
1734 return anchor.key();
1743 typename IteratorType::reference value()
const 1745 return anchor.value();
1750 template<
typename IteratorType>
class iteration_proxy
1754 typename IteratorType::reference container;
1758 explicit iteration_proxy(
typename IteratorType::reference cont) noexcept
1759 : container(cont) {}
1762 iteration_proxy_value<IteratorType> begin() noexcept
1764 return iteration_proxy_value<IteratorType>(container.begin());
1768 iteration_proxy_value<IteratorType> end() noexcept
1770 return iteration_proxy_value<IteratorType>(container.end());
1776 template <std::
size_t N,
typename IteratorType, enable_if_t<N == 0,
int> = 0>
1777 auto get(
const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
1784 template <std::
size_t N,
typename IteratorType, enable_if_t<N == 1,
int> = 0>
1785 auto get(
const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
1798 template <
typename IteratorType>
1799 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
1800 :
public std::integral_constant<std::size_t, 2> {};
1802 template <std::
size_t N,
typename IteratorType>
1803 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
1806 using type = decltype(
1807 get<N>(std::declval <
1808 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
1820 template<value_t>
struct external_constructor;
1823 struct external_constructor<value_t::boolean>
1825 template<
typename BasicJsonType>
1826 static void construct(BasicJsonType& j,
typename BasicJsonType::boolean_t b) noexcept
1828 j.m_type = value_t::boolean;
1830 j.assert_invariant();
1835 struct external_constructor<value_t::string>
1837 template<
typename BasicJsonType>
1838 static void construct(BasicJsonType& j,
const typename BasicJsonType::string_t& s)
1840 j.m_type = value_t::string;
1842 j.assert_invariant();
1845 template<
typename BasicJsonType>
1846 static void construct(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
1848 j.m_type = value_t::string;
1849 j.m_value = std::move(s);
1850 j.assert_invariant();
1853 template<
typename BasicJsonType,
typename CompatibleStringType,
1854 enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
1856 static void construct(BasicJsonType& j,
const CompatibleStringType& str)
1858 j.m_type = value_t::string;
1859 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
1860 j.assert_invariant();
1865 struct external_constructor<value_t::number_float>
1867 template<
typename BasicJsonType>
1868 static void construct(BasicJsonType& j,
typename BasicJsonType::number_float_t val) noexcept
1870 j.m_type = value_t::number_float;
1872 j.assert_invariant();
1877 struct external_constructor<value_t::number_unsigned>
1879 template<
typename BasicJsonType>
1880 static void construct(BasicJsonType& j,
typename BasicJsonType::number_unsigned_t val) noexcept
1882 j.m_type = value_t::number_unsigned;
1884 j.assert_invariant();
1889 struct external_constructor<value_t::number_integer>
1891 template<
typename BasicJsonType>
1892 static void construct(BasicJsonType& j,
typename BasicJsonType::number_integer_t val) noexcept
1894 j.m_type = value_t::number_integer;
1896 j.assert_invariant();
1901 struct external_constructor<value_t::array>
1903 template<
typename BasicJsonType>
1904 static void construct(BasicJsonType& j,
const typename BasicJsonType::array_t& arr)
1906 j.m_type = value_t::array;
1908 j.assert_invariant();
1911 template<
typename BasicJsonType>
1912 static void construct(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
1914 j.m_type = value_t::array;
1915 j.m_value = std::move(arr);
1916 j.assert_invariant();
1919 template<
typename BasicJsonType,
typename CompatibleArrayType,
1920 enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
1922 static void construct(BasicJsonType& j,
const CompatibleArrayType& arr)
1926 j.m_type = value_t::array;
1927 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
1928 j.assert_invariant();
1931 template<
typename BasicJsonType>
1932 static void construct(BasicJsonType& j,
const std::vector<bool>& arr)
1934 j.m_type = value_t::array;
1935 j.m_value = value_t::array;
1936 j.m_value.array->reserve(arr.size());
1937 for (
const bool x : arr)
1939 j.m_value.array->push_back(x);
1941 j.assert_invariant();
1944 template<
typename BasicJsonType,
typename T,
1945 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
1946 static void construct(BasicJsonType& j,
const std::valarray<T>& arr)
1948 j.m_type = value_t::array;
1949 j.m_value = value_t::array;
1950 j.m_value.array->resize(arr.size());
1951 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
1952 j.assert_invariant();
1957 struct external_constructor<value_t::object>
1959 template<
typename BasicJsonType>
1960 static void construct(BasicJsonType& j,
const typename BasicJsonType::object_t& obj)
1962 j.m_type = value_t::object;
1964 j.assert_invariant();
1967 template<
typename BasicJsonType>
1968 static void construct(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
1970 j.m_type = value_t::object;
1971 j.m_value = std::move(obj);
1972 j.assert_invariant();
1975 template<
typename BasicJsonType,
typename CompatibleObjectType,
1976 enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value,
int> = 0>
1977 static void construct(BasicJsonType& j,
const CompatibleObjectType& obj)
1982 j.m_type = value_t::object;
1983 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
1984 j.assert_invariant();
1992 template<
typename BasicJsonType,
typename T,
1993 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value,
int> = 0>
1994 void to_json(BasicJsonType& j, T b) noexcept
1996 external_constructor<value_t::boolean>::construct(j, b);
1999 template<
typename BasicJsonType,
typename CompatibleString,
2000 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value,
int> = 0>
2001 void to_json(BasicJsonType& j,
const CompatibleString& s)
2003 external_constructor<value_t::string>::construct(j, s);
2006 template<
typename BasicJsonType>
2007 void to_json(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
2009 external_constructor<value_t::string>::construct(j, std::move(s));
2012 template<
typename BasicJsonType,
typename FloatType,
2013 enable_if_t<std::is_floating_point<FloatType>::value,
int> = 0>
2014 void to_json(BasicJsonType& j, FloatType val) noexcept
2016 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
2019 template<
typename BasicJsonType,
typename CompatibleNumberUnsignedType,
2020 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value,
int> = 0>
2021 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
2023 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
2026 template<
typename BasicJsonType,
typename CompatibleNumberIntegerType,
2027 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value,
int> = 0>
2028 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
2030 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
2033 template<
typename BasicJsonType,
typename EnumType,
2034 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
2035 void to_json(BasicJsonType& j, EnumType e) noexcept
2037 using underlying_type =
typename std::underlying_type<EnumType>::type;
2038 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
2041 template<
typename BasicJsonType>
2042 void to_json(BasicJsonType& j,
const std::vector<bool>& e)
2044 external_constructor<value_t::array>::construct(j, e);
2047 template <
typename BasicJsonType,
typename CompatibleArrayType,
2048 enable_if_t<is_compatible_array_type<BasicJsonType,
2049 CompatibleArrayType>::value and
2050 not is_compatible_object_type<
2051 BasicJsonType, CompatibleArrayType>::value and
2052 not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
2053 not is_basic_json<CompatibleArrayType>::value,
2055 void to_json(BasicJsonType& j,
const CompatibleArrayType& arr)
2057 external_constructor<value_t::array>::construct(j, arr);
2060 template<
typename BasicJsonType,
typename T,
2061 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
2062 void to_json(BasicJsonType& j,
const std::valarray<T>& arr)
2064 external_constructor<value_t::array>::construct(j, std::move(arr));
2067 template<
typename BasicJsonType>
2068 void to_json(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
2070 external_constructor<value_t::array>::construct(j, std::move(arr));
2073 template<
typename BasicJsonType,
typename CompatibleObjectType,
2074 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value and not is_basic_json<CompatibleObjectType>::value,
int> = 0>
2075 void to_json(BasicJsonType& j,
const CompatibleObjectType& obj)
2077 external_constructor<value_t::object>::construct(j, obj);
2080 template<
typename BasicJsonType>
2081 void to_json(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
2083 external_constructor<value_t::object>::construct(j, std::move(obj));
2087 typename BasicJsonType,
typename T, std::size_t N,
2088 enable_if_t<not std::is_constructible<
typename BasicJsonType::string_t,
2089 const T(&)[N]>::value,
2091 void to_json(BasicJsonType& j,
const T(&arr)[N])
2093 external_constructor<value_t::array>::construct(j, arr);
2096 template<
typename BasicJsonType,
typename... Args>
2097 void to_json(BasicJsonType& j,
const std::pair<Args...>& p)
2099 j = { p.first, p.second };
2103 template <
typename BasicJsonType,
typename T,
2104 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value,
int> = 0>
2105 void to_json(BasicJsonType& j,
const T& b)
2107 j = { {b.key(), b.value()} };
2110 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
2111 void to_json_tuple_impl(BasicJsonType& j,
const Tuple& t, index_sequence<Idx...> )
2113 j = { std::get<Idx>(t)... };
2116 template<
typename BasicJsonType,
typename... Args>
2117 void to_json(BasicJsonType& j,
const std::tuple<Args...>& t)
2119 to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
2124 template<
typename BasicJsonType,
typename T>
2125 auto operator()(BasicJsonType& j, T&& val)
const noexcept(noexcept(
to_json(j, std::forward<T>(val))))
2126 -> decltype(
to_json(j, std::forward<T>(val)),
void())
2128 return to_json(j, std::forward<T>(val));
2136 constexpr
const auto&
to_json = detail::static_const<detail::to_json_fn>::value;
2151 #include <type_traits> 2163 enum class input_format_t {
json, cbor, msgpack, ubjson, bson };
2180 struct input_adapter_protocol
2183 virtual std::char_traits<char>::int_type get_character() = 0;
2184 virtual ~input_adapter_protocol() =
default;
2188 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
2194 class file_input_adapter :
public input_adapter_protocol
2197 explicit file_input_adapter(std::FILE* f) noexcept
2201 std::char_traits<char>::int_type get_character() noexcept
override 2203 return std::fgetc(m_file);
2220 class input_stream_adapter :
public input_adapter_protocol
2223 ~input_stream_adapter()
override 2227 is.clear(is.rdstate() & std::ios::eofbit);
2230 explicit input_stream_adapter(std::istream& i)
2231 : is(i), sb(*i.rdbuf())
2235 input_stream_adapter(
const input_stream_adapter&) =
delete;
2236 input_stream_adapter& operator=(input_stream_adapter&) =
delete;
2237 input_stream_adapter(input_stream_adapter&&) =
delete;
2238 input_stream_adapter& operator=(input_stream_adapter&&) =
delete;
2243 std::char_traits<char>::int_type get_character()
override 2245 auto res = sb.sbumpc();
2249 is.clear(is.rdstate() | std::ios::eofbit);
2261 class input_buffer_adapter :
public input_adapter_protocol
2264 input_buffer_adapter(
const char* b,
const std::size_t l) noexcept
2265 : cursor(b), limit(b + l)
2269 input_buffer_adapter(
const input_buffer_adapter&) =
delete;
2270 input_buffer_adapter& operator=(input_buffer_adapter&) =
delete;
2271 input_buffer_adapter(input_buffer_adapter&&) =
delete;
2272 input_buffer_adapter& operator=(input_buffer_adapter&&) =
delete;
2273 ~input_buffer_adapter()
override =
default;
2275 std::char_traits<char>::int_type get_character() noexcept
override 2277 if (JSON_LIKELY(cursor < limit))
2279 return std::char_traits<char>::to_int_type(*(cursor++));
2282 return std::char_traits<char>::eof();
2289 const char*
const limit;
2292 template<
typename W
ideStringType,
size_t T>
2293 struct wide_string_input_helper
2296 static void fill_buffer(
const WideStringType& str,
size_t& current_wchar, std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
size_t& utf8_bytes_index,
size_t& utf8_bytes_filled)
2298 utf8_bytes_index = 0;
2300 if (current_wchar == str.size())
2302 utf8_bytes[0] = std::char_traits<char>::eof();
2303 utf8_bytes_filled = 1;
2308 const auto wc =
static_cast<int>(str[current_wchar++]);
2314 utf8_bytes_filled = 1;
2316 else if (wc <= 0x7FF)
2318 utf8_bytes[0] = 0xC0 | ((wc >> 6) & 0x1F);
2319 utf8_bytes[1] = 0x80 | (wc & 0x3F);
2320 utf8_bytes_filled = 2;
2322 else if (wc <= 0xFFFF)
2324 utf8_bytes[0] = 0xE0 | ((wc >> 12) & 0x0F);
2325 utf8_bytes[1] = 0x80 | ((wc >> 6) & 0x3F);
2326 utf8_bytes[2] = 0x80 | (wc & 0x3F);
2327 utf8_bytes_filled = 3;
2329 else if (wc <= 0x10FFFF)
2331 utf8_bytes[0] = 0xF0 | ((wc >> 18) & 0x07);
2332 utf8_bytes[1] = 0x80 | ((wc >> 12) & 0x3F);
2333 utf8_bytes[2] = 0x80 | ((wc >> 6) & 0x3F);
2334 utf8_bytes[3] = 0x80 | (wc & 0x3F);
2335 utf8_bytes_filled = 4;
2341 utf8_bytes_filled = 1;
2347 template<
typename W
ideStringType>
2348 struct wide_string_input_helper<WideStringType, 2>
2351 static void fill_buffer(
const WideStringType& str,
size_t& current_wchar, std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
size_t& utf8_bytes_index,
size_t& utf8_bytes_filled)
2353 utf8_bytes_index = 0;
2355 if (current_wchar == str.size())
2357 utf8_bytes[0] = std::char_traits<char>::eof();
2358 utf8_bytes_filled = 1;
2363 const auto wc =
static_cast<int>(str[current_wchar++]);
2369 utf8_bytes_filled = 1;
2371 else if (wc <= 0x7FF)
2373 utf8_bytes[0] = 0xC0 | ((wc >> 6));
2374 utf8_bytes[1] = 0x80 | (wc & 0x3F);
2375 utf8_bytes_filled = 2;
2377 else if (0xD800 > wc or wc >= 0xE000)
2379 utf8_bytes[0] = 0xE0 | ((wc >> 12));
2380 utf8_bytes[1] = 0x80 | ((wc >> 6) & 0x3F);
2381 utf8_bytes[2] = 0x80 | (wc & 0x3F);
2382 utf8_bytes_filled = 3;
2386 if (current_wchar < str.size())
2388 const auto wc2 =
static_cast<int>(str[current_wchar++]);
2389 const int charcode = 0x10000 + (((wc & 0x3FF) << 10) | (wc2 & 0x3FF));
2390 utf8_bytes[0] = 0xf0 | (charcode >> 18);
2391 utf8_bytes[1] = 0x80 | ((charcode >> 12) & 0x3F);
2392 utf8_bytes[2] = 0x80 | ((charcode >> 6) & 0x3F);
2393 utf8_bytes[3] = 0x80 | (charcode & 0x3F);
2394 utf8_bytes_filled = 4;
2401 utf8_bytes_filled = 1;
2408 template<
typename W
ideStringType>
2409 class wide_string_input_adapter :
public input_adapter_protocol
2412 explicit wide_string_input_adapter(
const WideStringType& w) noexcept
2416 std::char_traits<char>::int_type get_character() noexcept
override 2419 if (utf8_bytes_index == utf8_bytes_filled)
2421 fill_buffer<sizeof(typename WideStringType::value_type)>();
2423 assert(utf8_bytes_filled > 0);
2424 assert(utf8_bytes_index == 0);
2428 assert(utf8_bytes_filled > 0);
2429 assert(utf8_bytes_index < utf8_bytes_filled);
2430 return utf8_bytes[utf8_bytes_index++];
2437 wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
2441 const WideStringType& str;
2444 std::size_t current_wchar = 0;
2447 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
2450 std::size_t utf8_bytes_index = 0;
2452 std::size_t utf8_bytes_filled = 0;
2459 input_adapter(std::FILE* file)
2460 : ia(std::make_shared<file_input_adapter>(file)) {}
2462 input_adapter(std::istream& i)
2463 : ia(std::make_shared<input_stream_adapter>(i)) {}
2466 input_adapter(std::istream&& i)
2467 : ia(std::make_shared<input_stream_adapter>(i)) {}
2469 input_adapter(
const std::wstring& ws)
2470 : ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {}
2472 input_adapter(
const std::u16string& ws)
2473 : ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {}
2475 input_adapter(
const std::u32string& ws)
2476 : ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {}
2479 template<
typename CharT,
2480 typename std::enable_if<
2481 std::is_pointer<CharT>::value and
2482 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2483 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
2485 input_adapter(CharT b, std::size_t l)
2486 : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
2491 template<
typename CharT,
2492 typename std::enable_if<
2493 std::is_pointer<CharT>::value and
2494 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2495 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
2497 input_adapter(CharT b)
2498 : input_adapter(reinterpret_cast<const char*>(b),
2499 std::strlen(reinterpret_cast<const char*>(b))) {}
2502 template<
class IteratorType,
2503 typename std::enable_if<
2504 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
2506 input_adapter(IteratorType first, IteratorType last)
2511 const auto is_contiguous = std::accumulate(
2512 first, last, std::pair<bool, int>(
true, 0),
2513 [&first](std::pair<bool, int> res, decltype(*first) val)
2515 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
2518 assert(is_contiguous);
2523 sizeof(
typename iterator_traits<IteratorType>::value_type) == 1,
2524 "each element in the iterator range must have the size of 1 byte");
2526 const auto len =
static_cast<size_t>(std::distance(first, last));
2527 if (JSON_LIKELY(len > 0))
2530 ia = std::make_shared<input_buffer_adapter>(
reinterpret_cast<const char*
>(&(*first)), len);
2535 ia = std::make_shared<input_buffer_adapter>(
nullptr, len);
2540 template<
class T, std::
size_t N>
2541 input_adapter(T (&array)[N])
2542 : input_adapter(std::begin(array), std::end(array)) {}
2545 template<
class ContiguousContainer,
typename 2546 std::enable_if<not std::is_pointer<ContiguousContainer>::value and
2547 std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
2549 input_adapter(
const ContiguousContainer& c)
2550 : input_adapter(std::begin(c), std::end(c)) {}
2552 operator input_adapter_t()
2559 input_adapter_t ia =
nullptr;
2571 #include <initializer_list> 2595 template<
typename BasicJsonType>
2598 using number_integer_t =
typename BasicJsonType::number_integer_t;
2599 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
2600 using number_float_t =
typename BasicJsonType::number_float_t;
2601 using string_t =
typename BasicJsonType::string_t;
2605 enum class token_type
2627 static const char* token_type_name(
const token_type t) noexcept
2631 case token_type::uninitialized:
2632 return "<uninitialized>";
2633 case token_type::literal_true:
2634 return "true literal";
2635 case token_type::literal_false:
2636 return "false literal";
2637 case token_type::literal_null:
2638 return "null literal";
2639 case token_type::value_string:
2640 return "string literal";
2641 case lexer::token_type::value_unsigned:
2642 case lexer::token_type::value_integer:
2643 case lexer::token_type::value_float:
2644 return "number literal";
2645 case token_type::begin_array:
2647 case token_type::begin_object:
2649 case token_type::end_array:
2651 case token_type::end_object:
2653 case token_type::name_separator:
2655 case token_type::value_separator:
2657 case token_type::parse_error:
2658 return "<parse error>";
2659 case token_type::end_of_input:
2660 return "end of input";
2661 case token_type::literal_or_value:
2662 return "'[', '{', or a literal";
2665 return "unknown token";
2670 explicit lexer(detail::input_adapter_t&& adapter)
2671 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
2674 lexer(
const lexer&) =
delete;
2675 lexer(lexer&&) =
delete;
2676 lexer& operator=(lexer&) =
delete;
2677 lexer& operator=(lexer&&) =
delete;
2686 static char get_decimal_point() noexcept
2688 const auto loc = localeconv();
2689 assert(loc !=
nullptr);
2690 return (loc->decimal_point ==
nullptr) ?
'.' : *(loc->decimal_point);
2715 assert(current ==
'u');
2718 const auto factors = { 12, 8, 4, 0 };
2719 for (
const auto factor : factors)
2723 if (current >=
'0' and current <=
'9')
2725 codepoint += ((current - 0x30) << factor);
2727 else if (current >=
'A' and current <=
'F')
2729 codepoint += ((current - 0x37) << factor);
2731 else if (current >=
'a' and current <=
'f')
2733 codepoint += ((current - 0x57) << factor);
2741 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
2760 bool next_byte_in_range(std::initializer_list<int> ranges)
2762 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
2765 for (
auto range = ranges.begin(); range != ranges.end(); ++range)
2768 if (JSON_LIKELY(*range <= current and current <= *(++range)))
2774 error_message =
"invalid string: ill-formed UTF-8 byte";
2797 token_type scan_string()
2803 assert(current ==
'\"');
2811 case std::char_traits<char>::eof():
2813 error_message =
"invalid string: missing closing quote";
2814 return token_type::parse_error;
2820 return token_type::value_string;
2864 const int codepoint1 = get_codepoint();
2865 int codepoint = codepoint1;
2867 if (JSON_UNLIKELY(codepoint1 == -1))
2869 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
2870 return token_type::parse_error;
2874 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
2877 if (JSON_LIKELY(
get() ==
'\\' and
get() ==
'u'))
2879 const int codepoint2 = get_codepoint();
2881 if (JSON_UNLIKELY(codepoint2 == -1))
2883 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
2884 return token_type::parse_error;
2888 if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
2903 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2904 return token_type::parse_error;
2909 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2910 return token_type::parse_error;
2915 if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
2917 error_message =
"invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
2918 return token_type::parse_error;
2923 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
2926 if (codepoint < 0x80)
2931 else if (codepoint <= 0x7FF)
2934 add(0xC0 | (codepoint >> 6));
2935 add(0x80 | (codepoint & 0x3F));
2937 else if (codepoint <= 0xFFFF)
2940 add(0xE0 | (codepoint >> 12));
2941 add(0x80 | ((codepoint >> 6) & 0x3F));
2942 add(0x80 | (codepoint & 0x3F));
2947 add(0xF0 | (codepoint >> 18));
2948 add(0x80 | ((codepoint >> 12) & 0x3F));
2949 add(0x80 | ((codepoint >> 6) & 0x3F));
2950 add(0x80 | (codepoint & 0x3F));
2958 error_message =
"invalid string: forbidden character after backslash";
2959 return token_type::parse_error;
2968 error_message =
"invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
2969 return token_type::parse_error;
2974 error_message =
"invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
2975 return token_type::parse_error;
2980 error_message =
"invalid string: control character U+0002 (STX) must be escaped to \\u0002";
2981 return token_type::parse_error;
2986 error_message =
"invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
2987 return token_type::parse_error;
2992 error_message =
"invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
2993 return token_type::parse_error;
2998 error_message =
"invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
2999 return token_type::parse_error;
3004 error_message =
"invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
3005 return token_type::parse_error;
3010 error_message =
"invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
3011 return token_type::parse_error;
3016 error_message =
"invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
3017 return token_type::parse_error;
3022 error_message =
"invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
3023 return token_type::parse_error;
3028 error_message =
"invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
3029 return token_type::parse_error;
3034 error_message =
"invalid string: control character U+000B (VT) must be escaped to \\u000B";
3035 return token_type::parse_error;
3040 error_message =
"invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
3041 return token_type::parse_error;
3046 error_message =
"invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
3047 return token_type::parse_error;
3052 error_message =
"invalid string: control character U+000E (SO) must be escaped to \\u000E";
3053 return token_type::parse_error;
3058 error_message =
"invalid string: control character U+000F (SI) must be escaped to \\u000F";
3059 return token_type::parse_error;
3064 error_message =
"invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
3065 return token_type::parse_error;
3070 error_message =
"invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
3071 return token_type::parse_error;
3076 error_message =
"invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
3077 return token_type::parse_error;
3082 error_message =
"invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
3083 return token_type::parse_error;
3088 error_message =
"invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
3089 return token_type::parse_error;
3094 error_message =
"invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
3095 return token_type::parse_error;
3100 error_message =
"invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
3101 return token_type::parse_error;
3106 error_message =
"invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
3107 return token_type::parse_error;
3112 error_message =
"invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
3113 return token_type::parse_error;
3118 error_message =
"invalid string: control character U+0019 (EM) must be escaped to \\u0019";
3119 return token_type::parse_error;
3124 error_message =
"invalid string: control character U+001A (SUB) must be escaped to \\u001A";
3125 return token_type::parse_error;
3130 error_message =
"invalid string: control character U+001B (ESC) must be escaped to \\u001B";
3131 return token_type::parse_error;
3136 error_message =
"invalid string: control character U+001C (FS) must be escaped to \\u001C";
3137 return token_type::parse_error;
3142 error_message =
"invalid string: control character U+001D (GS) must be escaped to \\u001D";
3143 return token_type::parse_error;
3148 error_message =
"invalid string: control character U+001E (RS) must be escaped to \\u001E";
3149 return token_type::parse_error;
3154 error_message =
"invalid string: control character U+001F (US) must be escaped to \\u001F";
3155 return token_type::parse_error;
3290 if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
3292 return token_type::parse_error;
3300 if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
3302 return token_type::parse_error;
3324 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
3326 return token_type::parse_error;
3334 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
3336 return token_type::parse_error;
3344 if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
3346 return token_type::parse_error;
3356 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
3358 return token_type::parse_error;
3366 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
3368 return token_type::parse_error;
3376 error_message =
"invalid string: ill-formed UTF-8 byte";
3377 return token_type::parse_error;
3383 static void strtof(
float& f,
const char* str,
char** endptr) noexcept
3385 f = std::strtof(str, endptr);
3388 static void strtof(
double& f,
const char* str,
char** endptr) noexcept
3390 f = std::strtod(str, endptr);
3393 static void strtof(
long double& f,
const char* str,
char** endptr) noexcept
3395 f = std::strtold(str, endptr);
3438 token_type scan_number()
3445 token_type number_type = token_type::value_unsigned;
3453 goto scan_number_minus;
3459 goto scan_number_zero;
3473 goto scan_number_any1;
3487 number_type = token_type::value_integer;
3493 goto scan_number_zero;
3507 goto scan_number_any1;
3512 error_message =
"invalid number; expected digit after '-'";
3513 return token_type::parse_error;
3523 add(decimal_point_char);
3524 goto scan_number_decimal1;
3531 goto scan_number_exponent;
3535 goto scan_number_done;
3554 goto scan_number_any1;
3559 add(decimal_point_char);
3560 goto scan_number_decimal1;
3567 goto scan_number_exponent;
3571 goto scan_number_done;
3574 scan_number_decimal1:
3576 number_type = token_type::value_float;
3591 goto scan_number_decimal2;
3596 error_message =
"invalid number; expected digit after '.'";
3597 return token_type::parse_error;
3601 scan_number_decimal2:
3617 goto scan_number_decimal2;
3624 goto scan_number_exponent;
3628 goto scan_number_done;
3631 scan_number_exponent:
3633 number_type = token_type::value_float;
3640 goto scan_number_sign;
3655 goto scan_number_any2;
3661 "invalid number; expected '+', '-', or digit after exponent";
3662 return token_type::parse_error;
3682 goto scan_number_any2;
3687 error_message =
"invalid number; expected digit after exponent sign";
3688 return token_type::parse_error;
3708 goto scan_number_any2;
3712 goto scan_number_done;
3720 char* endptr =
nullptr;
3724 if (number_type == token_type::value_unsigned)
3726 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
3729 assert(endptr == token_buffer.data() + token_buffer.size());
3733 value_unsigned =
static_cast<number_unsigned_t
>(x);
3734 if (value_unsigned == x)
3736 return token_type::value_unsigned;
3740 else if (number_type == token_type::value_integer)
3742 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
3745 assert(endptr == token_buffer.data() + token_buffer.size());
3749 value_integer =
static_cast<number_integer_t
>(x);
3750 if (value_integer == x)
3752 return token_type::value_integer;
3759 strtof(value_float, token_buffer.data(), &endptr);
3762 assert(endptr == token_buffer.data() + token_buffer.size());
3764 return token_type::value_float;
3772 token_type scan_literal(
const char* literal_text,
const std::size_t length,
3773 token_type return_type)
3775 assert(current == literal_text[0]);
3776 for (std::size_t i = 1; i < length; ++i)
3778 if (JSON_UNLIKELY(
get() != literal_text[i]))
3780 error_message =
"invalid literal";
3781 return token_type::parse_error;
3792 void reset() noexcept
3794 token_buffer.clear();
3795 token_string.clear();
3796 token_string.push_back(std::char_traits<char>::to_char_type(current));
3809 std::char_traits<char>::int_type
get()
3811 ++position.chars_read_total;
3812 ++position.chars_read_current_line;
3821 current = ia->get_character();
3824 if (JSON_LIKELY(current != std::char_traits<char>::eof()))
3826 token_string.push_back(std::char_traits<char>::to_char_type(current));
3829 if (current ==
'\n')
3831 ++position.lines_read;
3832 ++position.chars_read_current_line = 0;
3850 --position.chars_read_total;
3853 if (position.chars_read_current_line == 0)
3855 if (position.lines_read > 0)
3857 --position.lines_read;
3862 --position.chars_read_current_line;
3865 if (JSON_LIKELY(current != std::char_traits<char>::eof()))
3867 assert(token_string.size() != 0);
3868 token_string.pop_back();
3875 token_buffer.push_back(std::char_traits<char>::to_char_type(c));
3884 constexpr number_integer_t get_number_integer()
const noexcept
3886 return value_integer;
3890 constexpr number_unsigned_t get_number_unsigned()
const noexcept
3892 return value_unsigned;
3896 constexpr number_float_t get_number_float()
const noexcept
3902 string_t& get_string()
3904 return token_buffer;
3912 constexpr position_t get_position()
const noexcept
3920 std::string get_token_string()
const 3924 for (
const auto c : token_string)
3926 if (
'\x00' <= c and c <=
'\x1F')
3930 (std::snprintf)(cs, 9,
"<U+%.4X>", static_cast<unsigned char>(c));
3936 result.push_back(c);
3944 constexpr
const char* get_error_message()
const noexcept
3946 return error_message;
3962 return get() == 0xBB and
get() == 0xBF;
3974 if (position.chars_read_total == 0 and not skip_bom())
3976 error_message =
"invalid BOM; must be 0xEF 0xBB 0xBF if given";
3977 return token_type::parse_error;
3985 while (current ==
' ' or current ==
'\t' or current ==
'\n' or current ==
'\r');
3991 return token_type::begin_array;
3993 return token_type::end_array;
3995 return token_type::begin_object;
3997 return token_type::end_object;
3999 return token_type::name_separator;
4001 return token_type::value_separator;
4005 return scan_literal(
"true", 4, token_type::literal_true);
4007 return scan_literal(
"false", 5, token_type::literal_false);
4009 return scan_literal(
"null", 4, token_type::literal_null);
4013 return scan_string();
4027 return scan_number();
4032 case std::char_traits<char>::eof():
4033 return token_type::end_of_input;
4037 error_message =
"invalid literal";
4038 return token_type::parse_error;
4044 detail::input_adapter_t ia =
nullptr;
4047 std::char_traits<char>::int_type current = std::char_traits<char>::eof();
4050 bool next_unget =
false;
4053 position_t position;
4056 std::vector<char> token_string {};
4059 string_t token_buffer {};
4062 const char* error_message =
"";
4065 number_integer_t value_integer = 0;
4066 number_unsigned_t value_unsigned = 0;
4067 number_float_t value_float = 0;
4070 const char decimal_point_char =
'.';
4081 #include <functional> 4104 template <
typename T>
4105 using null_function_t = decltype(std::declval<T&>().null());
4107 template <
typename T>
4108 using boolean_function_t =
4109 decltype(std::declval<T&>().
boolean(std::declval<bool>()));
4111 template <
typename T,
typename Integer>
4112 using number_integer_function_t =
4113 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
4115 template <
typename T,
typename Un
signed>
4116 using number_unsigned_function_t =
4117 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
4119 template <
typename T,
typename Float,
typename String>
4120 using number_float_function_t = decltype(std::declval<T&>().number_float(
4121 std::declval<Float>(), std::declval<const String&>()));
4123 template <
typename T,
typename String>
4124 using string_function_t =
4125 decltype(std::declval<T&>().
string(std::declval<String&>()));
4127 template <
typename T>
4128 using start_object_function_t =
4129 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
4131 template <
typename T,
typename String>
4132 using key_function_t =
4133 decltype(std::declval<T&>().key(std::declval<String&>()));
4135 template <
typename T>
4136 using end_object_function_t = decltype(std::declval<T&>().end_object());
4138 template <
typename T>
4139 using start_array_function_t =
4140 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
4142 template <
typename T>
4143 using end_array_function_t = decltype(std::declval<T&>().end_array());
4145 template <
typename T,
typename Exception>
4146 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
4147 std::declval<std::size_t>(), std::declval<const std::string&>(),
4148 std::declval<const Exception&>()));
4150 template <
typename SAX,
typename BasicJsonType>
4154 static_assert(is_basic_json<BasicJsonType>::value,
4155 "BasicJsonType must be of type basic_json<...>");
4157 using number_integer_t =
typename BasicJsonType::number_integer_t;
4158 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
4159 using number_float_t =
typename BasicJsonType::number_float_t;
4160 using string_t =
typename BasicJsonType::string_t;
4161 using exception_t =
typename BasicJsonType::exception;
4164 static constexpr
bool value =
4165 is_detected_exact<bool, null_function_t, SAX>::value &&
4166 is_detected_exact<bool, boolean_function_t, SAX>::value &&
4167 is_detected_exact<bool, number_integer_function_t, SAX,
4168 number_integer_t>::value &&
4169 is_detected_exact<bool, number_unsigned_function_t, SAX,
4170 number_unsigned_t>::value &&
4171 is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
4173 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
4174 is_detected_exact<bool, start_object_function_t, SAX>::value &&
4175 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
4176 is_detected_exact<bool, end_object_function_t, SAX>::value &&
4177 is_detected_exact<bool, start_array_function_t, SAX>::value &&
4178 is_detected_exact<bool, end_array_function_t, SAX>::value &&
4179 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
4182 template <
typename SAX,
typename BasicJsonType>
4183 struct is_sax_static_asserts
4186 static_assert(is_basic_json<BasicJsonType>::value,
4187 "BasicJsonType must be of type basic_json<...>");
4189 using number_integer_t =
typename BasicJsonType::number_integer_t;
4190 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
4191 using number_float_t =
typename BasicJsonType::number_float_t;
4192 using string_t =
typename BasicJsonType::string_t;
4193 using exception_t =
typename BasicJsonType::exception;
4196 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
4197 "Missing/invalid function: bool null()");
4198 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
4199 "Missing/invalid function: bool boolean(bool)");
4200 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
4201 "Missing/invalid function: bool boolean(bool)");
4203 is_detected_exact<
bool, number_integer_function_t, SAX,
4204 number_integer_t>::value,
4205 "Missing/invalid function: bool number_integer(number_integer_t)");
4207 is_detected_exact<
bool, number_unsigned_function_t, SAX,
4208 number_unsigned_t>::value,
4209 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
4210 static_assert(is_detected_exact<
bool, number_float_function_t, SAX,
4211 number_float_t, string_t>::value,
4212 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
4214 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
4215 "Missing/invalid function: bool string(string_t&)");
4216 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
4217 "Missing/invalid function: bool start_object(std::size_t)");
4218 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
4219 "Missing/invalid function: bool key(string_t&)");
4220 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
4221 "Missing/invalid function: bool end_object()");
4222 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
4223 "Missing/invalid function: bool start_array(std::size_t)");
4224 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
4225 "Missing/invalid function: bool end_array()");
4227 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
4228 "Missing/invalid function: bool parse_error(std::size_t, const " 4229 "std::string&, const exception&)");
4259 template<
typename BasicJsonType>
4275 virtual bool null() = 0;
4282 virtual bool boolean(
bool val) = 0;
4312 virtual bool string(
string_t& val) = 0;
4320 virtual bool start_object(std::size_t elements) = 0;
4328 virtual bool key(
string_t& val) = 0;
4334 virtual bool end_object() = 0;
4342 virtual bool start_array(std::size_t elements) = 0;
4348 virtual bool end_array() = 0;
4357 virtual bool parse_error(std::size_t position,
4358 const std::string& last_token,
4359 const detail::exception& ex) = 0;
4380 template<
typename BasicJsonType>
4381 class json_sax_dom_parser
4387 using string_t =
typename BasicJsonType::string_t;
4394 explicit json_sax_dom_parser(BasicJsonType& r,
const bool allow_exceptions_ =
true)
4395 : root(r), allow_exceptions(allow_exceptions_)
4400 handle_value(
nullptr);
4404 bool boolean(
bool val)
4434 bool start_object(std::size_t len)
4436 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
4438 if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4440 JSON_THROW(out_of_range::create(408,
4441 "excessive object size: " + std::to_string(len)));
4450 object_element = &(ref_stack.back()->m_value.object->operator[](val));
4456 ref_stack.pop_back();
4460 bool start_array(std::size_t len)
4462 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
4464 if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4466 JSON_THROW(out_of_range::create(408,
4467 "excessive array size: " + std::to_string(len)));
4475 ref_stack.pop_back();
4479 bool parse_error(std::size_t ,
const std::string& ,
4480 const detail::exception& ex)
4483 if (allow_exceptions)
4486 switch ((ex.id / 100) % 100)
4489 JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex));
4491 JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex));
4494 JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex));
4496 JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex));
4498 JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex));
4507 constexpr
bool is_errored()
const 4519 template<
typename Value>
4520 BasicJsonType* handle_value(Value&& v)
4522 if (ref_stack.empty())
4524 root = BasicJsonType(std::forward<Value>(v));
4528 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
4530 if (ref_stack.back()->is_array())
4532 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
4533 return &(ref_stack.back()->m_value.array->back());
4537 assert(object_element);
4538 *object_element = BasicJsonType(std::forward<Value>(v));
4539 return object_element;
4544 BasicJsonType& root;
4546 std::vector<BasicJsonType*> ref_stack;
4548 BasicJsonType* object_element =
nullptr;
4550 bool errored =
false;
4552 const bool allow_exceptions =
true;
4555 template<
typename BasicJsonType>
4556 class json_sax_dom_callback_parser
4562 using string_t =
typename BasicJsonType::string_t;
4563 using parser_callback_t =
typename BasicJsonType::parser_callback_t;
4564 using parse_event_t =
typename BasicJsonType::parse_event_t;
4566 json_sax_dom_callback_parser(BasicJsonType& r,
4567 const parser_callback_t cb,
4568 const bool allow_exceptions_ =
true)
4569 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
4571 keep_stack.push_back(
true);
4576 handle_value(
nullptr);
4580 bool boolean(
bool val)
4610 bool start_object(std::size_t len)
4613 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
4614 keep_stack.push_back(keep);
4616 auto val = handle_value(BasicJsonType::value_t::object,
true);
4617 ref_stack.push_back(val.second);
4620 if (ref_stack.back())
4622 if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4624 JSON_THROW(out_of_range::create(408,
4625 "excessive object size: " + std::to_string(len)));
4634 BasicJsonType k = BasicJsonType(val);
4637 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
4638 key_keep_stack.push_back(keep);
4641 if (keep and ref_stack.back())
4643 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
4651 if (ref_stack.back())
4653 if (not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
4656 *ref_stack.back() = discarded;
4660 assert(not ref_stack.empty());
4661 assert(not keep_stack.empty());
4662 ref_stack.pop_back();
4663 keep_stack.pop_back();
4665 if (not ref_stack.empty() and ref_stack.back())
4668 if (ref_stack.back()->is_object())
4670 for (
auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
4672 if (it->is_discarded())
4674 ref_stack.back()->erase(it);
4684 bool start_array(std::size_t len)
4686 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
4687 keep_stack.push_back(keep);
4689 auto val = handle_value(BasicJsonType::value_t::array,
true);
4690 ref_stack.push_back(val.second);
4693 if (ref_stack.back())
4695 if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4697 JSON_THROW(out_of_range::create(408,
4698 "excessive array size: " + std::to_string(len)));
4709 if (ref_stack.back())
4711 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
4715 *ref_stack.back() = discarded;
4719 assert(not ref_stack.empty());
4720 assert(not keep_stack.empty());
4721 ref_stack.pop_back();
4722 keep_stack.pop_back();
4725 if (not keep and not ref_stack.empty())
4727 if (ref_stack.back()->is_array())
4729 ref_stack.back()->m_value.array->pop_back();
4736 bool parse_error(std::size_t ,
const std::string& ,
4737 const detail::exception& ex)
4740 if (allow_exceptions)
4743 switch ((ex.id / 100) % 100)
4746 JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex));
4748 JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex));
4751 JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex));
4753 JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex));
4755 JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex));
4764 constexpr
bool is_errored()
const 4785 template<
typename Value>
4786 std::pair<bool, BasicJsonType*> handle_value(Value&& v,
const bool skip_callback =
false)
4788 assert(not keep_stack.empty());
4792 if (not keep_stack.back())
4794 return {
false,
nullptr};
4798 auto value = BasicJsonType(std::forward<Value>(v));
4801 const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
4806 return {
false,
nullptr};
4809 if (ref_stack.empty())
4811 root = std::move(value);
4812 return {
true, &root};
4817 if (not ref_stack.back())
4819 return {
false,
nullptr};
4823 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
4825 if (ref_stack.back()->is_array())
4827 ref_stack.back()->m_value.array->push_back(std::move(value));
4828 return {
true, &(ref_stack.back()->m_value.array->back())};
4833 assert(not key_keep_stack.empty());
4834 const bool store_element = key_keep_stack.back();
4835 key_keep_stack.pop_back();
4837 if (not store_element)
4839 return {
false,
nullptr};
4842 assert(object_element);
4843 *object_element = std::move(value);
4844 return {
true, object_element};
4849 BasicJsonType& root;
4851 std::vector<BasicJsonType*> ref_stack;
4853 std::vector<bool> keep_stack;
4855 std::vector<bool> key_keep_stack;
4857 BasicJsonType* object_element =
nullptr;
4859 bool errored =
false;
4861 const parser_callback_t callback =
nullptr;
4863 const bool allow_exceptions =
true;
4865 BasicJsonType discarded = BasicJsonType::value_t::discarded;
4868 template<
typename BasicJsonType>
4869 class json_sax_acceptor
4875 using string_t =
typename BasicJsonType::string_t;
4907 bool start_object(std::size_t = std::size_t(-1))
4922 bool start_array(std::size_t = std::size_t(-1))
4932 bool parse_error(std::size_t ,
const std::string& ,
const detail::exception& )
4959 template<
typename BasicJsonType>
4965 using string_t =
typename BasicJsonType::string_t;
4966 using lexer_t = lexer<BasicJsonType>;
4967 using token_type =
typename lexer_t::token_type;
4970 enum class parse_event_t : uint8_t
4986 using parser_callback_t =
4987 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
4990 explicit parser(detail::input_adapter_t&& adapter,
4991 const parser_callback_t cb =
nullptr,
4992 const bool allow_exceptions_ =
true)
4993 : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
5009 void parse(
const bool strict, BasicJsonType& result)
5013 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
5014 sax_parse_internal(&sdp);
5015 result.assert_invariant();
5018 if (strict and (get_token() != token_type::end_of_input))
5020 sdp.parse_error(m_lexer.get_position(),
5021 m_lexer.get_token_string(),
5022 parse_error::create(101, m_lexer.get_position(),
5023 exception_message(token_type::end_of_input,
"value")));
5027 if (sdp.is_errored())
5029 result = value_t::discarded;
5035 if (result.is_discarded())
5042 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
5043 sax_parse_internal(&sdp);
5044 result.assert_invariant();
5047 if (strict and (get_token() != token_type::end_of_input))
5049 sdp.parse_error(m_lexer.get_position(),
5050 m_lexer.get_token_string(),
5051 parse_error::create(101, m_lexer.get_position(),
5052 exception_message(token_type::end_of_input,
"value")));
5056 if (sdp.is_errored())
5058 result = value_t::discarded;
5070 bool accept(
const bool strict =
true)
5072 json_sax_acceptor<BasicJsonType> sax_acceptor;
5073 return sax_parse(&sax_acceptor, strict);
5076 template <
typename SAX>
5077 bool sax_parse(SAX* sax,
const bool strict =
true)
5079 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
5080 const bool result = sax_parse_internal(sax);
5083 if (result and strict and (get_token() != token_type::end_of_input))
5085 return sax->parse_error(m_lexer.get_position(),
5086 m_lexer.get_token_string(),
5087 parse_error::create(101, m_lexer.get_position(),
5088 exception_message(token_type::end_of_input,
"value")));
5095 template <
typename SAX>
5096 bool sax_parse_internal(SAX* sax)
5100 std::vector<bool> states;
5102 bool skip_to_state_evaluation =
false;
5106 if (not skip_to_state_evaluation)
5111 case token_type::begin_object:
5113 if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
5119 if (get_token() == token_type::end_object)
5121 if (JSON_UNLIKELY(not sax->end_object()))
5129 if (JSON_UNLIKELY(last_token != token_type::value_string))
5131 return sax->parse_error(m_lexer.get_position(),
5132 m_lexer.get_token_string(),
5133 parse_error::create(101, m_lexer.get_position(),
5134 exception_message(token_type::value_string,
"object key")));
5136 if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
5142 if (JSON_UNLIKELY(get_token() != token_type::name_separator))
5144 return sax->parse_error(m_lexer.get_position(),
5145 m_lexer.get_token_string(),
5146 parse_error::create(101, m_lexer.get_position(),
5147 exception_message(token_type::name_separator,
"object separator")));
5151 states.push_back(
false);
5158 case token_type::begin_array:
5160 if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
5166 if (get_token() == token_type::end_array)
5168 if (JSON_UNLIKELY(not sax->end_array()))
5176 states.push_back(
true);
5182 case token_type::value_float:
5184 const auto res = m_lexer.get_number_float();
5186 if (JSON_UNLIKELY(not std::isfinite(res)))
5188 return sax->parse_error(m_lexer.get_position(),
5189 m_lexer.get_token_string(),
5190 out_of_range::create(406,
"number overflow parsing '" + m_lexer.get_token_string() +
"'"));
5194 if (JSON_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
5202 case token_type::literal_false:
5204 if (JSON_UNLIKELY(not sax->boolean(
false)))
5211 case token_type::literal_null:
5213 if (JSON_UNLIKELY(not sax->null()))
5220 case token_type::literal_true:
5222 if (JSON_UNLIKELY(not sax->boolean(
true)))
5229 case token_type::value_integer:
5231 if (JSON_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
5238 case token_type::value_string:
5240 if (JSON_UNLIKELY(not sax->string(m_lexer.get_string())))
5247 case token_type::value_unsigned:
5249 if (JSON_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
5256 case token_type::parse_error:
5259 return sax->parse_error(m_lexer.get_position(),
5260 m_lexer.get_token_string(),
5261 parse_error::create(101, m_lexer.get_position(),
5262 exception_message(token_type::uninitialized,
"value")));
5267 return sax->parse_error(m_lexer.get_position(),
5268 m_lexer.get_token_string(),
5269 parse_error::create(101, m_lexer.get_position(),
5270 exception_message(token_type::literal_or_value,
"value")));
5276 skip_to_state_evaluation =
false;
5290 if (get_token() == token_type::value_separator)
5298 if (JSON_LIKELY(last_token == token_type::end_array))
5300 if (JSON_UNLIKELY(not sax->end_array()))
5309 assert(not states.empty());
5311 skip_to_state_evaluation =
true;
5316 return sax->parse_error(m_lexer.get_position(),
5317 m_lexer.get_token_string(),
5318 parse_error::create(101, m_lexer.get_position(),
5319 exception_message(token_type::end_array,
"array")));
5325 if (get_token() == token_type::value_separator)
5328 if (JSON_UNLIKELY(get_token() != token_type::value_string))
5330 return sax->parse_error(m_lexer.get_position(),
5331 m_lexer.get_token_string(),
5332 parse_error::create(101, m_lexer.get_position(),
5333 exception_message(token_type::value_string,
"object key")));
5337 if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
5344 if (JSON_UNLIKELY(get_token() != token_type::name_separator))
5346 return sax->parse_error(m_lexer.get_position(),
5347 m_lexer.get_token_string(),
5348 parse_error::create(101, m_lexer.get_position(),
5349 exception_message(token_type::name_separator,
"object separator")));
5358 if (JSON_LIKELY(last_token == token_type::end_object))
5360 if (JSON_UNLIKELY(not sax->end_object()))
5369 assert(not states.empty());
5371 skip_to_state_evaluation =
true;
5376 return sax->parse_error(m_lexer.get_position(),
5377 m_lexer.get_token_string(),
5378 parse_error::create(101, m_lexer.get_position(),
5379 exception_message(token_type::end_object,
"object")));
5387 token_type get_token()
5389 return (last_token = m_lexer.scan());
5392 std::string exception_message(
const token_type expected,
const std::string& context)
5394 std::string error_msg =
"syntax error ";
5396 if (not context.empty())
5398 error_msg +=
"while parsing " + context +
" ";
5403 if (last_token == token_type::parse_error)
5405 error_msg += std::string(m_lexer.get_error_message()) +
"; last read: '" +
5406 m_lexer.get_token_string() +
"'";
5410 error_msg +=
"unexpected " + std::string(lexer_t::token_type_name(last_token));
5413 if (expected != token_type::uninitialized)
5415 error_msg +=
"; expected " + std::string(lexer_t::token_type_name(expected));
5423 const parser_callback_t callback =
nullptr;
5425 token_type last_token = token_type::uninitialized;
5429 const bool allow_exceptions =
true;
5453 class primitive_iterator_t
5456 using difference_type = std::ptrdiff_t;
5457 static constexpr difference_type begin_value = 0;
5458 static constexpr difference_type end_value = begin_value + 1;
5461 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
5464 constexpr difference_type get_value()
const noexcept
5470 void set_begin() noexcept
5476 void set_end() noexcept
5482 constexpr
bool is_begin()
const noexcept
5484 return m_it == begin_value;
5488 constexpr
bool is_end()
const noexcept
5490 return m_it == end_value;
5493 friend constexpr
bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
5495 return lhs.m_it == rhs.m_it;
5498 friend constexpr
bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
5500 return lhs.m_it < rhs.m_it;
5503 primitive_iterator_t operator+(difference_type n) noexcept
5505 auto result = *
this;
5510 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
5512 return lhs.m_it - rhs.m_it;
5515 primitive_iterator_t& operator++() noexcept
5521 primitive_iterator_t
const operator++(
int) noexcept
5523 auto result = *
this;
5528 primitive_iterator_t& operator--() noexcept
5534 primitive_iterator_t
const operator--(
int) noexcept
5536 auto result = *
this;
5541 primitive_iterator_t& operator+=(difference_type n) noexcept
5547 primitive_iterator_t& operator-=(difference_type n) noexcept
5572 template<
typename BasicJsonType>
struct internal_iterator
5575 typename BasicJsonType::object_t::iterator object_iterator {};
5577 typename BasicJsonType::array_t::iterator array_iterator {};
5579 primitive_iterator_t primitive_iterator {};
5589 #include <type_traits> 5609 template<
typename IteratorType>
class iteration_proxy;
5610 template<
typename IteratorType>
class iteration_proxy_value;
5628 template<
typename BasicJsonType>
5632 friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value,
typename std::remove_const<BasicJsonType>::type,
const BasicJsonType>::type>;
5633 friend BasicJsonType;
5634 friend iteration_proxy<iter_impl>;
5635 friend iteration_proxy_value<iter_impl>;
5637 using object_t =
typename BasicJsonType::object_t;
5638 using array_t =
typename BasicJsonType::array_t;
5640 static_assert(is_basic_json<
typename std::remove_const<BasicJsonType>::type>::value,
5641 "iter_impl only accepts (const) basic_json");
5650 using iterator_category = std::bidirectional_iterator_tag;
5653 using value_type =
typename BasicJsonType::value_type;
5655 using difference_type =
typename BasicJsonType::difference_type;
5657 using pointer =
typename std::conditional<std::is_const<BasicJsonType>::value,
5658 typename BasicJsonType::const_pointer,
5659 typename BasicJsonType::pointer>::type;
5662 typename std::conditional<std::is_const<BasicJsonType>::value,
5663 typename BasicJsonType::const_reference,
5664 typename BasicJsonType::reference>::type;
5667 iter_impl() =
default;
5675 explicit iter_impl(pointer
object) noexcept : m_object(
object)
5677 assert(m_object !=
nullptr);
5679 switch (m_object->m_type)
5681 case value_t::object:
5683 m_it.object_iterator =
typename object_t::iterator();
5687 case value_t::array:
5689 m_it.array_iterator =
typename array_t::iterator();
5695 m_it.primitive_iterator = primitive_iterator_t();
5715 iter_impl(
const iter_impl<
typename std::remove_const<BasicJsonType>::type>& other) noexcept
5716 : m_object(other.m_object), m_it(other.m_it) {}
5724 iter_impl& operator=(
const iter_impl<
typename std::remove_const<BasicJsonType>::type>& other) noexcept
5726 m_object = other.m_object;
5736 void set_begin() noexcept
5738 assert(m_object !=
nullptr);
5740 switch (m_object->m_type)
5742 case value_t::object:
5744 m_it.object_iterator = m_object->m_value.object->begin();
5748 case value_t::array:
5750 m_it.array_iterator = m_object->m_value.array->begin();
5757 m_it.primitive_iterator.set_end();
5763 m_it.primitive_iterator.set_begin();
5773 void set_end() noexcept
5775 assert(m_object !=
nullptr);
5777 switch (m_object->m_type)
5779 case value_t::object:
5781 m_it.object_iterator = m_object->m_value.object->end();
5785 case value_t::array:
5787 m_it.array_iterator = m_object->m_value.array->end();
5793 m_it.primitive_iterator.set_end();
5804 reference operator*()
const 5806 assert(m_object !=
nullptr);
5808 switch (m_object->m_type)
5810 case value_t::object:
5812 assert(m_it.object_iterator != m_object->m_value.object->end());
5813 return m_it.object_iterator->second;
5816 case value_t::array:
5818 assert(m_it.array_iterator != m_object->m_value.array->end());
5819 return *m_it.array_iterator;
5823 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
5827 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
5832 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
5841 pointer operator->()
const 5843 assert(m_object !=
nullptr);
5845 switch (m_object->m_type)
5847 case value_t::object:
5849 assert(m_it.object_iterator != m_object->m_value.object->end());
5850 return &(m_it.object_iterator->second);
5853 case value_t::array:
5855 assert(m_it.array_iterator != m_object->m_value.array->end());
5856 return &*m_it.array_iterator;
5861 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
5866 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
5875 iter_impl
const operator++(
int)
5877 auto result = *
this;
5886 iter_impl& operator++()
5888 assert(m_object !=
nullptr);
5890 switch (m_object->m_type)
5892 case value_t::object:
5894 std::advance(m_it.object_iterator, 1);
5898 case value_t::array:
5900 std::advance(m_it.array_iterator, 1);
5906 ++m_it.primitive_iterator;
5918 iter_impl
const operator--(
int)
5920 auto result = *
this;
5929 iter_impl& operator--()
5931 assert(m_object !=
nullptr);
5933 switch (m_object->m_type)
5935 case value_t::object:
5937 std::advance(m_it.object_iterator, -1);
5941 case value_t::array:
5943 std::advance(m_it.array_iterator, -1);
5949 --m_it.primitive_iterator;
5961 bool operator==(
const iter_impl& other)
const 5964 if (JSON_UNLIKELY(m_object != other.m_object))
5966 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
5969 assert(m_object !=
nullptr);
5971 switch (m_object->m_type)
5973 case value_t::object:
5974 return (m_it.object_iterator == other.m_it.object_iterator);
5976 case value_t::array:
5977 return (m_it.array_iterator == other.m_it.array_iterator);
5980 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
5988 bool operator!=(
const iter_impl& other)
const 5990 return not operator==(other);
5997 bool operator<(
const iter_impl& other)
const 6000 if (JSON_UNLIKELY(m_object != other.m_object))
6002 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
6005 assert(m_object !=
nullptr);
6007 switch (m_object->m_type)
6009 case value_t::object:
6010 JSON_THROW(invalid_iterator::create(213,
"cannot compare order of object iterators"));
6012 case value_t::array:
6013 return (m_it.array_iterator < other.m_it.array_iterator);
6016 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
6024 bool operator<=(
const iter_impl& other)
const 6026 return not other.operator < (*this);
6033 bool operator>(
const iter_impl& other)
const 6035 return not operator<=(other);
6042 bool operator>=(
const iter_impl& other)
const 6044 return not operator<(other);
6051 iter_impl& operator+=(difference_type i)
6053 assert(m_object !=
nullptr);
6055 switch (m_object->m_type)
6057 case value_t::object:
6058 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
6060 case value_t::array:
6062 std::advance(m_it.array_iterator, i);
6068 m_it.primitive_iterator += i;
6080 iter_impl& operator-=(difference_type i)
6082 return operator+=(-i);
6089 iter_impl operator+(difference_type i)
const 6091 auto result = *
this;
6100 friend iter_impl operator+(difference_type i,
const iter_impl& it)
6111 iter_impl operator-(difference_type i)
const 6113 auto result = *
this;
6122 difference_type operator-(
const iter_impl& other)
const 6124 assert(m_object !=
nullptr);
6126 switch (m_object->m_type)
6128 case value_t::object:
6129 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
6131 case value_t::array:
6132 return m_it.array_iterator - other.m_it.array_iterator;
6135 return m_it.primitive_iterator - other.m_it.primitive_iterator;
6143 reference operator[](difference_type n)
const 6145 assert(m_object !=
nullptr);
6147 switch (m_object->m_type)
6149 case value_t::object:
6150 JSON_THROW(invalid_iterator::create(208,
"cannot use operator[] for object iterators"));
6152 case value_t::array:
6153 return *std::next(m_it.array_iterator, n);
6156 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
6160 if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
6165 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
6174 const typename object_t::key_type& key()
const 6176 assert(m_object !=
nullptr);
6178 if (JSON_LIKELY(m_object->is_object()))
6180 return m_it.object_iterator->first;
6183 JSON_THROW(invalid_iterator::create(207,
"cannot use key() for non-object iterators"));
6190 reference value()
const 6197 pointer m_object =
nullptr;
6199 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it;
6238 template<
typename Base>
6239 class json_reverse_iterator :
public std::reverse_iterator<Base>
6242 using difference_type = std::ptrdiff_t;
6244 using base_iterator = std::reverse_iterator<Base>;
6246 using reference =
typename Base::reference;
6249 explicit json_reverse_iterator(
const typename base_iterator::iterator_type& it) noexcept
6250 : base_iterator(it) {}
6253 explicit json_reverse_iterator(
const base_iterator& it) noexcept : base_iterator(it) {}
6256 json_reverse_iterator
const operator++(
int)
6258 return static_cast<json_reverse_iterator
>(base_iterator::operator++(1));
6262 json_reverse_iterator& operator++()
6264 return static_cast<json_reverse_iterator&
>(base_iterator::operator++());
6268 json_reverse_iterator
const operator--(
int)
6270 return static_cast<json_reverse_iterator
>(base_iterator::operator--(1));
6274 json_reverse_iterator& operator--()
6276 return static_cast<json_reverse_iterator&
>(base_iterator::operator--());
6280 json_reverse_iterator& operator+=(difference_type i)
6282 return static_cast<json_reverse_iterator&
>(base_iterator::operator+=(i));
6286 json_reverse_iterator operator+(difference_type i)
const 6288 return static_cast<json_reverse_iterator
>(base_iterator::operator+(i));
6292 json_reverse_iterator operator-(difference_type i)
const 6294 return static_cast<json_reverse_iterator
>(base_iterator::operator-(i));
6298 difference_type operator-(
const json_reverse_iterator& other)
const 6300 return base_iterator(*
this) - base_iterator(other);
6304 reference operator[](difference_type n)
const 6306 return *(this->operator+(n));
6310 auto key()
const -> decltype(std::declval<Base>().key())
6312 auto it = --this->base();
6317 reference value()
const 6319 auto it = --this->base();
6320 return it.operator * ();
6329 #include <algorithm> 6343 template<
typename CharType>
struct output_adapter_protocol
6345 virtual void write_character(CharType c) = 0;
6346 virtual void write_characters(
const CharType* s, std::size_t length) = 0;
6347 virtual ~output_adapter_protocol() =
default;
6351 template<
typename CharType>
6352 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
6355 template<
typename CharType>
6356 class output_vector_adapter :
public output_adapter_protocol<CharType>
6359 explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
6363 void write_character(CharType c)
override 6368 void write_characters(
const CharType* s, std::size_t length)
override 6370 std::copy(s, s + length, std::back_inserter(v));
6374 std::vector<CharType>& v;
6378 template<
typename CharType>
6379 class output_stream_adapter :
public output_adapter_protocol<CharType>
6382 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
6386 void write_character(CharType c)
override 6391 void write_characters(
const CharType* s, std::size_t length)
override 6393 stream.write(s, static_cast<std::streamsize>(length));
6397 std::basic_ostream<CharType>& stream;
6401 template<
typename CharType,
typename StringType = std::basic_
string<CharType>>
6402 class output_string_adapter :
public output_adapter_protocol<CharType>
6405 explicit output_string_adapter(StringType& s) noexcept
6409 void write_character(CharType c)
override 6414 void write_characters(
const CharType* s, std::size_t length)
override 6416 str.append(s, length);
6423 template<
typename CharType,
typename StringType = std::basic_
string<CharType>>
6424 class output_adapter
6427 output_adapter(std::vector<CharType>& vec)
6428 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
6430 output_adapter(std::basic_ostream<CharType>& s)
6431 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
6433 output_adapter(StringType& s)
6434 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
6436 operator output_adapter_t<CharType>()
6442 output_adapter_t<CharType> oa =
nullptr;
6450 #include <algorithm> 6487 template<
typename BasicJsonType,
typename SAX = json_sax_dom_parser<BasicJsonType>>
6493 using string_t =
typename BasicJsonType::string_t;
6494 using json_sax_t = SAX;
6502 explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
6504 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
6515 bool sax_parse(
const input_format_t format,
6517 const bool strict =
true)
6520 bool result =
false;
6524 case input_format_t::bson:
6525 result = parse_bson_internal();
6528 case input_format_t::cbor:
6529 result = parse_cbor_internal();
6532 case input_format_t::msgpack:
6533 result = parse_msgpack_internal();
6536 case input_format_t::ubjson:
6537 result = parse_ubjson_internal();
6547 if (result and strict)
6549 if (format == input_format_t::ubjson)
6558 if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
6560 return sax->parse_error(chars_read, get_token_string(),
6561 parse_error::create(110, chars_read, exception_message(format,
"expected end of input; last byte: 0x" + get_token_string(),
"value")));
6575 static constexpr
bool little_endianess(
int num = 1) noexcept
6577 return (*reinterpret_cast<char*>(&num) == 1);
6589 bool parse_bson_internal()
6591 std::int32_t document_size;
6592 get_number<std::int32_t, true>(input_format_t::bson, document_size);
6594 if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
6599 if (JSON_UNLIKELY(not parse_bson_element_list(
false)))
6604 return sax->end_object();
6614 bool get_bson_cstr(
string_t& result)
6616 auto out = std::back_inserter(result);
6620 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson,
"cstring")))
6624 if (current == 0x00)
6628 *out++ =
static_cast<char>(current);
6645 template<
typename NumberType>
6646 bool get_bson_string(
const NumberType len,
string_t& result)
6648 if (JSON_UNLIKELY(len < 1))
6650 auto last_token = get_token_string();
6651 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson,
"string length must be at least 1, is " + std::to_string(len),
"string")));
6654 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) and
get() != std::char_traits<char>::eof();
6667 bool parse_bson_element_internal(
const int element_type,
6668 const std::size_t element_type_parse_position)
6670 switch (element_type)
6675 return get_number<double, true>(input_format_t::bson, number) and sax->number_float(static_cast<number_float_t>(number),
"");
6682 return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
6687 return parse_bson_internal();
6692 return parse_bson_array();
6697 return sax->boolean(
get() != 0);
6708 return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value);
6714 return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value);
6720 (std::snprintf)(cr,
sizeof(cr),
"%.2hhX",
static_cast<unsigned char>(element_type));
6721 return sax->parse_error(element_type_parse_position, std::string(cr), parse_error::create(114, element_type_parse_position,
"Unsupported BSON record type 0x" + std::string(cr)));
6738 bool parse_bson_element_list(
const bool is_array)
6741 while (
int element_type =
get())
6743 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson,
"element list")))
6748 const std::size_t element_type_parse_position = chars_read;
6749 if (JSON_UNLIKELY(not get_bson_cstr(key)))
6756 if (not sax->key(key))
6762 if (JSON_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
6778 bool parse_bson_array()
6780 std::int32_t document_size;
6781 get_number<std::int32_t, true>(input_format_t::bson, document_size);
6783 if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
6788 if (JSON_UNLIKELY(not parse_bson_element_list(
true)))
6793 return sax->end_array();
6807 bool parse_cbor_internal(
const bool get_char =
true)
6809 switch (get_char ?
get() : current)
6812 case std::char_traits<char>::eof():
6813 return unexpect_eof(input_format_t::cbor,
"value");
6840 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
6845 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6851 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6857 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6863 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6891 return sax->number_integer(static_cast<int8_t>(0x20 - 1 - current));
6896 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6902 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6908 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6914 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
6915 - static_cast<number_integer_t>(number));
6950 return get_cbor_string(s) and sax->string(s);
6978 return get_cbor_array(static_cast<std::size_t>(current & 0x1F));
6983 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6989 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6995 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
7001 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
7005 return get_cbor_array(std::size_t(-1));
7032 return get_cbor_object(static_cast<std::size_t>(current & 0x1F));
7037 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
7043 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
7049 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
7055 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
7059 return get_cbor_object(std::size_t(-1));
7062 return sax->boolean(
false);
7065 return sax->boolean(
true);
7072 const int byte1_raw =
get();
7073 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor,
"number")))
7077 const int byte2_raw =
get();
7078 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor,
"number")))
7083 const auto byte1 =
static_cast<unsigned char>(byte1_raw);
7084 const auto byte2 =
static_cast<unsigned char>(byte2_raw);
7094 const int half = (byte1 << 8) + byte2;
7095 const double val = [&half]
7097 const int exp = (half >> 10) & 0x1F;
7098 const int mant = half & 0x3FF;
7099 assert(0 <= exp and exp <= 32);
7100 assert(0 <= mant and mant <= 1024);
7104 return std::ldexp(mant, -24);
7107 ? std::numeric_limits<double>::infinity()
7108 : std::numeric_limits<double>::quiet_NaN();
7110 return std::ldexp(mant + 1024, exp - 25);
7113 return sax->number_float((half & 0x8000) != 0
7114 ? static_cast<number_float_t>(-val)
7115 : static_cast<number_float_t>(val),
"");
7121 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number),
"");
7127 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number),
"");
7132 auto last_token = get_token_string();
7133 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor,
"invalid byte: 0x" + last_token,
"value")));
7149 bool get_cbor_string(
string_t& result)
7151 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor,
"string")))
7184 return get_string(input_format_t::cbor, current & 0x1F, result);
7190 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
7196 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
7202 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
7208 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
7213 while (
get() != 0xFF)
7216 if (not get_cbor_string(chunk))
7220 result.append(chunk);
7227 auto last_token = get_token_string();
7228 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor,
"expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token,
"string")));
7238 bool get_cbor_array(
const std::size_t len)
7240 if (JSON_UNLIKELY(not sax->start_array(len)))
7245 if (len != std::size_t(-1))
7247 for (std::size_t i = 0; i < len; ++i)
7249 if (JSON_UNLIKELY(not parse_cbor_internal()))
7257 while (
get() != 0xFF)
7259 if (JSON_UNLIKELY(not parse_cbor_internal(
false)))
7266 return sax->end_array();
7274 bool get_cbor_object(
const std::size_t len)
7276 if (not JSON_UNLIKELY(sax->start_object(len)))
7282 if (len != std::size_t(-1))
7284 for (std::size_t i = 0; i < len; ++i)
7287 if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
7292 if (JSON_UNLIKELY(not parse_cbor_internal()))
7301 while (
get() != 0xFF)
7303 if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
7308 if (JSON_UNLIKELY(not parse_cbor_internal()))
7316 return sax->end_object();
7326 bool parse_msgpack_internal()
7331 case std::char_traits<char>::eof():
7332 return unexpect_eof(input_format_t::msgpack,
"value");
7463 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
7482 return get_msgpack_object(static_cast<std::size_t>(current & 0x0F));
7501 return get_msgpack_array(static_cast<std::size_t>(current & 0x0F));
7538 return get_msgpack_string(s) and sax->string(s);
7545 return sax->boolean(
false);
7548 return sax->boolean(
true);
7553 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number),
"");
7559 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number),
"");
7565 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7571 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7577 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7583 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7589 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7595 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7601 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7607 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7615 return get_msgpack_string(s) and sax->string(s);
7621 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
7627 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
7633 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
7639 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
7675 return sax->number_integer(static_cast<int8_t>(current));
7679 auto last_token = get_token_string();
7680 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack,
"invalid byte: 0x" + last_token,
"value")));
7695 bool get_msgpack_string(
string_t& result)
7697 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::msgpack,
"string")))
7738 return get_string(input_format_t::msgpack, current & 0x1F, result);
7744 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7750 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7756 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7761 auto last_token = get_token_string();
7762 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack,
"expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token,
"string")));
7771 bool get_msgpack_array(
const std::size_t len)
7773 if (JSON_UNLIKELY(not sax->start_array(len)))
7778 for (std::size_t i = 0; i < len; ++i)
7780 if (JSON_UNLIKELY(not parse_msgpack_internal()))
7786 return sax->end_array();
7793 bool get_msgpack_object(
const std::size_t len)
7795 if (JSON_UNLIKELY(not sax->start_object(len)))
7801 for (std::size_t i = 0; i < len; ++i)
7804 if (JSON_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
7809 if (JSON_UNLIKELY(not parse_msgpack_internal()))
7816 return sax->end_object();
7830 bool parse_ubjson_internal(
const bool get_char =
true)
7832 return get_ubjson_value(get_char ? get_ignore_noop() : current);
7849 bool get_ubjson_string(
string_t& result,
const bool get_char =
true)
7856 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson,
"value")))
7866 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7872 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7878 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7884 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7890 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7894 auto last_token = get_token_string();
7895 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson,
"expected length type specification (U, i, I, l, L); last byte: 0x" + last_token,
"string")));
7903 bool get_ubjson_size_value(std::size_t& result)
7905 switch (get_ignore_noop())
7910 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7914 result =
static_cast<std::size_t
>(number);
7921 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7925 result =
static_cast<std::size_t
>(number);
7932 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7936 result =
static_cast<std::size_t
>(number);
7943 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7947 result =
static_cast<std::size_t
>(number);
7954 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7958 result =
static_cast<std::size_t
>(number);
7964 auto last_token = get_token_string();
7965 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson,
"expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token,
"size")));
7980 bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
7982 result.first = string_t::npos;
7989 result.second =
get();
7990 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson,
"type")))
7996 if (JSON_UNLIKELY(current !=
'#'))
7998 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson,
"value")))
8002 auto last_token = get_token_string();
8003 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson,
"expected '#' after type information; last byte: 0x" + last_token,
"size")));
8006 return get_ubjson_size_value(result.first);
8008 else if (current ==
'#')
8010 return get_ubjson_size_value(result.first);
8019 bool get_ubjson_value(
const int prefix)
8023 case std::char_traits<char>::eof():
8024 return unexpect_eof(input_format_t::ubjson,
"value");
8027 return sax->boolean(
true);
8029 return sax->boolean(
false);
8037 return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
8043 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
8049 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
8055 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
8061 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
8067 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number),
"");
8073 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number),
"");
8079 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson,
"char")))
8083 if (JSON_UNLIKELY(current > 127))
8085 auto last_token = get_token_string();
8086 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson,
"byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token,
"char")));
8088 string_t s(1, static_cast<char>(current));
8089 return sax->string(s);
8095 return get_ubjson_string(s) and sax->string(s);
8099 return get_ubjson_array();
8102 return get_ubjson_object();
8106 auto last_token = get_token_string();
8107 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson,
"invalid byte: 0x" + last_token,
"value")));
8115 bool get_ubjson_array()
8117 std::pair<std::size_t, int> size_and_type;
8118 if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
8123 if (size_and_type.first != string_t::npos)
8125 if (JSON_UNLIKELY(not sax->start_array(size_and_type.first)))
8130 if (size_and_type.second != 0)
8132 if (size_and_type.second !=
'N')
8134 for (std::size_t i = 0; i < size_and_type.first; ++i)
8136 if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
8145 for (std::size_t i = 0; i < size_and_type.first; ++i)
8147 if (JSON_UNLIKELY(not parse_ubjson_internal()))
8156 if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
8161 while (current !=
']')
8163 if (JSON_UNLIKELY(not parse_ubjson_internal(
false)))
8171 return sax->end_array();
8177 bool get_ubjson_object()
8179 std::pair<std::size_t, int> size_and_type;
8180 if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
8186 if (size_and_type.first != string_t::npos)
8188 if (JSON_UNLIKELY(not sax->start_object(size_and_type.first)))
8193 if (size_and_type.second != 0)
8195 for (std::size_t i = 0; i < size_and_type.first; ++i)
8197 if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
8201 if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
8210 for (std::size_t i = 0; i < size_and_type.first; ++i)
8212 if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
8216 if (JSON_UNLIKELY(not parse_ubjson_internal()))
8226 if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
8231 while (current !=
'}')
8233 if (JSON_UNLIKELY(not get_ubjson_string(key,
false) or not sax->key(key)))
8237 if (JSON_UNLIKELY(not parse_ubjson_internal()))
8246 return sax->end_object();
8265 return (current = ia->get_character());
8271 int get_ignore_noop()
8277 while (current ==
'N');
8295 template<
typename NumberType,
bool InputIsLittleEndian = false>
8296 bool get_number(
const input_format_t format, NumberType& result)
8299 std::array<uint8_t, sizeof(NumberType)> vec;
8300 for (std::size_t i = 0; i <
sizeof(NumberType); ++i)
8303 if (JSON_UNLIKELY(not unexpect_eof(format,
"number")))
8309 if (is_little_endian && !InputIsLittleEndian)
8311 vec[
sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
8315 vec[i] =
static_cast<uint8_t
>(current);
8320 std::memcpy(&result, vec.data(),
sizeof(NumberType));
8338 template<
typename NumberType>
8339 bool get_string(
const input_format_t format,
8340 const NumberType len,
8343 bool success =
true;
8344 std::generate_n(std::back_inserter(result), len, [
this, &success, &format]()
8347 if (JSON_UNLIKELY(not unexpect_eof(format,
"string")))
8351 return static_cast<char>(current);
8361 bool unexpect_eof(
const input_format_t format,
const char* context)
const 8363 if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
8365 return sax->parse_error(chars_read,
"<end of file>",
8366 parse_error::create(110, chars_read, exception_message(format,
"unexpected end of input", context)));
8374 std::string get_token_string()
const 8377 (std::snprintf)(cr, 3,
"%.2hhX", static_cast<unsigned char>(current));
8378 return std::string{cr};
8387 std::string exception_message(
const input_format_t format,
8388 const std::string& detail,
8389 const std::string& context)
const 8391 std::string error_msg =
"syntax error while parsing ";
8395 case input_format_t::cbor:
8396 error_msg +=
"CBOR";
8399 case input_format_t::msgpack:
8400 error_msg +=
"MessagePack";
8403 case input_format_t::ubjson:
8404 error_msg +=
"UBJSON";
8407 case input_format_t::bson:
8408 error_msg +=
"BSON";
8417 return error_msg +
" " + context +
": " + detail;
8422 input_adapter_t ia =
nullptr;
8425 int current = std::char_traits<char>::eof();
8428 std::size_t chars_read = 0;
8431 const bool is_little_endian = little_endianess();
8434 json_sax_t* sax =
nullptr;
8442 #include <algorithm> 8464 template<
typename BasicJsonType,
typename CharType>
8467 using string_t =
typename BasicJsonType::string_t;
8475 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
8484 void write_bson(
const BasicJsonType& j)
8488 case value_t::object:
8490 write_bson_object(*j.m_value.object);
8496 JSON_THROW(type_error::create(317,
"to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
8504 void write_cbor(
const BasicJsonType& j)
8510 oa->write_character(to_char_type(0xF6));
8514 case value_t::boolean:
8516 oa->write_character(j.m_value.boolean
8517 ? to_char_type(0xF5)
8518 : to_char_type(0xF4));
8522 case value_t::number_integer:
8524 if (j.m_value.number_integer >= 0)
8529 if (j.m_value.number_integer <= 0x17)
8531 write_number(static_cast<uint8_t>(j.m_value.number_integer));
8533 else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
8535 oa->write_character(to_char_type(0x18));
8536 write_number(static_cast<uint8_t>(j.m_value.number_integer));
8538 else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
8540 oa->write_character(to_char_type(0x19));
8541 write_number(static_cast<uint16_t>(j.m_value.number_integer));
8543 else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
8545 oa->write_character(to_char_type(0x1A));
8546 write_number(static_cast<uint32_t>(j.m_value.number_integer));
8550 oa->write_character(to_char_type(0x1B));
8551 write_number(static_cast<uint64_t>(j.m_value.number_integer));
8558 const auto positive_number = -1 - j.m_value.number_integer;
8559 if (j.m_value.number_integer >= -24)
8561 write_number(static_cast<uint8_t>(0x20 + positive_number));
8563 else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
8565 oa->write_character(to_char_type(0x38));
8566 write_number(static_cast<uint8_t>(positive_number));
8568 else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
8570 oa->write_character(to_char_type(0x39));
8571 write_number(static_cast<uint16_t>(positive_number));
8573 else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
8575 oa->write_character(to_char_type(0x3A));
8576 write_number(static_cast<uint32_t>(positive_number));
8580 oa->write_character(to_char_type(0x3B));
8581 write_number(static_cast<uint64_t>(positive_number));
8587 case value_t::number_unsigned:
8589 if (j.m_value.number_unsigned <= 0x17)
8591 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
8593 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
8595 oa->write_character(to_char_type(0x18));
8596 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
8598 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
8600 oa->write_character(to_char_type(0x19));
8601 write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
8603 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
8605 oa->write_character(to_char_type(0x1A));
8606 write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
8610 oa->write_character(to_char_type(0x1B));
8611 write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
8616 case value_t::number_float:
8618 oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
8619 write_number(j.m_value.number_float);
8623 case value_t::string:
8626 const auto N = j.m_value.string->size();
8629 write_number(static_cast<uint8_t>(0x60 + N));
8631 else if (N <= (std::numeric_limits<uint8_t>::max)())
8633 oa->write_character(to_char_type(0x78));
8634 write_number(static_cast<uint8_t>(N));
8636 else if (N <= (std::numeric_limits<uint16_t>::max)())
8638 oa->write_character(to_char_type(0x79));
8639 write_number(static_cast<uint16_t>(N));
8641 else if (N <= (std::numeric_limits<uint32_t>::max)())
8643 oa->write_character(to_char_type(0x7A));
8644 write_number(static_cast<uint32_t>(N));
8647 else if (N <= (std::numeric_limits<uint64_t>::max)())
8649 oa->write_character(to_char_type(0x7B));
8650 write_number(static_cast<uint64_t>(N));
8655 oa->write_characters(
8656 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
8657 j.m_value.string->size());
8661 case value_t::array:
8664 const auto N = j.m_value.array->size();
8667 write_number(static_cast<uint8_t>(0x80 + N));
8669 else if (N <= (std::numeric_limits<uint8_t>::max)())
8671 oa->write_character(to_char_type(0x98));
8672 write_number(static_cast<uint8_t>(N));
8674 else if (N <= (std::numeric_limits<uint16_t>::max)())
8676 oa->write_character(to_char_type(0x99));
8677 write_number(static_cast<uint16_t>(N));
8679 else if (N <= (std::numeric_limits<uint32_t>::max)())
8681 oa->write_character(to_char_type(0x9A));
8682 write_number(static_cast<uint32_t>(N));
8685 else if (N <= (std::numeric_limits<uint64_t>::max)())
8687 oa->write_character(to_char_type(0x9B));
8688 write_number(static_cast<uint64_t>(N));
8693 for (
const auto& el : *j.m_value.array)
8700 case value_t::object:
8703 const auto N = j.m_value.object->size();
8706 write_number(static_cast<uint8_t>(0xA0 + N));
8708 else if (N <= (std::numeric_limits<uint8_t>::max)())
8710 oa->write_character(to_char_type(0xB8));
8711 write_number(static_cast<uint8_t>(N));
8713 else if (N <= (std::numeric_limits<uint16_t>::max)())
8715 oa->write_character(to_char_type(0xB9));
8716 write_number(static_cast<uint16_t>(N));
8718 else if (N <= (std::numeric_limits<uint32_t>::max)())
8720 oa->write_character(to_char_type(0xBA));
8721 write_number(static_cast<uint32_t>(N));
8724 else if (N <= (std::numeric_limits<uint64_t>::max)())
8726 oa->write_character(to_char_type(0xBB));
8727 write_number(static_cast<uint64_t>(N));
8732 for (
const auto& el : *j.m_value.object)
8734 write_cbor(el.first);
8735 write_cbor(el.second);
8748 void write_msgpack(
const BasicJsonType& j)
8754 oa->write_character(to_char_type(0xC0));
8758 case value_t::boolean:
8760 oa->write_character(j.m_value.boolean
8761 ? to_char_type(0xC3)
8762 : to_char_type(0xC2));
8766 case value_t::number_integer:
8768 if (j.m_value.number_integer >= 0)
8773 if (j.m_value.number_unsigned < 128)
8776 write_number(static_cast<uint8_t>(j.m_value.number_integer));
8778 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
8781 oa->write_character(to_char_type(0xCC));
8782 write_number(static_cast<uint8_t>(j.m_value.number_integer));
8784 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
8787 oa->write_character(to_char_type(0xCD));
8788 write_number(static_cast<uint16_t>(j.m_value.number_integer));
8790 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
8793 oa->write_character(to_char_type(0xCE));
8794 write_number(static_cast<uint32_t>(j.m_value.number_integer));
8796 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
8799 oa->write_character(to_char_type(0xCF));
8800 write_number(static_cast<uint64_t>(j.m_value.number_integer));
8805 if (j.m_value.number_integer >= -32)
8808 write_number(static_cast<int8_t>(j.m_value.number_integer));
8810 else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and
8811 j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
8814 oa->write_character(to_char_type(0xD0));
8815 write_number(static_cast<int8_t>(j.m_value.number_integer));
8817 else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and
8818 j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
8821 oa->write_character(to_char_type(0xD1));
8822 write_number(static_cast<int16_t>(j.m_value.number_integer));
8824 else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and
8825 j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
8828 oa->write_character(to_char_type(0xD2));
8829 write_number(static_cast<int32_t>(j.m_value.number_integer));
8831 else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and
8832 j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
8835 oa->write_character(to_char_type(0xD3));
8836 write_number(static_cast<int64_t>(j.m_value.number_integer));
8842 case value_t::number_unsigned:
8844 if (j.m_value.number_unsigned < 128)
8847 write_number(static_cast<uint8_t>(j.m_value.number_integer));
8849 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
8852 oa->write_character(to_char_type(0xCC));
8853 write_number(static_cast<uint8_t>(j.m_value.number_integer));
8855 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
8858 oa->write_character(to_char_type(0xCD));
8859 write_number(static_cast<uint16_t>(j.m_value.number_integer));
8861 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
8864 oa->write_character(to_char_type(0xCE));
8865 write_number(static_cast<uint32_t>(j.m_value.number_integer));
8867 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
8870 oa->write_character(to_char_type(0xCF));
8871 write_number(static_cast<uint64_t>(j.m_value.number_integer));
8876 case value_t::number_float:
8878 oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
8879 write_number(j.m_value.number_float);
8883 case value_t::string:
8886 const auto N = j.m_value.string->size();
8890 write_number(static_cast<uint8_t>(0xA0 | N));
8892 else if (N <= (std::numeric_limits<uint8_t>::max)())
8895 oa->write_character(to_char_type(0xD9));
8896 write_number(static_cast<uint8_t>(N));
8898 else if (N <= (std::numeric_limits<uint16_t>::max)())
8901 oa->write_character(to_char_type(0xDA));
8902 write_number(static_cast<uint16_t>(N));
8904 else if (N <= (std::numeric_limits<uint32_t>::max)())
8907 oa->write_character(to_char_type(0xDB));
8908 write_number(static_cast<uint32_t>(N));
8912 oa->write_characters(
8913 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
8914 j.m_value.string->size());
8918 case value_t::array:
8921 const auto N = j.m_value.array->size();
8925 write_number(static_cast<uint8_t>(0x90 | N));
8927 else if (N <= (std::numeric_limits<uint16_t>::max)())
8930 oa->write_character(to_char_type(0xDC));
8931 write_number(static_cast<uint16_t>(N));
8933 else if (N <= (std::numeric_limits<uint32_t>::max)())
8936 oa->write_character(to_char_type(0xDD));
8937 write_number(static_cast<uint32_t>(N));
8941 for (
const auto& el : *j.m_value.array)
8948 case value_t::object:
8951 const auto N = j.m_value.object->size();
8955 write_number(static_cast<uint8_t>(0x80 | (N & 0xF)));
8957 else if (N <= (std::numeric_limits<uint16_t>::max)())
8960 oa->write_character(to_char_type(0xDE));
8961 write_number(static_cast<uint16_t>(N));
8963 else if (N <= (std::numeric_limits<uint32_t>::max)())
8966 oa->write_character(to_char_type(0xDF));
8967 write_number(static_cast<uint32_t>(N));
8971 for (
const auto& el : *j.m_value.object)
8973 write_msgpack(el.first);
8974 write_msgpack(el.second);
8990 void write_ubjson(
const BasicJsonType& j,
const bool use_count,
8991 const bool use_type,
const bool add_prefix =
true)
8999 oa->write_character(to_char_type(
'Z'));
9004 case value_t::boolean:
9008 oa->write_character(j.m_value.boolean
9010 : to_char_type(
'F'));
9015 case value_t::number_integer:
9017 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
9021 case value_t::number_unsigned:
9023 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
9027 case value_t::number_float:
9029 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
9033 case value_t::string:
9037 oa->write_character(to_char_type(
'S'));
9039 write_number_with_ubjson_prefix(j.m_value.string->size(),
true);
9040 oa->write_characters(
9041 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
9042 j.m_value.string->size());
9046 case value_t::array:
9050 oa->write_character(to_char_type(
'['));
9053 bool prefix_required =
true;
9054 if (use_type and not j.m_value.array->empty())
9057 const CharType first_prefix = ubjson_prefix(j.front());
9058 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
9059 [
this, first_prefix](
const BasicJsonType & v)
9061 return ubjson_prefix(v) == first_prefix;
9066 prefix_required =
false;
9067 oa->write_character(to_char_type(
'$'));
9068 oa->write_character(first_prefix);
9074 oa->write_character(to_char_type(
'#'));
9075 write_number_with_ubjson_prefix(j.m_value.array->size(),
true);
9078 for (
const auto& el : *j.m_value.array)
9080 write_ubjson(el, use_count, use_type, prefix_required);
9085 oa->write_character(to_char_type(
']'));
9091 case value_t::object:
9095 oa->write_character(to_char_type(
'{'));
9098 bool prefix_required =
true;
9099 if (use_type and not j.m_value.object->empty())
9102 const CharType first_prefix = ubjson_prefix(j.front());
9103 const bool same_prefix = std::all_of(j.begin(), j.end(),
9104 [
this, first_prefix](
const BasicJsonType & v)
9106 return ubjson_prefix(v) == first_prefix;
9111 prefix_required =
false;
9112 oa->write_character(to_char_type(
'$'));
9113 oa->write_character(first_prefix);
9119 oa->write_character(to_char_type(
'#'));
9120 write_number_with_ubjson_prefix(j.m_value.object->size(),
true);
9123 for (
const auto& el : *j.m_value.object)
9125 write_number_with_ubjson_prefix(el.first.size(),
true);
9126 oa->write_characters(
9127 reinterpret_cast<const CharType*>(el.first.c_str()),
9129 write_ubjson(el.second, use_count, use_type, prefix_required);
9134 oa->write_character(to_char_type(
'}'));
9154 static std::size_t calc_bson_entry_header_size(
const string_t& name)
9156 const auto it = name.find(static_cast<typename string_t::value_type>(0));
9157 if (JSON_UNLIKELY(it != BasicJsonType::string_t::npos))
9159 JSON_THROW(out_of_range::create(409,
9160 "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) +
")"));
9163 return 1ul + name.size() + 1u;
9169 void write_bson_entry_header(
const string_t& name,
9170 const std::uint8_t element_type)
9172 oa->write_character(to_char_type(element_type));
9173 oa->write_characters(
9174 reinterpret_cast<const CharType*>(name.c_str()),
9181 void write_bson_boolean(
const string_t& name,
9184 write_bson_entry_header(name, 0x08);
9185 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
9191 void write_bson_double(
const string_t& name,
9194 write_bson_entry_header(name, 0x01);
9195 write_number<double, true>(value);
9201 static std::size_t calc_bson_string_size(
const string_t& value)
9203 return sizeof(std::int32_t) + value.size() + 1ul;
9209 void write_bson_string(
const string_t& name,
9212 write_bson_entry_header(name, 0x02);
9214 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(value.size() + 1ul));
9215 oa->write_characters(
9216 reinterpret_cast<const CharType*>(value.c_str()),
9223 void write_bson_null(
const string_t& name)
9225 write_bson_entry_header(name, 0x0A);
9231 static std::size_t calc_bson_integer_size(
const std::int64_t value)
9233 if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)())
9235 return sizeof(std::int32_t);
9239 return sizeof(std::int64_t);
9246 void write_bson_integer(
const string_t& name,
9247 const std::int64_t value)
9249 if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)())
9251 write_bson_entry_header(name, 0x10);
9252 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(value));
9256 write_bson_entry_header(name, 0x12);
9257 write_number<std::int64_t, true>(
static_cast<std::int64_t
>(value));
9264 static constexpr std::size_t calc_bson_unsigned_size(
const std::uint64_t value) noexcept
9266 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
9267 ?
sizeof(std::int32_t)
9268 :
sizeof(std::int64_t);
9274 void write_bson_unsigned(
const string_t& name,
9275 const std::uint64_t value)
9277 if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
9279 write_bson_entry_header(name, 0x10 );
9280 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(value));
9282 else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
9284 write_bson_entry_header(name, 0x12 );
9285 write_number<std::int64_t, true>(
static_cast<std::int64_t
>(value));
9289 JSON_THROW(out_of_range::create(407,
"integer number " + std::to_string(value) +
" cannot be represented by BSON as it does not fit int64"));
9296 void write_bson_object_entry(
const string_t& name,
9297 const typename BasicJsonType::object_t& value)
9299 write_bson_entry_header(name, 0x03);
9300 write_bson_object(value);
9306 static std::size_t calc_bson_array_size(
const typename BasicJsonType::array_t& value)
9308 std::size_t embedded_document_size = 0ul;
9309 std::size_t array_index = 0ul;
9311 for (
const auto& el : value)
9313 embedded_document_size += calc_bson_element_size(std::to_string(array_index++), el);
9316 return sizeof(std::int32_t) + embedded_document_size + 1ul;
9322 void write_bson_array(
const string_t& name,
9323 const typename BasicJsonType::array_t& value)
9325 write_bson_entry_header(name, 0x04);
9326 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(calc_bson_array_size(value)));
9328 std::size_t array_index = 0ul;
9330 for (
const auto& el : value)
9332 write_bson_element(std::to_string(array_index++), el);
9335 oa->write_character(to_char_type(0x00));
9342 static std::size_t calc_bson_element_size(
const string_t& name,
9343 const BasicJsonType& j)
9345 const auto header_size = calc_bson_entry_header_size(name);
9348 case value_t::object:
9349 return header_size + calc_bson_object_size(*j.m_value.object);
9351 case value_t::array:
9352 return header_size + calc_bson_array_size(*j.m_value.array);
9354 case value_t::boolean:
9355 return header_size + 1ul;
9357 case value_t::number_float:
9358 return header_size + 8ul;
9360 case value_t::number_integer:
9361 return header_size + calc_bson_integer_size(j.m_value.number_integer);
9363 case value_t::number_unsigned:
9364 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
9366 case value_t::string:
9367 return header_size + calc_bson_string_size(*j.m_value.string);
9370 return header_size + 0ul;
9387 void write_bson_element(
const string_t& name,
9388 const BasicJsonType& j)
9392 case value_t::object:
9393 return write_bson_object_entry(name, *j.m_value.object);
9395 case value_t::array:
9396 return write_bson_array(name, *j.m_value.array);
9398 case value_t::boolean:
9399 return write_bson_boolean(name, j.m_value.boolean);
9401 case value_t::number_float:
9402 return write_bson_double(name, j.m_value.number_float);
9404 case value_t::number_integer:
9405 return write_bson_integer(name, j.m_value.number_integer);
9407 case value_t::number_unsigned:
9408 return write_bson_unsigned(name, j.m_value.number_unsigned);
9410 case value_t::string:
9411 return write_bson_string(name, *j.m_value.string);
9414 return write_bson_null(name);
9430 static std::size_t calc_bson_object_size(
const typename BasicJsonType::object_t& value)
9432 std::size_t document_size = std::accumulate(value.begin(), value.end(), 0ul,
9433 [](
size_t result,
const typename BasicJsonType::object_t::value_type & el)
9435 return result += calc_bson_element_size(el.first, el.second);
9438 return sizeof(std::int32_t) + document_size + 1ul;
9445 void write_bson_object(
const typename BasicJsonType::object_t& value)
9447 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(calc_bson_object_size(value)));
9449 for (
const auto& el : value)
9451 write_bson_element(el.first, el.second);
9454 oa->write_character(to_char_type(0x00));
9461 static constexpr CharType get_cbor_float_prefix(
float )
9463 return to_char_type(0xFA);
9466 static constexpr CharType get_cbor_float_prefix(
double )
9468 return to_char_type(0xFB);
9475 static constexpr CharType get_msgpack_float_prefix(
float )
9477 return to_char_type(0xCA);
9480 static constexpr CharType get_msgpack_float_prefix(
double )
9482 return to_char_type(0xCB);
9490 template<
typename NumberType,
typename std::enable_if<
9491 std::is_floating_point<NumberType>::value,
int>::type = 0>
9492 void write_number_with_ubjson_prefix(
const NumberType n,
9493 const bool add_prefix)
9497 oa->write_character(get_ubjson_float_prefix(n));
9503 template<
typename NumberType,
typename std::enable_if<
9504 std::is_unsigned<NumberType>::value,
int>::type = 0>
9505 void write_number_with_ubjson_prefix(
const NumberType n,
9506 const bool add_prefix)
9508 if (n <= static_cast<uint64_t>((std::numeric_limits<int8_t>::max)()))
9512 oa->write_character(to_char_type(
'i'));
9514 write_number(static_cast<uint8_t>(n));
9516 else if (n <= (std::numeric_limits<uint8_t>::max)())
9520 oa->write_character(to_char_type(
'U'));
9522 write_number(static_cast<uint8_t>(n));
9524 else if (n <= static_cast<uint64_t>((std::numeric_limits<int16_t>::max)()))
9528 oa->write_character(to_char_type(
'I'));
9530 write_number(static_cast<int16_t>(n));
9532 else if (n <= static_cast<uint64_t>((std::numeric_limits<int32_t>::max)()))
9536 oa->write_character(to_char_type(
'l'));
9538 write_number(static_cast<int32_t>(n));
9540 else if (n <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)()))
9544 oa->write_character(to_char_type(
'L'));
9546 write_number(static_cast<int64_t>(n));
9550 JSON_THROW(out_of_range::create(407,
"integer number " + std::to_string(n) +
" cannot be represented by UBJSON as it does not fit int64"));
9555 template<
typename NumberType,
typename std::enable_if<
9556 std::is_signed<NumberType>::value and
9557 not std::is_floating_point<NumberType>::value,
int>::type = 0>
9558 void write_number_with_ubjson_prefix(
const NumberType n,
9559 const bool add_prefix)
9561 if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)())
9565 oa->write_character(to_char_type(
'i'));
9567 write_number(static_cast<int8_t>(n));
9569 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)()))
9573 oa->write_character(to_char_type(
'U'));
9575 write_number(static_cast<uint8_t>(n));
9577 else if ((std::numeric_limits<int16_t>::min)() <= n and n <= (std::numeric_limits<int16_t>::max)())
9581 oa->write_character(to_char_type(
'I'));
9583 write_number(static_cast<int16_t>(n));
9585 else if ((std::numeric_limits<int32_t>::min)() <= n and n <= (std::numeric_limits<int32_t>::max)())
9589 oa->write_character(to_char_type(
'l'));
9591 write_number(static_cast<int32_t>(n));
9593 else if ((std::numeric_limits<int64_t>::min)() <= n and n <= (std::numeric_limits<int64_t>::max)())
9597 oa->write_character(to_char_type(
'L'));
9599 write_number(static_cast<int64_t>(n));
9604 JSON_THROW(out_of_range::create(407,
"integer number " + std::to_string(n) +
" cannot be represented by UBJSON as it does not fit int64"));
9618 CharType ubjson_prefix(
const BasicJsonType& j)
const noexcept
9625 case value_t::boolean:
9626 return j.m_value.boolean ?
'T' :
'F';
9628 case value_t::number_integer:
9630 if ((std::numeric_limits<int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
9634 if ((std::numeric_limits<uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
9638 if ((std::numeric_limits<int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
9642 if ((std::numeric_limits<int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
9650 case value_t::number_unsigned:
9652 if (j.m_value.number_unsigned <= (std::numeric_limits<int8_t>::max)())
9656 if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
9660 if (j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max)())
9664 if (j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max)())
9672 case value_t::number_float:
9673 return get_ubjson_float_prefix(j.m_value.number_float);
9675 case value_t::string:
9678 case value_t::array:
9681 case value_t::object:
9689 static constexpr CharType get_ubjson_float_prefix(
float )
9694 static constexpr CharType get_ubjson_float_prefix(
double )
9714 template<
typename NumberType,
bool OutputIsLittleEndian = false>
9715 void write_number(
const NumberType n)
9718 std::array<CharType, sizeof(NumberType)> vec;
9719 std::memcpy(vec.data(), &n,
sizeof(NumberType));
9722 if (is_little_endian and not OutputIsLittleEndian)
9725 std::reverse(vec.begin(), vec.end());
9728 oa->write_characters(vec.data(),
sizeof(NumberType));
9736 template <
typename C = CharType,
9737 enable_if_t < std::is_signed<C>::value and std::is_signed<char>::value > * =
nullptr >
9738 static constexpr CharType to_char_type(std::uint8_t x) noexcept
9740 return *
reinterpret_cast<char*
>(&x);
9743 template <
typename C = CharType,
9744 enable_if_t < std::is_signed<C>::value and std::is_unsigned<char>::value > * =
nullptr >
9745 static CharType to_char_type(std::uint8_t x) noexcept
9747 static_assert(
sizeof(std::uint8_t) ==
sizeof(CharType),
"size of CharType must be equal to std::uint8_t");
9748 static_assert(std::is_pod<CharType>::value,
"CharType must be POD");
9750 std::memcpy(&result, &x,
sizeof(x));
9754 template<
typename C = CharType,
9755 enable_if_t<std::is_unsigned<C>::value>* =
nullptr>
9756 static constexpr CharType to_char_type(std::uint8_t x) noexcept
9761 template <
typename InputCharType,
typename C = CharType,
9763 std::is_signed<C>::value and
9764 std::is_signed<char>::value and
9765 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
9767 static constexpr CharType to_char_type(InputCharType x) noexcept
9774 const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
9777 output_adapter_t<CharType> oa =
nullptr;
9785 #include <algorithm> 9796 #include <type_traits> 9836 template <
typename Target,
typename Source>
9837 Target reinterpret_bits(
const Source source)
9839 static_assert(
sizeof(Target) ==
sizeof(Source),
"size mismatch");
9842 std::memcpy(&target, &source,
sizeof(Source));
9848 static constexpr
int kPrecision = 64;
9853 constexpr diyfp(uint64_t f_,
int e_) noexcept : f(f_), e(e_) {}
9859 static diyfp sub(
const diyfp& x,
const diyfp& y) noexcept
9864 return {x.f - y.f, x.e};
9871 static diyfp mul(
const diyfp& x,
const diyfp& y) noexcept
9873 static_assert(kPrecision == 64,
"internal error");
9898 const uint64_t u_lo = x.f & 0xFFFFFFFF;
9899 const uint64_t u_hi = x.f >> 32;
9900 const uint64_t v_lo = y.f & 0xFFFFFFFF;
9901 const uint64_t v_hi = y.f >> 32;
9903 const uint64_t p0 = u_lo * v_lo;
9904 const uint64_t p1 = u_lo * v_hi;
9905 const uint64_t p2 = u_hi * v_lo;
9906 const uint64_t p3 = u_hi * v_hi;
9908 const uint64_t p0_hi = p0 >> 32;
9909 const uint64_t p1_lo = p1 & 0xFFFFFFFF;
9910 const uint64_t p1_hi = p1 >> 32;
9911 const uint64_t p2_lo = p2 & 0xFFFFFFFF;
9912 const uint64_t p2_hi = p2 >> 32;
9914 uint64_t Q = p0_hi + p1_lo + p2_lo;
9925 Q += uint64_t{1} << (64 - 32 - 1);
9927 const uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32);
9929 return {h, x.e + y.e + 64};
9936 static diyfp normalize(diyfp x) noexcept
9940 while ((x.f >> 63) == 0)
9953 static diyfp normalize_to(
const diyfp& x,
const int target_exponent) noexcept
9955 const int delta = x.e - target_exponent;
9958 assert(((x.f << delta) >> delta) == x.f);
9960 return {x.f << delta, target_exponent};
9977 template <
typename FloatType>
9978 boundaries compute_boundaries(FloatType value)
9980 assert(std::isfinite(value));
9990 static_assert(std::numeric_limits<FloatType>::is_iec559,
9991 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
9993 constexpr
int kPrecision = std::numeric_limits<FloatType>::digits;
9994 constexpr
int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
9995 constexpr
int kMinExp = 1 - kBias;
9996 constexpr uint64_t kHiddenBit = uint64_t{1} << (kPrecision - 1);
9998 using bits_type =
typename std::conditional< kPrecision == 24, uint32_t, uint64_t >::type;
10000 const uint64_t bits = reinterpret_bits<bits_type>(value);
10001 const uint64_t E = bits >> (kPrecision - 1);
10002 const uint64_t F = bits & (kHiddenBit - 1);
10004 const bool is_denormal = (E == 0);
10005 const diyfp v = is_denormal
10006 ? diyfp(F, kMinExp)
10007 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
10030 const bool lower_boundary_is_closer = (F == 0 and E > 1);
10031 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
10032 const diyfp m_minus = lower_boundary_is_closer
10033 ? diyfp(4 * v.f - 1, v.e - 2)
10034 : diyfp(2 * v.f - 1, v.e - 1);
10037 const diyfp w_plus = diyfp::normalize(m_plus);
10040 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
10042 return {diyfp::normalize(v), w_minus, w_plus};
10100 constexpr
int kAlpha = -60;
10101 constexpr
int kGamma = -32;
10103 struct cached_power
10117 inline cached_power get_cached_power_for_binary_exponent(
int e)
10169 constexpr
int kCachedPowersSize = 79;
10170 constexpr
int kCachedPowersMinDecExp = -300;
10171 constexpr
int kCachedPowersDecStep = 8;
10173 static constexpr cached_power kCachedPowers[] =
10175 { 0xAB70FE17C79AC6CA, -1060, -300 },
10176 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
10177 { 0xBE5691EF416BD60C, -1007, -284 },
10178 { 0x8DD01FAD907FFC3C, -980, -276 },
10179 { 0xD3515C2831559A83, -954, -268 },
10180 { 0x9D71AC8FADA6C9B5, -927, -260 },
10181 { 0xEA9C227723EE8BCB, -901, -252 },
10182 { 0xAECC49914078536D, -874, -244 },
10183 { 0x823C12795DB6CE57, -847, -236 },
10184 { 0xC21094364DFB5637, -821, -228 },
10185 { 0x9096EA6F3848984F, -794, -220 },
10186 { 0xD77485CB25823AC7, -768, -212 },
10187 { 0xA086CFCD97BF97F4, -741, -204 },
10188 { 0xEF340A98172AACE5, -715, -196 },
10189 { 0xB23867FB2A35B28E, -688, -188 },
10190 { 0x84C8D4DFD2C63F3B, -661, -180 },
10191 { 0xC5DD44271AD3CDBA, -635, -172 },
10192 { 0x936B9FCEBB25C996, -608, -164 },
10193 { 0xDBAC6C247D62A584, -582, -156 },
10194 { 0xA3AB66580D5FDAF6, -555, -148 },
10195 { 0xF3E2F893DEC3F126, -529, -140 },
10196 { 0xB5B5ADA8AAFF80B8, -502, -132 },
10197 { 0x87625F056C7C4A8B, -475, -124 },
10198 { 0xC9BCFF6034C13053, -449, -116 },
10199 { 0x964E858C91BA2655, -422, -108 },
10200 { 0xDFF9772470297EBD, -396, -100 },
10201 { 0xA6DFBD9FB8E5B88F, -369, -92 },
10202 { 0xF8A95FCF88747D94, -343, -84 },
10203 { 0xB94470938FA89BCF, -316, -76 },
10204 { 0x8A08F0F8BF0F156B, -289, -68 },
10205 { 0xCDB02555653131B6, -263, -60 },
10206 { 0x993FE2C6D07B7FAC, -236, -52 },
10207 { 0xE45C10C42A2B3B06, -210, -44 },
10208 { 0xAA242499697392D3, -183, -36 },
10209 { 0xFD87B5F28300CA0E, -157, -28 },
10210 { 0xBCE5086492111AEB, -130, -20 },
10211 { 0x8CBCCC096F5088CC, -103, -12 },
10212 { 0xD1B71758E219652C, -77, -4 },
10213 { 0x9C40000000000000, -50, 4 },
10214 { 0xE8D4A51000000000, -24, 12 },
10215 { 0xAD78EBC5AC620000, 3, 20 },
10216 { 0x813F3978F8940984, 30, 28 },
10217 { 0xC097CE7BC90715B3, 56, 36 },
10218 { 0x8F7E32CE7BEA5C70, 83, 44 },
10219 { 0xD5D238A4ABE98068, 109, 52 },
10220 { 0x9F4F2726179A2245, 136, 60 },
10221 { 0xED63A231D4C4FB27, 162, 68 },
10222 { 0xB0DE65388CC8ADA8, 189, 76 },
10223 { 0x83C7088E1AAB65DB, 216, 84 },
10224 { 0xC45D1DF942711D9A, 242, 92 },
10225 { 0x924D692CA61BE758, 269, 100 },
10226 { 0xDA01EE641A708DEA, 295, 108 },
10227 { 0xA26DA3999AEF774A, 322, 116 },
10228 { 0xF209787BB47D6B85, 348, 124 },
10229 { 0xB454E4A179DD1877, 375, 132 },
10230 { 0x865B86925B9BC5C2, 402, 140 },
10231 { 0xC83553C5C8965D3D, 428, 148 },
10232 { 0x952AB45CFA97A0B3, 455, 156 },
10233 { 0xDE469FBD99A05FE3, 481, 164 },
10234 { 0xA59BC234DB398C25, 508, 172 },
10235 { 0xF6C69A72A3989F5C, 534, 180 },
10236 { 0xB7DCBF5354E9BECE, 561, 188 },
10237 { 0x88FCF317F22241E2, 588, 196 },
10238 { 0xCC20CE9BD35C78A5, 614, 204 },
10239 { 0x98165AF37B2153DF, 641, 212 },
10240 { 0xE2A0B5DC971F303A, 667, 220 },
10241 { 0xA8D9D1535CE3B396, 694, 228 },
10242 { 0xFB9B7CD9A4A7443C, 720, 236 },
10243 { 0xBB764C4CA7A44410, 747, 244 },
10244 { 0x8BAB8EEFB6409C1A, 774, 252 },
10245 { 0xD01FEF10A657842C, 800, 260 },
10246 { 0x9B10A4E5E9913129, 827, 268 },
10247 { 0xE7109BFBA19C0C9D, 853, 276 },
10248 { 0xAC2820D9623BF429, 880, 284 },
10249 { 0x80444B5E7AA7CF85, 907, 292 },
10250 { 0xBF21E44003ACDD2D, 933, 300 },
10251 { 0x8E679C2F5E44FF8F, 960, 308 },
10252 { 0xD433179D9C8CB841, 986, 316 },
10253 { 0x9E19DB92B4E31BA9, 1013, 324 },
10260 assert(e >= -1500);
10262 const int f = kAlpha - e - 1;
10263 const int k = (f * 78913) / (1 << 18) +
static_cast<int>(f > 0);
10265 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
10266 assert(index >= 0);
10267 assert(index < kCachedPowersSize);
10268 static_cast<void>(kCachedPowersSize);
10270 const cached_power cached = kCachedPowers[index];
10271 assert(kAlpha <= cached.e + e + 64);
10272 assert(kGamma >= cached.e + e + 64);
10281 inline int find_largest_pow10(
const uint32_t n, uint32_t& pow10)
10284 if (n >= 1000000000)
10286 pow10 = 1000000000;
10290 else if (n >= 100000000)
10295 else if (n >= 10000000)
10300 else if (n >= 1000000)
10305 else if (n >= 100000)
10310 else if (n >= 10000)
10315 else if (n >= 1000)
10337 inline void grisu2_round(
char* buf,
int len, uint64_t dist, uint64_t delta,
10338 uint64_t rest, uint64_t ten_k)
10341 assert(dist <= delta);
10342 assert(rest <= delta);
10365 and delta - rest >= ten_k
10366 and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
10368 assert(buf[len - 1] !=
'0');
10378 inline void grisu2_digit_gen(
char* buffer,
int& length,
int& decimal_exponent,
10379 diyfp M_minus, diyfp w, diyfp M_plus)
10381 static_assert(kAlpha >= -60,
"internal error");
10382 static_assert(kGamma <= -32,
"internal error");
10396 assert(M_plus.e >= kAlpha);
10397 assert(M_plus.e <= kGamma);
10399 uint64_t delta = diyfp::sub(M_plus, M_minus).f;
10400 uint64_t dist = diyfp::sub(M_plus, w ).f;
10409 const diyfp one(uint64_t{1} << -M_plus.e, M_plus.e);
10411 auto p1 =
static_cast<uint32_t
>(M_plus.f >> -one.e);
10412 uint64_t p2 = M_plus.f & (one.f - 1);
10421 const int k = find_largest_pow10(p1, pow10);
10448 const uint32_t d = p1 / pow10;
10449 const uint32_t r = p1 % pow10;
10455 buffer[length++] =
static_cast<char>(
'0' + d);
10474 const uint64_t rest = (uint64_t{p1} << -one.e) + p2;
10479 decimal_exponent += n;
10490 const uint64_t ten_n = uint64_t{pow10} << -one.e;
10491 grisu2_round(buffer, length, dist, delta, rest, ten_n);
10541 assert(p2 > delta);
10552 assert(p2 <= UINT64_MAX / 10);
10554 const uint64_t d = p2 >> -one.e;
10555 const uint64_t r = p2 & (one.f - 1);
10562 buffer[length++] =
static_cast<char>(
'0' + d);
10587 decimal_exponent -= m;
10595 const uint64_t ten_m = one.f;
10596 grisu2_round(buffer, length, dist, delta, p2, ten_m);
10618 inline void grisu2(
char* buf,
int& len,
int& decimal_exponent,
10619 diyfp m_minus, diyfp v, diyfp m_plus)
10621 assert(m_plus.e == m_minus.e);
10622 assert(m_plus.e == v.e);
10633 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
10635 const diyfp c_minus_k(cached.f, cached.e);
10638 const diyfp w = diyfp::mul(v, c_minus_k);
10639 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
10640 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
10663 const diyfp M_minus(w_minus.f + 1, w_minus.e);
10664 const diyfp M_plus (w_plus.f - 1, w_plus.e );
10666 decimal_exponent = -cached.k;
10668 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
10676 template <
typename FloatType>
10677 void grisu2(
char* buf,
int& len,
int& decimal_exponent, FloatType value)
10679 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
10680 "internal error: not enough precision");
10682 assert(std::isfinite(value));
10702 const boundaries w = compute_boundaries(static_cast<double>(value));
10704 const boundaries w = compute_boundaries(value);
10707 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
10715 inline char* append_exponent(
char* buf,
int e)
10730 auto k =
static_cast<uint32_t
>(e);
10736 *buf++ =
static_cast<char>(
'0' + k);
10740 *buf++ =
static_cast<char>(
'0' + k / 10);
10742 *buf++ =
static_cast<char>(
'0' + k);
10746 *buf++ =
static_cast<char>(
'0' + k / 100);
10748 *buf++ =
static_cast<char>(
'0' + k / 10);
10750 *buf++ =
static_cast<char>(
'0' + k);
10765 inline char* format_buffer(
char* buf,
int len,
int decimal_exponent,
10766 int min_exp,
int max_exp)
10768 assert(min_exp < 0);
10769 assert(max_exp > 0);
10772 const int n = len + decimal_exponent;
10778 if (k <= n and n <= max_exp)
10783 std::memset(buf + k,
'0', static_cast<size_t>(n - k));
10787 return buf + (n + 2);
10790 if (0 < n and n <= max_exp)
10797 std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
10799 return buf + (k + 1);
10802 if (min_exp < n and n <= 0)
10807 std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
10810 std::memset(buf + 2,
'0', static_cast<size_t>(-n));
10811 return buf + (2 + (-n) + k);
10826 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
10832 return append_exponent(buf, n - 1);
10847 template <
typename FloatType>
10848 char* to_chars(
char* first,
const char* last, FloatType value)
10850 static_cast<void>(last);
10851 assert(std::isfinite(value));
10854 if (std::signbit(value))
10869 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
10876 int decimal_exponent = 0;
10877 dtoa_impl::grisu2(first, len, decimal_exponent, value);
10879 assert(len <= std::numeric_limits<FloatType>::max_digits10);
10882 constexpr
int kMinExp = -4;
10884 constexpr
int kMaxExp = std::numeric_limits<FloatType>::digits10;
10886 assert(last - first >= kMaxExp + 2);
10887 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
10888 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
10890 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
10916 enum class error_handler_t
10923 template<
typename BasicJsonType>
10926 using string_t =
typename BasicJsonType::string_t;
10930 static constexpr uint8_t UTF8_ACCEPT = 0;
10931 static constexpr uint8_t UTF8_REJECT = 1;
10939 serializer(output_adapter_t<char> s,
const char ichar,
10940 error_handler_t error_handler_ = error_handler_t::strict)
10942 , loc(std::localeconv())
10943 , thousands_sep(loc->thousands_sep ==
nullptr ?
'\0' : * (loc->thousands_sep))
10944 , decimal_point(loc->decimal_point ==
nullptr ?
'\0' : * (loc->decimal_point))
10945 , indent_char(ichar)
10946 , indent_string(512, indent_char)
10947 , error_handler(error_handler_)
10951 serializer(
const serializer&) =
delete;
10952 serializer& operator=(
const serializer&) =
delete;
10953 serializer(serializer&&) =
delete;
10954 serializer& operator=(serializer&&) =
delete;
10955 ~serializer() =
default;
10974 void dump(
const BasicJsonType& val,
const bool pretty_print,
10975 const bool ensure_ascii,
10976 const unsigned int indent_step,
10977 const unsigned int current_indent = 0)
10979 switch (val.m_type)
10981 case value_t::object:
10983 if (val.m_value.object->empty())
10985 o->write_characters(
"{}", 2);
10991 o->write_characters(
"{\n", 2);
10994 const auto new_indent = current_indent + indent_step;
10995 if (JSON_UNLIKELY(indent_string.size() < new_indent))
10997 indent_string.resize(indent_string.size() * 2,
' ');
11001 auto i = val.m_value.object->cbegin();
11002 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
11004 o->write_characters(indent_string.c_str(), new_indent);
11005 o->write_character(
'\"');
11006 dump_escaped(i->first, ensure_ascii);
11007 o->write_characters(
"\": ", 3);
11008 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
11009 o->write_characters(
",\n", 2);
11013 assert(i != val.m_value.object->cend());
11014 assert(std::next(i) == val.m_value.object->cend());
11015 o->write_characters(indent_string.c_str(), new_indent);
11016 o->write_character(
'\"');
11017 dump_escaped(i->first, ensure_ascii);
11018 o->write_characters(
"\": ", 3);
11019 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
11021 o->write_character(
'\n');
11022 o->write_characters(indent_string.c_str(), current_indent);
11023 o->write_character(
'}');
11027 o->write_character(
'{');
11030 auto i = val.m_value.object->cbegin();
11031 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
11033 o->write_character(
'\"');
11034 dump_escaped(i->first, ensure_ascii);
11035 o->write_characters(
"\":", 2);
11036 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
11037 o->write_character(
',');
11041 assert(i != val.m_value.object->cend());
11042 assert(std::next(i) == val.m_value.object->cend());
11043 o->write_character(
'\"');
11044 dump_escaped(i->first, ensure_ascii);
11045 o->write_characters(
"\":", 2);
11046 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
11048 o->write_character(
'}');
11054 case value_t::array:
11056 if (val.m_value.array->empty())
11058 o->write_characters(
"[]", 2);
11064 o->write_characters(
"[\n", 2);
11067 const auto new_indent = current_indent + indent_step;
11068 if (JSON_UNLIKELY(indent_string.size() < new_indent))
11070 indent_string.resize(indent_string.size() * 2,
' ');
11074 for (
auto i = val.m_value.array->cbegin();
11075 i != val.m_value.array->cend() - 1; ++i)
11077 o->write_characters(indent_string.c_str(), new_indent);
11078 dump(*i,
true, ensure_ascii, indent_step, new_indent);
11079 o->write_characters(
",\n", 2);
11083 assert(not val.m_value.array->empty());
11084 o->write_characters(indent_string.c_str(), new_indent);
11085 dump(val.m_value.array->back(),
true, ensure_ascii, indent_step, new_indent);
11087 o->write_character(
'\n');
11088 o->write_characters(indent_string.c_str(), current_indent);
11089 o->write_character(
']');
11093 o->write_character(
'[');
11096 for (
auto i = val.m_value.array->cbegin();
11097 i != val.m_value.array->cend() - 1; ++i)
11099 dump(*i,
false, ensure_ascii, indent_step, current_indent);
11100 o->write_character(
',');
11104 assert(not val.m_value.array->empty());
11105 dump(val.m_value.array->back(),
false, ensure_ascii, indent_step, current_indent);
11107 o->write_character(
']');
11113 case value_t::string:
11115 o->write_character(
'\"');
11116 dump_escaped(*val.m_value.string, ensure_ascii);
11117 o->write_character(
'\"');
11121 case value_t::boolean:
11123 if (val.m_value.boolean)
11125 o->write_characters(
"true", 4);
11129 o->write_characters(
"false", 5);
11134 case value_t::number_integer:
11136 dump_integer(val.m_value.number_integer);
11140 case value_t::number_unsigned:
11142 dump_integer(val.m_value.number_unsigned);
11146 case value_t::number_float:
11148 dump_float(val.m_value.number_float);
11152 case value_t::discarded:
11154 o->write_characters(
"<discarded>", 11);
11158 case value_t::null:
11160 o->write_characters(
"null", 4);
11181 void dump_escaped(
const string_t& s,
const bool ensure_ascii)
11183 uint32_t codepoint;
11184 uint8_t state = UTF8_ACCEPT;
11185 std::size_t bytes = 0;
11188 std::size_t bytes_after_last_accept = 0;
11189 std::size_t undumped_chars = 0;
11191 for (std::size_t i = 0; i < s.size(); ++i)
11193 const auto byte =
static_cast<uint8_t
>(s[i]);
11195 switch (decode(state, codepoint, byte))
11203 string_buffer[bytes++] =
'\\';
11204 string_buffer[bytes++] =
'b';
11210 string_buffer[bytes++] =
'\\';
11211 string_buffer[bytes++] =
't';
11217 string_buffer[bytes++] =
'\\';
11218 string_buffer[bytes++] =
'n';
11224 string_buffer[bytes++] =
'\\';
11225 string_buffer[bytes++] =
'f';
11231 string_buffer[bytes++] =
'\\';
11232 string_buffer[bytes++] =
'r';
11238 string_buffer[bytes++] =
'\\';
11239 string_buffer[bytes++] =
'\"';
11245 string_buffer[bytes++] =
'\\';
11246 string_buffer[bytes++] =
'\\';
11254 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
11256 if (codepoint <= 0xFFFF)
11258 (std::snprintf)(string_buffer.data() + bytes, 7,
"\\u%04x",
11259 static_cast<uint16_t
>(codepoint));
11264 (std::snprintf)(string_buffer.data() + bytes, 13,
"\\u%04x\\u%04x",
11265 static_cast<uint16_t
>(0xD7C0 + (codepoint >> 10)),
11266 static_cast<uint16_t
>(0xDC00 + (codepoint & 0x3FF)));
11274 string_buffer[bytes++] = s[i];
11283 if (string_buffer.size() - bytes < 13)
11285 o->write_characters(string_buffer.data(), bytes);
11290 bytes_after_last_accept = bytes;
11291 undumped_chars = 0;
11297 switch (error_handler)
11299 case error_handler_t::strict:
11301 std::string sn(3,
'\0');
11302 (std::snprintf)(&sn[0], sn.size(),
"%.2X", byte);
11303 JSON_THROW(type_error::create(316,
"invalid UTF-8 byte at index " + std::to_string(i) +
": 0x" + sn));
11306 case error_handler_t::ignore:
11307 case error_handler_t::replace:
11313 if (undumped_chars > 0)
11320 bytes = bytes_after_last_accept;
11322 if (error_handler == error_handler_t::replace)
11327 string_buffer[bytes++] =
'\\';
11328 string_buffer[bytes++] =
'u';
11329 string_buffer[bytes++] =
'f';
11330 string_buffer[bytes++] =
'f';
11331 string_buffer[bytes++] =
'f';
11332 string_buffer[bytes++] =
'd';
11336 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type(
'\xEF');
11337 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type(
'\xBF');
11338 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type(
'\xBD');
11340 bytes_after_last_accept = bytes;
11343 undumped_chars = 0;
11346 state = UTF8_ACCEPT;
11355 if (not ensure_ascii)
11358 string_buffer[bytes++] = s[i];
11367 if (JSON_LIKELY(state == UTF8_ACCEPT))
11372 o->write_characters(string_buffer.data(), bytes);
11378 switch (error_handler)
11380 case error_handler_t::strict:
11382 std::string sn(3,
'\0');
11383 (std::snprintf)(&sn[0], sn.size(),
"%.2X",
static_cast<uint8_t
>(s.back()));
11384 JSON_THROW(type_error::create(316,
"incomplete UTF-8 string; last byte: 0x" + sn));
11387 case error_handler_t::ignore:
11390 o->write_characters(string_buffer.data(), bytes_after_last_accept);
11394 case error_handler_t::replace:
11397 o->write_characters(string_buffer.data(), bytes_after_last_accept);
11401 o->write_characters(
"\\ufffd", 6);
11405 o->write_characters(
"\xEF\xBF\xBD", 3);
11422 template<
typename NumberType, detail::enable_if_t<
11423 std::is_same<NumberType, number_unsigned_t>::value or
11424 std::is_same<NumberType, number_integer_t>::value,
11426 void dump_integer(NumberType x)
11431 o->write_character(
'0');
11435 const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not (x >= 0);
11441 assert(i < number_buffer.size() - 1);
11443 const auto digit = std::labs(static_cast<long>(x % 10));
11444 number_buffer[i++] =
static_cast<char>(
'0' + digit);
11451 assert(i < number_buffer.size() - 2);
11452 number_buffer[i++] =
'-';
11455 std::reverse(number_buffer.begin(), number_buffer.begin() + i);
11456 o->write_characters(number_buffer.data(), i);
11470 if (not std::isfinite(x))
11472 o->write_characters(
"null", 4);
11481 static constexpr
bool is_ieee_single_or_double
11482 = (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
11483 (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);
11485 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
11490 char* begin = number_buffer.data();
11491 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
11493 o->write_characters(begin, static_cast<size_t>(end - begin));
11499 static constexpr
auto d = std::numeric_limits<number_float_t>::max_digits10;
11502 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(),
"%.*g", d, x);
11507 assert(static_cast<std::size_t>(len) < number_buffer.size());
11510 if (thousands_sep !=
'\0')
11512 const auto end = std::remove(number_buffer.begin(),
11513 number_buffer.begin() + len, thousands_sep);
11514 std::fill(end, number_buffer.end(),
'\0');
11515 assert((end - number_buffer.begin()) <= len);
11516 len = (end - number_buffer.begin());
11520 if (decimal_point !=
'\0' and decimal_point !=
'.')
11522 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
11523 if (dec_pos != number_buffer.end())
11529 o->write_characters(number_buffer.data(),
static_cast<std::size_t
>(len));
11532 const bool value_is_int_like =
11533 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
11536 return (c ==
'.' or c ==
'e');
11539 if (value_is_int_like)
11541 o->write_characters(
".0", 2);
11566 static uint8_t decode(uint8_t& state, uint32_t& codep,
const uint8_t byte) noexcept
11568 static const std::array<uint8_t, 400> utf8d =
11571 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,
11572 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,
11573 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,
11574 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,
11575 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,
11576 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,
11577 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,
11578 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
11579 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
11580 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
11581 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,
11582 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,
11583 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,
11584 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
11588 const uint8_t type = utf8d[byte];
11590 codep = (state != UTF8_ACCEPT)
11591 ? (byte & 0x3fu) | (codep << 6)
11592 : static_cast<uint32_t>(0xff >> type) & (byte);
11594 state = utf8d[256u + state * 16u + type];
11600 output_adapter_t<char> o =
nullptr;
11603 std::array<char, 64> number_buffer{{}};
11606 const std::lconv* loc =
nullptr;
11608 const char thousands_sep =
'\0';
11610 const char decimal_point =
'\0';
11613 std::array<char, 512> string_buffer{{}};
11616 const char indent_char;
11621 const error_handler_t error_handler;
11629 #include <initializer_list> 11639 template<
typename BasicJsonType>
11643 using value_type = BasicJsonType;
11645 json_ref(value_type&& value)
11646 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(
true)
11649 json_ref(
const value_type& value)
11650 : value_ref(const_cast<value_type*>(&value)), is_rvalue(
false)
11653 json_ref(std::initializer_list<json_ref> init)
11654 : owned_value(init), value_ref(&owned_value), is_rvalue(
true)
11659 enable_if_t<std::is_constructible<value_type, Args...>::value,
int> = 0 >
11660 json_ref(Args && ... args)
11661 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
11665 json_ref(json_ref&&) =
default;
11666 json_ref(
const json_ref&) =
delete;
11667 json_ref& operator=(
const json_ref&) =
delete;
11668 json_ref& operator=(json_ref&&) =
delete;
11669 ~json_ref() =
default;
11671 value_type moved_or_copied()
const 11675 return std::move(*value_ref);
11680 value_type
const& operator*()
const 11682 return *
static_cast<value_type const*
>(value_ref);
11685 value_type
const* operator->()
const 11687 return static_cast<value_type const*
>(value_ref);
11691 mutable value_type owned_value =
nullptr;
11692 value_type* value_ref =
nullptr;
11693 const bool is_rvalue;
11715 template<
typename BasicJsonType>
11719 NLOHMANN_BASIC_JSON_TPL_DECLARATION
11745 : reference_tokens(split(s))
11763 std::string to_string()
const 11765 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
11767 [](
const std::string & a,
const std::string & b)
11769 return a +
"/" + escape(b);
11774 operator std::string()
const 11776 return to_string();
11786 static int array_index(
const std::string& s)
11788 std::size_t processed_chars = 0;
11789 const int res = std::stoi(s, &processed_chars);
11792 if (JSON_UNLIKELY(processed_chars != s.size()))
11794 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + s +
"'"));
11805 std::string pop_back()
11807 if (JSON_UNLIKELY(is_root()))
11809 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
11812 auto last = reference_tokens.back();
11813 reference_tokens.pop_back();
11818 bool is_root()
const noexcept
11820 return reference_tokens.empty();
11825 if (JSON_UNLIKELY(is_root()))
11827 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
11831 result.reference_tokens = {reference_tokens[0]};
11843 BasicJsonType& get_and_create(BasicJsonType& j)
const 11845 using size_type =
typename BasicJsonType::size_type;
11850 for (
const auto& reference_token : reference_tokens)
11852 switch (result->m_type)
11854 case detail::value_t::null:
11856 if (reference_token ==
"0")
11859 result = &result->operator[](0);
11864 result = &result->operator[](reference_token);
11869 case detail::value_t::object:
11872 result = &result->operator[](reference_token);
11876 case detail::value_t::array:
11881 result = &result->operator[](
static_cast<size_type
>(array_index(reference_token)));
11883 JSON_CATCH(std::invalid_argument&)
11885 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
11897 JSON_THROW(detail::type_error::create(313,
"invalid value to unflatten"));
11923 BasicJsonType& get_unchecked(BasicJsonType* ptr)
const 11925 using size_type =
typename BasicJsonType::size_type;
11926 for (
const auto& reference_token : reference_tokens)
11929 if (ptr->m_type == detail::value_t::null)
11933 std::all_of(reference_token.begin(), reference_token.end(),
11936 return (x >=
'0' and x <=
'9');
11940 *ptr = (nums or reference_token ==
"-")
11941 ? detail::value_t::array
11942 : detail::value_t::object;
11945 switch (ptr->m_type)
11947 case detail::value_t::object:
11950 ptr = &ptr->operator[](reference_token);
11954 case detail::value_t::array:
11957 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0'))
11959 JSON_THROW(detail::parse_error::create(106, 0,
11960 "array index '" + reference_token +
11961 "' must not begin with '0'"));
11964 if (reference_token ==
"-")
11967 ptr = &ptr->operator[](ptr->m_value.array->size());
11974 ptr = &ptr->operator[](
11975 static_cast<size_type
>(array_index(reference_token)));
11977 JSON_CATCH(std::invalid_argument&)
11979 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
11986 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
11999 BasicJsonType& get_checked(BasicJsonType* ptr)
const 12001 using size_type =
typename BasicJsonType::size_type;
12002 for (
const auto& reference_token : reference_tokens)
12004 switch (ptr->m_type)
12006 case detail::value_t::object:
12009 ptr = &ptr->at(reference_token);
12013 case detail::value_t::array:
12015 if (JSON_UNLIKELY(reference_token ==
"-"))
12018 JSON_THROW(detail::out_of_range::create(402,
12019 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12020 ") is out of range"));
12024 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0'))
12026 JSON_THROW(detail::parse_error::create(106, 0,
12027 "array index '" + reference_token +
12028 "' must not begin with '0'"));
12034 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
12036 JSON_CATCH(std::invalid_argument&)
12038 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
12044 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
12064 const BasicJsonType& get_unchecked(
const BasicJsonType* ptr)
const 12066 using size_type =
typename BasicJsonType::size_type;
12067 for (
const auto& reference_token : reference_tokens)
12069 switch (ptr->m_type)
12071 case detail::value_t::object:
12074 ptr = &ptr->operator[](reference_token);
12078 case detail::value_t::array:
12080 if (JSON_UNLIKELY(reference_token ==
"-"))
12083 JSON_THROW(detail::out_of_range::create(402,
12084 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12085 ") is out of range"));
12089 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0'))
12091 JSON_THROW(detail::parse_error::create(106, 0,
12092 "array index '" + reference_token +
12093 "' must not begin with '0'"));
12099 ptr = &ptr->operator[](
12100 static_cast<size_type
>(array_index(reference_token)));
12102 JSON_CATCH(std::invalid_argument&)
12104 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
12110 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
12123 const BasicJsonType& get_checked(
const BasicJsonType* ptr)
const 12125 using size_type =
typename BasicJsonType::size_type;
12126 for (
const auto& reference_token : reference_tokens)
12128 switch (ptr->m_type)
12130 case detail::value_t::object:
12133 ptr = &ptr->at(reference_token);
12137 case detail::value_t::array:
12139 if (JSON_UNLIKELY(reference_token ==
"-"))
12142 JSON_THROW(detail::out_of_range::create(402,
12143 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12144 ") is out of range"));
12148 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] ==
'0'))
12150 JSON_THROW(detail::parse_error::create(106, 0,
12151 "array index '" + reference_token +
12152 "' must not begin with '0'"));
12158 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
12160 JSON_CATCH(std::invalid_argument&)
12162 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
12168 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
12184 static std::vector<std::string> split(
const std::string& reference_string)
12186 std::vector<std::string> result;
12189 if (reference_string.empty())
12195 if (JSON_UNLIKELY(reference_string[0] !=
'/'))
12197 JSON_THROW(detail::parse_error::create(107, 1,
12198 "JSON pointer must be empty or begin with '/' - was: '" +
12199 reference_string +
"'"));
12207 std::size_t slash = reference_string.find_first_of(
'/', 1),
12214 start = (slash == std::string::npos) ? 0 : slash + 1,
12216 slash = reference_string.find_first_of(
'/', start))
12220 auto reference_token = reference_string.substr(start, slash - start);
12223 for (std::size_t pos = reference_token.find_first_of(
'~');
12224 pos != std::string::npos;
12225 pos = reference_token.find_first_of(
'~', pos + 1))
12227 assert(reference_token[pos] ==
'~');
12230 if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
12231 (reference_token[pos + 1] !=
'0' and
12232 reference_token[pos + 1] !=
'1')))
12234 JSON_THROW(detail::parse_error::create(108, 0,
"escape character '~' must be followed with '0' or '1'"));
12239 unescape(reference_token);
12240 result.push_back(reference_token);
12259 static void replace_substring(std::string& s,
const std::string& f,
12260 const std::string& t)
12262 assert(not f.empty());
12263 for (
auto pos = s.find(f);
12264 pos != std::string::npos;
12265 s.replace(pos, f.size(), t),
12266 pos = s.find(f, pos + t.size()))
12271 static std::string escape(std::string s)
12273 replace_substring(s,
"~",
"~0");
12274 replace_substring(s,
"/",
"~1");
12279 static void unescape(std::string& s)
12281 replace_substring(s,
"~1",
"/");
12282 replace_substring(s,
"~0",
"~");
12292 static void flatten(
const std::string& reference_string,
12293 const BasicJsonType& value,
12294 BasicJsonType& result)
12296 switch (value.m_type)
12298 case detail::value_t::array:
12300 if (value.m_value.array->empty())
12303 result[reference_string] =
nullptr;
12308 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
12310 flatten(reference_string +
"/" + std::to_string(i),
12311 value.m_value.array->operator[](i), result);
12317 case detail::value_t::object:
12319 if (value.m_value.object->empty())
12322 result[reference_string] =
nullptr;
12327 for (
const auto& element : *value.m_value.object)
12329 flatten(reference_string +
"/" + escape(element.first), element.second, result);
12338 result[reference_string] = value;
12354 static BasicJsonType
12355 unflatten(
const BasicJsonType& value)
12357 if (JSON_UNLIKELY(not value.is_object()))
12359 JSON_THROW(detail::type_error::create(314,
"only objects can be unflattened"));
12362 BasicJsonType result;
12365 for (
const auto& element : *value.m_value.object)
12367 if (JSON_UNLIKELY(not element.second.is_primitive()))
12369 JSON_THROW(detail::type_error::create(315,
"values in object must be primitive"));
12376 json_pointer(element.first).get_and_create(result) = element.second;
12385 return (lhs.reference_tokens == rhs.reference_tokens);
12391 return not (lhs == rhs);
12395 std::vector<std::string> reference_tokens;
12412 template<
typename,
typename>
12424 template<
typename BasicJsonType,
typename ValueType>
12425 static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
12426 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
12427 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val),
void())
12429 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
12441 template <
typename BasicJsonType,
typename ValueType>
12442 static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
12443 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
12444 -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)),
void())
12446 ::nlohmann::to_json(j, std::forward<ValueType>(val));
12542 NLOHMANN_BASIC_JSON_TPL_DECLARATION
12546 template<detail::value_t>
friend struct detail::external_constructor;
12547 friend ::nlohmann::json_pointer<basic_json>;
12548 friend ::nlohmann::detail::parser<basic_json>;
12549 friend ::nlohmann::detail::serializer<basic_json>;
12550 template<
typename BasicJsonType>
12551 friend class ::nlohmann::detail::iter_impl;
12552 template<
typename BasicJsonType,
typename CharType>
12553 friend class ::nlohmann::detail::binary_writer;
12554 template<
typename BasicJsonType,
typename SAX>
12555 friend class ::nlohmann::detail::binary_reader;
12556 template<
typename BasicJsonType>
12557 friend class ::nlohmann::detail::json_sax_dom_parser;
12558 template<
typename BasicJsonType>
12559 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
12562 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
12565 using lexer = ::nlohmann::detail::lexer<basic_json>;
12566 using parser = ::nlohmann::detail::parser<basic_json>;
12568 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
12569 template<
typename BasicJsonType>
12570 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
12571 template<
typename BasicJsonType>
12572 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
12573 template<
typename Iterator>
12574 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
12575 template<
typename Base>
using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
12577 template<
typename CharType>
12578 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
12580 using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
12581 template<
typename CharType>
using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
12583 using serializer = ::nlohmann::detail::serializer<basic_json>;
12586 using value_t = detail::value_t;
12589 template<
typename T,
typename SFINAE>
12592 using error_handler_t = detail::error_handler_t;
12596 using input_format_t = detail::input_format_t;
12650 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
12652 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
12659 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
12704 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
12705 result[
"name"] =
"JSON for Modern C++";
12706 result[
"url"] =
"https://github.com/nlohmann/json";
12707 result[
"version"][
"string"] =
12708 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) +
"." +
12709 std::to_string(NLOHMANN_JSON_VERSION_MINOR) +
"." +
12710 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
12711 result[
"version"][
"major"] = NLOHMANN_JSON_VERSION_MAJOR;
12712 result[
"version"][
"minor"] = NLOHMANN_JSON_VERSION_MINOR;
12713 result[
"version"][
"patch"] = NLOHMANN_JSON_VERSION_PATCH;
12716 result[
"platform"] =
"win32";
12717 #elif defined __linux__ 12718 result[
"platform"] =
"linux";
12719 #elif defined __APPLE__ 12720 result[
"platform"] =
"apple";
12721 #elif defined __unix__ 12722 result[
"platform"] =
"unix";
12724 result[
"platform"] =
"unknown";
12727 #if defined(__ICC) || defined(__INTEL_COMPILER) 12728 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
12729 #elif defined(__clang__) 12730 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
12731 #elif defined(__GNUC__) || defined(__GNUG__) 12732 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(__GNUC_PATCHLEVEL__)}};
12733 #elif defined(__HP_cc) || defined(__HP_aCC) 12734 result[
"compiler"] =
"hp" 12735 #elif defined(__IBMCPP__) 12736 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
12737 #elif defined(_MSC_VER) 12738 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
12739 #elif defined(__PGI) 12740 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
12741 #elif defined(__SUNPRO_CC) 12742 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
12744 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
12748 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
12750 result[
"compiler"][
"c++"] =
"unknown";
12765 #if defined(JSON_HAS_CPP_14) 12856 using object_t = ObjectType<StringType,
12859 AllocatorType<std::pair<
const StringType,
12906 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
13203 template<
typename T,
typename... Args>
13204 static T* create(Args&& ... args)
13206 AllocatorType<T> alloc;
13207 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
13209 auto deleter = [&](T * object)
13211 AllocatorTraits::deallocate(alloc,
object, 1);
13213 std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
13214 AllocatorTraits::construct(alloc,
object.
get(), std::forward<Args>(args)...);
13215 assert(
object !=
nullptr);
13216 return object.release();
13265 json_value() =
default;
13267 json_value(
boolean_t v) noexcept : boolean(v) {}
13275 json_value(value_t t)
13279 case value_t::object:
13281 object = create<object_t>();
13285 case value_t::array:
13287 array = create<array_t>();
13291 case value_t::string:
13293 string = create<string_t>(
"");
13297 case value_t::boolean:
13303 case value_t::number_integer:
13309 case value_t::number_unsigned:
13315 case value_t::number_float:
13321 case value_t::null:
13330 if (JSON_UNLIKELY(t == value_t::null))
13332 JSON_THROW(other_error::create(500,
"961c151d2e87f2686a955a9be24d316f1362bf21 3.5.0"));
13342 string = create<string_t>(value);
13348 string = create<string_t>(std::move(value));
13354 object = create<object_t>(value);
13360 object = create<object_t>(std::move(value));
13364 json_value(
const array_t& value)
13366 array = create<array_t>(value);
13372 array = create<array_t>(std::move(value));
13375 void destroy(value_t t) noexcept
13379 case value_t::object:
13381 AllocatorType<object_t> alloc;
13382 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
13383 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
13387 case value_t::array:
13389 AllocatorType<array_t> alloc;
13390 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
13391 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
13395 case value_t::string:
13397 AllocatorType<string_t> alloc;
13398 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
13399 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
13420 void assert_invariant()
const noexcept
13422 assert(m_type != value_t::object or m_value.object !=
nullptr);
13423 assert(m_type != value_t::array or m_value.array !=
nullptr);
13424 assert(m_type != value_t::string or m_value.string !=
nullptr);
13538 basic_json(
const value_t v)
13539 : m_type(v), m_value(v)
13541 assert_invariant();
13562 basic_json(std::nullptr_t =
nullptr) noexcept
13563 : basic_json(value_t::null)
13565 assert_invariant();
13625 template <
typename CompatibleType,
13626 typename U = detail::uncvref_t<CompatibleType>,
13627 detail::enable_if_t<
13628 not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value,
int> = 0>
13629 basic_json(CompatibleType && val) noexcept(noexcept(
13630 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
13631 std::forward<CompatibleType>(val))))
13633 JSONSerializer<U>::to_json(*
this, std::forward<CompatibleType>(val));
13634 assert_invariant();
13663 template <
typename BasicJsonType,
13664 detail::enable_if_t<
13665 detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value,
int> = 0>
13666 basic_json(
const BasicJsonType& val)
13668 using other_boolean_t =
typename BasicJsonType::boolean_t;
13669 using other_number_float_t =
typename BasicJsonType::number_float_t;
13670 using other_number_integer_t =
typename BasicJsonType::number_integer_t;
13671 using other_number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
13672 using other_string_t =
typename BasicJsonType::string_t;
13673 using other_object_t =
typename BasicJsonType::object_t;
13674 using other_array_t =
typename BasicJsonType::array_t;
13676 switch (val.type())
13678 case value_t::boolean:
13679 JSONSerializer<other_boolean_t>::to_json(*
this, val.template get<other_boolean_t>());
13681 case value_t::number_float:
13682 JSONSerializer<other_number_float_t>::to_json(*
this, val.template get<other_number_float_t>());
13684 case value_t::number_integer:
13685 JSONSerializer<other_number_integer_t>::to_json(*
this, val.template get<other_number_integer_t>());
13687 case value_t::number_unsigned:
13688 JSONSerializer<other_number_unsigned_t>::to_json(*
this, val.template get<other_number_unsigned_t>());
13690 case value_t::string:
13691 JSONSerializer<other_string_t>::to_json(*
this, val.template get_ref<const other_string_t&>());
13693 case value_t::object:
13694 JSONSerializer<other_object_t>::to_json(*
this, val.template get_ref<const other_object_t&>());
13696 case value_t::array:
13697 JSONSerializer<other_array_t>::to_json(*
this, val.template get_ref<const other_array_t&>());
13699 case value_t::null:
13702 case value_t::discarded:
13703 m_type = value_t::discarded;
13706 assert_invariant();
13784 bool type_deduction =
true,
13785 value_t manual_type = value_t::array)
13789 bool is_an_object = std::all_of(init.begin(), init.end(),
13790 [](
const detail::json_ref<basic_json>& element_ref)
13792 return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
13796 if (not type_deduction)
13799 if (manual_type == value_t::array)
13801 is_an_object =
false;
13805 if (JSON_UNLIKELY(manual_type == value_t::object and not is_an_object))
13807 JSON_THROW(type_error::create(301,
"cannot create object from initializer list"));
13814 m_type = value_t::object;
13815 m_value = value_t::object;
13817 std::for_each(init.begin(), init.end(), [
this](
const detail::json_ref<basic_json>& element_ref)
13819 auto element = element_ref.moved_or_copied();
13820 m_value.object->emplace(
13821 std::move(*((*element.m_value.array)[0].m_value.string)),
13822 std::move((*element.m_value.array)[1]));
13828 m_type = value_t::array;
13829 m_value.array = create<array_t>(init.begin(), init.end());
13832 assert_invariant();
13874 return basic_json(init,
false, value_t::array);
13917 return basic_json(init,
false, value_t::object);
13942 basic_json(
size_type cnt,
const basic_json& val)
13943 : m_type(value_t::array)
13945 m_value.array = create<array_t>(cnt, val);
13946 assert_invariant();
14004 template<
class InputIT,
typename std::enable_if<
14005 std::is_same<InputIT, typename basic_json_t::iterator>::value or
14006 std::is_same<InputIT, typename basic_json_t::const_iterator>::value,
int>::type = 0>
14007 basic_json(InputIT first, InputIT last)
14009 assert(first.m_object !=
nullptr);
14010 assert(last.m_object !=
nullptr);
14013 if (JSON_UNLIKELY(first.m_object != last.m_object))
14015 JSON_THROW(invalid_iterator::create(201,
"iterators are not compatible"));
14019 m_type = first.m_object->m_type;
14024 case value_t::boolean:
14025 case value_t::number_float:
14026 case value_t::number_integer:
14027 case value_t::number_unsigned:
14028 case value_t::string:
14030 if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
14031 or not last.m_it.primitive_iterator.is_end()))
14033 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
14044 case value_t::number_integer:
14046 m_value.number_integer = first.m_object->m_value.number_integer;
14050 case value_t::number_unsigned:
14052 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
14056 case value_t::number_float:
14058 m_value.number_float = first.m_object->m_value.number_float;
14062 case value_t::boolean:
14064 m_value.boolean = first.m_object->m_value.boolean;
14068 case value_t::string:
14070 m_value = *first.m_object->m_value.string;
14074 case value_t::object:
14076 m_value.object = create<object_t>(first.m_it.object_iterator,
14077 last.m_it.object_iterator);
14081 case value_t::array:
14083 m_value.array = create<array_t>(first.m_it.array_iterator,
14084 last.m_it.array_iterator);
14089 JSON_THROW(invalid_iterator::create(206,
"cannot construct with iterators from " +
14090 std::string(first.m_object->type_name())));
14093 assert_invariant();
14102 basic_json(
const detail::json_ref<basic_json>& ref)
14103 : basic_json(ref.moved_or_copied())
14131 basic_json(
const basic_json& other)
14132 : m_type(other.m_type)
14135 other.assert_invariant();
14139 case value_t::object:
14141 m_value = *other.m_value.object;
14145 case value_t::array:
14147 m_value = *other.m_value.array;
14151 case value_t::string:
14153 m_value = *other.m_value.string;
14157 case value_t::boolean:
14159 m_value = other.m_value.boolean;
14163 case value_t::number_integer:
14165 m_value = other.m_value.number_integer;
14169 case value_t::number_unsigned:
14171 m_value = other.m_value.number_unsigned;
14175 case value_t::number_float:
14177 m_value = other.m_value.number_float;
14185 assert_invariant();
14214 basic_json(basic_json&& other) noexcept
14215 : m_type(std::move(other.m_type)),
14216 m_value(std::move(other.m_value))
14219 other.assert_invariant();
14222 other.m_type = value_t::null;
14223 other.m_value = {};
14225 assert_invariant();
14251 basic_json& operator=(basic_json other) noexcept (
14252 std::is_nothrow_move_constructible<value_t>::value and
14253 std::is_nothrow_move_assignable<value_t>::value and
14254 std::is_nothrow_move_constructible<json_value>::value and
14255 std::is_nothrow_move_assignable<json_value>::value
14259 other.assert_invariant();
14262 swap(m_type, other.m_type);
14263 swap(m_value, other.m_value);
14265 assert_invariant();
14284 ~basic_json() noexcept
14286 assert_invariant();
14287 m_value.destroy(m_type);
14342 string_t dump(
const int indent = -1,
14343 const char indent_char =
' ',
14344 const bool ensure_ascii =
false,
14345 const error_handler_t error_handler = error_handler_t::strict)
const 14348 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
14352 s.dump(*
this,
true, ensure_ascii, static_cast<unsigned int>(indent));
14356 s.dump(*
this,
false, ensure_ascii, 0);
14394 constexpr value_t type() const noexcept
14424 constexpr
bool is_primitive() const noexcept
14426 return is_null() or is_string() or is_boolean() or is_number();
14451 constexpr
bool is_structured() const noexcept
14453 return is_array() or is_object();
14473 constexpr
bool is_null() const noexcept
14475 return (m_type == value_t::null);
14495 constexpr
bool is_boolean() const noexcept
14497 return (m_type == value_t::boolean);
14525 constexpr
bool is_number() const noexcept
14527 return is_number_integer() or is_number_float();
14554 constexpr
bool is_number_integer() const noexcept
14556 return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
14582 constexpr
bool is_number_unsigned() const noexcept
14584 return (m_type == value_t::number_unsigned);
14610 constexpr
bool is_number_float() const noexcept
14612 return (m_type == value_t::number_float);
14632 constexpr
bool is_object() const noexcept
14634 return (m_type == value_t::object);
14654 constexpr
bool is_array() const noexcept
14656 return (m_type == value_t::array);
14676 constexpr
bool is_string() const noexcept
14678 return (m_type == value_t::string);
14703 constexpr
bool is_discarded() const noexcept
14705 return (m_type == value_t::discarded);
14729 constexpr
operator value_t() const noexcept
14744 if (JSON_LIKELY(is_boolean()))
14746 return m_value.boolean;
14749 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(type_name())));
14755 return is_object() ? m_value.object :
nullptr;
14761 return is_object() ? m_value.object :
nullptr;
14767 return is_array() ? m_value.array :
nullptr;
14771 constexpr
const array_t* get_impl_ptr(
const array_t* )
const noexcept
14773 return is_array() ? m_value.array :
nullptr;
14779 return is_string() ? m_value.string :
nullptr;
14785 return is_string() ? m_value.string :
nullptr;
14791 return is_boolean() ? &m_value.boolean :
nullptr;
14797 return is_boolean() ? &m_value.boolean :
nullptr;
14803 return is_number_integer() ? &m_value.number_integer :
nullptr;
14809 return is_number_integer() ? &m_value.number_integer :
nullptr;
14815 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
14821 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
14827 return is_number_float() ? &m_value.number_float :
nullptr;
14833 return is_number_float() ? &m_value.number_float :
nullptr;
14847 template<
typename ReferenceType,
typename ThisType>
14848 static ReferenceType get_ref_impl(ThisType& obj)
14851 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
14853 if (JSON_LIKELY(ptr !=
nullptr))
14858 JSON_THROW(type_error::create(303,
"incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
14880 template<
typename BasicJsonType, detail::enable_if_t<
14881 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
14883 basic_json
get()
const 14903 template<
typename BasicJsonType, detail::enable_if_t<
14904 not std::is_same<BasicJsonType, basic_json>::value and
14905 detail::is_basic_json<BasicJsonType>::value,
int> = 0>
14906 BasicJsonType
get()
const 14950 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
14951 detail::enable_if_t <
14952 not detail::is_basic_json<ValueType>::value and
14953 detail::has_from_json<basic_json_t, ValueType>::value and
14954 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
14956 ValueType
get()
const noexcept(noexcept(
14957 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
14962 static_assert(not std::is_reference<ValueTypeCV>::value,
14963 "get() cannot be used with reference types, you might want to use get_ref()");
14964 static_assert(std::is_default_constructible<ValueType>::value,
14965 "types must be DefaultConstructible when used with get()");
14968 JSONSerializer<ValueType>::from_json(*
this, ret);
15003 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
15004 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
15005 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
15007 ValueType
get()
const noexcept(noexcept(
15008 JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
15010 static_assert(not std::is_reference<ValueTypeCV>::value,
15011 "get() cannot be used with reference types, you might want to use get_ref()");
15012 return JSONSerializer<ValueTypeCV>::from_json(*
this);
15048 template<
typename ValueType,
15049 detail::enable_if_t <
15050 not detail::is_basic_json<ValueType>::value and
15051 detail::has_from_json<basic_json_t, ValueType>::value,
15053 ValueType & get_to(ValueType& v)
const noexcept(noexcept(
15054 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
15056 JSONSerializer<ValueType>::from_json(*
this, v);
15087 template<
typename PointerType,
typename std::enable_if<
15088 std::is_pointer<PointerType>::value,
int>::type = 0>
15089 auto get_ptr() noexcept -> decltype(
std::declval<basic_json_t&>().get_impl_ptr(
std::declval<PointerType>()))
15092 return get_impl_ptr(static_cast<PointerType>(
nullptr));
15099 template<
typename PointerType,
typename std::enable_if<
15100 std::is_pointer<PointerType>::value and
15101 std::is_const<typename std::remove_pointer<PointerType>::type>::value,
int>::type = 0>
15102 constexpr
auto get_ptr() const noexcept -> decltype(
std::declval<const basic_json_t&>().get_impl_ptr(
std::declval<PointerType>()))
15105 return get_impl_ptr(static_cast<PointerType>(
nullptr));
15135 template<
typename PointerType,
typename std::enable_if<
15136 std::is_pointer<PointerType>::value,
int>::type = 0>
15137 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
15140 return get_ptr<PointerType>();
15147 template<
typename PointerType,
typename std::enable_if<
15148 std::is_pointer<PointerType>::value,
int>::type = 0>
15149 constexpr
auto get()
const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
15152 return get_ptr<PointerType>();
15181 template<
typename ReferenceType,
typename std::enable_if<
15182 std::is_reference<ReferenceType>::value,
int>::type = 0>
15183 ReferenceType get_ref()
15186 return get_ref_impl<ReferenceType>(*this);
15193 template<
typename ReferenceType,
typename std::enable_if<
15194 std::is_reference<ReferenceType>::value and
15195 std::is_const<typename std::remove_reference<ReferenceType>::type>::value,
int>::type = 0>
15196 ReferenceType get_ref()
const 15199 return get_ref_impl<ReferenceType>(*this);
15231 template <
typename ValueType,
typename std::enable_if <
15232 not std::is_pointer<ValueType>::value and
15233 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
15234 not std::is_same<ValueType, typename string_t::value_type>::value and
15235 not detail::is_basic_json<ValueType>::value
15237 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015 15238 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
15239 #if defined(JSON_HAS_CPP_17) && defined(_MSC_VER) and _MSC_VER <= 1914 15240 and not std::is_same<ValueType, typename std::string_view>::value
15243 and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
15244 ,
int >::type = 0 >
15245 operator ValueType()
const 15248 return get<ValueType>();
15291 if (JSON_LIKELY(is_array()))
15295 return m_value.array->at(idx);
15297 JSON_CATCH (std::out_of_range&)
15300 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
15305 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
15338 if (JSON_LIKELY(is_array()))
15342 return m_value.array->at(idx);
15344 JSON_CATCH (std::out_of_range&)
15347 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
15352 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
15386 reference at(
const typename object_t::key_type& key)
15389 if (JSON_LIKELY(is_object()))
15393 return m_value.object->at(key);
15395 JSON_CATCH (std::out_of_range&)
15398 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
15403 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
15440 if (JSON_LIKELY(is_object()))
15444 return m_value.object->at(key);
15446 JSON_CATCH (std::out_of_range&)
15449 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
15454 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
15488 m_type = value_t::array;
15489 m_value.
array = create<array_t>();
15490 assert_invariant();
15494 if (JSON_LIKELY(is_array()))
15497 if (idx >= m_value.array->size())
15499 m_value.array->insert(m_value.array->end(),
15500 idx - m_value.array->size() + 1,
15504 return m_value.array->operator[](idx);
15507 JSON_THROW(type_error::create(305,
"cannot use operator[] with a numeric argument with " + std::string(type_name())));
15532 if (JSON_LIKELY(is_array()))
15534 return m_value.
array->operator[](idx);
15537 JSON_THROW(type_error::create(305,
"cannot use operator[] with a numeric argument with " + std::string(type_name())));
15567 reference operator[](
const typename object_t::key_type& key)
15572 m_type = value_t::object;
15573 m_value.
object = create<object_t>();
15574 assert_invariant();
15578 if (JSON_LIKELY(is_object()))
15580 return m_value.object->operator[](key);
15583 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
15616 const_reference operator[](
const typename object_t::key_type& key)
const 15619 if (JSON_LIKELY(is_object()))
15621 assert(m_value.object->find(key) != m_value.object->end());
15625 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
15655 template<
typename T>
15661 m_type = value_t::object;
15662 m_value = value_t::object;
15663 assert_invariant();
15667 if (JSON_LIKELY(is_object()))
15669 return m_value.object->operator[](key);
15672 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
15705 template<
typename T>
15709 if (JSON_LIKELY(is_object()))
15711 assert(m_value.object->find(key) != m_value.object->end());
15715 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
15766 template<
class ValueType,
typename std::enable_if<
15767 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
15768 ValueType value(
const typename object_t::key_type& key,
const ValueType& default_value)
const 15771 if (JSON_LIKELY(is_object()))
15774 const auto it = find(key);
15780 return default_value;
15783 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
15790 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 15792 return value(key,
string_t(default_value));
15836 template<
class ValueType,
typename std::enable_if<
15837 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
15838 ValueType value(
const json_pointer& ptr,
const ValueType& default_value)
const 15841 if (JSON_LIKELY(is_object()))
15846 return ptr.get_checked(
this);
15850 return default_value;
15854 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
15863 return value(ptr,
string_t(default_value));
15998 template<
class IteratorType,
typename std::enable_if<
15999 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
16000 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>::type
16002 IteratorType erase(IteratorType pos)
16005 if (JSON_UNLIKELY(
this != pos.m_object))
16007 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
16010 IteratorType result = end();
16014 case value_t::boolean:
16015 case value_t::number_float:
16016 case value_t::number_integer:
16017 case value_t::number_unsigned:
16018 case value_t::string:
16020 if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
16022 JSON_THROW(invalid_iterator::create(205,
"iterator out of range"));
16027 AllocatorType<string_t> alloc;
16028 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
16029 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
16030 m_value.string =
nullptr;
16033 m_type = value_t::null;
16034 assert_invariant();
16038 case value_t::object:
16040 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
16044 case value_t::array:
16046 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
16051 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
16103 template<
class IteratorType,
typename std::enable_if<
16104 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
16105 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>::type
16107 IteratorType erase(IteratorType first, IteratorType last)
16110 if (JSON_UNLIKELY(
this != first.m_object or
this != last.m_object))
16112 JSON_THROW(invalid_iterator::create(203,
"iterators do not fit current value"));
16115 IteratorType result = end();
16119 case value_t::boolean:
16120 case value_t::number_float:
16121 case value_t::number_integer:
16122 case value_t::number_unsigned:
16123 case value_t::string:
16125 if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
16126 or not last.m_it.primitive_iterator.is_end()))
16128 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
16133 AllocatorType<string_t> alloc;
16134 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
16135 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
16136 m_value.string =
nullptr;
16139 m_type = value_t::null;
16140 assert_invariant();
16144 case value_t::object:
16146 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
16147 last.m_it.object_iterator);
16151 case value_t::array:
16153 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
16154 last.m_it.array_iterator);
16159 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
16194 size_type erase(
const typename object_t::key_type& key)
16197 if (JSON_LIKELY(is_object()))
16199 return m_value.object->erase(key);
16202 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
16232 if (JSON_LIKELY(is_array()))
16234 if (JSON_UNLIKELY(idx >= size()))
16236 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
16239 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
16243 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
16279 template<
typename KeyT>
16282 auto result = end();
16286 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
16296 template<
typename KeyT>
16299 auto result = cend();
16303 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
16330 template<
typename KeyT>
16334 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
16374 result.set_begin();
16414 result.set_begin();
16679 static iteration_proxy<iterator> iterator_wrapper(
reference ref) noexcept
16681 return ref.
items();
16688 static iteration_proxy<const_iterator> iterator_wrapper(
const_reference ref) noexcept
16690 return ref.
items();
16756 iteration_proxy<iterator> items() noexcept
16758 return iteration_proxy<iterator>(*this);
16764 iteration_proxy<const_iterator> items()
const noexcept
16766 return iteration_proxy<const_iterator>(*this);
16820 bool empty() const noexcept
16824 case value_t::null:
16830 case value_t::array:
16833 return m_value.array->empty();
16836 case value_t::object:
16839 return m_value.object->empty();
16896 case value_t::null:
16902 case value_t::array:
16905 return m_value.array->size();
16908 case value_t::object:
16911 return m_value.object->size();
16966 case value_t::array:
16969 return m_value.array->max_size();
16972 case value_t::object:
16975 return m_value.object->max_size();
17032 void clear() noexcept
17036 case value_t::number_integer:
17038 m_value.number_integer = 0;
17042 case value_t::number_unsigned:
17044 m_value.number_unsigned = 0;
17048 case value_t::number_float:
17050 m_value.number_float = 0.0;
17054 case value_t::boolean:
17056 m_value.boolean =
false;
17060 case value_t::string:
17062 m_value.string->clear();
17066 case value_t::array:
17068 m_value.array->clear();
17072 case value_t::object:
17074 m_value.object->clear();
17103 void push_back(basic_json&& val)
17106 if (JSON_UNLIKELY(not(is_null() or is_array())))
17108 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
17114 m_type = value_t::array;
17115 m_value = value_t::array;
17116 assert_invariant();
17120 m_value.array->push_back(std::move(val));
17122 val.m_type = value_t::null;
17131 push_back(std::move(val));
17139 void push_back(
const basic_json& val)
17142 if (JSON_UNLIKELY(not(is_null() or is_array())))
17144 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
17150 m_type = value_t::array;
17151 m_value = value_t::array;
17152 assert_invariant();
17156 m_value.array->push_back(val);
17163 reference operator+=(
const basic_json& val)
17189 void push_back(
const typename object_t::value_type& val)
17192 if (JSON_UNLIKELY(not(is_null() or is_object())))
17194 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
17200 m_type = value_t::object;
17201 m_value = value_t::object;
17202 assert_invariant();
17206 m_value.object->insert(val);
17213 reference operator+=(
const typename object_t::value_type& val)
17246 if (is_object() and init.size() == 2 and (*init.begin())->is_string())
17248 basic_json&& key = init.begin()->moved_or_copied();
17249 push_back(
typename object_t::value_type(
17250 std::move(key.
get_ref<
string_t&>()), (init.begin() + 1)->moved_or_copied()));
17254 push_back(basic_json(init));
17289 template<
class... Args>
17290 void emplace_back(Args&& ... args)
17293 if (JSON_UNLIKELY(not(is_null() or is_array())))
17295 JSON_THROW(type_error::create(311,
"cannot use emplace_back() with " + std::string(type_name())));
17301 m_type = value_t::array;
17302 m_value = value_t::array;
17303 assert_invariant();
17307 m_value.array->emplace_back(std::forward<Args>(args)...);
17337 template<
class... Args>
17338 std::pair<iterator, bool> emplace(Args&& ... args)
17341 if (JSON_UNLIKELY(not(is_null() or is_object())))
17343 JSON_THROW(type_error::create(311,
"cannot use emplace() with " + std::string(type_name())));
17349 m_type = value_t::object;
17350 m_value = value_t::object;
17351 assert_invariant();
17355 auto res = m_value.object->emplace(std::forward<Args>(args)...);
17358 it.m_it.object_iterator = res.first;
17361 return {it, res.second};
17367 template<
typename... Args>
17371 assert(m_value.array !=
nullptr);
17373 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
17374 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
17375 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
17409 if (JSON_LIKELY(is_array()))
17412 if (JSON_UNLIKELY(pos.m_object !=
this))
17414 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
17418 return insert_iterator(pos, val);
17421 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
17430 return insert(pos, val);
17460 if (JSON_LIKELY(is_array()))
17463 if (JSON_UNLIKELY(pos.m_object !=
this))
17465 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
17469 return insert_iterator(pos, cnt, val);
17472 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
17508 if (JSON_UNLIKELY(not is_array()))
17510 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
17514 if (JSON_UNLIKELY(pos.m_object !=
this))
17516 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
17520 if (JSON_UNLIKELY(first.m_object != last.m_object))
17522 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
17525 if (JSON_UNLIKELY(first.m_object ==
this))
17527 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container"));
17531 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
17561 if (JSON_UNLIKELY(not is_array()))
17563 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
17567 if (JSON_UNLIKELY(pos.m_object !=
this))
17569 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
17573 return insert_iterator(pos, ilist.begin(), ilist.end());
17602 if (JSON_UNLIKELY(not is_object()))
17604 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
17608 if (JSON_UNLIKELY(first.m_object != last.m_object))
17610 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
17614 if (JSON_UNLIKELY(not first.m_object->is_object()))
17616 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
17619 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
17646 m_type = value_t::object;
17647 m_value.object = create<object_t>();
17648 assert_invariant();
17651 if (JSON_UNLIKELY(not is_object()))
17653 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
17657 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(j.
type_name())));
17660 for (
auto it = j.
cbegin(); it != j.
cend(); ++it)
17662 m_value.object->operator[](it.key()) = it.value();
17697 m_type = value_t::object;
17698 m_value.object = create<object_t>();
17699 assert_invariant();
17702 if (JSON_UNLIKELY(not is_object()))
17704 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
17708 if (JSON_UNLIKELY(first.m_object != last.m_object))
17710 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
17714 if (JSON_UNLIKELY(not first.m_object->is_object()
17715 or not last.m_object->is_object()))
17717 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
17720 for (
auto it = first; it != last; ++it)
17722 m_value.object->operator[](it.key()) = it.value();
17744 std::is_nothrow_move_constructible<value_t>::value and
17745 std::is_nothrow_move_assignable<value_t>::value and
17746 std::is_nothrow_move_constructible<json_value>::value and
17747 std::is_nothrow_move_assignable<json_value>::value
17750 std::swap(m_type, other.m_type);
17751 std::swap(m_value, other.m_value);
17752 assert_invariant();
17778 if (JSON_LIKELY(is_array()))
17780 std::swap(*(m_value.array), other);
17784 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
17811 if (JSON_LIKELY(is_object()))
17813 std::swap(*(m_value.object), other);
17817 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
17844 if (JSON_LIKELY(is_string()))
17846 std::swap(*(m_value.string), other);
17850 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
17905 const auto lhs_type = lhs.type();
17906 const auto rhs_type = rhs.type();
17908 if (lhs_type == rhs_type)
17912 case value_t::array:
17913 return (*lhs.m_value.array == *rhs.m_value.array);
17915 case value_t::object:
17916 return (*lhs.m_value.object == *rhs.m_value.object);
17918 case value_t::null:
17921 case value_t::string:
17922 return (*lhs.m_value.string == *rhs.m_value.string);
17924 case value_t::boolean:
17925 return (lhs.m_value.boolean == rhs.m_value.boolean);
17927 case value_t::number_integer:
17928 return (lhs.m_value.number_integer == rhs.m_value.number_integer);
17930 case value_t::number_unsigned:
17931 return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
17933 case value_t::number_float:
17934 return (lhs.m_value.number_float == rhs.m_value.number_float);
17940 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
17942 return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
17944 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
17946 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
17948 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
17950 return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
17952 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
17954 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
17956 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
17958 return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
17960 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
17962 return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
17972 template<
typename ScalarType,
typename std::enable_if<
17973 std::is_scalar<ScalarType>::value,
int>::type = 0>
17974 friend bool operator==(
const_reference lhs,
const ScalarType rhs) noexcept
17976 return (lhs == basic_json(rhs));
17983 template<
typename ScalarType,
typename std::enable_if<
17984 std::is_scalar<ScalarType>::value,
int>::type = 0>
17985 friend bool operator==(
const ScalarType lhs,
const_reference rhs) noexcept
17987 return (basic_json(lhs) == rhs);
18010 return not (lhs == rhs);
18017 template<
typename ScalarType,
typename std::enable_if<
18018 std::is_scalar<ScalarType>::value,
int>::type = 0>
18019 friend bool operator!=(
const_reference lhs,
const ScalarType rhs) noexcept
18021 return (lhs != basic_json(rhs));
18028 template<
typename ScalarType,
typename std::enable_if<
18029 std::is_scalar<ScalarType>::value,
int>::type = 0>
18030 friend bool operator!=(
const ScalarType lhs,
const_reference rhs) noexcept
18032 return (basic_json(lhs) != rhs);
18063 const auto lhs_type = lhs.
type();
18064 const auto rhs_type = rhs.type();
18066 if (lhs_type == rhs_type)
18070 case value_t::array:
18071 return (*lhs.m_value.array) < (*rhs.m_value.array);
18073 case value_t::object:
18074 return *lhs.m_value.object < *rhs.m_value.object;
18076 case value_t::null:
18079 case value_t::string:
18080 return *lhs.m_value.string < *rhs.m_value.string;
18082 case value_t::boolean:
18083 return lhs.m_value.boolean < rhs.m_value.boolean;
18085 case value_t::number_integer:
18086 return lhs.m_value.number_integer < rhs.m_value.number_integer;
18088 case value_t::number_unsigned:
18089 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
18091 case value_t::number_float:
18092 return lhs.m_value.number_float < rhs.m_value.number_float;
18098 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
18100 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
18102 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
18104 return lhs.m_value.number_float <
static_cast<number_float_t
>(rhs.m_value.number_integer);
18106 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
18108 return static_cast<number_float_t
>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
18110 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
18112 return lhs.m_value.number_float <
static_cast<number_float_t
>(rhs.m_value.number_unsigned);
18114 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
18116 return lhs.m_value.number_integer <
static_cast<number_integer_t
>(rhs.m_value.number_unsigned);
18118 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
18120 return static_cast<number_integer_t
>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
18126 return operator<(lhs_type, rhs_type);
18133 template<
typename ScalarType,
typename std::enable_if<
18134 std::is_scalar<ScalarType>::value,
int>::type = 0>
18135 friend bool operator<(const_reference lhs,
const ScalarType rhs) noexcept
18137 return (lhs < basic_json(rhs));
18144 template<
typename ScalarType,
typename std::enable_if<
18145 std::is_scalar<ScalarType>::value,
int>::type = 0>
18146 friend bool operator<(
const ScalarType lhs, const_reference rhs) noexcept
18148 return (basic_json(lhs) < rhs);
18172 return not (rhs < lhs);
18179 template<
typename ScalarType,
typename std::enable_if<
18180 std::is_scalar<ScalarType>::value,
int>::type = 0>
18181 friend bool operator<=(
const_reference lhs,
const ScalarType rhs) noexcept
18183 return (lhs <= basic_json(rhs));
18190 template<
typename ScalarType,
typename std::enable_if<
18191 std::is_scalar<ScalarType>::value,
int>::type = 0>
18192 friend bool operator<=(
const ScalarType lhs,
const_reference rhs) noexcept
18194 return (basic_json(lhs) <= rhs);
18218 return not (lhs <= rhs);
18225 template<
typename ScalarType,
typename std::enable_if<
18226 std::is_scalar<ScalarType>::value,
int>::type = 0>
18227 friend bool operator>(
const_reference lhs,
const ScalarType rhs) noexcept
18229 return (lhs > basic_json(rhs));
18236 template<
typename ScalarType,
typename std::enable_if<
18237 std::is_scalar<ScalarType>::value,
int>::type = 0>
18238 friend bool operator>(
const ScalarType lhs,
const_reference rhs) noexcept
18240 return (basic_json(lhs) > rhs);
18264 return not (lhs < rhs);
18271 template<
typename ScalarType,
typename std::enable_if<
18272 std::is_scalar<ScalarType>::value,
int>::type = 0>
18273 friend bool operator>=(
const_reference lhs,
const ScalarType rhs) noexcept
18275 return (lhs >= basic_json(rhs));
18282 template<
typename ScalarType,
typename std::enable_if<
18283 std::is_scalar<ScalarType>::value,
int>::type = 0>
18284 friend bool operator>=(
const ScalarType lhs,
const_reference rhs) noexcept
18286 return (basic_json(lhs) >= rhs);
18329 friend std::ostream& operator<<(std::ostream& o,
const basic_json& j)
18332 const bool pretty_print = (o.width() > 0);
18333 const auto indentation = (pretty_print ? o.width() : 0);
18339 serializer s(detail::output_adapter<char>(o), o.fill());
18340 s.dump(j, pretty_print,
false, static_cast<unsigned int>(indentation));
18353 friend std::ostream& operator>>(
const basic_json& j, std::ostream& o)
18432 static basic_json parse(detail::input_adapter&& i,
18434 const bool allow_exceptions =
true)
18437 parser(i, cb, allow_exceptions).
parse(
true, result);
18441 static bool accept(detail::input_adapter&& i)
18443 return parser(i).
accept(
true);
18502 template <
typename SAX>
18503 static bool sax_parse(detail::input_adapter&& i, SAX* sax,
18504 input_format_t format = input_format_t::json,
18505 const bool strict =
true)
18510 case input_format_t::json:
18511 return parser(std::move(i)).sax_parse(sax, strict);
18513 return detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
18564 template<
class IteratorType,
typename std::enable_if<
18566 std::random_access_iterator_tag,
18567 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
18568 static basic_json parse(IteratorType first, IteratorType last,
18570 const bool allow_exceptions =
true)
18573 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(
true, result);
18577 template<
class IteratorType,
typename std::enable_if<
18579 std::random_access_iterator_tag,
18580 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
18581 static bool accept(IteratorType first, IteratorType last)
18583 return parser(detail::input_adapter(first, last)).
accept(
true);
18586 template<
class IteratorType,
class SAX,
typename std::enable_if<
18588 std::random_access_iterator_tag,
18589 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
18590 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
18592 return parser(detail::input_adapter(first, last)).sax_parse(sax);
18604 friend std::istream& operator<<(basic_json& j, std::istream& i)
18606 return operator>>(i, j);
18634 friend std::istream& operator>>(std::istream& i, basic_json& j)
18636 parser(detail::input_adapter(i)).parse(
false, j);
18676 const char* type_name()
const noexcept
18681 case value_t::null:
18683 case value_t::object:
18685 case value_t::array:
18687 case value_t::string:
18689 case value_t::boolean:
18691 case value_t::discarded:
18692 return "discarded";
18706 value_t m_type = value_t::null;
18709 json_value m_value = {};
18807 static std::vector<uint8_t> to_cbor(
const basic_json& j)
18809 std::vector<uint8_t> result;
18810 to_cbor(j, result);
18814 static void to_cbor(
const basic_json& j, detail::output_adapter<uint8_t> o)
18816 binary_writer<uint8_t>(o).write_cbor(j);
18819 static void to_cbor(
const basic_json& j, detail::output_adapter<char> o)
18821 binary_writer<char>(o).write_cbor(j);
18903 static std::vector<uint8_t> to_msgpack(
const basic_json& j)
18905 std::vector<uint8_t> result;
18906 to_msgpack(j, result);
18910 static void to_msgpack(
const basic_json& j, detail::output_adapter<uint8_t> o)
18912 binary_writer<uint8_t>(o).write_msgpack(j);
18915 static void to_msgpack(
const basic_json& j, detail::output_adapter<char> o)
18917 binary_writer<char>(o).write_msgpack(j);
19000 static std::vector<uint8_t> to_ubjson(
const basic_json& j,
19001 const bool use_size =
false,
19002 const bool use_type =
false)
19004 std::vector<uint8_t> result;
19005 to_ubjson(j, result, use_size, use_type);
19009 static void to_ubjson(
const basic_json& j, detail::output_adapter<uint8_t> o,
19010 const bool use_size =
false,
const bool use_type =
false)
19012 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
19015 static void to_ubjson(
const basic_json& j, detail::output_adapter<char> o,
19016 const bool use_size =
false,
const bool use_type =
false)
19018 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
19077 static std::vector<uint8_t> to_bson(
const basic_json& j)
19079 std::vector<uint8_t> result;
19080 to_bson(j, result);
19092 static void to_bson(
const basic_json& j, detail::output_adapter<uint8_t> o)
19094 binary_writer<uint8_t>(o).write_bson(j);
19100 static void to_bson(
const basic_json& j, detail::output_adapter<char> o)
19102 binary_writer<char>(o).write_bson(j);
19203 static basic_json from_cbor(detail::input_adapter&& i,
19204 const bool strict =
true,
19205 const bool allow_exceptions =
true)
19208 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19209 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::cbor, &sdp, strict);
19210 return res ? result : basic_json(value_t::discarded);
19216 template<
typename A1,
typename A2,
19217 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
19219 const bool strict =
true,
19220 const bool allow_exceptions =
true)
19223 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19224 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict);
19225 return res ? result : basic_json(value_t::discarded);
19308 static basic_json from_msgpack(detail::input_adapter&& i,
19309 const bool strict =
true,
19310 const bool allow_exceptions =
true)
19313 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19314 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::msgpack, &sdp, strict);
19315 return res ? result : basic_json(value_t::discarded);
19321 template<
typename A1,
typename A2,
19322 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
19324 const bool strict =
true,
19325 const bool allow_exceptions =
true)
19328 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19329 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict);
19330 return res ? result : basic_json(value_t::discarded);
19392 static basic_json from_ubjson(detail::input_adapter&& i,
19393 const bool strict =
true,
19394 const bool allow_exceptions =
true)
19397 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19398 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::ubjson, &sdp, strict);
19399 return res ? result : basic_json(value_t::discarded);
19405 template<
typename A1,
typename A2,
19406 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
19408 const bool strict =
true,
19409 const bool allow_exceptions =
true)
19412 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19413 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict);
19414 return res ? result : basic_json(value_t::discarded);
19475 static basic_json from_bson(detail::input_adapter&& i,
19476 const bool strict =
true,
19477 const bool allow_exceptions =
true)
19480 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19481 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::bson, &sdp, strict);
19482 return res ? result : basic_json(value_t::discarded);
19488 template<
typename A1,
typename A2,
19489 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
19491 const bool strict =
true,
19492 const bool allow_exceptions =
true)
19495 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19496 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::bson, &sdp, strict);
19497 return res ? result : basic_json(value_t::discarded);
19546 return ptr.get_unchecked(
this);
19574 return ptr.get_unchecked(
this);
19617 return ptr.get_checked(
this);
19660 return ptr.get_checked(
this);
19685 basic_json flatten()
const 19687 basic_json result(value_t::object);
19688 json_pointer::flatten(
"", *
this, result);
19722 basic_json unflatten()
const 19724 return json_pointer::unflatten(*
this);
19783 basic_json patch(
const basic_json& json_patch)
const 19786 basic_json result = *
this;
19789 enum class patch_operations {add,
remove, replace, move, copy, test, invalid};
19791 const auto get_op = [](
const std::string & op)
19795 return patch_operations::add;
19797 if (op ==
"remove")
19799 return patch_operations::remove;
19801 if (op ==
"replace")
19803 return patch_operations::replace;
19807 return patch_operations::move;
19811 return patch_operations::copy;
19815 return patch_operations::test;
19818 return patch_operations::invalid;
19822 const auto operation_add = [&result](
json_pointer & ptr, basic_json val)
19833 if (top_pointer != ptr)
19835 result.
at(top_pointer);
19839 const auto last_path = ptr.pop_back();
19840 basic_json& parent = result[ptr];
19842 switch (parent.m_type)
19844 case value_t::null:
19845 case value_t::object:
19848 parent[last_path] = val;
19852 case value_t::array:
19854 if (last_path ==
"-")
19862 if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.
size()))
19865 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
19886 const auto operation_remove = [&result](
json_pointer & ptr)
19889 const auto last_path = ptr.pop_back();
19890 basic_json& parent = result.
at(ptr);
19896 auto it = parent.
find(last_path);
19897 if (JSON_LIKELY(it != parent.
end()))
19903 JSON_THROW(out_of_range::create(403,
"key '" + last_path +
"' not found"));
19914 if (JSON_UNLIKELY(not json_patch.
is_array()))
19916 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
19920 for (
const auto& val : json_patch)
19923 const auto get_value = [&val](
const std::string & op,
19924 const std::string & member,
19925 bool string_type) -> basic_json &
19928 auto it = val.m_value.object->find(member);
19931 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
19934 if (JSON_UNLIKELY(it == val.m_value.object->end()))
19936 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have member '" + member +
"'"));
19940 if (JSON_UNLIKELY(string_type and not it->second.is_string()))
19942 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have string member '" + member +
"'"));
19950 if (JSON_UNLIKELY(not val.
is_object()))
19952 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
19956 const std::string op = get_value(
"op",
"op",
true);
19957 const std::string path = get_value(op,
"path",
true);
19960 switch (get_op(op))
19962 case patch_operations::add:
19964 operation_add(ptr, get_value(
"add",
"value",
false));
19968 case patch_operations::remove:
19970 operation_remove(ptr);
19974 case patch_operations::replace:
19977 result.
at(ptr) = get_value(
"replace",
"value",
false);
19981 case patch_operations::move:
19983 const std::string from_path = get_value(
"move",
"from",
true);
19987 basic_json v = result.
at(from_ptr);
19993 operation_remove(from_ptr);
19994 operation_add(ptr, v);
19998 case patch_operations::copy:
20000 const std::string from_path = get_value(
"copy",
"from",
true);
20004 basic_json v = result.
at(from_ptr);
20009 operation_add(ptr, v);
20013 case patch_operations::test:
20015 bool success =
false;
20020 success = (result.
at(ptr) == get_value(
"test",
"value",
false));
20028 if (JSON_UNLIKELY(not success))
20030 JSON_THROW(other_error::create(501,
"unsuccessful: " + val.
dump()));
20036 case patch_operations::invalid:
20040 JSON_THROW(parse_error::create(105, 0,
"operation value '" + op +
"' is invalid"));
20081 static basic_json diff(
const basic_json& source,
const basic_json& target,
20082 const std::string& path =
"")
20085 basic_json result(value_t::array);
20088 if (source == target)
20093 if (source.
type() != target.
type())
20098 {
"op",
"replace"}, {
"path", path}, {
"value", target}
20103 switch (source.
type())
20105 case value_t::array:
20109 while (i < source.
size() and i < target.
size())
20112 auto temp_diff = diff(source[i], target[i], path +
"/" + std::to_string(i));
20113 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
20122 while (i < source.
size())
20126 result.
insert(result.
begin() + end_index, object(
20129 {
"path", path +
"/" + std::to_string(i)}
20135 while (i < target.
size())
20140 {
"path", path +
"/" + std::to_string(i)},
20141 {
"value", target[i]}
20149 case value_t::object:
20152 for (
auto it = source.
cbegin(); it != source.
cend(); ++it)
20155 const auto key = json_pointer::escape(it.key());
20157 if (target.
find(it.key()) != target.
end())
20160 auto temp_diff = diff(it.value(), target[it.key()], path +
"/" + key);
20161 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
20168 {
"op",
"remove"}, {
"path", path +
"/" + key}
20174 for (
auto it = target.
cbegin(); it != target.
cend(); ++it)
20176 if (source.
find(it.key()) == source.
end())
20179 const auto key = json_pointer::escape(it.key());
20182 {
"op",
"add"}, {
"path", path +
"/" + key},
20183 {
"value", it.value()}
20196 {
"op",
"replace"}, {
"path", path}, {
"value", target}
20257 void merge_patch(
const basic_json& apply_patch)
20261 if (not is_object())
20265 for (
auto it = apply_patch.
begin(); it != apply_patch.
end(); ++it)
20267 if (it.value().is_null())
20273 operator[](it.key()).merge_patch(it.value());
20279 *
this = apply_patch;
20297 struct hash<nlohmann::
json>
20307 const auto& h = hash<nlohmann::json::string_t>();
20308 return h(j.
dump());
20316 struct less< ::nlohmann::detail::value_t>
20322 bool operator()(nlohmann::detail::value_t lhs,
20323 nlohmann::detail::value_t rhs)
const noexcept
20325 return nlohmann::detail::operator<(lhs, rhs);
20336 is_nothrow_move_constructible<nlohmann::json>::value and
20337 is_nothrow_move_assignable<nlohmann::json>::value
20358 inline nlohmann::json operator "" _json(
const char* s, std::size_t n)
20385 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 20386 #pragma GCC diagnostic pop 20388 #if defined(__clang__) 20389 #pragma GCC diagnostic pop 20393 #undef JSON_INTERNAL_CATCH 20398 #undef JSON_UNLIKELY 20399 #undef JSON_DEPRECATED 20400 #undef JSON_HAS_CPP_14 20401 #undef JSON_HAS_CPP_17 20402 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION 20403 #undef NLOHMANN_BASIC_JSON_TPL iter_impl< basic_json > iterator
an iterator for a basic_json container
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
typename BasicJsonType::number_unsigned_t number_unsigned_t
type for unsigned integers
static std::vector< uint8_t > to_bson(const basic_json &j)
Serializes the given JSON object j to BSON and returns a vector containing the corresponding BSON-rep...
JSONSerializer< T, SFINAE > json_serializer
NumberFloatType number_float_t
a type for a number (floating-point)
BooleanType boolean_t
a type for a boolean
static basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
iterator begin() noexcept
returns an iterator to the first element
iterator end() noexcept
returns an iterator to one past the last element
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
static std::vector< uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
ReferenceType get_ref()
get a reference value (implicit)
a class to store JSON values
static bool accept(detail::input_adapter &&i)
default JSONSerializer template argument
iterator find(KeyT &&key)
find an element in a JSON object
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
detail::other_error other_error
exception indicating other library errors
reference at(size_type idx)
access specified array element with bounds checking
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
typename parser::parser_callback_t parser_callback_t
per-element parser callback type
std::size_t size_type
a type to represent container sizes
std::less< StringType > object_comparator_t
static basic_json from_msgpack(detail::input_adapter &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
NumberIntegerType number_integer_t
a type for a number (integer)
constexpr bool is_array() const noexcept
return whether value is an array
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > >> object_t
a type for an object
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
size_type size() const noexcept
returns the number of elements
detail::out_of_range out_of_range
exception indicating access out of the defined range
const_iterator cbegin() const noexcept
returns a const iterator to the first element
static int array_index(const std::string &s)
constexpr const auto & from_json
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
detail::type_error type_error
exception indicating executing a member function with a wrong type
typename BasicJsonType::string_t string_t
type for strings
static basic_json from_bson(detail::input_adapter &&i, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
namespace for Niels Lohmann
constexpr bool is_object() const noexcept
return whether value is an object
static basic_json from_cbor(detail::input_adapter &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in CBOR format
detail::parse_error parse_error
exception indicating a parse error
typename BasicJsonType::number_integer_t number_integer_t
type for (signed) integers
const_iterator cend() const noexcept
returns a const iterator to one past the last element
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
typename BasicJsonType::number_float_t number_float_t
type for floating-point numbers
constexpr const auto & to_json
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
std::ptrdiff_t difference_type
a type to represent differences between iterators
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
AllocatorType< basic_json > allocator_type
the allocator type
typename parser::parse_event_t parse_event_t
parser event types
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
StringType string_t
a type for a string
static basic_json from_ubjson(detail::input_adapter &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
void push_back(basic_json &&val)
add an object to an array
iterator insert(const_iterator pos, const basic_json &val)
inserts element
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
detail::exception exception
general exception of the basic_json class
detail::invalid_iterator invalid_iterator
exception indicating errors with iterators
static basic_json parse(detail::input_adapter &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true)
deserialize from a compatible input
IteratorType erase(IteratorType pos)
remove element given an iterator
json_pointer(const std::string &s="")
create JSON pointer
const char * type_name() const noexcept
return the type as string