29 #ifndef NLOHMANN_JSON_HPP 30 #define NLOHMANN_JSON_HPP 42 #include <forward_list> 44 #include <initializer_list> 54 #include <type_traits> 59 #if defined(__clang__) 60 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 61 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" 63 #elif defined(__GNUC__) 64 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900 65 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" 70 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 71 #pragma GCC diagnostic push 72 #pragma GCC diagnostic ignored "-Wfloat-equal" 76 #if defined(__clang__) 77 #pragma GCC diagnostic push 78 #pragma GCC diagnostic ignored "-Wdocumentation" 82 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 83 #define JSON_DEPRECATED __attribute__((deprecated)) 84 #elif defined(_MSC_VER) 85 #define JSON_DEPRECATED __declspec(deprecated) 87 #define JSON_DEPRECATED 91 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && not defined(JSON_NOEXCEPTION) 92 #define JSON_THROW(exception) throw exception 94 #define JSON_CATCH(exception) catch(exception) 96 #define JSON_THROW(exception) std::abort() 97 #define JSON_TRY if(true) 98 #define JSON_CATCH(exception) if(false) 135 class exception :
public std::exception
139 virtual const char* what()
const noexcept
override 148 exception(
int id_,
const char* what_arg)
149 : id(id_), m(what_arg)
152 static std::string name(
const std::string& ename,
int id)
154 return "[json.exception." + ename +
"." + std::to_string(
id) +
"] ";
159 std::runtime_error m;
197 class parse_error :
public exception
208 static parse_error create(
int id,
size_t byte_,
const std::string& what_arg)
210 std::string w = exception::name(
"parse_error",
id) +
"parse error" +
211 (byte_ != 0 ? (
" at " + std::to_string(byte_)) :
"") +
213 return parse_error(
id, byte_, w.c_str());
229 parse_error(
int id_,
size_t byte_,
const char* what_arg)
230 : exception(id_, what_arg), byte(byte_)
258 class invalid_iterator :
public exception
261 static invalid_iterator create(
int id,
const std::string& what_arg)
263 std::string w = exception::name(
"invalid_iterator",
id) + what_arg;
264 return invalid_iterator(
id, w.c_str());
268 invalid_iterator(
int id_,
const char* what_arg)
269 : exception(id_, what_arg)
297 class type_error :
public exception
300 static type_error create(
int id,
const std::string& what_arg)
302 std::string w = exception::name(
"type_error",
id) + what_arg;
303 return type_error(
id, w.c_str());
307 type_error(
int id_,
const char* what_arg)
308 : exception(id_, what_arg)
328 class out_of_range :
public exception
331 static out_of_range create(
int id,
const std::string& what_arg)
333 std::string w = exception::name(
"out_of_range",
id) + what_arg;
334 return out_of_range(
id, w.c_str());
338 out_of_range(
int id_,
const char* what_arg)
339 : exception(id_, what_arg)
354 class other_error :
public exception
357 static other_error create(
int id,
const std::string& what_arg)
359 std::string w = exception::name(
"other_error",
id) + what_arg;
360 return other_error(
id, w.c_str());
364 other_error(
int id_,
const char* what_arg)
365 : exception(id_, what_arg)
399 enum class value_t : uint8_t
421 inline bool operator<(
const value_t lhs,
const value_t rhs) noexcept
423 static constexpr std::array<uint8_t, 8> order = {{
436 if (lhs == value_t::discarded or rhs == value_t::discarded)
441 return order[
static_cast<std::size_t
>(lhs)] <
442 order[static_cast<std::size_t>(rhs)];
451 template<
bool B,
typename T =
void>
452 using enable_if_t =
typename std::enable_if<B, T>::type;
455 using uncvref_t =
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
470 template<
class...>
struct conjunction : std::true_type {};
471 template<
class B1>
struct conjunction<B1> : B1 {};
472 template<
class B1,
class... Bn>
473 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
475 template<
class B>
struct negation : std::integral_constant < bool, !B::value > {};
478 template<
unsigned N>
struct priority_tag : priority_tag < N - 1 > {};
479 template<>
struct priority_tag<0> {};
486 template<value_t>
struct external_constructor;
489 struct external_constructor<value_t::boolean>
491 template<
typename BasicJsonType>
492 static void construct(BasicJsonType& j,
typename BasicJsonType::boolean_t b) noexcept
494 j.m_type = value_t::boolean;
496 j.assert_invariant();
501 struct external_constructor<value_t::string>
503 template<
typename BasicJsonType>
504 static void construct(BasicJsonType& j,
const typename BasicJsonType::string_t& s)
506 j.m_type = value_t::string;
508 j.assert_invariant();
513 struct external_constructor<value_t::number_float>
515 template<
typename BasicJsonType>
516 static void construct(BasicJsonType& j,
typename BasicJsonType::number_float_t val) noexcept
518 j.m_type = value_t::number_float;
520 j.assert_invariant();
525 struct external_constructor<value_t::number_unsigned>
527 template<
typename BasicJsonType>
528 static void construct(BasicJsonType& j,
typename BasicJsonType::number_unsigned_t val) noexcept
530 j.m_type = value_t::number_unsigned;
532 j.assert_invariant();
537 struct external_constructor<value_t::number_integer>
539 template<
typename BasicJsonType>
540 static void construct(BasicJsonType& j,
typename BasicJsonType::number_integer_t val) noexcept
542 j.m_type = value_t::number_integer;
544 j.assert_invariant();
549 struct external_constructor<value_t::array>
551 template<
typename BasicJsonType>
552 static void construct(BasicJsonType& j,
const typename BasicJsonType::array_t& arr)
554 j.m_type = value_t::array;
556 j.assert_invariant();
559 template<
typename BasicJsonType,
typename CompatibleArrayType,
560 enable_if_t<not std::is_same<CompatibleArrayType,
561 typename BasicJsonType::array_t>::value,
563 static void construct(BasicJsonType& j,
const CompatibleArrayType& arr)
567 j.m_type = value_t::array;
568 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
569 j.assert_invariant();
572 template<
typename BasicJsonType>
573 static void construct(BasicJsonType& j,
const std::vector<bool>& arr)
575 j.m_type = value_t::array;
576 j.m_value = value_t::array;
577 j.m_value.array->reserve(arr.size());
580 j.m_value.array->push_back(x);
582 j.assert_invariant();
587 struct external_constructor<value_t::object>
589 template<
typename BasicJsonType>
590 static void construct(BasicJsonType& j,
const typename BasicJsonType::object_t& obj)
592 j.m_type = value_t::object;
594 j.assert_invariant();
597 template<
typename BasicJsonType,
typename CompatibleObjectType,
598 enable_if_t<not std::is_same<CompatibleObjectType,
599 typename BasicJsonType::object_t>::value,
601 static void construct(BasicJsonType& j,
const CompatibleObjectType& obj)
606 j.m_type = value_t::object;
607 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
608 j.assert_invariant();
627 #define NLOHMANN_JSON_HAS_HELPER(type) \ 628 template<typename T> struct has_##type { \ 630 template<typename U, typename = typename U::type> \ 631 static int detect(U &&); \ 632 static void detect(...); \ 634 static constexpr bool value = \ 635 std::is_integral<decltype(detect(std::declval<T>()))>::value; \ 638 NLOHMANN_JSON_HAS_HELPER(mapped_type);
639 NLOHMANN_JSON_HAS_HELPER(key_type);
640 NLOHMANN_JSON_HAS_HELPER(value_type);
641 NLOHMANN_JSON_HAS_HELPER(iterator);
643 #undef NLOHMANN_JSON_HAS_HELPER 646 template<
bool B,
class RealType,
class CompatibleObjectType>
647 struct is_compatible_object_type_impl : std::false_type {};
649 template<
class RealType,
class CompatibleObjectType>
650 struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType>
652 static constexpr
auto value =
653 std::is_constructible<
typename RealType::key_type,
654 typename CompatibleObjectType::key_type>::value and
655 std::is_constructible<
typename RealType::mapped_type,
656 typename CompatibleObjectType::mapped_type>::value;
659 template<
class BasicJsonType,
class CompatibleObjectType>
660 struct is_compatible_object_type
662 static auto constexpr value = is_compatible_object_type_impl <
663 conjunction<negation<std::is_same<void, CompatibleObjectType>>,
664 has_mapped_type<CompatibleObjectType>,
665 has_key_type<CompatibleObjectType>>::value,
666 typename BasicJsonType::object_t, CompatibleObjectType >::value;
669 template<
typename BasicJsonType,
typename T>
670 struct is_basic_json_nested_type
672 static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
673 std::is_same<T, typename BasicJsonType::const_iterator>::value or
674 std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
675 std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value or
676 std::is_same<T, typename BasicJsonType::json_pointer>::value;
679 template<
class BasicJsonType,
class CompatibleArrayType>
680 struct is_compatible_array_type
682 static auto constexpr value =
683 conjunction<negation<std::is_same<void, CompatibleArrayType>>,
684 negation<is_compatible_object_type<
685 BasicJsonType, CompatibleArrayType>>,
686 negation<std::is_constructible<
typename BasicJsonType::string_t,
687 CompatibleArrayType>>,
688 negation<is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>>,
689 has_value_type<CompatibleArrayType>,
690 has_iterator<CompatibleArrayType>>::value;
693 template<
bool,
typename,
typename>
694 struct is_compatible_integer_type_impl : std::false_type {};
696 template<
typename RealIntegerType,
typename CompatibleNumberIntegerType>
697 struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType>
700 using RealLimits = std::numeric_limits<RealIntegerType>;
701 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
703 static constexpr
auto value =
704 std::is_constructible<RealIntegerType,
705 CompatibleNumberIntegerType>::value and
706 CompatibleLimits::is_integer and
707 RealLimits::is_signed == CompatibleLimits::is_signed;
710 template<
typename RealIntegerType,
typename CompatibleNumberIntegerType>
711 struct is_compatible_integer_type
713 static constexpr
auto value =
714 is_compatible_integer_type_impl <
715 std::is_integral<CompatibleNumberIntegerType>::value and
716 not std::is_same<bool, CompatibleNumberIntegerType>::value,
717 RealIntegerType, CompatibleNumberIntegerType > ::value;
722 template<
typename BasicJsonType,
typename T>
727 template<typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
728 std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
729 static int detect(U&&);
730 static void detect(...);
733 static constexpr
bool value = std::is_integral<decltype(
734 detect(std::declval<
typename BasicJsonType::template json_serializer<T, void>>()))>::value;
739 template<
typename BasicJsonType,
typename T>
740 struct has_non_default_from_json
745 typename = enable_if_t<std::is_same<
746 T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
747 static int detect(U&&);
748 static void detect(...);
751 static constexpr
bool value = std::is_integral<decltype(detect(
752 std::declval<
typename BasicJsonType::template json_serializer<T, void>>()))>::value;
756 template<
typename BasicJsonType,
typename T>
760 template<typename U, typename = decltype(uncvref_t<U>::to_json(
761 std::declval<BasicJsonType&>(), std::declval<T>()))>
762 static int detect(U&&);
763 static void detect(...);
766 static constexpr
bool value = std::is_integral<decltype(detect(
767 std::declval<
typename BasicJsonType::template json_serializer<T, void>>()))>::value;
775 template<
typename BasicJsonType,
typename T, enable_if_t<
776 std::is_same<T, typename BasicJsonType::boolean_t>::value,
int> = 0>
777 void to_json(BasicJsonType& j, T b) noexcept
779 external_constructor<value_t::boolean>::construct(j, b);
782 template<
typename BasicJsonType,
typename CompatibleString,
783 enable_if_t<std::is_constructible<
typename BasicJsonType::string_t,
784 CompatibleString>::value,
int> = 0>
785 void to_json(BasicJsonType& j,
const CompatibleString& s)
787 external_constructor<value_t::string>::construct(j, s);
790 template<
typename BasicJsonType,
typename FloatType,
791 enable_if_t<std::is_floating_point<FloatType>::value,
int> = 0>
792 void to_json(BasicJsonType& j, FloatType val) noexcept
794 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
798 typename BasicJsonType,
typename CompatibleNumberUnsignedType,
799 enable_if_t<is_compatible_integer_type<
typename BasicJsonType::number_unsigned_t,
800 CompatibleNumberUnsignedType>::value,
int> = 0 >
801 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
803 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
807 typename BasicJsonType,
typename CompatibleNumberIntegerType,
808 enable_if_t<is_compatible_integer_type<
typename BasicJsonType::number_integer_t,
809 CompatibleNumberIntegerType>::value,
int> = 0 >
810 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
812 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
815 template<
typename BasicJsonType,
typename EnumType,
816 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
817 void to_json(BasicJsonType& j, EnumType e) noexcept
819 using underlying_type =
typename std::underlying_type<EnumType>::type;
820 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
823 template<
typename BasicJsonType>
824 void to_json(BasicJsonType& j,
const std::vector<bool>& e)
826 external_constructor<value_t::array>::construct(j, e);
830 typename BasicJsonType,
typename CompatibleArrayType,
832 is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value or
833 std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
835 void to_json(BasicJsonType& j,
const CompatibleArrayType& arr)
837 external_constructor<value_t::array>::construct(j, arr);
841 typename BasicJsonType,
typename CompatibleObjectType,
842 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
844 void to_json(BasicJsonType& j,
const CompatibleObjectType& arr)
846 external_constructor<value_t::object>::construct(j, arr);
849 template <
typename BasicJsonType,
typename T, std::size_t N,
850 enable_if_t<not std::is_constructible<
851 typename BasicJsonType::string_t, T (&)[N]>::value,
853 void to_json(BasicJsonType& j, T (&arr)[N])
855 external_constructor<value_t::array>::construct(j, arr);
863 template<
typename BasicJsonType,
typename ArithmeticType,
864 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
865 not std::is_same<ArithmeticType,
866 typename BasicJsonType::boolean_t>::value,
868 void get_arithmetic_value(
const BasicJsonType& j, ArithmeticType& val)
870 switch (static_cast<value_t>(j))
872 case value_t::number_unsigned:
874 val =
static_cast<ArithmeticType
>(
875 *j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
878 case value_t::number_integer:
880 val =
static_cast<ArithmeticType
>(
881 *j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
884 case value_t::number_float:
886 val =
static_cast<ArithmeticType
>(
887 *j.template get_ptr<const typename BasicJsonType::number_float_t*>());
892 JSON_THROW(type_error::create(302,
"type must be number, but is " + j.type_name()));
897 template<
typename BasicJsonType>
898 void from_json(
const BasicJsonType& j,
typename BasicJsonType::boolean_t& b)
900 if (not j.is_boolean())
902 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + j.type_name()));
904 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
907 template<
typename BasicJsonType>
908 void from_json(
const BasicJsonType& j,
typename BasicJsonType::string_t& s)
910 if (not j.is_string())
912 JSON_THROW(type_error::create(302,
"type must be string, but is " + j.type_name()));
914 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
917 template<
typename BasicJsonType>
918 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_float_t& val)
920 get_arithmetic_value(j, val);
923 template<
typename BasicJsonType>
924 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_unsigned_t& val)
926 get_arithmetic_value(j, val);
929 template<
typename BasicJsonType>
930 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_integer_t& val)
932 get_arithmetic_value(j, val);
935 template<
typename BasicJsonType,
typename EnumType,
936 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
937 void from_json(
const BasicJsonType& j, EnumType& e)
939 typename std::underlying_type<EnumType>::type val;
940 get_arithmetic_value(j, val);
941 e =
static_cast<EnumType
>(val);
944 template<
typename BasicJsonType>
945 void from_json(
const BasicJsonType& j,
typename BasicJsonType::array_t& arr)
947 if (not j.is_array())
949 JSON_THROW(type_error::create(302,
"type must be array, but is " + j.type_name()));
951 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
955 template<
typename BasicJsonType,
typename T,
typename Allocator,
956 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
957 void from_json(
const BasicJsonType& j, std::forward_list<T, Allocator>& l)
959 if (not j.is_array())
961 JSON_THROW(type_error::create(302,
"type must be array, but is " + j.type_name()));
964 for (
auto it = j.rbegin(), end = j.rend(); it != end; ++it)
966 l.push_front(it->template get<T>());
970 template<
typename BasicJsonType,
typename CompatibleArrayType>
971 void from_json_array_impl(
const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0>)
976 std::transform(j.begin(), j.end(),
977 std::inserter(arr, end(arr)), [](
const BasicJsonType & i)
981 return i.template get<typename CompatibleArrayType::value_type>();
985 template<
typename BasicJsonType,
typename CompatibleArrayType>
986 auto from_json_array_impl(
const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1>)
988 arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
994 arr.reserve(j.size());
995 std::transform(j.begin(), j.end(),
996 std::inserter(arr, end(arr)), [](
const BasicJsonType & i)
1000 return i.template get<typename CompatibleArrayType::value_type>();
1004 template<
typename BasicJsonType,
typename CompatibleArrayType,
1005 enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
1006 std::is_convertible<BasicJsonType, typename CompatibleArrayType::value_type>::value and
1007 not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
int> = 0>
1008 void from_json(
const BasicJsonType& j, CompatibleArrayType& arr)
1010 if (not j.is_array())
1012 JSON_THROW(type_error::create(302,
"type must be array, but is " + j.type_name()));
1015 from_json_array_impl(j, arr, priority_tag<1> {});
1018 template<
typename BasicJsonType,
typename CompatibleObjectType,
1019 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
int> = 0>
1020 void from_json(
const BasicJsonType& j, CompatibleObjectType& obj)
1022 if (not j.is_object())
1024 JSON_THROW(type_error::create(302,
"type must be object, but is " + j.type_name()));
1027 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1033 obj = CompatibleObjectType(begin(*inner_object), end(*inner_object));
1040 template<
typename BasicJsonType,
typename ArithmeticType,
1042 std::is_arithmetic<ArithmeticType>::value and
1043 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1044 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1045 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1046 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1048 void from_json(
const BasicJsonType& j, ArithmeticType& val)
1050 switch (static_cast<value_t>(j))
1052 case value_t::number_unsigned:
1054 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1057 case value_t::number_integer:
1059 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1062 case value_t::number_float:
1064 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1067 case value_t::boolean:
1069 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1074 JSON_THROW(type_error::create(302,
"type must be number, but is " + j.type_name()));
1082 template<
typename BasicJsonType,
typename T>
1083 auto call(BasicJsonType& j, T&& val, priority_tag<1>)
const noexcept(noexcept(to_json(j, std::forward<T>(val))))
1084 -> decltype(to_json(j, std::forward<T>(val)),
void())
1086 return to_json(j, std::forward<T>(val));
1089 template<
typename BasicJsonType,
typename T>
1090 void call(BasicJsonType&, T&&, priority_tag<0>)
const noexcept
1092 static_assert(
sizeof(BasicJsonType) == 0,
1093 "could not find to_json() method in T's namespace");
1097 template<
typename BasicJsonType,
typename T>
1098 void operator()(BasicJsonType& j, T&& val)
const 1099 noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1> {})))
1101 return call(j, std::forward<T>(val), priority_tag<1> {});
1108 template<
typename BasicJsonType,
typename T>
1109 auto call(
const BasicJsonType& j, T& val, priority_tag<1>)
const 1110 noexcept(noexcept(from_json(j, val)))
1111 -> decltype(from_json(j, val),
void())
1113 return from_json(j, val);
1116 template<
typename BasicJsonType,
typename T>
1117 void call(
const BasicJsonType&, T&, priority_tag<0>)
const noexcept
1119 static_assert(
sizeof(BasicJsonType) == 0,
1120 "could not find from_json() method in T's namespace");
1124 template<
typename BasicJsonType,
typename T>
1125 void operator()(
const BasicJsonType& j, T& val)
const 1126 noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
1128 return call(j, val, priority_tag<1> {});
1133 template<
typename T>
1136 static constexpr T value{};
1139 template<
typename T>
1140 constexpr T static_const<T>::value;
1147 constexpr
const auto&
to_json = detail::static_const<detail::to_json_fn>::value;
1148 constexpr
const auto&
from_json = detail::static_const<detail::from_json_fn>::value;
1159 template<
typename =
void,
typename =
void>
1171 template<
typename BasicJsonType,
typename ValueType>
1172 static void from_json(BasicJsonType&& j, ValueType& val) noexcept(
1173 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
1175 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
1187 template<
typename BasicJsonType,
typename ValueType>
1188 static void to_json(BasicJsonType& j, ValueType&& val) noexcept(
1189 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
1191 ::nlohmann::to_json(j, std::forward<ValueType>(val));
1278 template<
typename U,
typename V,
typename... Args>
class ObjectType = std::map,
1279 template<
typename U,
typename... Args>
class ArrayType = std::vector,
1280 class StringType = std::string,
1281 class BooleanType = bool,
1282 class NumberIntegerType = std::int64_t,
1283 class NumberUnsignedType = std::uint64_t,
1284 class NumberFloatType = double,
1285 template<
typename U>
class AllocatorType = std::allocator,
1286 template<
typename T,
typename SFINAE =
void>
class JSONSerializer =
adl_serializer 1291 template<detail::value_t>
friend struct detail::external_constructor;
1294 BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType,
1295 AllocatorType, JSONSerializer>;
1298 using value_t = detail::value_t;
1303 template<
typename T,
typename SFINAE>
1357 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
1359 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
1408 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
1409 result[
"name"] =
"JSON for Modern C++";
1410 result[
"url"] =
"https://github.com/nlohmann/json";
1413 {
"string",
"2.1.1"}, {
"major", 2}, {
"minor", 1}, {
"patch", 1}
1417 result[
"platform"] =
"win32";
1418 #elif defined __linux__ 1419 result[
"platform"] =
"linux";
1420 #elif defined __APPLE__ 1421 result[
"platform"] =
"apple";
1422 #elif defined __unix__ 1423 result[
"platform"] =
"unix";
1425 result[
"platform"] =
"unknown";
1428 #if defined(__clang__) 1429 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
1430 #elif defined(__ICC) || defined(__INTEL_COMPILER) 1431 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
1432 #elif defined(__GNUC__) || defined(__GNUG__) 1433 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(__GNUC_PATCHLEVEL__)}};
1434 #elif defined(__HP_cc) || defined(__HP_aCC) 1435 result[
"compiler"] =
"hp" 1436 #elif defined(__IBMCPP__) 1437 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
1438 #elif defined(_MSC_VER) 1439 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
1440 #elif defined(__PGI) 1441 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
1442 #elif defined(__SUNPRO_CC) 1443 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
1445 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
1449 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
1451 result[
"compiler"][
"c++"] =
"unknown";
1549 using object_t = ObjectType<StringType,
1551 std::less<StringType>,
1552 AllocatorType<std::pair<
const StringType,
1599 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
1896 template<
typename T,
typename... Args>
1897 static T* create(Args&& ... args)
1899 AllocatorType<T> alloc;
1900 auto deleter = [&](T * object)
1902 alloc.deallocate(
object, 1);
1904 std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
1905 alloc.construct(
object.
get(), std::forward<Args>(args)...);
1906 assert(
object !=
nullptr);
1907 return object.release();
1956 json_value() =
default;
1958 json_value(
boolean_t v) noexcept : boolean(v) {}
1966 json_value(value_t t)
1970 case value_t::object:
1972 object = create<object_t>();
1976 case value_t::array:
1978 array = create<array_t>();
1982 case value_t::string:
1984 string = create<string_t>(
"");
1988 case value_t::boolean:
1994 case value_t::number_integer:
2000 case value_t::number_unsigned:
2006 case value_t::number_float:
2019 if (t == value_t::null)
2021 JSON_THROW(other_error::create(500,
"961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1"));
2031 string = create<string_t>(value);
2037 object = create<object_t>(value);
2041 json_value(
const array_t& value)
2043 array = create<array_t>(value);
2056 void assert_invariant()
const 2058 assert(m_type != value_t::object or m_value.object !=
nullptr);
2059 assert(m_type != value_t::array or m_value.array !=
nullptr);
2060 assert(m_type != value_t::string or m_value.string !=
nullptr);
2148 basic_json& parsed)>;
2185 : m_type(value_type), m_value(value_type)
2267 template<
typename CompatibleType,
typename U = detail::uncvref_t<CompatibleType>,
2268 detail::enable_if_t<not std::is_base_of<std::istream, U>::value and
2269 not std::is_same<U, basic_json_t>::value and
2270 not detail::is_basic_json_nested_type<
2271 basic_json_t, U>::value and
2272 detail::has_to_json<basic_json, U>::value,
2274 basic_json(CompatibleType && val) noexcept(noexcept(JSONSerializer<U>::to_json(
2275 std::declval<basic_json_t&>(), std::forward<CompatibleType>(val))))
2277 JSONSerializer<U>::to_json(*
this, std::forward<CompatibleType>(val));
2353 bool type_deduction =
true,
2354 value_t manual_type = value_t::array)
2358 bool is_an_object = std::all_of(init.begin(), init.end(),
2361 return element.is_array() and element.size() == 2 and element[0].is_string();
2365 if (not type_deduction)
2368 if (manual_type == value_t::array)
2370 is_an_object =
false;
2374 if (manual_type == value_t::object and not is_an_object)
2376 JSON_THROW(type_error::create(301,
"cannot create object from initializer list"));
2383 m_type = value_t::object;
2384 m_value = value_t::object;
2386 std::for_each(init.begin(), init.end(), [
this](
const basic_json & element)
2388 m_value.object->emplace(*(element[0].m_value.string), element[1]);
2394 m_type = value_t::array;
2395 m_value.array = create<array_t>(init);
2436 std::initializer_list<basic_json>())
2438 return basic_json(init,
false, value_t::array);
2477 std::initializer_list<basic_json>())
2479 return basic_json(init,
false, value_t::object);
2501 : m_type(value_t::array)
2503 m_value.array = create<array_t>(cnt, val);
2549 template<
class InputIT,
typename std::enable_if<
2550 std::is_same<InputIT, typename basic_json_t::iterator>::value or
2551 std::is_same<InputIT, typename basic_json_t::const_iterator>::value,
int>::type = 0>
2554 assert(first.m_object !=
nullptr);
2555 assert(last.m_object !=
nullptr);
2558 if (first.m_object != last.m_object)
2560 JSON_THROW(invalid_iterator::create(201,
"iterators are not compatible"));
2564 m_type = first.m_object->m_type;
2569 case value_t::boolean:
2570 case value_t::number_float:
2571 case value_t::number_integer:
2572 case value_t::number_unsigned:
2573 case value_t::string:
2575 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
2577 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
2590 case value_t::number_integer:
2592 m_value.number_integer = first.m_object->m_value.number_integer;
2596 case value_t::number_unsigned:
2598 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
2602 case value_t::number_float:
2604 m_value.number_float = first.m_object->m_value.number_float;
2608 case value_t::boolean:
2610 m_value.boolean = first.m_object->m_value.boolean;
2614 case value_t::string:
2616 m_value = *first.m_object->m_value.string;
2620 case value_t::object:
2622 m_value.object = create<object_t>(first.m_it.object_iterator,
2623 last.m_it.object_iterator);
2627 case value_t::array:
2629 m_value.array = create<array_t>(first.m_it.array_iterator,
2630 last.m_it.array_iterator);
2636 JSON_THROW(invalid_iterator::create(206,
"cannot construct with iterators from " +
2637 first.m_object->type_name()));
2670 : m_type(other.m_type)
2673 other.assert_invariant();
2677 case value_t::object:
2679 m_value = *other.m_value.object;
2683 case value_t::array:
2685 m_value = *other.m_value.array;
2689 case value_t::string:
2691 m_value = *other.m_value.string;
2695 case value_t::boolean:
2697 m_value = other.m_value.boolean;
2701 case value_t::number_integer:
2703 m_value = other.m_value.number_integer;
2707 case value_t::number_unsigned:
2709 m_value = other.m_value.number_unsigned;
2713 case value_t::number_float:
2715 m_value = other.m_value.number_float;
2747 : m_type(std::move(other.m_type)),
2748 m_value(std::move(other.m_value))
2751 other.assert_invariant();
2754 other.m_type = value_t::null;
2784 std::is_nothrow_move_constructible<value_t>::value and
2785 std::is_nothrow_move_assignable<value_t>::value and
2786 std::is_nothrow_move_constructible<json_value>::value and
2787 std::is_nothrow_move_assignable<json_value>::value
2791 other.assert_invariant();
2794 swap(m_type, other.m_type);
2795 swap(m_value, other.m_value);
2822 case value_t::object:
2824 AllocatorType<object_t> alloc;
2825 alloc.destroy(m_value.object);
2826 alloc.deallocate(m_value.object, 1);
2830 case value_t::array:
2832 AllocatorType<array_t> alloc;
2833 alloc.destroy(m_value.array);
2834 alloc.deallocate(m_value.array, 1);
2838 case value_t::string:
2840 AllocatorType<string_t> alloc;
2841 alloc.destroy(m_value.string);
2842 alloc.deallocate(m_value.string, 1);
2890 std::stringstream ss;
2895 s.dump(*
this,
true, static_cast<unsigned int>(indent));
2899 s.dump(*
this,
false, 0);
2923 constexpr value_t
type() const noexcept
2955 return is_null() or is_string() or is_boolean() or is_number();
2982 return is_array() or is_object();
3004 return m_type == value_t::null;
3026 return m_type == value_t::boolean;
3056 return is_number_integer() or is_number_float();
3085 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
3113 return m_type == value_t::number_unsigned;
3141 return m_type == value_t::number_float;
3163 return m_type == value_t::object;
3185 return m_type == value_t::array;
3207 return m_type == value_t::string;
3234 return m_type == value_t::discarded;
3255 constexpr
operator value_t() const noexcept
3272 return m_value.boolean;
3275 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + type_name()));
3281 return is_object() ? m_value.object :
nullptr;
3287 return is_object() ? m_value.object :
nullptr;
3293 return is_array() ? m_value.array :
nullptr;
3297 constexpr
const array_t* get_impl_ptr(
const array_t* )
const noexcept
3299 return is_array() ? m_value.array :
nullptr;
3305 return is_string() ? m_value.string :
nullptr;
3311 return is_string() ? m_value.string :
nullptr;
3317 return is_boolean() ? &m_value.boolean :
nullptr;
3323 return is_boolean() ? &m_value.boolean :
nullptr;
3329 return is_number_integer() ? &m_value.number_integer :
nullptr;
3335 return is_number_integer() ? &m_value.number_integer :
nullptr;
3341 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
3347 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
3353 return is_number_float() ? &m_value.number_float :
nullptr;
3359 return is_number_float() ? &m_value.number_float :
nullptr;
3373 template<
typename ReferenceType,
typename ThisType>
3374 static ReferenceType get_ref_impl(ThisType& obj)
3377 using PointerType =
typename std::add_pointer<ReferenceType>::type;
3380 auto ptr = obj.template get_ptr<PointerType>();
3387 JSON_THROW(type_error::create(303,
"incompatible ReferenceType for get_ref, actual type is " + obj.type_name()));
3410 typename BasicJsonType,
3411 detail::enable_if_t<std::is_same<typename std::remove_const<BasicJsonType>::type,
3459 typename ValueTypeCV,
3460 typename ValueType = detail::uncvref_t<ValueTypeCV>,
3461 detail::enable_if_t <
3462 not std::is_same<basic_json_t, ValueType>::value and
3463 detail::has_from_json<basic_json_t, ValueType>::value and
3464 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
3466 ValueType
get()
const noexcept(noexcept(
3467 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
3472 static_assert(not std::is_reference<ValueTypeCV>::value,
3473 "get() cannot be used with reference types, you might want to use get_ref()");
3474 static_assert(std::is_default_constructible<ValueType>::value,
3475 "types must be DefaultConstructible when used with get()");
3478 JSONSerializer<ValueType>::from_json(*
this, ret);
3514 typename ValueTypeCV,
3515 typename ValueType = detail::uncvref_t<ValueTypeCV>,
3516 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
3518 ValueType>::value,
int> = 0 >
3519 ValueType
get()
const noexcept(noexcept(
3520 JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
3522 static_assert(not std::is_reference<ValueTypeCV>::value,
3523 "get() cannot be used with reference types, you might want to use get_ref()");
3524 return JSONSerializer<ValueTypeCV>::from_json(*
this);
3554 template<
typename PointerType,
typename std::enable_if<
3555 std::is_pointer<PointerType>::value,
int>::type = 0>
3556 PointerType
get() noexcept
3559 return get_ptr<PointerType>();
3566 template<
typename PointerType,
typename std::enable_if<
3567 std::is_pointer<PointerType>::value,
int>::type = 0>
3568 constexpr
const PointerType
get()
const noexcept
3571 return get_ptr<PointerType>();
3600 template<
typename PointerType,
typename std::enable_if<
3601 std::is_pointer<PointerType>::value,
int>::type = 0>
3605 using pointee_t =
typename std::remove_const<
typename 3606 std::remove_pointer<
typename 3607 std::remove_const<PointerType>::type>::type>::type;
3610 std::is_same<object_t, pointee_t>::value
3611 or std::is_same<array_t, pointee_t>::value
3612 or std::is_same<string_t, pointee_t>::value
3613 or std::is_same<boolean_t, pointee_t>::value
3614 or std::is_same<number_integer_t, pointee_t>::value
3615 or std::is_same<number_unsigned_t, pointee_t>::value
3616 or std::is_same<number_float_t, pointee_t>::value
3617 ,
"incompatible pointer type");
3620 return get_impl_ptr(static_cast<PointerType>(
nullptr));
3627 template<
typename PointerType,
typename std::enable_if<
3628 std::is_pointer<PointerType>::value and
3629 std::is_const<typename std::remove_pointer<PointerType>::type>::value,
int>::type = 0>
3630 constexpr
const PointerType
get_ptr() const noexcept
3633 using pointee_t =
typename std::remove_const<
typename 3634 std::remove_pointer<
typename 3635 std::remove_const<PointerType>::type>::type>::type;
3638 std::is_same<object_t, pointee_t>::value
3639 or std::is_same<array_t, pointee_t>::value
3640 or std::is_same<string_t, pointee_t>::value
3641 or std::is_same<boolean_t, pointee_t>::value
3642 or std::is_same<number_integer_t, pointee_t>::value
3643 or std::is_same<number_unsigned_t, pointee_t>::value
3644 or std::is_same<number_float_t, pointee_t>::value
3645 ,
"incompatible pointer type");
3648 return get_impl_ptr(static_cast<const PointerType>(
nullptr));
3677 template<
typename ReferenceType,
typename std::enable_if<
3678 std::is_reference<ReferenceType>::value,
int>::type = 0>
3682 return get_ref_impl<ReferenceType>(*this);
3689 template<
typename ReferenceType,
typename std::enable_if<
3690 std::is_reference<ReferenceType>::value and
3691 std::is_const<typename std::remove_reference<ReferenceType>::type>::value,
int>::type = 0>
3695 return get_ref_impl<ReferenceType>(*this);
3727 template <
typename ValueType,
typename std::enable_if <
3728 not std::is_pointer<ValueType>::value and
3729 not std::is_same<ValueType, typename string_t::value_type>::value
3730 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015 3731 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
3733 #if defined(_MSC_VER) && _MSC_VER >1900 && defined(_HAS_CXX17) && _HAS_CXX17 == 1 // fix for issue #464 3734 and not std::is_same<ValueType, typename std::string_view>::value
3737 operator ValueType()
const 3740 return get<ValueType>();
3787 return m_value.array->at(idx);
3789 JSON_CATCH (std::out_of_range&)
3792 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
3797 JSON_THROW(type_error::create(304,
"cannot use at() with " + type_name()));
3834 return m_value.array->at(idx);
3836 JSON_CATCH (std::out_of_range&)
3839 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
3844 JSON_THROW(type_error::create(304,
"cannot use at() with " + type_name()));
3878 reference at(
const typename object_t::key_type& key)
3885 return m_value.object->at(key);
3887 JSON_CATCH (std::out_of_range&)
3890 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
3895 JSON_THROW(type_error::create(304,
"cannot use at() with " + type_name()));
3936 return m_value.object->at(key);
3938 JSON_CATCH (std::out_of_range&)
3941 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
3946 JSON_THROW(type_error::create(304,
"cannot use at() with " + type_name()));
3980 m_type = value_t::array;
3981 m_value.
array = create<array_t>();
3989 if (idx >= m_value.array->size())
3991 m_value.array->insert(m_value.array->end(),
3992 idx - m_value.array->size() + 1,
3996 return m_value.array->operator[](idx);
3999 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + type_name()));
4026 return m_value.
array->operator[](idx);
4029 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + type_name()));
4059 reference operator[](
const typename object_t::key_type& key)
4064 m_type = value_t::object;
4065 m_value.
object = create<object_t>();
4072 return m_value.object->operator[](key);
4075 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + type_name()));
4108 const_reference operator[](
const typename object_t::key_type& key)
const 4113 assert(m_value.object->find(key) != m_value.object->end());
4117 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + type_name()));
4147 template<
typename T, std::
size_t n>
4150 return operator[](static_cast<const T>(key));
4182 template<
typename T, std::
size_t n>
4185 return operator[](static_cast<const T>(key));
4215 template<
typename T>
4221 m_type = value_t::object;
4222 m_value = value_t::object;
4229 return m_value.object->operator[](key);
4232 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + type_name()));
4265 template<
typename T>
4271 assert(m_value.object->find(key) != m_value.object->end());
4275 JSON_THROW(type_error::create(305,
"cannot use operator[] with " + type_name()));
4326 template<
class ValueType,
typename std::enable_if<
4327 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
4328 ValueType value(
const typename object_t::key_type& key, ValueType default_value)
const 4334 const auto it = find(key);
4340 return default_value;
4344 JSON_THROW(type_error::create(306,
"cannot use value() with " + type_name()));
4352 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 4354 return value(key,
string_t(default_value));
4398 template<
class ValueType,
typename std::enable_if<
4399 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
4400 ValueType value(
const json_pointer& ptr, ValueType default_value)
const 4408 return ptr.get_checked(
this);
4412 return default_value;
4416 JSON_THROW(type_error::create(306,
"cannot use value() with " + type_name()));
4425 return value(ptr,
string_t(default_value));
4560 template<
class IteratorType,
typename std::enable_if<
4561 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
4562 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>::type
4564 IteratorType erase(IteratorType pos)
4567 if (
this != pos.m_object)
4569 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
4572 IteratorType result = end();
4576 case value_t::boolean:
4577 case value_t::number_float:
4578 case value_t::number_integer:
4579 case value_t::number_unsigned:
4580 case value_t::string:
4582 if (not pos.m_it.primitive_iterator.is_begin())
4584 JSON_THROW(invalid_iterator::create(205,
"iterator out of range"));
4589 AllocatorType<string_t> alloc;
4590 alloc.destroy(m_value.string);
4591 alloc.deallocate(m_value.string, 1);
4592 m_value.string =
nullptr;
4595 m_type = value_t::null;
4600 case value_t::object:
4602 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
4606 case value_t::array:
4608 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
4614 JSON_THROW(type_error::create(307,
"cannot use erase() with " + type_name()));
4667 template<
class IteratorType,
typename std::enable_if<
4668 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
4669 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>::type
4671 IteratorType erase(IteratorType first, IteratorType last)
4674 if (
this != first.m_object or
this != last.m_object)
4676 JSON_THROW(invalid_iterator::create(203,
"iterators do not fit current value"));
4679 IteratorType result = end();
4683 case value_t::boolean:
4684 case value_t::number_float:
4685 case value_t::number_integer:
4686 case value_t::number_unsigned:
4687 case value_t::string:
4689 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
4691 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
4696 AllocatorType<string_t> alloc;
4697 alloc.destroy(m_value.string);
4698 alloc.deallocate(m_value.string, 1);
4699 m_value.string =
nullptr;
4702 m_type = value_t::null;
4707 case value_t::object:
4709 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
4710 last.m_it.object_iterator);
4714 case value_t::array:
4716 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
4717 last.m_it.array_iterator);
4723 JSON_THROW(type_error::create(307,
"cannot use erase() with " + type_name()));
4759 size_type erase(
const typename object_t::key_type& key)
4764 return m_value.object->erase(key);
4767 JSON_THROW(type_error::create(307,
"cannot use erase() with " + type_name()));
4801 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
4804 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
4808 JSON_THROW(type_error::create(307,
"cannot use erase() with " + type_name()));
4844 iterator find(
typename object_t::key_type key)
4846 auto result = end();
4850 result.m_it.object_iterator = m_value.object->find(key);
4862 auto result = cend();
4866 result.m_it.object_iterator = m_value.object->find(key);
4893 size_type count(
typename object_t::key_type key)
const 4896 return is_object() ? m_value.object->count(key) : 0;
5184 template<
typename IteratorType>
class iteration_proxy;
5198 static iteration_proxy<iterator> iterator_wrapper(
reference cont)
5200 return iteration_proxy<iterator>(cont);
5208 return iteration_proxy<const_iterator>(cont);
5258 bool empty()
const noexcept
5268 case value_t::array:
5271 return m_value.array->empty();
5274 case value_t::object:
5277 return m_value.object->empty();
5336 case value_t::array:
5339 return m_value.array->size();
5342 case value_t::object:
5345 return m_value.object->size();
5396 case value_t::array:
5399 return m_value.array->max_size();
5402 case value_t::object:
5405 return m_value.object->max_size();
5448 void clear() noexcept
5452 case value_t::number_integer:
5454 m_value.number_integer = 0;
5458 case value_t::number_unsigned:
5460 m_value.number_unsigned = 0;
5464 case value_t::number_float:
5466 m_value.number_float = 0.0;
5470 case value_t::boolean:
5472 m_value.boolean =
false;
5476 case value_t::string:
5478 m_value.string->clear();
5482 case value_t::array:
5484 m_value.array->clear();
5488 case value_t::object:
5490 m_value.object->clear();
5524 if (not(is_null() or is_array()))
5526 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + type_name()));
5532 m_type = value_t::array;
5533 m_value = value_t::array;
5538 m_value.array->push_back(std::move(val));
5540 val.m_type = value_t::null;
5549 push_back(std::move(val));
5560 if (not(is_null() or is_array()))
5562 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + type_name()));
5568 m_type = value_t::array;
5569 m_value = value_t::array;
5574 m_value.array->push_back(val);
5607 void push_back(
const typename object_t::value_type& val)
5610 if (not(is_null() or is_object()))
5612 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + type_name()));
5618 m_type = value_t::object;
5619 m_value = value_t::object;
5624 m_value.object->insert(val);
5631 reference operator+=(
const typename object_t::value_type& val)
5662 void push_back(std::initializer_list<basic_json> init)
5664 if (is_object() and init.size() == 2 and init.begin()->is_string())
5666 const string_t key = *init.begin();
5667 push_back(
typename object_t::value_type(key, *(init.begin() + 1)));
5679 reference operator+=(std::initializer_list<basic_json> init)
5706 template<
class... Args>
5707 void emplace_back(Args&& ... args)
5710 if (not(is_null() or is_array()))
5712 JSON_THROW(type_error::create(311,
"cannot use emplace_back() with " + type_name()));
5718 m_type = value_t::array;
5719 m_value = value_t::array;
5724 m_value.array->emplace_back(std::forward<Args>(args)...);
5754 template<
class... Args>
5755 std::pair<iterator, bool> emplace(Args&& ... args)
5758 if (not(is_null() or is_object()))
5760 JSON_THROW(type_error::create(311,
"cannot use emplace() with " + type_name()));
5766 m_type = value_t::object;
5767 m_value = value_t::object;
5772 auto res = m_value.object->emplace(std::forward<Args>(args)...);
5775 it.m_it.object_iterator = res.first;
5778 return {it, res.second};
5809 if (pos.m_object !=
this)
5811 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
5816 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
5820 JSON_THROW(type_error::create(309,
"cannot use insert() with " + type_name()));
5829 return insert(pos, val);
5862 if (pos.m_object !=
this)
5864 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
5869 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
5873 JSON_THROW(type_error::create(309,
"cannot use insert() with " + type_name()));
5911 JSON_THROW(type_error::create(309,
"cannot use insert() with " + type_name()));
5915 if (pos.m_object !=
this)
5917 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
5921 if (first.m_object != last.m_object)
5923 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
5926 if (first.m_object ==
this or last.m_object ==
this)
5928 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container"));
5933 result.m_it.array_iterator = m_value.array->insert(
5934 pos.m_it.array_iterator,
5935 first.m_it.array_iterator,
5936 last.m_it.array_iterator);
5969 JSON_THROW(type_error::create(309,
"cannot use insert() with " + type_name()));
5973 if (pos.m_object !=
this)
5975 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
5980 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
6010 if (not is_object())
6012 JSON_THROW(type_error::create(309,
"cannot use insert() with " + type_name()));
6016 if (first.m_object != last.m_object)
6018 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
6022 if (not first.m_object->is_object() or not first.m_object->is_object())
6024 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
6027 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
6048 std::is_nothrow_move_constructible<value_t>::value and
6049 std::is_nothrow_move_assignable<value_t>::value and
6050 std::is_nothrow_move_constructible<json_value>::value and
6051 std::is_nothrow_move_assignable<json_value>::value
6054 std::swap(m_type, other.m_type);
6055 std::swap(m_value, other.m_value);
6084 std::swap(*(m_value.array), other);
6088 JSON_THROW(type_error::create(310,
"cannot use swap() with " + type_name()));
6117 std::swap(*(m_value.object), other);
6121 JSON_THROW(type_error::create(310,
"cannot use swap() with " + type_name()));
6150 std::swap(*(m_value.string), other);
6154 JSON_THROW(type_error::create(310,
"cannot use swap() with " + type_name()));
6197 const auto lhs_type = lhs.
type();
6198 const auto rhs_type = rhs.
type();
6200 if (lhs_type == rhs_type)
6204 case value_t::array:
6206 return *lhs.m_value.array == *rhs.m_value.array;
6208 case value_t::object:
6210 return *lhs.m_value.object == *rhs.m_value.object;
6216 case value_t::string:
6218 return *lhs.m_value.string == *rhs.m_value.string;
6220 case value_t::boolean:
6222 return lhs.m_value.boolean == rhs.m_value.boolean;
6224 case value_t::number_integer:
6226 return lhs.m_value.number_integer == rhs.m_value.number_integer;
6228 case value_t::number_unsigned:
6230 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
6232 case value_t::number_float:
6234 return lhs.m_value.number_float == rhs.m_value.number_float;
6242 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
6244 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
6246 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
6248 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
6250 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
6252 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
6254 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
6256 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
6258 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
6260 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
6262 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
6264 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
6274 template<
typename ScalarType,
typename std::enable_if<
6275 std::is_scalar<ScalarType>::value,
int>::type = 0>
6276 friend bool operator==(
const_reference lhs,
const ScalarType rhs) noexcept
6285 template<
typename ScalarType,
typename std::enable_if<
6286 std::is_scalar<ScalarType>::value,
int>::type = 0>
6287 friend bool operator==(
const ScalarType lhs,
const_reference rhs) noexcept
6310 return not (lhs == rhs);
6317 template<
typename ScalarType,
typename std::enable_if<
6318 std::is_scalar<ScalarType>::value,
int>::type = 0>
6319 friend bool operator!=(
const_reference lhs,
const ScalarType rhs) noexcept
6328 template<
typename ScalarType,
typename std::enable_if<
6329 std::is_scalar<ScalarType>::value,
int>::type = 0>
6330 friend bool operator!=(
const ScalarType lhs,
const_reference rhs) noexcept
6361 const auto lhs_type = lhs.
type();
6362 const auto rhs_type = rhs.
type();
6364 if (lhs_type == rhs_type)
6368 case value_t::array:
6370 return *lhs.m_value.array < *rhs.m_value.array;
6372 case value_t::object:
6374 return *lhs.m_value.object < *rhs.m_value.object;
6380 case value_t::string:
6382 return *lhs.m_value.string < *rhs.m_value.string;
6384 case value_t::boolean:
6386 return lhs.m_value.boolean < rhs.m_value.boolean;
6388 case value_t::number_integer:
6390 return lhs.m_value.number_integer < rhs.m_value.number_integer;
6392 case value_t::number_unsigned:
6394 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
6396 case value_t::number_float:
6398 return lhs.m_value.number_float < rhs.m_value.number_float;
6406 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
6408 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
6410 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
6412 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
6414 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
6416 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
6418 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
6420 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
6422 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
6424 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
6426 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
6428 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
6434 return operator<(lhs_type, rhs_type);
6441 template<
typename ScalarType,
typename std::enable_if<
6442 std::is_scalar<ScalarType>::value,
int>::type = 0>
6443 friend bool operator<(
const_reference lhs,
const ScalarType rhs) noexcept
6452 template<
typename ScalarType,
typename std::enable_if<
6453 std::is_scalar<ScalarType>::value,
int>::type = 0>
6454 friend bool operator<(
const ScalarType lhs,
const_reference rhs) noexcept
6478 return not (rhs < lhs);
6485 template<
typename ScalarType,
typename std::enable_if<
6486 std::is_scalar<ScalarType>::value,
int>::type = 0>
6487 friend bool operator<=(
const_reference lhs,
const ScalarType rhs) noexcept
6496 template<
typename ScalarType,
typename std::enable_if<
6497 std::is_scalar<ScalarType>::value,
int>::type = 0>
6498 friend bool operator<=(
const ScalarType lhs,
const_reference rhs) noexcept
6522 return not (lhs <= rhs);
6529 template<
typename ScalarType,
typename std::enable_if<
6530 std::is_scalar<ScalarType>::value,
int>::type = 0>
6531 friend bool operator>(
const_reference lhs,
const ScalarType rhs) noexcept
6540 template<
typename ScalarType,
typename std::enable_if<
6541 std::is_scalar<ScalarType>::value,
int>::type = 0>
6542 friend bool operator>(
const ScalarType lhs,
const_reference rhs) noexcept
6566 return not (lhs < rhs);
6573 template<
typename ScalarType,
typename std::enable_if<
6574 std::is_scalar<ScalarType>::value,
int>::type = 0>
6575 friend bool operator>=(
const_reference lhs,
const ScalarType rhs) noexcept
6584 template<
typename ScalarType,
typename std::enable_if<
6585 std::is_scalar<ScalarType>::value,
int>::type = 0>
6586 friend bool operator>=(
const ScalarType lhs,
const_reference rhs) noexcept
6608 serializer(
const serializer&) =
delete;
6609 serializer& operator=(
const serializer&) =
delete;
6615 serializer(std::ostream& s)
6616 : o(s), loc(std::localeconv()),
6617 thousands_sep(!loc->thousands_sep ?
'\0' : loc->thousands_sep[0]),
6618 decimal_point(!loc->decimal_point ?
'\0' : loc->decimal_point[0])
6639 const bool pretty_print,
6640 const unsigned int indent_step,
6641 const unsigned int current_indent = 0)
6645 case value_t::object:
6647 if (val.m_value.object->empty())
6658 const auto new_indent = current_indent + indent_step;
6659 if (indent_string.size() < new_indent)
6661 indent_string.resize(new_indent,
' ');
6665 auto i = val.m_value.object->cbegin();
6666 for (
size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
6668 o.write(indent_string.c_str(),
static_cast<std::streamsize
>(new_indent));
6670 dump_escaped(i->first);
6672 dump(i->second,
true, indent_step, new_indent);
6677 assert(i != val.m_value.object->cend());
6678 o.write(indent_string.c_str(),
static_cast<std::streamsize
>(new_indent));
6680 dump_escaped(i->first);
6682 dump(i->second,
true, indent_step, new_indent);
6685 o.write(indent_string.c_str(),
static_cast<std::streamsize
>(current_indent));
6693 auto i = val.m_value.object->cbegin();
6694 for (
size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
6697 dump_escaped(i->first);
6699 dump(i->second,
false, indent_step, current_indent);
6704 assert(i != val.m_value.object->cend());
6706 dump_escaped(i->first);
6708 dump(i->second,
false, indent_step, current_indent);
6716 case value_t::array:
6718 if (val.m_value.array->empty())
6729 const auto new_indent = current_indent + indent_step;
6730 if (indent_string.size() < new_indent)
6732 indent_string.resize(new_indent,
' ');
6736 for (
auto i = val.m_value.array->cbegin(); i != val.m_value.array->cend() - 1; ++i)
6738 o.write(indent_string.c_str(),
static_cast<std::streamsize
>(new_indent));
6739 dump(*i,
true, indent_step, new_indent);
6744 assert(not val.m_value.array->empty());
6745 o.write(indent_string.c_str(),
static_cast<std::streamsize
>(new_indent));
6746 dump(val.m_value.array->back(),
true, indent_step, new_indent);
6749 o.write(indent_string.c_str(),
static_cast<std::streamsize
>(current_indent));
6757 for (
auto i = val.m_value.array->cbegin(); i != val.m_value.array->cend() - 1; ++i)
6759 dump(*i,
false, indent_step, current_indent);
6764 assert(not val.m_value.array->empty());
6765 dump(val.m_value.array->back(),
false, indent_step, current_indent);
6773 case value_t::string:
6776 dump_escaped(*val.m_value.string);
6781 case value_t::boolean:
6783 if (val.m_value.boolean)
6789 o.write(
"false", 5);
6794 case value_t::number_integer:
6796 dump_integer(val.m_value.number_integer);
6800 case value_t::number_unsigned:
6802 dump_integer(val.m_value.number_unsigned);
6806 case value_t::number_float:
6808 dump_float(val.m_value.number_float);
6812 case value_t::discarded:
6814 o.write(
"<discarded>", 11);
6835 static std::size_t extra_space(
const string_t& s) noexcept
6837 return std::accumulate(s.begin(), s.end(),
size_t{},
6838 [](
size_t res,
typename string_t::value_type c)
6906 void dump_escaped(
const string_t& s)
const 6908 const auto space = extra_space(s);
6911 o.write(s.c_str(),
static_cast<std::streamsize
>(s.size()));
6916 string_t result(s.size() + space,
'\\');
6917 std::size_t pos = 0;
6919 for (
const auto& c : s)
6926 result[pos + 1] =
'"';
6942 result[pos + 1] =
'b';
6950 result[pos + 1] =
'f';
6958 result[pos + 1] =
'n';
6966 result[pos + 1] =
'r';
6974 result[pos + 1] =
't';
7009 static const char hexify[16] =
7011 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
7012 '8',
'9',
'a',
'b',
'c',
'd',
'e',
'f' 7017 {
'u',
'0',
'0', hexify[c >> 4], hexify[c & 0x0f]
7036 assert(pos == s.size() + space);
7037 o.write(result.c_str(),
static_cast<std::streamsize
>(result.size()));
7049 template<
typename NumberType, detail::enable_if_t <
7050 std::is_same<NumberType, number_unsigned_t>::value or
7051 std::is_same<NumberType, number_integer_t>::value,
int> = 0>
7052 void dump_integer(NumberType x)
7061 const bool is_negative = x < 0;
7065 while (x != 0 and i < number_buffer.size() - 1)
7067 const auto digit = std::labs(static_cast<long>(x % 10));
7068 number_buffer[i++] =
static_cast<char>(
'0' + digit);
7078 assert(i < number_buffer.size() - 2);
7079 number_buffer[i++] =
'-';
7082 std::reverse(number_buffer.begin(), number_buffer.begin() + i);
7083 o.write(number_buffer.data(),
static_cast<std::streamsize
>(i));
7097 if (not std::isfinite(x) or std::isnan(x))
7106 if (std::signbit(x))
7118 static constexpr
auto d = std::numeric_limits<number_float_t>::digits10;
7121 std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(),
7127 assert(static_cast<size_t>(len) < number_buffer.size());
7130 if (thousands_sep !=
'\0')
7132 const auto end = std::remove(number_buffer.begin(),
7133 number_buffer.begin() + len,
7135 std::fill(end, number_buffer.end(),
'\0');
7136 assert((end - number_buffer.begin()) <= len);
7137 len = (end - number_buffer.begin());
7141 if (decimal_point !=
'\0' and decimal_point !=
'.')
7143 for (
auto& c : number_buffer)
7145 if (c == decimal_point)
7153 o.write(number_buffer.data(),
static_cast<std::streamsize
>(len));
7156 const bool value_is_int_like = std::none_of(number_buffer.begin(),
7157 number_buffer.begin() + len + 1,
7160 return c ==
'.' or c ==
'e';
7163 if (value_is_int_like)
7174 std::array<char, 64> number_buffer{{}};
7177 const std::lconv* loc =
nullptr;
7179 const char thousands_sep =
'\0';
7181 const char decimal_point =
'\0';
7210 friend std::ostream& operator<<(std::ostream& o,
const basic_json& j)
7213 const bool pretty_print = (o.width() > 0);
7214 const auto indentation = (pretty_print ? o.width() : 0);
7221 s.dump(j, pretty_print, static_cast<unsigned int>(indentation));
7233 friend std::ostream& operator>>(
const basic_json& j, std::ostream& o)
7280 template<
class T, std::
size_t N>
7285 return parse(std::begin(array), std::end(array), cb);
7319 template<
typename CharT,
typename std::enable_if<
7320 std::is_pointer<CharT>::value and
7321 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
7322 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
int>::type = 0>
7326 return parser(reinterpret_cast<const char*>(s), cb).
parse();
7361 return parser(i, cb).
parse();
7370 return parser(i, cb).
parse();
7418 template<
class IteratorType,
typename std::enable_if<
7420 std::random_access_iterator_tag,
7421 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
7422 static basic_json parse(IteratorType first, IteratorType last,
7427 assert(std::accumulate(first, last, std::pair<bool, int>(
true, 0),
7428 [&first](std::pair<bool, int> res, decltype(*first) val)
7430 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
7435 static_assert(
sizeof(
typename std::iterator_traits<IteratorType>::value_type) == 1,
7436 "each element in the iterator range must have the size of 1 byte");
7440 if (std::distance(first, last) <= 0)
7442 return parser(
"").parse();
7445 return parser(first, last, cb).parse();
7492 template<
class ContiguousContainer,
typename std::enable_if<
7493 not std::is_pointer<ContiguousContainer>::value and
7495 std::random_access_iterator_tag,
7496 typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value
7498 static basic_json parse(
const ContiguousContainer& c,
7502 return parse(std::begin(c), std::end(c), cb);
7513 friend std::istream& operator<<(
basic_json& j, std::istream& i)
7515 j = parser(i).
parse();
7545 friend std::istream& operator>>(std::istream& i,
basic_json& j)
7547 j = parser(i).
parse();
7566 template<
typename T>
7567 static void add_to_vector(std::vector<uint8_t>& vec,
size_t bytes,
const T number)
7569 assert(bytes == 1 or bytes == 2 or bytes == 4 or bytes == 8);
7575 vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 070) & 0xff));
7576 vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 060) & 0xff));
7577 vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 050) & 0xff));
7578 vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 040) & 0xff));
7579 vec.push_back(static_cast<uint8_t>((number >> 030) & 0xff));
7580 vec.push_back(static_cast<uint8_t>((number >> 020) & 0xff));
7581 vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
7582 vec.push_back(static_cast<uint8_t>(number & 0xff));
7588 vec.push_back(static_cast<uint8_t>((number >> 030) & 0xff));
7589 vec.push_back(static_cast<uint8_t>((number >> 020) & 0xff));
7590 vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
7591 vec.push_back(static_cast<uint8_t>(number & 0xff));
7597 vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
7598 vec.push_back(static_cast<uint8_t>(number & 0xff));
7604 vec.push_back(static_cast<uint8_t>(number & 0xff));
7646 template<
typename T>
7647 static T get_from_vector(
const std::vector<uint8_t>& vec,
const size_t current_index)
7650 check_length(vec.size(),
sizeof(T), current_index + 1);
7653 auto* ptr =
reinterpret_cast<uint8_t*
>(&result);
7654 for (
size_t i = 0; i <
sizeof(T); ++i)
7656 *ptr++ = vec[current_index +
sizeof(T) - i];
7671 static void to_msgpack_internal(
const basic_json& j, std::vector<uint8_t>& v)
7682 case value_t::boolean:
7685 v.push_back(j.m_value.boolean ? 0xc3 : 0xc2);
7689 case value_t::number_integer:
7691 if (j.m_value.number_integer >= 0)
7697 if (j.m_value.number_unsigned < 128)
7700 add_to_vector(v, 1, j.m_value.number_unsigned);
7702 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
7706 add_to_vector(v, 1, j.m_value.number_unsigned);
7708 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
7712 add_to_vector(v, 2, j.m_value.number_unsigned);
7714 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
7718 add_to_vector(v, 4, j.m_value.number_unsigned);
7720 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
7724 add_to_vector(v, 8, j.m_value.number_unsigned);
7729 if (j.m_value.number_integer >= -32)
7732 add_to_vector(v, 1, j.m_value.number_integer);
7734 else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
7738 add_to_vector(v, 1, j.m_value.number_integer);
7740 else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
7744 add_to_vector(v, 2, j.m_value.number_integer);
7746 else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
7750 add_to_vector(v, 4, j.m_value.number_integer);
7752 else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
7756 add_to_vector(v, 8, j.m_value.number_integer);
7762 case value_t::number_unsigned:
7764 if (j.m_value.number_unsigned < 128)
7767 add_to_vector(v, 1, j.m_value.number_unsigned);
7769 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
7773 add_to_vector(v, 1, j.m_value.number_unsigned);
7775 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
7779 add_to_vector(v, 2, j.m_value.number_unsigned);
7781 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
7785 add_to_vector(v, 4, j.m_value.number_unsigned);
7787 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
7791 add_to_vector(v, 8, j.m_value.number_unsigned);
7796 case value_t::number_float:
7800 const auto* helper =
reinterpret_cast<const uint8_t*
>(&(j.m_value.number_float));
7801 for (
size_t i = 0; i < 8; ++i)
7803 v.push_back(helper[7 - i]);
7808 case value_t::string:
7810 const auto N = j.m_value.string->size();
7814 v.push_back(static_cast<uint8_t>(0xa0 | N));
7820 add_to_vector(v, 1, N);
7822 else if (N <= 65535)
7826 add_to_vector(v, 2, N);
7828 else if (N <= 4294967295)
7832 add_to_vector(v, 4, N);
7836 std::copy(j.m_value.string->begin(), j.m_value.string->end(),
7837 std::back_inserter(v));
7841 case value_t::array:
7843 const auto N = j.m_value.array->size();
7847 v.push_back(static_cast<uint8_t>(0x90 | N));
7849 else if (N <= 0xffff)
7853 add_to_vector(v, 2, N);
7855 else if (N <= 0xffffffff)
7859 add_to_vector(v, 4, N);
7863 for (
const auto& el : *j.m_value.array)
7865 to_msgpack_internal(el, v);
7870 case value_t::object:
7872 const auto N = j.m_value.object->size();
7876 v.push_back(static_cast<uint8_t>(0x80 | (N & 0xf)));
7878 else if (N <= 65535)
7882 add_to_vector(v, 2, N);
7884 else if (N <= 4294967295)
7888 add_to_vector(v, 4, N);
7892 for (
const auto& el : *j.m_value.object)
7894 to_msgpack_internal(el.first, v);
7895 to_msgpack_internal(el.second, v);
7917 static void to_cbor_internal(
const basic_json& j, std::vector<uint8_t>& v)
7927 case value_t::boolean:
7929 v.push_back(j.m_value.boolean ? 0xf5 : 0xf4);
7933 case value_t::number_integer:
7935 if (j.m_value.number_integer >= 0)
7940 if (j.m_value.number_integer <= 0x17)
7942 add_to_vector(v, 1, j.m_value.number_integer);
7944 else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
7948 add_to_vector(v, 1, j.m_value.number_integer);
7950 else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
7954 add_to_vector(v, 2, j.m_value.number_integer);
7956 else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
7960 add_to_vector(v, 4, j.m_value.number_integer);
7966 add_to_vector(v, 8, j.m_value.number_integer);
7973 const auto positive_number = -1 - j.m_value.number_integer;
7974 if (j.m_value.number_integer >= -24)
7976 v.push_back(static_cast<uint8_t>(0x20 + positive_number));
7978 else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
7982 add_to_vector(v, 1, positive_number);
7984 else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
7988 add_to_vector(v, 2, positive_number);
7990 else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
7994 add_to_vector(v, 4, positive_number);
8000 add_to_vector(v, 8, positive_number);
8006 case value_t::number_unsigned:
8008 if (j.m_value.number_unsigned <= 0x17)
8010 v.push_back(static_cast<uint8_t>(j.m_value.number_unsigned));
8012 else if (j.m_value.number_unsigned <= 0xff)
8016 add_to_vector(v, 1, j.m_value.number_unsigned);
8018 else if (j.m_value.number_unsigned <= 0xffff)
8022 add_to_vector(v, 2, j.m_value.number_unsigned);
8024 else if (j.m_value.number_unsigned <= 0xffffffff)
8028 add_to_vector(v, 4, j.m_value.number_unsigned);
8030 else if (j.m_value.number_unsigned <= 0xffffffffffffffff)
8034 add_to_vector(v, 8, j.m_value.number_unsigned);
8039 case value_t::number_float:
8043 const auto* helper =
reinterpret_cast<const uint8_t*
>(&(j.m_value.number_float));
8044 for (
size_t i = 0; i < 8; ++i)
8046 v.push_back(helper[7 - i]);
8051 case value_t::string:
8053 const auto N = j.m_value.string->size();
8056 v.push_back(static_cast<uint8_t>(0x60 + N));
8061 add_to_vector(v, 1, N);
8063 else if (N <= 0xffff)
8066 add_to_vector(v, 2, N);
8068 else if (N <= 0xffffffff)
8071 add_to_vector(v, 4, N);
8074 else if (N <= 0xffffffffffffffff)
8077 add_to_vector(v, 8, N);
8082 std::copy(j.m_value.string->begin(), j.m_value.string->end(),
8083 std::back_inserter(v));
8087 case value_t::array:
8089 const auto N = j.m_value.array->size();
8092 v.push_back(static_cast<uint8_t>(0x80 + N));
8097 add_to_vector(v, 1, N);
8099 else if (N <= 0xffff)
8102 add_to_vector(v, 2, N);
8104 else if (N <= 0xffffffff)
8107 add_to_vector(v, 4, N);
8110 else if (N <= 0xffffffffffffffff)
8113 add_to_vector(v, 8, N);
8118 for (
const auto& el : *j.m_value.array)
8120 to_cbor_internal(el, v);
8125 case value_t::object:
8127 const auto N = j.m_value.object->size();
8130 v.push_back(static_cast<uint8_t>(0xa0 + N));
8135 add_to_vector(v, 1, N);
8137 else if (N <= 0xffff)
8140 add_to_vector(v, 2, N);
8142 else if (N <= 0xffffffff)
8145 add_to_vector(v, 4, N);
8148 else if (N <= 0xffffffffffffffff)
8151 add_to_vector(v, 8, N);
8156 for (
const auto& el : *j.m_value.object)
8158 to_cbor_internal(el.first, v);
8159 to_cbor_internal(el.second, v);
8194 static void check_length(
const size_t size,
const size_t len,
const size_t offset)
8197 if (len > size or offset > size)
8199 JSON_THROW(parse_error::create(110, offset + 1,
"cannot read " + std::to_string(len) +
" bytes from vector"));
8203 if ((size > ((std::numeric_limits<size_t>::max)() - offset)))
8205 JSON_THROW(parse_error::create(110, offset + 1,
"cannot read " + std::to_string(len) +
" bytes from vector"));
8209 if (len + offset > size)
8211 JSON_THROW(parse_error::create(110, offset + 1,
"cannot read " + std::to_string(len) +
" bytes from vector"));
8231 static void msgpack_expect_string(
const std::vector<uint8_t>& v,
size_t idx)
8233 check_length(v.size(), 1, idx);
8235 const auto byte = v[idx];
8236 if ((byte >= 0xa0 and byte <= 0xbf) or (byte >= 0xd9 and byte <= 0xdb))
8241 std::stringstream ss;
8242 ss << std::hex << static_cast<int>(v[idx]);
8243 JSON_THROW(parse_error::create(113, idx + 1,
"expected a MessagePack string; last byte: 0x" + ss.str()));
8261 static void cbor_expect_string(
const std::vector<uint8_t>& v,
size_t idx)
8263 check_length(v.size(), 1, idx);
8265 const auto byte = v[idx];
8266 if ((byte >= 0x60 and byte <= 0x7b) or byte == 0x7f)
8271 std::stringstream ss;
8272 ss << std::hex << static_cast<int>(v[idx]);
8273 JSON_THROW(parse_error::create(113, idx + 1,
"expected a CBOR string; last byte: 0x" + ss.str()));
8291 static basic_json from_msgpack_internal(
const std::vector<uint8_t>& v,
size_t& idx)
8294 const size_t current_idx = idx++;
8297 check_length(v.size(), 1, current_idx);
8299 if (v[current_idx] <= 0xbf)
8301 if (v[current_idx] <= 0x7f)
8303 return v[current_idx];
8305 if (v[current_idx] <= 0x8f)
8308 const size_t len = v[current_idx] & 0x0f;
8309 for (
size_t i = 0; i < len; ++i)
8311 msgpack_expect_string(v, idx);
8312 std::string key = from_msgpack_internal(v, idx);
8313 result[key] = from_msgpack_internal(v, idx);
8317 else if (v[current_idx] <= 0x9f)
8320 const size_t len = v[current_idx] & 0x0f;
8321 for (
size_t i = 0; i < len; ++i)
8323 result.
push_back(from_msgpack_internal(v, idx));
8329 const size_t len = v[current_idx] & 0x1f;
8330 const size_t offset = current_idx + 1;
8332 check_length(v.size(), len, offset);
8333 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8336 else if (v[current_idx] >= 0xe0)
8338 return static_cast<int8_t
>(v[current_idx]);
8342 switch (v[current_idx])
8346 return value_t::null;
8363 check_length(v.size(),
sizeof(float), current_idx + 1);
8364 for (
size_t byte = 0; byte <
sizeof(float); ++byte)
8366 reinterpret_cast<uint8_t*
>(&res)[
sizeof(
float) - byte - 1] = v[current_idx + 1 + byte];
8368 idx +=
sizeof(float);
8376 check_length(v.size(),
sizeof(double), current_idx + 1);
8377 for (
size_t byte = 0; byte <
sizeof(double); ++byte)
8379 reinterpret_cast<uint8_t*
>(&res)[
sizeof(
double) - byte - 1] = v[current_idx + 1 + byte];
8381 idx +=
sizeof(double);
8388 return get_from_vector<uint8_t>(v, current_idx);
8394 return get_from_vector<uint16_t>(v, current_idx);
8400 return get_from_vector<uint32_t>(v, current_idx);
8406 return get_from_vector<uint64_t>(v, current_idx);
8412 return get_from_vector<int8_t>(v, current_idx);
8418 return get_from_vector<int16_t>(v, current_idx);
8424 return get_from_vector<int32_t>(v, current_idx);
8430 return get_from_vector<int64_t>(v, current_idx);
8435 const auto len =
static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
8436 const size_t offset = current_idx + 2;
8438 check_length(v.size(), len, offset);
8439 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8444 const auto len =
static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
8445 const size_t offset = current_idx + 3;
8447 check_length(v.size(), len, offset);
8448 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8453 const auto len =
static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
8454 const size_t offset = current_idx + 5;
8456 check_length(v.size(), len, offset);
8457 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8463 const auto len =
static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
8465 for (
size_t i = 0; i < len; ++i)
8467 result.
push_back(from_msgpack_internal(v, idx));
8475 const auto len =
static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
8477 for (
size_t i = 0; i < len; ++i)
8479 result.
push_back(from_msgpack_internal(v, idx));
8487 const auto len =
static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
8489 for (
size_t i = 0; i < len; ++i)
8491 msgpack_expect_string(v, idx);
8492 std::string key = from_msgpack_internal(v, idx);
8493 result[key] = from_msgpack_internal(v, idx);
8501 const auto len =
static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
8503 for (
size_t i = 0; i < len; ++i)
8505 msgpack_expect_string(v, idx);
8506 std::string key = from_msgpack_internal(v, idx);
8507 result[key] = from_msgpack_internal(v, idx);
8514 std::stringstream ss;
8515 ss << std::hex << static_cast<int>(v[current_idx]);
8516 JSON_THROW(parse_error::create(112, current_idx + 1,
"error reading MessagePack; last byte: 0x" + ss.str()));
8537 static basic_json from_cbor_internal(
const std::vector<uint8_t>& v,
size_t& idx)
8540 const size_t current_idx = idx++;
8543 check_length(v.size(), 1, current_idx);
8545 switch (v[current_idx])
8573 return v[current_idx];
8579 return get_from_vector<uint8_t>(v, current_idx);
8585 return get_from_vector<uint16_t>(v, current_idx);
8591 return get_from_vector<uint32_t>(v, current_idx);
8597 return get_from_vector<uint64_t>(v, current_idx);
8626 return static_cast<int8_t
>(0x20 - 1 - v[current_idx]);
8633 return static_cast<number_integer_t>(-1) - get_from_vector<uint8_t>(v, current_idx);
8639 return static_cast<number_integer_t>(-1) - get_from_vector<uint16_t>(v, current_idx);
8645 return static_cast<number_integer_t>(-1) - get_from_vector<uint32_t>(v, current_idx);
8651 return static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(get_from_vector<uint64_t>(v, current_idx));
8680 const auto len =
static_cast<size_t>(v[current_idx] - 0x60);
8681 const size_t offset = current_idx + 1;
8683 check_length(v.size(), len, offset);
8684 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8689 const auto len =
static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
8690 const size_t offset = current_idx + 2;
8692 check_length(v.size(), len, offset);
8693 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8698 const auto len =
static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
8699 const size_t offset = current_idx + 3;
8701 check_length(v.size(), len, offset);
8702 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8707 const auto len =
static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
8708 const size_t offset = current_idx + 5;
8710 check_length(v.size(), len, offset);
8711 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8716 const auto len =
static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
8717 const size_t offset = current_idx + 9;
8719 check_length(v.size(), len, offset);
8720 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8726 while (static_cast<void>(check_length(v.size(), 1, idx)), v[idx] != 0xff)
8728 string_t s = from_cbor_internal(v, idx);
8763 const auto len =
static_cast<size_t>(v[current_idx] - 0x80);
8764 for (
size_t i = 0; i < len; ++i)
8766 result.
push_back(from_cbor_internal(v, idx));
8774 const auto len =
static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
8776 for (
size_t i = 0; i < len; ++i)
8778 result.
push_back(from_cbor_internal(v, idx));
8786 const auto len =
static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
8788 for (
size_t i = 0; i < len; ++i)
8790 result.
push_back(from_cbor_internal(v, idx));
8798 const auto len =
static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
8800 for (
size_t i = 0; i < len; ++i)
8802 result.
push_back(from_cbor_internal(v, idx));
8810 const auto len =
static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
8812 for (
size_t i = 0; i < len; ++i)
8814 result.
push_back(from_cbor_internal(v, idx));
8822 while (static_cast<void>(check_length(v.size(), 1, idx)), v[idx] != 0xff)
8824 result.
push_back(from_cbor_internal(v, idx));
8858 const auto len =
static_cast<size_t>(v[current_idx] - 0xa0);
8859 for (
size_t i = 0; i < len; ++i)
8861 cbor_expect_string(v, idx);
8862 std::string key = from_cbor_internal(v, idx);
8863 result[key] = from_cbor_internal(v, idx);
8871 const auto len =
static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
8873 for (
size_t i = 0; i < len; ++i)
8875 cbor_expect_string(v, idx);
8876 std::string key = from_cbor_internal(v, idx);
8877 result[key] = from_cbor_internal(v, idx);
8885 const auto len =
static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
8887 for (
size_t i = 0; i < len; ++i)
8889 cbor_expect_string(v, idx);
8890 std::string key = from_cbor_internal(v, idx);
8891 result[key] = from_cbor_internal(v, idx);
8899 const auto len =
static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
8901 for (
size_t i = 0; i < len; ++i)
8903 cbor_expect_string(v, idx);
8904 std::string key = from_cbor_internal(v, idx);
8905 result[key] = from_cbor_internal(v, idx);
8913 const auto len =
static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
8915 for (
size_t i = 0; i < len; ++i)
8917 cbor_expect_string(v, idx);
8918 std::string key = from_cbor_internal(v, idx);
8919 result[key] = from_cbor_internal(v, idx);
8927 while (static_cast<void>(check_length(v.size(), 1, idx)), v[idx] != 0xff)
8929 cbor_expect_string(v, idx);
8930 std::string key = from_cbor_internal(v, idx);
8931 result[key] = from_cbor_internal(v, idx);
8950 return value_t::null;
8964 check_length(v.size(), 2, current_idx + 1);
8965 const int half = (v[current_idx + 1] << 8) + v[current_idx + 2];
8966 const int exp = (half >> 10) & 0x1f;
8967 const int mant = half & 0x3ff;
8971 val = std::ldexp(mant, -24);
8975 val = std::ldexp(mant + 1024, exp - 25);
8980 ? std::numeric_limits<double>::infinity()
8981 :
std::numeric_limits<double>::quiet_NaN();
8983 return (half & 0x8000) != 0 ? -val : val;
8990 check_length(v.size(),
sizeof(float), current_idx + 1);
8991 for (
size_t byte = 0; byte <
sizeof(float); ++byte)
8993 reinterpret_cast<uint8_t*
>(&res)[
sizeof(
float) - byte - 1] = v[current_idx + 1 + byte];
8995 idx +=
sizeof(float);
9003 check_length(v.size(),
sizeof(double), current_idx + 1);
9004 for (
size_t byte = 0; byte <
sizeof(double); ++byte)
9006 reinterpret_cast<uint8_t*
>(&res)[
sizeof(
double) - byte - 1] = v[current_idx + 1 + byte];
9008 idx +=
sizeof(double);
9014 std::stringstream ss;
9015 ss << std::hex << static_cast<int>(v[current_idx]);
9016 JSON_THROW(parse_error::create(112, current_idx + 1,
"error reading CBOR; last byte: 0x" + ss.str()));
9096 static std::vector<uint8_t> to_msgpack(
const basic_json& j)
9098 std::vector<uint8_t> result;
9099 to_msgpack_internal(j, result);
9170 static basic_json from_msgpack(
const std::vector<uint8_t>& v,
9171 const size_t start_index = 0)
9173 size_t i = start_index;
9174 return from_msgpack_internal(v, i);
9259 static std::vector<uint8_t> to_cbor(
const basic_json& j)
9261 std::vector<uint8_t> result;
9262 to_cbor_internal(j, result);
9353 static basic_json from_cbor(
const std::vector<uint8_t>& v,
9354 const size_t start_index = 0)
9356 size_t i = start_index;
9357 return from_cbor_internal(v, i);
9381 std::string type_name()
const 9388 case value_t::object:
9390 case value_t::array:
9392 case value_t::string:
9394 case value_t::boolean:
9396 case value_t::discarded:
9411 value_t m_type = value_t::null;
9414 json_value m_value = {};
9431 class primitive_iterator_t
9440 void set_begin() noexcept
9446 void set_end() noexcept
9452 constexpr
bool is_begin()
const noexcept
9454 return (m_it == begin_value);
9458 constexpr
bool is_end()
const noexcept
9460 return (m_it == end_value);
9463 friend constexpr
bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9465 return lhs.m_it == rhs.m_it;
9468 friend constexpr
bool operator!=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9470 return !(lhs == rhs);
9473 friend constexpr
bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9475 return lhs.m_it < rhs.m_it;
9478 friend constexpr
bool operator<=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9480 return lhs.m_it <= rhs.m_it;
9483 friend constexpr
bool operator>(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9485 return lhs.m_it > rhs.m_it;
9488 friend constexpr
bool operator>=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9490 return lhs.m_it >= rhs.m_it;
9495 auto result = *
this;
9500 friend constexpr
difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9502 return lhs.m_it - rhs.m_it;
9505 friend std::ostream& operator<<(std::ostream& os, primitive_iterator_t it)
9507 return os << it.m_it;
9510 primitive_iterator_t& operator++()
9516 primitive_iterator_t operator++(
int)
9518 auto result = *
this;
9523 primitive_iterator_t& operator--()
9529 primitive_iterator_t operator--(
int)
9531 auto result = *
this;
9553 difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
9563 struct internal_iterator
9566 typename object_t::iterator object_iterator;
9568 typename array_t::iterator array_iterator;
9570 primitive_iterator_t primitive_iterator;
9573 internal_iterator() noexcept
9574 : object_iterator(), array_iterator(), primitive_iterator()
9579 template<
typename IteratorType>
9580 class iteration_proxy
9584 class iteration_proxy_internal
9588 IteratorType anchor;
9590 size_t array_index = 0;
9593 explicit iteration_proxy_internal(IteratorType it) noexcept
9598 iteration_proxy_internal& operator*()
9604 iteration_proxy_internal& operator++()
9613 bool operator!= (
const iteration_proxy_internal& o)
const 9615 return anchor != o.anchor;
9621 assert(anchor.m_object !=
nullptr);
9623 switch (anchor.m_object->type())
9626 case value_t::array:
9628 return std::to_string(array_index);
9632 case value_t::object:
9634 return anchor.key();
9646 typename IteratorType::reference value()
const 9648 return anchor.value();
9653 typename IteratorType::reference container;
9657 explicit iteration_proxy(
typename IteratorType::reference cont)
9662 iteration_proxy_internal begin() noexcept
9664 return iteration_proxy_internal(container.begin());
9668 iteration_proxy_internal end() noexcept
9670 return iteration_proxy_internal(container.end());
9694 template<
typename U>
9695 class iter_impl :
public std::iterator<std::random_access_iterator_tag, U>
9701 static_assert(std::is_same<U, basic_json>::value
9702 or std::is_same<U, const basic_json>::value,
9703 "iter_impl only accepts (const) basic_json");
9711 using pointer =
typename std::conditional<std::is_const<U>::value,
9715 using reference =
typename std::conditional<std::is_const<U>::value,
9733 assert(m_object !=
nullptr);
9735 switch (m_object->m_type)
9737 case basic_json::value_t::object:
9739 m_it.object_iterator =
typename object_t::iterator();
9743 case basic_json::value_t::array:
9745 m_it.array_iterator =
typename array_t::iterator();
9751 m_it.primitive_iterator = primitive_iterator_t();
9771 ret.m_object = m_object;
9784 : m_object(other.m_object), m_it(other.m_it)
9793 std::is_nothrow_move_constructible<pointer>::value and
9794 std::is_nothrow_move_assignable<pointer>::value and
9795 std::is_nothrow_move_constructible<internal_iterator>::value and
9796 std::is_nothrow_move_assignable<internal_iterator>::value
9799 std::swap(m_object, other.m_object);
9800 std::swap(m_it, other.m_it);
9809 void set_begin() noexcept
9811 assert(m_object !=
nullptr);
9813 switch (m_object->m_type)
9815 case basic_json::value_t::object:
9817 m_it.object_iterator = m_object->m_value.object->begin();
9821 case basic_json::value_t::array:
9823 m_it.array_iterator = m_object->m_value.array->begin();
9827 case basic_json::value_t::null:
9830 m_it.primitive_iterator.set_end();
9836 m_it.primitive_iterator.set_begin();
9846 void set_end() noexcept
9848 assert(m_object !=
nullptr);
9850 switch (m_object->m_type)
9852 case basic_json::value_t::object:
9854 m_it.object_iterator = m_object->m_value.object->end();
9858 case basic_json::value_t::array:
9860 m_it.array_iterator = m_object->m_value.array->end();
9866 m_it.primitive_iterator.set_end();
9879 assert(m_object !=
nullptr);
9881 switch (m_object->m_type)
9883 case basic_json::value_t::object:
9885 assert(m_it.object_iterator != m_object->m_value.object->end());
9886 return m_it.object_iterator->second;
9889 case basic_json::value_t::array:
9891 assert(m_it.array_iterator != m_object->m_value.array->end());
9892 return *m_it.array_iterator;
9895 case basic_json::value_t::null:
9897 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
9902 if (m_it.primitive_iterator.is_begin())
9907 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
9918 assert(m_object !=
nullptr);
9920 switch (m_object->m_type)
9922 case basic_json::value_t::object:
9924 assert(m_it.object_iterator != m_object->m_value.object->end());
9925 return &(m_it.object_iterator->second);
9928 case basic_json::value_t::array:
9930 assert(m_it.array_iterator != m_object->m_value.array->end());
9931 return &*m_it.array_iterator;
9936 if (m_it.primitive_iterator.is_begin())
9941 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
9952 auto result = *
this;
9963 assert(m_object !=
nullptr);
9965 switch (m_object->m_type)
9967 case basic_json::value_t::object:
9969 std::advance(m_it.object_iterator, 1);
9973 case basic_json::value_t::array:
9975 std::advance(m_it.array_iterator, 1);
9981 ++m_it.primitive_iterator;
9995 auto result = *
this;
10006 assert(m_object !=
nullptr);
10008 switch (m_object->m_type)
10010 case basic_json::value_t::object:
10012 std::advance(m_it.object_iterator, -1);
10016 case basic_json::value_t::array:
10018 std::advance(m_it.array_iterator, -1);
10024 --m_it.primitive_iterator;
10036 bool operator==(
const iter_impl& other)
const 10039 if (m_object != other.m_object)
10041 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
10044 assert(m_object !=
nullptr);
10046 switch (m_object->m_type)
10048 case basic_json::value_t::object:
10050 return (m_it.object_iterator == other.m_it.object_iterator);
10053 case basic_json::value_t::array:
10055 return (m_it.array_iterator == other.m_it.array_iterator);
10060 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
10069 bool operator!=(
const iter_impl& other)
const 10071 return not operator==(other);
10078 bool operator<(
const iter_impl& other)
const 10081 if (m_object != other.m_object)
10083 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
10086 assert(m_object !=
nullptr);
10088 switch (m_object->m_type)
10090 case basic_json::value_t::object:
10092 JSON_THROW(invalid_iterator::create(213,
"cannot compare order of object iterators"));
10095 case basic_json::value_t::array:
10097 return (m_it.array_iterator < other.m_it.array_iterator);
10102 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
10111 bool operator<=(
const iter_impl& other)
const 10113 return not other.operator < (*this);
10120 bool operator>(
const iter_impl& other)
const 10122 return not operator<=(other);
10129 bool operator>=(
const iter_impl& other)
const 10131 return not operator<(other);
10140 assert(m_object !=
nullptr);
10142 switch (m_object->m_type)
10144 case basic_json::value_t::object:
10146 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
10149 case basic_json::value_t::array:
10151 std::advance(m_it.array_iterator, i);
10157 m_it.primitive_iterator += i;
10171 return operator+=(-i);
10180 auto result = *
this;
10191 auto result = *
this;
10202 assert(m_object !=
nullptr);
10204 switch (m_object->m_type)
10206 case basic_json::value_t::object:
10208 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
10211 case basic_json::value_t::array:
10213 return m_it.array_iterator - other.m_it.array_iterator;
10218 return m_it.primitive_iterator - other.m_it.primitive_iterator;
10229 assert(m_object !=
nullptr);
10231 switch (m_object->m_type)
10233 case basic_json::value_t::object:
10235 JSON_THROW(invalid_iterator::create(208,
"cannot use operator[] for object iterators"));
10238 case basic_json::value_t::array:
10240 return *std::next(m_it.array_iterator, n);
10243 case basic_json::value_t::null:
10245 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
10250 if (m_it.primitive_iterator.get_value() == -n)
10255 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
10264 typename object_t::key_type key()
const 10266 assert(m_object !=
nullptr);
10268 if (m_object->is_object())
10270 return m_it.object_iterator->first;
10273 JSON_THROW(invalid_iterator::create(207,
"cannot use key() for non-object iterators"));
10282 return operator*();
10289 internal_iterator m_it = internal_iterator();
10309 template<
typename Base>
10314 using base_iterator = std::reverse_iterator<Base>;
10316 using reference =
typename Base::reference;
10320 : base_iterator(it)
10331 return base_iterator::operator++(1);
10337 base_iterator::operator++();
10344 return base_iterator::operator--(1);
10350 base_iterator::operator--();
10357 base_iterator::operator+=(i);
10364 auto result = *
this;
10372 auto result = *
this;
10380 return this->base() - other.base();
10386 return *(this->operator+(n));
10390 typename object_t::key_type key()
const 10392 auto it = --this->base();
10399 auto it = --this->base();
10400 return it.operator * ();
10421 enum class token_type
10442 using lexer_char_t =
unsigned char;
10445 lexer(
const lexer_char_t* buff,
const size_t len) noexcept
10448 assert(m_content !=
nullptr);
10449 m_start = m_cursor = m_content;
10450 m_limit = m_content + len;
10457 explicit lexer(std::istream& s)
10458 : m_stream(&s), m_line_buffer()
10463 JSON_THROW(parse_error::create(111, 0,
"bad input stream"));
10467 fill_line_buffer();
10470 if (m_line_buffer.size() >= 3 and m_line_buffer.substr(0, 3) ==
"\xEF\xBB\xBF")
10472 m_line_buffer[0] =
' ';
10473 m_line_buffer[1] =
' ';
10474 m_line_buffer[2] =
' ';
10480 lexer(
const lexer&) =
delete;
10481 lexer operator=(
const lexer&) =
delete;
10506 string_t to_unicode(
const std::size_t codepoint1,
10507 const std::size_t codepoint2 = 0)
const 10510 std::size_t codepoint = codepoint1;
10513 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
10516 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
10530 JSON_THROW(parse_error::create(102, get_position(),
"missing or wrong low surrogate"));
10536 if (codepoint < 0x80)
10539 result.append(1, static_cast<typename string_t::value_type>(codepoint));
10541 else if (codepoint <= 0x7ff)
10544 result.append(1, static_cast<typename string_t::value_type>(0xC0 | (codepoint >> 6)));
10545 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
10547 else if (codepoint <= 0xffff)
10550 result.append(1, static_cast<typename string_t::value_type>(0xE0 | (codepoint >> 12)));
10551 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
10552 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
10554 else if (codepoint <= 0x10ffff)
10557 result.append(1, static_cast<typename string_t::value_type>(0xF0 | (codepoint >> 18)));
10558 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
10559 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
10560 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
10564 JSON_THROW(parse_error::create(103, get_position(),
"code points above 0x10FFFF are invalid"));
10571 static std::string token_type_name(
const token_type t)
10575 case token_type::uninitialized:
10576 return "<uninitialized>";
10577 case token_type::literal_true:
10578 return "true literal";
10579 case token_type::literal_false:
10580 return "false literal";
10581 case token_type::literal_null:
10582 return "null literal";
10583 case token_type::value_string:
10584 return "string literal";
10585 case lexer::token_type::value_unsigned:
10586 case lexer::token_type::value_integer:
10587 case lexer::token_type::value_float:
10588 return "number literal";
10589 case token_type::begin_array:
10591 case token_type::begin_object:
10593 case token_type::end_array:
10595 case token_type::end_object:
10597 case token_type::name_separator:
10599 case token_type::value_separator:
10601 case token_type::parse_error:
10602 return "<parse error>";
10603 case token_type::end_of_input:
10604 return "end of input";
10608 return "unknown token";
10638 m_marker =
nullptr;
10641 m_start = m_cursor;
10642 assert(m_start !=
nullptr);
10647 unsigned int yyaccept = 0;
10648 static const unsigned char yybm[] =
10650 0, 0, 0, 0, 0, 0, 0, 0,
10651 0, 32, 32, 0, 0, 32, 0, 0,
10652 0, 0, 0, 0, 0, 0, 0, 0,
10653 0, 0, 0, 0, 0, 0, 0, 0,
10654 160, 128, 0, 128, 128, 128, 128, 128,
10655 128, 128, 128, 128, 128, 128, 128, 128,
10656 192, 192, 192, 192, 192, 192, 192, 192,
10657 192, 192, 128, 128, 128, 128, 128, 128,
10658 128, 128, 128, 128, 128, 128, 128, 128,
10659 128, 128, 128, 128, 128, 128, 128, 128,
10660 128, 128, 128, 128, 128, 128, 128, 128,
10661 128, 128, 128, 128, 0, 128, 128, 128,
10662 128, 128, 128, 128, 128, 128, 128, 128,
10663 128, 128, 128, 128, 128, 128, 128, 128,
10664 128, 128, 128, 128, 128, 128, 128, 128,
10665 128, 128, 128, 128, 128, 128, 128, 128,
10666 0, 0, 0, 0, 0, 0, 0, 0,
10667 0, 0, 0, 0, 0, 0, 0, 0,
10668 0, 0, 0, 0, 0, 0, 0, 0,
10669 0, 0, 0, 0, 0, 0, 0, 0,
10670 0, 0, 0, 0, 0, 0, 0, 0,
10671 0, 0, 0, 0, 0, 0, 0, 0,
10672 0, 0, 0, 0, 0, 0, 0, 0,
10673 0, 0, 0, 0, 0, 0, 0, 0,
10674 0, 0, 0, 0, 0, 0, 0, 0,
10675 0, 0, 0, 0, 0, 0, 0, 0,
10676 0, 0, 0, 0, 0, 0, 0, 0,
10677 0, 0, 0, 0, 0, 0, 0, 0,
10678 0, 0, 0, 0, 0, 0, 0, 0,
10679 0, 0, 0, 0, 0, 0, 0, 0,
10680 0, 0, 0, 0, 0, 0, 0, 0,
10681 0, 0, 0, 0, 0, 0, 0, 0,
10683 if ((m_limit - m_cursor) < 5)
10685 fill_line_buffer(5);
10688 if (yybm[0 + yych] & 32)
10690 goto basic_json_parser_6;
10700 goto basic_json_parser_2;
10704 goto basic_json_parser_4;
10706 goto basic_json_parser_9;
10712 goto basic_json_parser_4;
10716 goto basic_json_parser_10;
10718 goto basic_json_parser_12;
10727 goto basic_json_parser_4;
10731 goto basic_json_parser_13;
10733 goto basic_json_parser_15;
10739 goto basic_json_parser_17;
10743 goto basic_json_parser_4;
10745 goto basic_json_parser_19;
10757 goto basic_json_parser_21;
10759 goto basic_json_parser_4;
10765 goto basic_json_parser_23;
10769 goto basic_json_parser_4;
10771 goto basic_json_parser_24;
10780 goto basic_json_parser_25;
10782 goto basic_json_parser_4;
10788 goto basic_json_parser_26;
10792 goto basic_json_parser_28;
10794 goto basic_json_parser_4;
10798 basic_json_parser_2:
10801 last_token_type = token_type::end_of_input;
10804 basic_json_parser_4:
10806 basic_json_parser_5:
10808 last_token_type = token_type::parse_error;
10811 basic_json_parser_6:
10813 if (m_limit <= m_cursor)
10815 fill_line_buffer(1);
10818 if (yybm[0 + yych] & 32)
10820 goto basic_json_parser_6;
10823 position +=
static_cast<size_t>((m_cursor - m_start));
10826 basic_json_parser_9:
10828 yych = *(m_marker = ++m_cursor);
10831 goto basic_json_parser_5;
10835 goto basic_json_parser_31;
10839 goto basic_json_parser_5;
10843 goto basic_json_parser_31;
10845 goto basic_json_parser_5;
10846 basic_json_parser_10:
10849 last_token_type = token_type::value_separator;
10852 basic_json_parser_12:
10853 yych = *++m_cursor;
10856 goto basic_json_parser_5;
10860 goto basic_json_parser_43;
10864 goto basic_json_parser_45;
10866 goto basic_json_parser_5;
10867 basic_json_parser_13:
10869 yych = *(m_marker = ++m_cursor);
10874 goto basic_json_parser_47;
10878 goto basic_json_parser_48;
10887 goto basic_json_parser_51;
10894 goto basic_json_parser_51;
10898 basic_json_parser_14:
10900 last_token_type = token_type::value_unsigned;
10903 basic_json_parser_15:
10905 m_marker = ++m_cursor;
10906 if ((m_limit - m_cursor) < 3)
10908 fill_line_buffer(3);
10911 if (yybm[0 + yych] & 64)
10913 goto basic_json_parser_15;
10919 goto basic_json_parser_47;
10921 goto basic_json_parser_14;
10927 goto basic_json_parser_51;
10931 goto basic_json_parser_51;
10933 goto basic_json_parser_14;
10935 basic_json_parser_17:
10938 last_token_type = token_type::name_separator;
10941 basic_json_parser_19:
10944 last_token_type = token_type::begin_array;
10947 basic_json_parser_21:
10950 last_token_type = token_type::end_array;
10953 basic_json_parser_23:
10955 yych = *(m_marker = ++m_cursor);
10958 goto basic_json_parser_52;
10960 goto basic_json_parser_5;
10961 basic_json_parser_24:
10963 yych = *(m_marker = ++m_cursor);
10966 goto basic_json_parser_53;
10968 goto basic_json_parser_5;
10969 basic_json_parser_25:
10971 yych = *(m_marker = ++m_cursor);
10974 goto basic_json_parser_54;
10976 goto basic_json_parser_5;
10977 basic_json_parser_26:
10980 last_token_type = token_type::begin_object;
10983 basic_json_parser_28:
10986 last_token_type = token_type::end_object;
10989 basic_json_parser_30:
10991 if (m_limit <= m_cursor)
10993 fill_line_buffer(1);
10996 basic_json_parser_31:
10997 if (yybm[0 + yych] & 128)
10999 goto basic_json_parser_30;
11007 goto basic_json_parser_32;
11011 goto basic_json_parser_33;
11013 goto basic_json_parser_35;
11019 goto basic_json_parser_32;
11023 goto basic_json_parser_36;
11025 goto basic_json_parser_37;
11034 goto basic_json_parser_39;
11036 goto basic_json_parser_38;
11042 goto basic_json_parser_40;
11046 goto basic_json_parser_41;
11050 goto basic_json_parser_42;
11054 basic_json_parser_32:
11055 m_cursor = m_marker;
11060 goto basic_json_parser_5;
11064 goto basic_json_parser_14;
11071 goto basic_json_parser_44;
11075 goto basic_json_parser_58;
11078 basic_json_parser_33:
11081 last_token_type = token_type::value_string;
11084 basic_json_parser_35:
11086 if (m_limit <= m_cursor)
11088 fill_line_buffer(1);
11097 goto basic_json_parser_30;
11101 goto basic_json_parser_32;
11103 goto basic_json_parser_30;
11111 goto basic_json_parser_32;
11113 goto basic_json_parser_30;
11119 goto basic_json_parser_30;
11121 goto basic_json_parser_32;
11131 goto basic_json_parser_30;
11135 goto basic_json_parser_30;
11137 goto basic_json_parser_32;
11145 goto basic_json_parser_30;
11147 goto basic_json_parser_32;
11153 goto basic_json_parser_30;
11157 goto basic_json_parser_55;
11159 goto basic_json_parser_32;
11163 basic_json_parser_36:
11165 if (m_limit <= m_cursor)
11167 fill_line_buffer(1);
11172 goto basic_json_parser_32;
11176 goto basic_json_parser_30;
11178 goto basic_json_parser_32;
11179 basic_json_parser_37:
11181 if (m_limit <= m_cursor)
11183 fill_line_buffer(1);
11188 goto basic_json_parser_32;
11192 goto basic_json_parser_36;
11194 goto basic_json_parser_32;
11195 basic_json_parser_38:
11197 if (m_limit <= m_cursor)
11199 fill_line_buffer(1);
11204 goto basic_json_parser_32;
11208 goto basic_json_parser_36;
11210 goto basic_json_parser_32;
11211 basic_json_parser_39:
11213 if (m_limit <= m_cursor)
11215 fill_line_buffer(1);
11220 goto basic_json_parser_32;
11224 goto basic_json_parser_36;
11226 goto basic_json_parser_32;
11227 basic_json_parser_40:
11229 if (m_limit <= m_cursor)
11231 fill_line_buffer(1);
11236 goto basic_json_parser_32;
11240 goto basic_json_parser_38;
11242 goto basic_json_parser_32;
11243 basic_json_parser_41:
11245 if (m_limit <= m_cursor)
11247 fill_line_buffer(1);
11252 goto basic_json_parser_32;
11256 goto basic_json_parser_38;
11258 goto basic_json_parser_32;
11259 basic_json_parser_42:
11261 if (m_limit <= m_cursor)
11263 fill_line_buffer(1);
11268 goto basic_json_parser_32;
11272 goto basic_json_parser_38;
11274 goto basic_json_parser_32;
11275 basic_json_parser_43:
11277 yych = *(m_marker = ++m_cursor);
11282 goto basic_json_parser_47;
11286 goto basic_json_parser_48;
11295 goto basic_json_parser_51;
11302 goto basic_json_parser_51;
11306 basic_json_parser_44:
11308 last_token_type = token_type::value_integer;
11311 basic_json_parser_45:
11313 m_marker = ++m_cursor;
11314 if ((m_limit - m_cursor) < 3)
11316 fill_line_buffer(3);
11323 goto basic_json_parser_47;
11327 goto basic_json_parser_44;
11329 goto basic_json_parser_45;
11337 goto basic_json_parser_44;
11339 goto basic_json_parser_51;
11345 goto basic_json_parser_51;
11347 goto basic_json_parser_44;
11350 basic_json_parser_47:
11351 yych = *++m_cursor;
11354 goto basic_json_parser_32;
11358 goto basic_json_parser_56;
11360 goto basic_json_parser_32;
11361 basic_json_parser_48:
11363 if (m_limit <= m_cursor)
11365 fill_line_buffer(1);
11370 goto basic_json_parser_50;
11374 goto basic_json_parser_48;
11376 basic_json_parser_50:
11378 last_token_type = token_type::parse_error;
11381 basic_json_parser_51:
11382 yych = *++m_cursor;
11387 goto basic_json_parser_59;
11389 goto basic_json_parser_32;
11395 goto basic_json_parser_59;
11399 goto basic_json_parser_32;
11403 goto basic_json_parser_60;
11405 goto basic_json_parser_32;
11407 basic_json_parser_52:
11408 yych = *++m_cursor;
11411 goto basic_json_parser_62;
11413 goto basic_json_parser_32;
11414 basic_json_parser_53:
11415 yych = *++m_cursor;
11418 goto basic_json_parser_63;
11420 goto basic_json_parser_32;
11421 basic_json_parser_54:
11422 yych = *++m_cursor;
11425 goto basic_json_parser_64;
11427 goto basic_json_parser_32;
11428 basic_json_parser_55:
11430 if (m_limit <= m_cursor)
11432 fill_line_buffer(1);
11439 goto basic_json_parser_32;
11443 goto basic_json_parser_65;
11445 goto basic_json_parser_32;
11451 goto basic_json_parser_65;
11455 goto basic_json_parser_32;
11459 goto basic_json_parser_65;
11461 goto basic_json_parser_32;
11463 basic_json_parser_56:
11465 m_marker = ++m_cursor;
11466 if ((m_limit - m_cursor) < 3)
11468 fill_line_buffer(3);
11475 goto basic_json_parser_58;
11479 goto basic_json_parser_56;
11486 goto basic_json_parser_51;
11490 goto basic_json_parser_51;
11493 basic_json_parser_58:
11495 last_token_type = token_type::value_float;
11498 basic_json_parser_59:
11499 yych = *++m_cursor;
11502 goto basic_json_parser_32;
11506 goto basic_json_parser_32;
11508 basic_json_parser_60:
11510 if (m_limit <= m_cursor)
11512 fill_line_buffer(1);
11517 goto basic_json_parser_58;
11521 goto basic_json_parser_60;
11523 goto basic_json_parser_58;
11524 basic_json_parser_62:
11525 yych = *++m_cursor;
11528 goto basic_json_parser_66;
11530 goto basic_json_parser_32;
11531 basic_json_parser_63:
11532 yych = *++m_cursor;
11535 goto basic_json_parser_67;
11537 goto basic_json_parser_32;
11538 basic_json_parser_64:
11539 yych = *++m_cursor;
11542 goto basic_json_parser_69;
11544 goto basic_json_parser_32;
11545 basic_json_parser_65:
11547 if (m_limit <= m_cursor)
11549 fill_line_buffer(1);
11556 goto basic_json_parser_32;
11560 goto basic_json_parser_71;
11562 goto basic_json_parser_32;
11568 goto basic_json_parser_71;
11572 goto basic_json_parser_32;
11576 goto basic_json_parser_71;
11578 goto basic_json_parser_32;
11580 basic_json_parser_66:
11581 yych = *++m_cursor;
11584 goto basic_json_parser_72;
11586 goto basic_json_parser_32;
11587 basic_json_parser_67:
11590 last_token_type = token_type::literal_null;
11593 basic_json_parser_69:
11596 last_token_type = token_type::literal_true;
11599 basic_json_parser_71:
11601 if (m_limit <= m_cursor)
11603 fill_line_buffer(1);
11610 goto basic_json_parser_32;
11614 goto basic_json_parser_74;
11616 goto basic_json_parser_32;
11622 goto basic_json_parser_74;
11626 goto basic_json_parser_32;
11630 goto basic_json_parser_74;
11632 goto basic_json_parser_32;
11634 basic_json_parser_72:
11637 last_token_type = token_type::literal_false;
11640 basic_json_parser_74:
11642 if (m_limit <= m_cursor)
11644 fill_line_buffer(1);
11651 goto basic_json_parser_32;
11655 goto basic_json_parser_30;
11657 goto basic_json_parser_32;
11663 goto basic_json_parser_30;
11667 goto basic_json_parser_32;
11671 goto basic_json_parser_30;
11673 goto basic_json_parser_32;
11679 position +=
static_cast<size_t>((m_cursor - m_start));
11680 return last_token_type;
11711 void fill_line_buffer(
size_t n = 0)
11714 assert(m_line_buffer.empty()
11715 or m_content ==
reinterpret_cast<const lexer_char_t*
>(m_line_buffer.data()));
11718 assert(m_line_buffer.empty()
11719 or m_limit == m_content + m_line_buffer.size());
11722 assert(m_content <= m_start);
11723 assert(m_start <= m_cursor);
11724 assert(m_cursor <= m_limit);
11725 assert(m_marker ==
nullptr or m_marker <= m_limit);
11728 const auto num_processed_chars =
static_cast<size_t>(m_start - m_content);
11730 const auto offset_marker = (m_marker ==
nullptr) ? 0 : m_marker - m_start;
11732 const auto offset_cursor = m_cursor - m_start;
11735 if (m_stream ==
nullptr or m_stream->eof())
11740 m_line_buffer.assign(m_start, m_limit);
11744 m_line_buffer.append(1,
'\x00');
11747 m_line_buffer.append(n - 1,
'\x01');
11753 m_line_buffer.erase(0, num_processed_chars);
11755 m_line_buffer_tmp.clear();
11758 if (m_stream->fail())
11760 JSON_THROW(parse_error::create(111, 0,
"bad input stream"));
11763 std::getline(*m_stream, m_line_buffer_tmp,
'\n');
11766 m_line_buffer += m_line_buffer_tmp;
11767 m_line_buffer.push_back(
'\n');
11771 m_content =
reinterpret_cast<const lexer_char_t*
>(m_line_buffer.data());
11772 assert(m_content !=
nullptr);
11773 m_start = m_content;
11774 m_marker = m_start + offset_marker;
11775 m_cursor = m_start + offset_cursor;
11776 m_limit = m_start + m_line_buffer.size();
11782 assert(m_start !=
nullptr);
11783 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
11784 static_cast<size_t>(m_cursor - m_start));
11847 assert(m_cursor - m_start >= 2);
11850 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
11853 for (
const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
11856 auto e = std::find(i, m_cursor - 1,
'\\');
11860 for (
auto k = i; k < e; k++)
11862 result.push_back(static_cast<typename string_t::value_type>(*k));
11920 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
11921 4).c_str(),
nullptr, 16);
11924 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
11927 if ((i + 6 >= m_limit) or * (i + 5) !=
'\\' or * (i + 6) !=
'u')
11929 JSON_THROW(parse_error::create(102, get_position(),
"missing low surrogate"));
11933 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
11934 (i + 7), 4).c_str(),
nullptr, 16);
11935 result += to_unicode(codepoint, codepoint2);
11939 else if (codepoint >= 0xDC00 and codepoint <= 0xDFFF)
11942 JSON_THROW(parse_error::create(102, get_position(),
"missing high surrogate"));
11947 result += to_unicode(codepoint);
11973 strtonum(
const char* start,
const char* end)
11974 : m_start(start), m_end(end)
11983 template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
11984 bool to(T& val)
const 11986 return parse(val, std::is_integral<T>());
11990 const char*
const m_start =
nullptr;
11991 const char*
const m_end =
nullptr;
11997 static void strtof(
float& f,
const char* str,
char** endptr)
11999 f = std::strtof(str, endptr);
12002 static void strtof(
double& f,
const char* str,
char** endptr)
12004 f = std::strtod(str, endptr);
12007 static void strtof(
long double& f,
const char* str,
char** endptr)
12009 f = std::strtold(str, endptr);
12012 template<
typename T>
12013 bool parse(T& value, std::false_type)
const 12018 std::string tempstr;
12019 std::array<char, 64> buf;
12020 const size_t len =
static_cast<size_t>(m_end - m_start);
12028 const auto loc = localeconv();
12029 assert(loc !=
nullptr);
12030 const char decimal_point_char = (loc->decimal_point ==
nullptr) ?
'.' : loc->decimal_point[0];
12032 const char* data = m_start;
12034 if (decimal_point_char !=
'.')
12036 const size_t ds_pos =
static_cast<size_t>(std::find(m_start, m_end,
'.') - m_start);
12043 if ((len + 1) < buf.size())
12045 std::copy(m_start, m_end, buf.begin());
12047 buf[ds_pos] = decimal_point_char;
12052 tempstr.assign(m_start, m_end);
12053 tempstr[ds_pos] = decimal_point_char;
12054 data = tempstr.c_str();
12059 char* endptr =
nullptr;
12062 strtof(value, data, &endptr);
12066 const bool ok = (endptr == (data + len));
12068 if (ok and (value == static_cast<T>(0.0)) and (*data ==
'-'))
12079 signed long long parse_integral(
char** endptr, std::true_type)
const 12081 return std::strtoll(m_start, endptr, 10);
12084 unsigned long long parse_integral(
char** endptr, std::false_type)
const 12086 return std::strtoull(m_start, endptr, 10);
12089 template<
typename T>
12090 bool parse(T& value, std::true_type)
const 12092 char* endptr =
nullptr;
12094 const auto x = parse_integral(&endptr, std::is_signed<T>());
12097 static_assert(std::is_signed<T>() == std::is_signed<decltype(x)>(),
"");
12099 value =
static_cast<T
>(x);
12101 return (x ==
static_cast<decltype(x)
>(value))
12102 and (x < 0) == (value < 0)
12105 and (m_start < m_end)
12106 and (endptr == m_end);
12129 bool get_number(
basic_json& result,
const token_type token)
const 12131 assert(m_start !=
nullptr);
12132 assert(m_start < m_cursor);
12133 assert((token == token_type::value_unsigned) or
12134 (token == token_type::value_integer) or
12135 (token == token_type::value_float));
12137 strtonum num_converter(reinterpret_cast<const char*>(m_start),
12138 reinterpret_cast<const char*>(m_cursor));
12142 case lexer::token_type::value_unsigned:
12145 if (num_converter.to(val))
12148 result.m_type = value_t::number_unsigned;
12149 result.m_value = val;
12155 case lexer::token_type::value_integer:
12158 if (num_converter.to(val))
12161 result.m_type = value_t::number_integer;
12162 result.m_value = val;
12177 if (num_converter.to(val))
12180 result.m_type = value_t::number_float;
12181 result.m_value = val;
12184 if (not std::isfinite(result.m_value.number_float))
12186 JSON_THROW(out_of_range::create(406,
"number overflow parsing '" + get_token_string() +
"'"));
12196 constexpr
size_t get_position()
const 12203 std::istream* m_stream =
nullptr;
12209 const lexer_char_t* m_content =
nullptr;
12211 const lexer_char_t* m_start =
nullptr;
12213 const lexer_char_t* m_marker =
nullptr;
12215 const lexer_char_t* m_cursor =
nullptr;
12217 const lexer_char_t* m_limit =
nullptr;
12219 token_type last_token_type = token_type::end_of_input;
12221 size_t position = 0;
12235 m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(buff), std::strlen(buff))
12243 : callback(cb), m_lexer(is)
12247 template<
class IteratorType,
typename std::enable_if<
12248 std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value
12251 parser(IteratorType first, IteratorType last,
const parser_callback_t cb =
nullptr)
12253 m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(&(*first)),
12254 static_cast<size_t>(std::distance(first, last)))
12269 result.assert_invariant();
12271 expect(lexer::token_type::end_of_input);
12287 auto result =
basic_json(value_t::discarded);
12289 switch (last_token)
12291 case lexer::token_type::begin_object:
12293 if (keep and (not callback
12294 or ((keep = callback(depth++, parse_event_t::object_start, result)) != 0)))
12297 result.m_type = value_t::object;
12298 result.m_value = value_t::object;
12305 if (last_token == lexer::token_type::end_object)
12308 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
12316 unexpect(lexer::token_type::value_separator);
12322 if (last_token == lexer::token_type::value_separator)
12328 expect(lexer::token_type::value_string);
12329 const auto key = m_lexer.get_string();
12331 bool keep_tag =
false;
12337 keep_tag = callback(depth, parse_event_t::key, k);
12347 expect(lexer::token_type::name_separator);
12351 auto value = parse_internal(keep);
12352 if (keep and keep_tag and not value.is_discarded())
12354 result[key] = std::move(value);
12357 while (last_token == lexer::token_type::value_separator);
12360 expect(lexer::token_type::end_object);
12362 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
12370 case lexer::token_type::begin_array:
12372 if (keep and (not callback
12373 or ((keep = callback(depth++, parse_event_t::array_start, result)) != 0)))
12376 result.m_type = value_t::array;
12377 result.m_value = value_t::array;
12384 if (last_token == lexer::token_type::end_array)
12387 if (callback and not callback(--depth, parse_event_t::array_end, result))
12395 unexpect(lexer::token_type::value_separator);
12401 if (last_token == lexer::token_type::value_separator)
12407 auto value = parse_internal(keep);
12408 if (keep and not value.is_discarded())
12413 while (last_token == lexer::token_type::value_separator);
12416 expect(lexer::token_type::end_array);
12418 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
12426 case lexer::token_type::literal_null:
12429 result.m_type = value_t::null;
12433 case lexer::token_type::value_string:
12435 const auto s = m_lexer.get_string();
12441 case lexer::token_type::literal_true:
12444 result.m_type = value_t::boolean;
12445 result.m_value =
true;
12449 case lexer::token_type::literal_false:
12452 result.m_type = value_t::boolean;
12453 result.m_value =
false;
12457 case lexer::token_type::value_unsigned:
12458 case lexer::token_type::value_integer:
12459 case lexer::token_type::value_float:
12461 m_lexer.get_number(result, last_token);
12469 unexpect(last_token);
12473 if (keep and callback and not callback(depth, parse_event_t::value, result))
12481 typename lexer::token_type get_token()
12483 last_token = m_lexer.scan();
12490 void expect(
typename lexer::token_type t)
const 12492 if (t != last_token)
12494 std::string error_msg =
"parse error - unexpected ";
12495 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token_string() +
12497 lexer::token_type_name(last_token));
12498 error_msg +=
"; expected " + lexer::token_type_name(t);
12499 JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
12506 void unexpect(
typename lexer::token_type t)
const 12508 if (t == last_token)
12510 std::string error_msg =
"parse error - unexpected ";
12511 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token_string() +
12513 lexer::token_type_name(last_token));
12514 JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
12524 typename lexer::token_type last_token = lexer::token_type::uninitialized;
12570 : reference_tokens(split(s))
12588 std::string to_string()
const noexcept
12590 return std::accumulate(reference_tokens.begin(),
12591 reference_tokens.end(), std::string{},
12592 [](
const std::string & a,
const std::string & b)
12594 return a +
"/" + escape(b);
12599 operator std::string()
const 12601 return to_string();
12609 std::string pop_back()
12613 JSON_THROW(out_of_range::create(405,
"JSON pointer has no parent"));
12616 auto last = reference_tokens.back();
12617 reference_tokens.pop_back();
12622 bool is_root()
const 12624 return reference_tokens.empty();
12631 JSON_THROW(out_of_range::create(405,
"JSON pointer has no parent"));
12635 result.reference_tokens = {reference_tokens[0]};
12653 for (
const auto& reference_token : reference_tokens)
12655 switch (result->m_type)
12657 case value_t::null:
12659 if (reference_token ==
"0")
12662 result = &result->operator[](0);
12667 result = &result->operator[](reference_token);
12672 case value_t::object:
12675 result = &result->operator[](reference_token);
12679 case value_t::array:
12684 result = &result->operator[](
static_cast<size_type>(std::stoi(reference_token)));
12686 JSON_CATCH (std::invalid_argument&)
12688 JSON_THROW(parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
12702 JSON_THROW(type_error::create(313,
"invalid value to unflatten"));
12731 for (
const auto& reference_token : reference_tokens)
12734 if (ptr->m_type == value_t::null)
12737 const bool nums = std::all_of(reference_token.begin(),
12738 reference_token.end(),
12741 return (x >=
'0' and x <=
'9');
12746 if (nums or reference_token ==
"-")
12748 *ptr = value_t::array;
12752 *ptr = value_t::object;
12756 switch (ptr->m_type)
12758 case value_t::object:
12761 ptr = &ptr->operator[](reference_token);
12765 case value_t::array:
12768 if (reference_token.size() > 1 and reference_token[0] ==
'0')
12770 JSON_THROW(parse_error::create(106, 0,
"array index '" + reference_token +
"' must not begin with '0'"));
12773 if (reference_token ==
"-")
12776 ptr = &ptr->operator[](ptr->m_value.array->size());
12783 ptr = &ptr->operator[](
static_cast<size_type>(std::stoi(reference_token)));
12785 JSON_CATCH (std::invalid_argument&)
12787 JSON_THROW(parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
12795 JSON_THROW(out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
12811 for (
const auto& reference_token : reference_tokens)
12813 switch (ptr->m_type)
12815 case value_t::object:
12818 ptr = &ptr->
at(reference_token);
12822 case value_t::array:
12824 if (reference_token ==
"-")
12827 JSON_THROW(out_of_range::create(402,
"array index '-' (" +
12828 std::to_string(ptr->m_value.array->size()) +
12829 ") is out of range"));
12833 if (reference_token.size() > 1 and reference_token[0] ==
'0')
12835 JSON_THROW(parse_error::create(106, 0,
"array index '" + reference_token +
"' must not begin with '0'"));
12841 ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
12843 JSON_CATCH (std::invalid_argument&)
12845 JSON_THROW(parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
12852 JSON_THROW(out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
12875 for (
const auto& reference_token : reference_tokens)
12877 switch (ptr->m_type)
12879 case value_t::object:
12882 ptr = &ptr->operator[](reference_token);
12886 case value_t::array:
12888 if (reference_token ==
"-")
12891 JSON_THROW(out_of_range::create(402,
"array index '-' (" +
12892 std::to_string(ptr->m_value.array->size()) +
12893 ") is out of range"));
12897 if (reference_token.size() > 1 and reference_token[0] ==
'0')
12899 JSON_THROW(parse_error::create(106, 0,
"array index '" + reference_token +
"' must not begin with '0'"));
12905 ptr = &ptr->operator[](
static_cast<size_type>(std::stoi(reference_token)));
12907 JSON_CATCH (std::invalid_argument&)
12909 JSON_THROW(parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
12916 JSON_THROW(out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
12932 for (
const auto& reference_token : reference_tokens)
12934 switch (ptr->m_type)
12936 case value_t::object:
12939 ptr = &ptr->
at(reference_token);
12943 case value_t::array:
12945 if (reference_token ==
"-")
12948 JSON_THROW(out_of_range::create(402,
"array index '-' (" +
12949 std::to_string(ptr->m_value.array->size()) +
12950 ") is out of range"));
12954 if (reference_token.size() > 1 and reference_token[0] ==
'0')
12956 JSON_THROW(parse_error::create(106, 0,
"array index '" + reference_token +
"' must not begin with '0'"));
12962 ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
12964 JSON_CATCH (std::invalid_argument&)
12966 JSON_THROW(parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
12973 JSON_THROW(out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
12990 static std::vector<std::string> split(
const std::string& reference_string)
12992 std::vector<std::string> result;
12995 if (reference_string.empty())
13001 if (reference_string[0] !=
'/')
13003 JSON_THROW(parse_error::create(107, 1,
"JSON pointer must be empty or begin with '/' - was: '" + reference_string +
"'"));
13011 size_t slash = reference_string.find_first_of(
'/', 1),
13020 slash = reference_string.find_first_of(
'/', start))
13024 auto reference_token = reference_string.substr(start, slash - start);
13027 for (
size_t pos = reference_token.find_first_of(
'~');
13028 pos != std::string::npos;
13029 pos = reference_token.find_first_of(
'~', pos + 1))
13031 assert(reference_token[pos] ==
'~');
13034 if (pos == reference_token.size() - 1 or
13035 (reference_token[pos + 1] !=
'0' and
13036 reference_token[pos + 1] !=
'1'))
13038 JSON_THROW(parse_error::create(108, 0,
"escape character '~' must be followed with '0' or '1'"));
13043 unescape(reference_token);
13044 result.push_back(reference_token);
13063 static void replace_substring(std::string& s,
13064 const std::string& f,
13065 const std::string& t)
13067 assert(not f.empty());
13070 size_t pos = s.find(f);
13071 pos != std::string::npos;
13072 s.replace(pos, f.size(), t),
13073 pos = s.find(f, pos + t.size())
13078 static std::string escape(std::string s)
13081 replace_substring(s,
"~",
"~0");
13082 replace_substring(s,
"/",
"~1");
13087 static void unescape(std::string& s)
13090 replace_substring(s,
"~1",
"/");
13092 replace_substring(s,
"~0",
"~");
13102 static void flatten(
const std::string& reference_string,
13106 switch (value.m_type)
13108 case value_t::array:
13110 if (value.m_value.array->empty())
13113 result[reference_string] =
nullptr;
13118 for (
size_t i = 0; i < value.m_value.array->size(); ++i)
13120 flatten(reference_string +
"/" + std::to_string(i),
13121 value.m_value.array->operator[](i), result);
13127 case value_t::object:
13129 if (value.m_value.object->empty())
13132 result[reference_string] =
nullptr;
13137 for (
const auto& element : *value.m_value.object)
13139 flatten(reference_string +
"/" + escape(element.first),
13140 element.second, result);
13149 result[reference_string] = value;
13169 JSON_THROW(type_error::create(314,
"only objects can be unflattened"));
13175 for (
const auto& element : *value.m_value.object)
13177 if (not element.second.is_primitive())
13179 JSON_THROW(type_error::create(315,
"values in object must be primitive"));
13187 json_pointer(element.first).get_and_create(result) = element.second;
13196 return lhs.reference_tokens == rhs.reference_tokens;
13202 return !(lhs == rhs);
13206 std::vector<std::string> reference_tokens {};
13251 return ptr.get_unchecked(
this);
13279 return ptr.get_unchecked(
this);
13319 return ptr.get_checked(
this);
13359 return ptr.get_checked(
this);
13387 json_pointer::flatten(
"", *
this, result);
13423 return json_pointer::unflatten(*
this);
13488 enum class patch_operations {add,
remove, replace, move, copy, test, invalid};
13490 const auto get_op = [](
const std::string & op)
13494 return patch_operations::add;
13496 if (op ==
"remove")
13498 return patch_operations::remove;
13500 if (op ==
"replace")
13502 return patch_operations::replace;
13506 return patch_operations::move;
13510 return patch_operations::copy;
13514 return patch_operations::test;
13517 return patch_operations::invalid;
13532 if (top_pointer != ptr)
13534 result.
at(top_pointer);
13538 const auto last_path = ptr.pop_back();
13541 switch (parent.m_type)
13543 case value_t::null:
13544 case value_t::object:
13547 parent[last_path] = val;
13551 case value_t::array:
13553 if (last_path ==
"-")
13560 const auto idx = std::stoi(last_path);
13561 if (static_cast<size_type>(idx) > parent.
size())
13564 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
13585 const auto operation_remove = [&result](
json_pointer & ptr)
13588 const auto last_path = ptr.pop_back();
13595 auto it = parent.
find(last_path);
13596 if (it != parent.
end())
13602 JSON_THROW(out_of_range::create(403,
"key '" + last_path +
"' not found"));
13608 parent.
erase(static_cast<size_type>(std::stoi(last_path)));
13615 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
13619 for (
const auto& val : json_patch)
13622 const auto get_value = [&val](
const std::string & op,
13623 const std::string & member,
13627 auto it = val.m_value.object->find(member);
13630 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
13633 if (it == val.m_value.object->end())
13635 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have member '" + member +
"'"));
13639 if (string_type and not it->second.is_string())
13641 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have string member '" + member +
"'"));
13649 if (not val.is_object())
13651 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
13655 const std::string op = get_value(
"op",
"op",
true);
13656 const std::string path = get_value(op,
"path",
true);
13659 switch (get_op(op))
13661 case patch_operations::add:
13663 operation_add(ptr, get_value(
"add",
"value",
false));
13667 case patch_operations::remove:
13669 operation_remove(ptr);
13673 case patch_operations::replace:
13676 result.
at(ptr) = get_value(
"replace",
"value",
false);
13680 case patch_operations::move:
13682 const std::string from_path = get_value(
"move",
"from",
true);
13692 operation_remove(from_ptr);
13693 operation_add(ptr, v);
13697 case patch_operations::copy:
13699 const std::string from_path = get_value(
"copy",
"from",
true);;
13703 result[ptr] = result.
at(from_ptr);
13707 case patch_operations::test:
13709 bool success =
false;
13714 success = (result.
at(ptr) == get_value(
"test",
"value",
false));
13724 JSON_THROW(other_error::create(501,
"unsuccessful: " + val.dump()));
13730 case patch_operations::invalid:
13734 JSON_THROW(parse_error::create(105, 0,
"operation value '" + op +
"' is invalid"));
13776 const std::string& path =
"")
13782 if (source == target)
13787 if (source.
type() != target.
type())
13799 switch (source.
type())
13801 case value_t::array:
13805 while (i < source.
size() and i < target.
size())
13808 auto temp_diff = diff(source[i], target[i], path +
"/" + std::to_string(i));
13809 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
13818 while (i < source.
size())
13822 result.
insert(result.
begin() + end_index, object(
13825 {
"path", path +
"/" + std::to_string(i)}
13831 while (i < target.
size())
13836 {
"path", path +
"/" + std::to_string(i)},
13837 {
"value", target[i]}
13845 case value_t::object:
13848 for (
auto it = source.
begin(); it != source.
end(); ++it)
13851 const auto key = json_pointer::escape(it.key());
13853 if (target.
find(it.key()) != target.
end())
13856 auto temp_diff = diff(it.value(), target[it.key()], path +
"/" + key);
13857 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
13865 {
"path", path +
"/" + key}
13871 for (
auto it = target.
begin(); it != target.
end(); ++it)
13873 if (source.
find(it.key()) == source.
end())
13876 const auto key = json_pointer::escape(it.key());
13880 {
"path", path +
"/" + key},
13881 {
"value", it.value()}
13940 is_nothrow_move_constructible<nlohmann::json>::value and
13941 is_nothrow_move_assignable<nlohmann::json>::value
13949 struct hash<nlohmann::
json>
13959 const auto& h = hash<nlohmann::json::string_t>();
13960 return h(j.
dump());
13966 struct less<::nlohmann::detail::value_t>
13972 bool operator()(nlohmann::detail::value_t lhs,
13973 nlohmann::detail::value_t rhs)
const noexcept
13975 return nlohmann::detail::operator<(lhs, rhs);
13994 inline nlohmann::json operator "" _json(
const char* s, std::size_t n)
14018 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 14019 #pragma GCC diagnostic pop 14021 #if defined(__clang__) 14022 #pragma GCC diagnostic pop 14029 #undef JSON_DEPRECATED typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
JSONSerializer< T, SFINAE > json_serializer
NumberFloatType number_float_t
a type for a number (floating-point)
BooleanType boolean_t
a type for a boolean
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adaptor
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)
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
static basic_json object(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an object from an initializer list
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
ReferenceType get_ref()
get a reference value (implicit)
a class to store JSON values
typename std::conditional< std::is_const< U >::value, typename basic_json::const_pointer, typename basic_json::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
static allocator_type get_allocator()
returns the allocator associated with the container
default JSONSerializer template argument
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
iterator find(typename object_t::key_type key)
find an element in a JSON object
constexpr bool is_structured() const noexcept
return whether type is structured
ObjectType< StringType, basic_json, std::less< StringType >, AllocatorType< std::pair< const StringType, basic_json > >> object_t
a type for an object
static basic_json parse(T(&array)[N], const parser_callback_t cb=nullptr)
deserialize from an array
typename std::conditional< std::is_const< U >::value, typename basic_json::const_reference, typename basic_json::reference >::type reference
defines a reference to the type iterated over (value_type)
reference & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
copy assignment
detail::other_error other_error
exception indicating other errors
std::bidirectional_iterator_tag iterator_category
the category of the iterator
basic_json(std::initializer_list< basic_json > init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
reference at(size_type idx)
access specified array element with bounds checking
constexpr bool is_number() const noexcept
return whether value is a number
const value_type & const_reference
the type of an element const reference
constexpr bool is_primitive() const noexcept
return whether type is primitive
reference front()
access the first element
std::size_t size_type
a type to represent container sizes
ReferenceType get_ref() const
get a reference value (implicit)
static iteration_proxy< iterator > iterator_wrapper(reference cont)
wrapper to access iterator member functions in range-based for
static void from_json(BasicJsonType &&j, ValueType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val)))
convert a JSON value to any value type
NumberIntegerType number_integer_t
a type for a number (integer)
constexpr bool is_array() const noexcept
return whether value is an array
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
size_type size() const noexcept
returns the number of elements
parse string into a built-in arithmetic type as if the current locale is POSIX.
detail::out_of_range out_of_range
exception indicating access out of the defined range
static basic_json meta()
returns version information on the library
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
constexpr const auto & from_json
constexpr bool is_boolean() const noexcept
return whether value is a boolean
detail::type_error type_error
exception indicating executing a member function with a wrong type
PointerType get_ptr() noexcept
get a pointer value (implicit)
namespace for Niels Lohmann
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
basic_json(const value_t value_type)
create an empty value with a given type
constexpr bool is_object() const noexcept
return whether value is an object
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
detail::parse_error parse_error
exception indicating a parse error
static void to_json(BasicJsonType &j, ValueType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< ValueType >(val))))
convert any value type to a JSON value
std::function< bool(int depth, parse_event_t event, basic_json &parsed)> parser_callback_t
per-element parser callback type
constexpr bool is_string() const noexcept
return whether value is a string
constexpr const auto & to_json
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
string_t dump(const int indent=-1) const
serialization
std::ptrdiff_t difference_type
a type to represent differences between iterators
AllocatorType< basic_json > allocator_type
the allocator type
basic_json(CompatibleType &&val) noexcept(noexcept(JSONSerializer< U >::to_json(std::declval< basic_json_t &>(), std::forward< CompatibleType >(val))))
create a JSON value
constexpr bool is_null() const noexcept
return whether value is null
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 array(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an array from an initializer list
basic_json(basic_json &&other) noexcept
move constructor
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
typename basic_json::difference_type difference_type
a type to represent differences between iterators
constexpr const PointerType get_ptr() const noexcept
get a pointer value (implicit)
typename Base::reference reference
the reference type for the pointed-to element
a template for a reverse iterator class
void push_back(basic_json &&val)
add an object to an array
iterator insert(const_iterator pos, const basic_json &val)
inserts element
basic_json value_type
the type of elements in a basic_json container
detail::exception exception
general exception of the basic_json class
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
basic_json(const basic_json &other)
copy constructor
detail::invalid_iterator invalid_iterator
exception indicating errors with iterators
IteratorType erase(IteratorType pos)
remove element given an iterator
a template for a random access iterator for the basic_json class
constexpr bool is_discarded() const noexcept
return whether value is discarded
parse_event_t
JSON callback events.
reverse_iterator rend() noexcept
returns an iterator to the reverse-end