99 :
public ::nlohmann::detail::json_base_class<CustomBaseClass>
105 friend class ::nlohmann::json_pointer;
109 template<
typename BasicJsonType,
typename InputType>
110 friend class ::nlohmann::detail::parser;
111 friend ::nlohmann::detail::serializer<basic_json>;
112 template<
typename BasicJsonType>
113 friend class ::nlohmann::detail::iter_impl;
114 template<
typename BasicJsonType,
typename CharType>
115 friend class ::nlohmann::detail::binary_writer;
116 template<
typename BasicJsonType,
typename InputType,
typename SAX>
117 friend class ::nlohmann::detail::binary_reader;
118 template<
typename BasicJsonType,
typename InputAdapterType>
119 friend class ::nlohmann::detail::json_sax_dom_parser;
120 template<
typename BasicJsonType,
typename InputAdapterType>
121 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
122 friend class ::nlohmann::detail::exception;
125 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
126 using json_base_class_t = ::nlohmann::detail::json_base_class<CustomBaseClass>;
128 JSON_PRIVATE_UNLESS_TESTED:
130 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
132 template<
typename InputAdapterType>
133 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
134 InputAdapterType adapter,
135 detail::parser_callback_t<basic_json>cb =
nullptr,
136 const bool allow_exceptions =
true,
137 const bool ignore_comments =
false,
138 const bool ignore_trailing_commas =
false
141 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
142 std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas);
146 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
147 template<
typename BasicJsonType>
148 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
149 template<
typename BasicJsonType>
150 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
151 template<
typename Iterator>
152 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
153 template<
typename Base>
using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
155 template<
typename CharType>
156 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
158 template<
typename InputType>
159 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
160 template<
typename CharType>
using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
162 JSON_PRIVATE_UNLESS_TESTED:
163 using serializer = ::nlohmann::detail::serializer<basic_json>;
169 template<
typename T,
typename SFINAE>
170 using json_serializer = JSONSerializer<T, SFINAE>;
227 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
229 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
251 JSON_HEDLEY_WARN_UNUSED_RESULT
256 result[
"copyright"] =
"(C) 2013-2025 Niels Lohmann";
257 result[
"name"] =
"JSON for Modern C++";
258 result[
"url"] =
"https://github.com/nlohmann/json";
259 result[
"version"][
"string"] =
260 detail::concat(std::to_string(NLOHMANN_JSON_VERSION_MAJOR),
'.',
261 std::to_string(NLOHMANN_JSON_VERSION_MINOR),
'.',
262 std::to_string(NLOHMANN_JSON_VERSION_PATCH));
263 result[
"version"][
"major"] = NLOHMANN_JSON_VERSION_MAJOR;
264 result[
"version"][
"minor"] = NLOHMANN_JSON_VERSION_MINOR;
265 result[
"version"][
"patch"] = NLOHMANN_JSON_VERSION_PATCH;
268 result[
"platform"] =
"win32";
269#elif defined __linux__
270 result[
"platform"] =
"linux";
271#elif defined __APPLE__
272 result[
"platform"] =
"apple";
273#elif defined __unix__
274 result[
"platform"] =
"unix";
276 result[
"platform"] =
"unknown";
279#if defined(__ICC) || defined(__INTEL_COMPILER)
280 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
281#elif defined(__clang__)
282 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
283#elif defined(__GNUC__) || defined(__GNUG__)
284 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", detail::concat(
285 std::to_string(__GNUC__),
'.',
286 std::to_string(__GNUC_MINOR__),
'.',
287 std::to_string(__GNUC_PATCHLEVEL__))
290#elif defined(__HP_cc) || defined(__HP_aCC)
291 result[
"compiler"] =
"hp"
292#elif defined(__IBMCPP__)
293 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
294#elif defined(_MSC_VER)
295 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
297 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
298#elif defined(__SUNPRO_CC)
299 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
301 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
304#if defined(_MSVC_LANG)
305 result[
"compiler"][
"c++"] = std::to_string(_MSVC_LANG);
306#elif defined(__cplusplus)
307 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
309 result[
"compiler"][
"c++"] =
"unknown";
327#if defined(JSON_HAS_CPP_14)
340 AllocatorType<std::pair<
const StringType,
345 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
369 using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
380 template<
typename T,
typename... Args>
381 JSON_HEDLEY_RETURNS_NON_NULL
382 static T* create(Args&& ... args)
384 AllocatorType<T> alloc;
385 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
387 auto deleter = [&](T * obj)
389 AllocatorTraits::deallocate(alloc, obj, 1);
391 std::unique_ptr<T,
decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
392 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
393 JSON_ASSERT(obj !=
nullptr);
394 return obj.release();
401 JSON_PRIVATE_UNLESS_TESTED:
447 json_value() =
default;
449 json_value(
boolean_t v) noexcept : boolean(v) {}
457 json_value(value_t t)
461 case value_t::object:
463 object = create<object_t>();
469 array = create<array_t>();
473 case value_t::string:
475 string = create<string_t>(
"");
479 case value_t::binary:
481 binary = create<binary_t>();
485 case value_t::boolean:
491 case value_t::number_integer:
497 case value_t::number_unsigned:
503 case value_t::number_float:
515 case value_t::discarded:
519 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
521 JSON_THROW(other_error::create(500,
"961c151d2e87f2686a955a9be24d316f1362bf21 3.12.0",
nullptr));
558 void destroy(value_t t)
561 (t == value_t::object &&
object ==
nullptr) ||
562 (t == value_t::array && array ==
nullptr) ||
563 (t == value_t::string &&
string ==
nullptr) ||
564 (t == value_t::binary && binary ==
nullptr)
570 if (t == value_t::array || t == value_t::object)
573 std::vector<basic_json> stack;
576 if (t == value_t::array)
578 stack.reserve(
array->size());
579 std::move(
array->begin(),
array->end(), std::back_inserter(stack));
584 for (
auto&& it : *
object)
586 stack.push_back(std::move(it.second));
590 while (!stack.empty())
593 basic_json current_item(std::move(stack.back()));
598 if (current_item.is_array())
600 std::move(current_item.m_data.m_value.array->begin(), current_item.m_data.m_value.array->end(), std::back_inserter(stack));
602 current_item.m_data.m_value.array->clear();
604 else if (current_item.is_object())
606 for (
auto&& it : *current_item.m_data.m_value.object)
608 stack.push_back(std::move(it.second));
611 current_item.m_data.m_value.object->clear();
621 case value_t::object:
623 AllocatorType<object_t> alloc;
624 std::allocator_traits<
decltype(alloc)>::destroy(alloc,
object);
625 std::allocator_traits<
decltype(alloc)>::deallocate(alloc,
object, 1);
631 AllocatorType<array_t> alloc;
632 std::allocator_traits<
decltype(alloc)>::destroy(alloc, array);
633 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, array, 1);
637 case value_t::string:
639 AllocatorType<string_t> alloc;
640 std::allocator_traits<
decltype(alloc)>::destroy(alloc,
string);
641 std::allocator_traits<
decltype(alloc)>::deallocate(alloc,
string, 1);
645 case value_t::binary:
647 AllocatorType<binary_t> alloc;
648 std::allocator_traits<
decltype(alloc)>::destroy(alloc, binary);
649 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, binary, 1);
654 case value_t::boolean:
655 case value_t::number_integer:
656 case value_t::number_unsigned:
657 case value_t::number_float:
658 case value_t::discarded:
686 void assert_invariant(
bool check_parents =
true) const noexcept
688 JSON_ASSERT(m_data.m_type != value_t::object || m_data.m_value.object !=
nullptr);
689 JSON_ASSERT(m_data.m_type != value_t::array || m_data.m_value.array !=
nullptr);
690 JSON_ASSERT(m_data.m_type != value_t::string || m_data.m_value.string !=
nullptr);
691 JSON_ASSERT(m_data.m_type != value_t::binary || m_data.m_value.binary !=
nullptr);
699 return j.m_parent ==
this;
704 static_cast<void>(check_parents);
710 switch (m_data.m_type)
714 for (
auto& element : *m_data.m_value.array)
716 element.m_parent =
this;
721 case value_t::object:
723 for (
auto& element : *m_data.m_value.object)
725 element.second.m_parent =
this;
731 case value_t::string:
732 case value_t::boolean:
733 case value_t::number_integer:
734 case value_t::number_unsigned:
735 case value_t::number_float:
736 case value_t::binary:
737 case value_t::discarded:
744 iterator set_parents(
iterator it,
typename iterator::difference_type count_set_parents)
747 for (
typename iterator::difference_type i = 0; i < count_set_parents; ++i)
749 (it + i)->m_parent =
this;
752 static_cast<void>(count_set_parents);
760 if (old_capacity != detail::unknown_size())
763 JSON_ASSERT(
type() == value_t::array);
764 if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
774#ifdef JSON_HEDLEY_MSVC_VERSION
775#pragma warning(push )
776#pragma warning(disable : 4127)
778 if (detail::is_ordered_map<object_t>::value)
783#ifdef JSON_HEDLEY_MSVC_VERSION
784#pragma warning( pop )
789 static_cast<void>(j);
790 static_cast<void>(old_capacity);
835 template <
typename CompatibleType,
836 typename U = detail::uncvref_t<CompatibleType>,
837 detail::enable_if_t <
840 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
841 std::forward<CompatibleType>(val))))
843 JSONSerializer<U>::to_json(*
this, std::forward<CompatibleType>(val));
850 template <
typename BasicJsonType,
851 detail::enable_if_t <
854#if JSON_DIAGNOSTIC_POSITIONS
855 : start_position(val.start_pos()),
856 end_position(val.end_pos())
859 using other_boolean_t =
typename BasicJsonType::boolean_t;
860 using other_number_float_t =
typename BasicJsonType::number_float_t;
861 using other_number_integer_t =
typename BasicJsonType::number_integer_t;
862 using other_number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
863 using other_string_t =
typename BasicJsonType::string_t;
864 using other_object_t =
typename BasicJsonType::object_t;
865 using other_array_t =
typename BasicJsonType::array_t;
866 using other_binary_t =
typename BasicJsonType::binary_t;
870 case value_t::boolean:
873 case value_t::number_float:
876 case value_t::number_integer:
879 case value_t::number_unsigned:
882 case value_t::string:
885 case value_t::object:
891 case value_t::binary:
897 case value_t::discarded:
898 m_data.m_type = value_t::discarded;
903 JSON_ASSERT(m_data.m_type == val.type());
912 bool type_deduction =
true,
913 value_t manual_type = value_t::array)
917 bool is_an_object = std::all_of(init.begin(), init.end(),
923 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[static_cast<size_type>(0)].is_string();
930 if (manual_type == value_t::array)
932 is_an_object =
false;
936 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
938 JSON_THROW(type_error::create(301,
"cannot create object from initializer list",
nullptr));
945 m_data.m_type = value_t::object;
946 m_data.m_value = value_t::object;
948 for (
auto& element_ref : init)
950 auto element = element_ref.moved_or_copied();
951 m_data.
m_value.object->emplace(
952 std::move(*((*element.m_data.m_value.array)[0].m_data.m_value.string)),
953 std::move((*element.m_data.m_value.array)[1]));
959 m_data.m_type = value_t::array;
960 m_data.m_value.array = create<array_t>(init.begin(), init.end());
969 JSON_HEDLEY_WARN_UNUSED_RESULT
973 res.m_data.m_type = value_t::binary;
974 res.m_data.m_value = init;
980 JSON_HEDLEY_WARN_UNUSED_RESULT
981 static basic_json binary(
const typename binary_t::container_type& init,
typename binary_t::subtype_type subtype)
984 res.m_data.m_type = value_t::binary;
985 res.m_data.m_value =
binary_t(init, subtype);
991 JSON_HEDLEY_WARN_UNUSED_RESULT
995 res.m_data.m_type = value_t::binary;
996 res.m_data.m_value = std::move(init);
1002 JSON_HEDLEY_WARN_UNUSED_RESULT
1003 static basic_json binary(
typename binary_t::container_type&& init,
typename binary_t::subtype_type subtype)
1006 res.m_data.m_type = value_t::binary;
1007 res.m_data.m_value =
binary_t(std::move(init), subtype);
1013 JSON_HEDLEY_WARN_UNUSED_RESULT
1016 return basic_json(init,
false, value_t::array);
1021 JSON_HEDLEY_WARN_UNUSED_RESULT
1024 return basic_json(init,
false, value_t::object);
1038 template <
class InputIT,
typename std::enable_if <
1039 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
1040 std::is_same<InputIT, typename basic_json_t::const_iterator>::value,
int >
::type = 0 >
1043 JSON_ASSERT(first.m_object !=
nullptr);
1044 JSON_ASSERT(last.m_object !=
nullptr);
1047 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
1049 JSON_THROW(invalid_iterator::create(201,
"iterators are not compatible",
nullptr));
1053 m_data.m_type = first.m_object->m_data.m_type;
1056 switch (m_data.m_type)
1058 case value_t::boolean:
1059 case value_t::number_float:
1060 case value_t::number_integer:
1061 case value_t::number_unsigned:
1062 case value_t::string:
1064 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
1065 || !last.m_it.primitive_iterator.is_end()))
1067 JSON_THROW(invalid_iterator::create(204,
"iterators out of range", first.m_object));
1073 case value_t::object:
1074 case value_t::array:
1075 case value_t::binary:
1076 case value_t::discarded:
1081 switch (m_data.m_type)
1083 case value_t::number_integer:
1085 m_data.m_value.number_integer = first.m_object->m_data.m_value.number_integer;
1089 case value_t::number_unsigned:
1091 m_data.m_value.number_unsigned = first.m_object->m_data.m_value.number_unsigned;
1095 case value_t::number_float:
1097 m_data.m_value.number_float = first.m_object->m_data.m_value.number_float;
1101 case value_t::boolean:
1103 m_data.m_value.boolean = first.m_object->m_data.m_value.boolean;
1107 case value_t::string:
1109 m_data.m_value = *first.m_object->m_data.m_value.string;
1113 case value_t::object:
1115 m_data.m_value.object = create<object_t>(first.m_it.object_iterator,
1116 last.m_it.object_iterator);
1120 case value_t::array:
1122 m_data.m_value.array = create<array_t>(first.m_it.array_iterator,
1123 last.m_it.array_iterator);
1127 case value_t::binary:
1129 m_data.m_value = *first.m_object->m_data.m_value.binary;
1134 case value_t::discarded:
1136 JSON_THROW(invalid_iterator::create(206, detail::concat(
"cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
1147 template<
typename JsonRef,
1148 detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
1149 std::is_same<typename JsonRef::value_type, basic_json>>
::value,
int> = 0 >
1155 : json_base_class_t(other)
1156#if JSON_DIAGNOSTIC_POSITIONS
1157 , start_position(other.start_position)
1158 , end_position(other.end_position)
1161 m_data.m_type = other.m_data.m_type;
1163 other.assert_invariant();
1165 switch (m_data.m_type)
1167 case value_t::object:
1169 m_data.m_value = *other.m_data.m_value.object;
1173 case value_t::array:
1175 m_data.m_value = *other.m_data.m_value.array;
1179 case value_t::string:
1181 m_data.m_value = *other.m_data.m_value.string;
1185 case value_t::boolean:
1187 m_data.m_value = other.m_data.m_value.boolean;
1191 case value_t::number_integer:
1193 m_data.m_value = other.m_data.m_value.number_integer;
1197 case value_t::number_unsigned:
1199 m_data.m_value = other.m_data.m_value.number_unsigned;
1203 case value_t::number_float:
1205 m_data.m_value = other.m_data.m_value.number_float;
1209 case value_t::binary:
1211 m_data.m_value = *other.m_data.m_value.binary;
1216 case value_t::discarded:
1228 : json_base_class_t(std::forward<json_base_class_t>(other)),
1229 m_data(std::move(other.m_data))
1230#if JSON_DIAGNOSTIC_POSITIONS
1231 , start_position(other.start_position)
1232 , end_position(other.end_position)
1236 other.assert_invariant(
false);
1239 other.m_data.m_type = value_t::null;
1240 other.m_data.m_value = {};
1242#if JSON_DIAGNOSTIC_POSITIONS
1243 other.start_position = std::string::npos;
1244 other.end_position = std::string::npos;
1254 std::is_nothrow_move_constructible<value_t>::value&&
1255 std::is_nothrow_move_assignable<value_t>::value&&
1256 std::is_nothrow_move_constructible<json_value>::value&&
1257 std::is_nothrow_move_assignable<json_value>::value&&
1258 std::is_nothrow_move_assignable<json_base_class_t>::value
1262 other.assert_invariant();
1265 swap(m_data.m_type, other.m_data.m_type);
1266 swap(m_data.m_value, other.m_data.m_value);
1268#if JSON_DIAGNOSTIC_POSITIONS
1269 swap(start_position, other.start_position);
1270 swap(end_position, other.end_position);
1273 json_base_class_t::operator=(std::move(other));
1284 assert_invariant(
false);
1301 const char indent_char =
' ',
1302 const bool ensure_ascii =
false,
1310 s.dump(*
this,
true, ensure_ascii,
static_cast<unsigned int>(indent));
1314 s.dump(*
this,
false, ensure_ascii, 0);
1322 constexpr value_t
type() const noexcept
1324 return m_data.m_type;
1345 return m_data.m_type == value_t::null;
1352 return m_data.m_type == value_t::boolean;
1366 return m_data.m_type == value_t::number_integer || m_data.m_type == value_t::number_unsigned;
1373 return m_data.m_type == value_t::number_unsigned;
1380 return m_data.m_type == value_t::number_float;
1387 return m_data.m_type == value_t::object;
1394 return m_data.m_type == value_t::array;
1401 return m_data.m_type == value_t::string;
1408 return m_data.m_type == value_t::binary;
1415 return m_data.m_type == value_t::discarded;
1420 constexpr operator value_t() const noexcept
1422 return m_data.m_type;
1433 boolean_t get_impl(boolean_t* )
const
1435 if (JSON_HEDLEY_LIKELY(is_boolean()))
1437 return m_data.m_value.boolean;
1440 JSON_THROW(type_error::create(302, detail::concat(
"type must be boolean, but is ", type_name()),
this));
1444 object_t* get_impl_ptr(object_t* )
noexcept
1446 return is_object() ? m_data.m_value.object :
nullptr;
1450 constexpr const object_t* get_impl_ptr(
const object_t* )
const noexcept
1452 return is_object() ? m_data.m_value.object :
nullptr;
1456 array_t* get_impl_ptr(array_t* )
noexcept
1458 return is_array() ? m_data.m_value.array :
nullptr;
1462 constexpr const array_t* get_impl_ptr(
const array_t* )
const noexcept
1464 return is_array() ? m_data.m_value.array :
nullptr;
1468 string_t* get_impl_ptr(string_t* )
noexcept
1470 return is_string() ? m_data.m_value.string :
nullptr;
1474 constexpr const string_t* get_impl_ptr(
const string_t* )
const noexcept
1476 return is_string() ? m_data.m_value.string :
nullptr;
1480 boolean_t* get_impl_ptr(boolean_t* )
noexcept
1482 return is_boolean() ? &m_data.m_value.boolean :
nullptr;
1486 constexpr const boolean_t* get_impl_ptr(
const boolean_t* )
const noexcept
1488 return is_boolean() ? &m_data.m_value.boolean :
nullptr;
1492 number_integer_t* get_impl_ptr(number_integer_t* )
noexcept
1494 return m_data.m_type == value_t::number_integer ? &m_data.m_value.number_integer :
nullptr;
1498 constexpr const number_integer_t* get_impl_ptr(
const number_integer_t* )
const noexcept
1500 return m_data.m_type == value_t::number_integer ? &m_data.m_value.number_integer :
nullptr;
1504 number_unsigned_t* get_impl_ptr(number_unsigned_t* )
noexcept
1506 return is_number_unsigned() ? &m_data.m_value.number_unsigned :
nullptr;
1510 constexpr const number_unsigned_t* get_impl_ptr(
const number_unsigned_t* )
const noexcept
1512 return is_number_unsigned() ? &m_data.m_value.number_unsigned :
nullptr;
1516 number_float_t* get_impl_ptr(number_float_t* )
noexcept
1518 return is_number_float() ? &m_data.m_value.number_float :
nullptr;
1522 constexpr const number_float_t* get_impl_ptr(
const number_float_t* )
const noexcept
1524 return is_number_float() ? &m_data.m_value.number_float :
nullptr;
1528 binary_t* get_impl_ptr(binary_t* )
noexcept
1530 return is_binary() ? m_data.m_value.binary :
nullptr;
1534 constexpr const binary_t* get_impl_ptr(
const binary_t* )
const noexcept
1536 return is_binary() ? m_data.m_value.binary :
nullptr;
1550 template<
typename ReferenceType,
typename ThisType>
1551 static ReferenceType get_ref_impl(ThisType& obj)
1554 auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
1556 if (JSON_HEDLEY_LIKELY(ptr !=
nullptr))
1561 JSON_THROW(type_error::create(303, detail::concat(
"incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
1571 template<
typename PointerType,
typename std::enable_if<
1572 std::is_pointer<PointerType>::value,
int>::type = 0>
1573 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
1576 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
1581 template <
typename PointerType,
typename std::enable_if <
1582 std::is_pointer<PointerType>::value&&
1583 std::is_const<typename std::remove_pointer<PointerType>::type>::value,
int >::type = 0 >
1584 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
1587 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
1629 template <
typename ValueType,
1630 detail::enable_if_t <
1635 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
1637 auto ret = ValueType();
1638 JSONSerializer<ValueType>::from_json(*
this, ret);
1672 template <
typename ValueType,
1673 detail::enable_if_t <
1677 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
1679 return JSONSerializer<ValueType>::from_json(*
this);
1697 template <
typename BasicJsonType,
1698 detail::enable_if_t <
1720 template<
typename BasicJsonType,
1721 detail::enable_if_t<
1722 std::is_same<BasicJsonType, basic_json_t>::value,
1733 template<
typename PointerType,
1734 detail::enable_if_t<
1735 std::is_pointer<PointerType>::value,
1738 ->
decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
1741 return get_ptr<PointerType>();
1768 template <
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>>
1769#if defined(JSON_HAS_CPP_14)
1773 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(
detail::priority_tag<4> {})))
1779 static_assert(!std::is_reference<ValueTypeCV>::value,
1780 "get() cannot be used with reference types, you might want to use get_ref()");
1811 template<
typename PointerType,
typename std::enable_if<
1812 std::is_pointer<PointerType>::value,
int>::type = 0>
1813 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template
get_ptr<PointerType>())
1821 template <
typename ValueType,
1822 detail::enable_if_t <
1826 ValueType &
get_to(ValueType& v)
const noexcept(
noexcept(
1827 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
1829 JSONSerializer<ValueType>::from_json(*
this, v);
1835 template<
typename ValueType,
1836 detail::enable_if_t <
1839 ValueType & get_to(ValueType& v)
const
1846 typename T, std::size_t N,
1847 typename Array = T (&)[N],
1848 detail::enable_if_t <
1850 Array get_to(T (&v)[N])
const
1851 noexcept(
noexcept(JSONSerializer<Array>::from_json(
1852 std::declval<const basic_json_t&>(), v)))
1854 JSONSerializer<Array>::from_json(*
this, v);
1860 template<
typename ReferenceType,
typename std::enable_if<
1861 std::is_reference<ReferenceType>::value,
int>::type = 0>
1865 return get_ref_impl<ReferenceType>(*
this);
1870 template <
typename ReferenceType,
typename std::enable_if <
1871 std::is_reference<ReferenceType>::value&&
1872 std::is_const<typename std::remove_reference<ReferenceType>::type>::value,
int >::type = 0 >
1876 return get_ref_impl<ReferenceType>(*
this);
1908 template <
typename ValueType,
typename std::enable_if <
1916#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
1919#if defined(JSON_HAS_CPP_17) && JSON_HAS_STATIC_RTTI
1923 >::value,
int >::type = 0 >
1924 JSON_EXPLICIT
operator ValueType()
const
1936 JSON_THROW(type_error::create(302, detail::concat(
"type must be binary, but is ",
type_name()),
this));
1948 JSON_THROW(type_error::create(302, detail::concat(
"type must be binary, but is ",
type_name()),
this));
1969 if (JSON_HEDLEY_LIKELY(
is_array()))
1973 return set_parent(m_data.m_value.array->at(idx));
1975 JSON_CATCH (std::out_of_range&)
1978 JSON_THROW(out_of_range::create(401, detail::concat(
"array index ", std::to_string(idx),
" is out of range"),
this));
1983 JSON_THROW(type_error::create(304, detail::concat(
"cannot use at() with ",
type_name()),
this));
1992 if (JSON_HEDLEY_LIKELY(
is_array()))
1996 return m_data.m_value.array->at(idx);
1998 JSON_CATCH (std::out_of_range&)
2001 JSON_THROW(out_of_range::create(401, detail::concat(
"array index ", std::to_string(idx),
" is out of range"),
this));
2006 JSON_THROW(type_error::create(304, detail::concat(
"cannot use at() with ",
type_name()),
this));
2017 JSON_THROW(type_error::create(304, detail::concat(
"cannot use at() with ",
type_name()),
this));
2020 auto it = m_data.
m_value.object->find(key);
2021 if (it == m_data.m_value.object->end())
2023 JSON_THROW(out_of_range::create(403, detail::concat(
"key '", key,
"' not found"),
this));
2025 return set_parent(it->second);
2030 template<
class KeyType, detail::enable_if_t<
2031 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value,
int> = 0>
2037 JSON_THROW(type_error::create(304, detail::concat(
"cannot use at() with ",
type_name()),
this));
2040 auto it = m_data.
m_value.object->find(std::forward<KeyType>(key));
2041 if (it == m_data.m_value.object->end())
2043 JSON_THROW(out_of_range::create(403, detail::concat(
"key '",
string_t(std::forward<KeyType>(key)),
"' not found"),
this));
2045 return set_parent(it->second);
2055 JSON_THROW(type_error::create(304, detail::concat(
"cannot use at() with ",
type_name()),
this));
2058 auto it = m_data.
m_value.object->find(key);
2059 if (it == m_data.m_value.object->end())
2061 JSON_THROW(out_of_range::create(403, detail::concat(
"key '", key,
"' not found"),
this));
2068 template<
class KeyType, detail::enable_if_t<
2069 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value,
int> = 0>
2075 JSON_THROW(type_error::create(304, detail::concat(
"cannot use at() with ",
type_name()),
this));
2078 auto it = m_data.
m_value.object->find(std::forward<KeyType>(key));
2079 if (it == m_data.m_value.object->end())
2081 JSON_THROW(out_of_range::create(403, detail::concat(
"key '",
string_t(std::forward<KeyType>(key)),
"' not found"),
this));
2093 m_data.m_type = value_t::array;
2094 m_data.m_value.array = create<array_t>();
2099 if (JSON_HEDLEY_LIKELY(
is_array()))
2102 if (idx >= m_data.m_value.array->size())
2106 const auto old_size = m_data.m_value.array->size();
2107 const auto old_capacity = m_data.m_value.array->capacity();
2109 m_data.m_value.array->resize(idx + 1);
2112 if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
2120 set_parents(
begin() +
static_cast<typename iterator::difference_type
>(old_size),
static_cast<typename iterator::difference_type
>(idx + 1 - old_size));
2126 return m_data.m_value.array->operator[](idx);
2129 JSON_THROW(type_error::create(305, detail::concat(
"cannot use operator[] with a numeric argument with ",
type_name()),
this));
2137 if (JSON_HEDLEY_LIKELY(
is_array()))
2139 return m_data.m_value.array->operator[](idx);
2142 JSON_THROW(type_error::create(305, detail::concat(
"cannot use operator[] with a numeric argument with ",
type_name()),
this));
2152 m_data.m_type = value_t::object;
2153 m_data.m_value.object = create<object_t>();
2160 auto result = m_data.m_value.object->emplace(std::move(key),
nullptr);
2161 return set_parent(result.first->second);
2164 JSON_THROW(type_error::create(305, detail::concat(
"cannot use operator[] with a string argument with ",
type_name()),
this));
2174 auto it = m_data.m_value.object->find(key);
2175 JSON_ASSERT(it != m_data.m_value.object->end());
2179 JSON_THROW(type_error::create(305, detail::concat(
"cannot use operator[] with a string argument with ",
type_name()),
this));
2184 template<
typename T>
2185 reference operator[](T* key)
2187 return operator[](
typename object_t::key_type(key));
2190 template<
typename T>
2191 const_reference operator[](T* key)
const
2193 return operator[](
typename object_t::key_type(key));
2198 template<
class KeyType, detail::enable_if_t<
2199 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value,
int > = 0 >
2205 m_data.m_type = value_t::object;
2206 m_data.m_value.object = create<object_t>();
2213 auto result = m_data.m_value.object->emplace(std::forward<KeyType>(key),
nullptr);
2214 return set_parent(result.first->second);
2217 JSON_THROW(type_error::create(305, detail::concat(
"cannot use operator[] with a string argument with ",
type_name()),
this));
2222 template<
class KeyType, detail::enable_if_t<
2223 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value,
int > = 0 >
2229 auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
2230 JSON_ASSERT(it != m_data.m_value.object->end());
2234 JSON_THROW(type_error::create(305, detail::concat(
"cannot use operator[] with a string argument with ",
type_name()),
this));
2238 template<
typename KeyType>
2240 object_comparator_t,
const typename object_t::key_type&, KeyType >;
2242 template<
typename ValueType>
2243 using value_return_type = std::conditional <
2244 detail::is_c_string_uncvref<ValueType>::value,
2245 string_t,
typename std::decay<ValueType>::type >;
2250 template <
class ValueType, detail::enable_if_t <
2252 && detail::is_getable<basic_json_t, ValueType>::value
2253 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value,
int > = 0 >
2254 ValueType
value(
const typename object_t::key_type& key,
const ValueType& default_value)
const
2260 const auto it =
find(key);
2266 return default_value;
2269 JSON_THROW(type_error::create(306, detail::concat(
"cannot use value() with ",
type_name()),
this));
2274 template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
2275 detail::enable_if_t <
2277 && detail::is_getable<basic_json_t, ReturnType>::value
2278 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value,
int > = 0 >
2279 ReturnType
value(
const typename object_t::key_type& key, ValueType && default_value)
const
2285 const auto it =
find(key);
2291 return std::forward<ValueType>(default_value);
2294 JSON_THROW(type_error::create(306, detail::concat(
"cannot use value() with ",
type_name()),
this));
2299 template <
class ValueType,
class KeyType, detail::enable_if_t <
2301 && !detail::is_json_pointer<KeyType>::value
2302 && is_comparable_with_object_key<KeyType>::value
2303 && detail::is_getable<basic_json_t, ValueType>::value
2304 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value,
int > = 0 >
2305 ValueType
value(KeyType && key,
const ValueType& default_value)
const
2311 const auto it =
find(std::forward<KeyType>(key));
2317 return default_value;
2320 JSON_THROW(type_error::create(306, detail::concat(
"cannot use value() with ",
type_name()),
this));
2325 template < class ValueType, class KeyType, class ReturnType = typename value_return_type<ValueType>::type,
2326 detail::enable_if_t <
2328 && !detail::is_json_pointer<KeyType>::value
2329 && is_comparable_with_object_key<KeyType>::value
2330 && detail::is_getable<basic_json_t, ReturnType>::value
2331 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value,
int > = 0 >
2332 ReturnType
value(KeyType && key, ValueType && default_value)
const
2338 const auto it =
find(std::forward<KeyType>(key));
2344 return std::forward<ValueType>(default_value);
2347 JSON_THROW(type_error::create(306, detail::concat(
"cannot use value() with ",
type_name()),
this));
2352 template <
class ValueType, detail::enable_if_t <
2353 detail::is_getable<basic_json_t, ValueType>::value
2354 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value,
int > = 0 >
2355 ValueType
value(
const json_pointer& ptr,
const ValueType& default_value)
const
2366 JSON_INTERNAL_CATCH (out_of_range&)
2368 return default_value;
2372 JSON_THROW(type_error::create(306, detail::concat(
"cannot use value() with ",
type_name()),
this));
2377 template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
2378 detail::enable_if_t <
2379 detail::is_getable<basic_json_t, ReturnType>::value
2380 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value,
int > = 0 >
2381 ReturnType
value(
const json_pointer& ptr, ValueType && default_value)
const
2392 JSON_INTERNAL_CATCH (out_of_range&)
2394 return std::forward<ValueType>(default_value);
2398 JSON_THROW(type_error::create(306, detail::concat(
"cannot use value() with ",
type_name()),
this));
2401 template <
class ValueType,
class BasicJsonType, detail::enable_if_t <
2403 && detail::is_getable<basic_json_t, ValueType>::value
2404 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value,
int > = 0 >
2406 ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr,
const ValueType& default_value)
const
2408 return value(ptr.convert(), default_value);
2411 template < class ValueType, class BasicJsonType, class ReturnType = typename value_return_type<ValueType>::type,
2412 detail::enable_if_t <
2414 && detail::is_getable<basic_json_t, ReturnType>::value
2415 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value,
int > = 0 >
2417 ReturnType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, ValueType && default_value)
const
2419 return value(ptr.convert(), std::forward<ValueType>(default_value));
2456 template <
class IteratorType, detail::enable_if_t <
2457 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
2458 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int > = 0 >
2462 if (JSON_HEDLEY_UNLIKELY(
this != pos.m_object))
2464 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value",
this));
2467 IteratorType result =
end();
2469 switch (m_data.m_type)
2471 case value_t::boolean:
2472 case value_t::number_float:
2473 case value_t::number_integer:
2474 case value_t::number_unsigned:
2475 case value_t::string:
2476 case value_t::binary:
2478 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
2480 JSON_THROW(invalid_iterator::create(205,
"iterator out of range",
this));
2485 AllocatorType<string_t> alloc;
2486 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_data.m_value.string);
2487 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
2488 m_data.m_value.string =
nullptr;
2492 AllocatorType<binary_t> alloc;
2493 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
2494 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
2495 m_data.m_value.binary =
nullptr;
2498 m_data.m_type = value_t::null;
2503 case value_t::object:
2505 result.m_it.object_iterator = m_data.m_value.object->erase(pos.m_it.object_iterator);
2509 case value_t::array:
2511 result.m_it.array_iterator = m_data.m_value.array->erase(pos.m_it.array_iterator);
2516 case value_t::discarded:
2518 JSON_THROW(type_error::create(307, detail::concat(
"cannot use erase() with ",
type_name()),
this));
2526 template <
class IteratorType, detail::enable_if_t <
2527 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
2528 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int > = 0 >
2529 IteratorType
erase(IteratorType first, IteratorType last)
2532 if (JSON_HEDLEY_UNLIKELY(
this != first.m_object ||
this != last.m_object))
2534 JSON_THROW(invalid_iterator::create(203,
"iterators do not fit current value",
this));
2537 IteratorType result =
end();
2539 switch (m_data.m_type)
2541 case value_t::boolean:
2542 case value_t::number_float:
2543 case value_t::number_integer:
2544 case value_t::number_unsigned:
2545 case value_t::string:
2546 case value_t::binary:
2548 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
2549 || !last.m_it.primitive_iterator.is_end()))
2551 JSON_THROW(invalid_iterator::create(204,
"iterators out of range",
this));
2556 AllocatorType<string_t> alloc;
2557 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_data.m_value.string);
2558 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
2559 m_data.m_value.string =
nullptr;
2563 AllocatorType<binary_t> alloc;
2564 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
2565 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
2566 m_data.m_value.binary =
nullptr;
2569 m_data.m_type = value_t::null;
2574 case value_t::object:
2576 result.m_it.object_iterator = m_data.m_value.object->erase(first.m_it.object_iterator,
2577 last.m_it.object_iterator);
2581 case value_t::array:
2583 result.m_it.array_iterator = m_data.m_value.array->erase(first.m_it.array_iterator,
2584 last.m_it.array_iterator);
2589 case value_t::discarded:
2591 JSON_THROW(type_error::create(307, detail::concat(
"cannot use erase() with ",
type_name()),
this));
2598 template <
typename KeyType, detail::enable_if_t <
2599 detail::has_erase_with_key_type<basic_json_t, KeyType>::value,
int > = 0 >
2600 size_type erase_internal(KeyType && key)
2603 if (JSON_HEDLEY_UNLIKELY(!is_object()))
2605 JSON_THROW(type_error::create(307, detail::concat(
"cannot use erase() with ", type_name()),
this));
2608 return m_data.m_value.object->erase(std::forward<KeyType>(key));
2611 template <
typename KeyType, detail::enable_if_t <
2612 !detail::has_erase_with_key_type<basic_json_t, KeyType>::value,
int > = 0 >
2613 size_type erase_internal(KeyType && key)
2616 if (JSON_HEDLEY_UNLIKELY(!is_object()))
2618 JSON_THROW(type_error::create(307, detail::concat(
"cannot use erase() with ", type_name()),
this));
2621 const auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
2622 if (it != m_data.m_value.object->end())
2624 m_data.m_value.object->erase(it);
2638 return erase_internal(key);
2643 template<
class KeyType, detail::enable_if_t<
2644 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value,
int> = 0>
2647 return erase_internal(std::forward<KeyType>(key));
2655 if (JSON_HEDLEY_LIKELY(
is_array()))
2657 if (JSON_HEDLEY_UNLIKELY(idx >=
size()))
2659 JSON_THROW(out_of_range::create(401, detail::concat(
"array index ", std::to_string(idx),
" is out of range"),
this));
2662 m_data.m_value.array->erase(m_data.m_value.array->begin() +
static_cast<difference_type>(idx));
2666 JSON_THROW(type_error::create(307, detail::concat(
"cannot use erase() with ",
type_name()),
this));
2683 auto result =
end();
2687 result.m_it.object_iterator = m_data.m_value.object->find(key);
2697 auto result =
cend();
2701 result.m_it.object_iterator = m_data.m_value.object->find(key);
2709 template<
class KeyType, detail::enable_if_t<
2710 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value,
int> = 0>
2713 auto result =
end();
2717 result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
2725 template<
class KeyType, detail::enable_if_t<
2726 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value,
int> = 0>
2729 auto result =
cend();
2733 result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
2744 return is_object() ? m_data.m_value.object->count(key) : 0;
2749 template<
class KeyType, detail::enable_if_t<
2750 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value,
int> = 0>
2754 return is_object() ? m_data.m_value.object->count(std::forward<KeyType>(key)) : 0;
2759 bool contains(
const typename object_t::key_type& key)
const
2761 return is_object() && m_data.m_value.object->find(key) != m_data.m_value.object->end();
2766 template<
class KeyType, detail::enable_if_t<
2767 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value,
int> = 0>
2770 return is_object() && m_data.m_value.object->find(std::forward<KeyType>(key)) != m_data.m_value.object->end();
2777 return ptr.contains(
this);
2780 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value,
int> = 0>
2782 bool contains(
const typename ::nlohmann::json_pointer<BasicJsonType>& ptr)
const
2784 return ptr.contains(
this);
2894 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
2905 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
2913 iteration_proxy<iterator>
items() noexcept
2915 return iteration_proxy<iterator>(*
this);
2920 iteration_proxy<const_iterator>
items() const noexcept
2922 return iteration_proxy<const_iterator>(*
this);
2938 switch (m_data.m_type)
2946 case value_t::array:
2949 return m_data.m_value.array->empty();
2952 case value_t::object:
2955 return m_data.m_value.object->empty();
2958 case value_t::string:
2959 case value_t::boolean:
2960 case value_t::number_integer:
2961 case value_t::number_unsigned:
2962 case value_t::number_float:
2963 case value_t::binary:
2964 case value_t::discarded:
2977 switch (m_data.m_type)
2985 case value_t::array:
2988 return m_data.m_value.array->size();
2991 case value_t::object:
2994 return m_data.m_value.object->size();
2997 case value_t::string:
2998 case value_t::boolean:
2999 case value_t::number_integer:
3000 case value_t::number_unsigned:
3001 case value_t::number_float:
3002 case value_t::binary:
3003 case value_t::discarded:
3016 switch (m_data.m_type)
3018 case value_t::array:
3021 return m_data.m_value.array->max_size();
3024 case value_t::object:
3027 return m_data.m_value.object->max_size();
3031 case value_t::string:
3032 case value_t::boolean:
3033 case value_t::number_integer:
3034 case value_t::number_unsigned:
3035 case value_t::number_float:
3036 case value_t::binary:
3037 case value_t::discarded:
3059 switch (m_data.m_type)
3061 case value_t::number_integer:
3063 m_data.m_value.number_integer = 0;
3067 case value_t::number_unsigned:
3069 m_data.m_value.number_unsigned = 0;
3073 case value_t::number_float:
3075 m_data.m_value.number_float = 0.0;
3079 case value_t::boolean:
3081 m_data.m_value.boolean =
false;
3085 case value_t::string:
3087 m_data.m_value.string->clear();
3091 case value_t::binary:
3093 m_data.m_value.binary->clear();
3097 case value_t::array:
3099 m_data.m_value.array->clear();
3103 case value_t::object:
3105 m_data.m_value.object->clear();
3110 case value_t::discarded:
3123 JSON_THROW(type_error::create(308, detail::concat(
"cannot use push_back() with ",
type_name()),
this));
3129 m_data.m_type = value_t::array;
3130 m_data.m_value = value_t::array;
3135 const auto old_capacity = m_data.m_value.array->capacity();
3136 m_data.m_value.array->push_back(std::move(val));
3137 set_parent(m_data.m_value.array->back(), old_capacity);
3156 JSON_THROW(type_error::create(308, detail::concat(
"cannot use push_back() with ",
type_name()),
this));
3162 m_data.m_type = value_t::array;
3163 m_data.m_value = value_t::array;
3168 const auto old_capacity = m_data.m_value.array->capacity();
3169 m_data.m_value.array->push_back(val);
3170 set_parent(m_data.m_value.array->back(), old_capacity);
3188 JSON_THROW(type_error::create(308, detail::concat(
"cannot use push_back() with ",
type_name()),
this));
3194 m_data.m_type = value_t::object;
3195 m_data.m_value = value_t::object;
3200 auto res = m_data.m_value.object->insert(val);
3201 set_parent(res.first->second);
3216 if (
is_object() && init.size() == 2 && (*init.begin())->is_string())
3218 basic_json&& key = init.begin()->moved_or_copied();
3219 push_back(
typename object_t::value_type(
3220 std::move(key.get_ref<
string_t&>()), (init.begin() + 1)->moved_or_copied()));
3238 template<
class... Args>
3244 JSON_THROW(type_error::create(311, detail::concat(
"cannot use emplace_back() with ",
type_name()),
this));
3250 m_data.m_type = value_t::array;
3251 m_data.m_value = value_t::array;
3256 const auto old_capacity = m_data.
m_value.array->capacity();
3257 m_data.m_value.array->emplace_back(std::forward<Args>(args)...);
3258 return set_parent(m_data.m_value.array->back(), old_capacity);
3263 template<
class... Args>
3264 std::pair<iterator, bool>
emplace(Args&& ... args)
3269 JSON_THROW(type_error::create(311, detail::concat(
"cannot use emplace() with ",
type_name()),
this));
3275 m_data.m_type = value_t::object;
3276 m_data.m_value = value_t::object;
3281 auto res = m_data.m_value.object->emplace(std::forward<Args>(args)...);
3282 set_parent(res.first->second);
3286 it.m_it.object_iterator = res.first;
3289 return {it, res.second};
3295 template<
typename... Args>
3299 JSON_ASSERT(m_data.m_value.array !=
nullptr);
3301 auto insert_pos = std::distance(m_data.m_value.array->begin(), pos.m_it.array_iterator);
3302 m_data.m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
3303 result.m_it.array_iterator = m_data.m_value.array->begin() + insert_pos;
3318 if (JSON_HEDLEY_LIKELY(
is_array()))
3321 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
3323 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value",
this));
3330 JSON_THROW(type_error::create(309, detail::concat(
"cannot use insert() with ",
type_name()),
this));
3345 if (JSON_HEDLEY_LIKELY(
is_array()))
3348 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
3350 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value",
this));
3357 JSON_THROW(type_error::create(309, detail::concat(
"cannot use insert() with ",
type_name()),
this));
3365 if (JSON_HEDLEY_UNLIKELY(!
is_array()))
3367 JSON_THROW(type_error::create(309, detail::concat(
"cannot use insert() with ",
type_name()),
this));
3371 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
3373 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value",
this));
3377 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
3379 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit",
this));
3382 if (JSON_HEDLEY_UNLIKELY(first.m_object ==
this))
3384 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container",
this));
3388 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
3396 if (JSON_HEDLEY_UNLIKELY(!
is_array()))
3398 JSON_THROW(type_error::create(309, detail::concat(
"cannot use insert() with ",
type_name()),
this));
3402 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
3404 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value",
this));
3418 JSON_THROW(type_error::create(309, detail::concat(
"cannot use insert() with ",
type_name()),
this));
3422 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
3424 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit",
this));
3428 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
3430 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects",
this));
3433 m_data.m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
3451 m_data.m_type = value_t::object;
3452 m_data.m_value.object = create<object_t>();
3458 JSON_THROW(type_error::create(312, detail::concat(
"cannot use update() with ",
type_name()),
this));
3462 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
3464 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit",
this));
3468 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
3470 JSON_THROW(type_error::create(312, detail::concat(
"cannot use update() with ", first.m_object->type_name()), first.m_object));
3473 for (
auto it = first; it != last; ++it)
3475 if (merge_objects && it.value().is_object())
3477 auto it2 = m_data.m_value.object->find(it.key());
3478 if (it2 != m_data.m_value.object->end())
3480 it2->second.update(it.value(),
true);
3484 m_data.m_value.object->operator[](it.key()) = it.value();
3486 m_data.m_value.object->operator[](it.key()).m_parent =
this;
3494 std::is_nothrow_move_constructible<value_t>::value&&
3495 std::is_nothrow_move_assignable<value_t>::value&&
3496 std::is_nothrow_move_constructible<json_value>::value&&
3497 std::is_nothrow_move_assignable<json_value>::value
3500 std::swap(m_data.m_type, other.m_data.m_type);
3501 std::swap(m_data.m_value, other.m_data.m_value);
3504 other.set_parents();
3511 std::is_nothrow_move_constructible<value_t>::value&&
3512 std::is_nothrow_move_assignable<value_t>::value&&
3513 std::is_nothrow_move_constructible<json_value>::value&&
3514 std::is_nothrow_move_assignable<json_value>::value
3525 if (JSON_HEDLEY_LIKELY(
is_array()))
3528 swap(*(m_data.m_value.array), other);
3532 JSON_THROW(type_error::create(310, detail::concat(
"cannot use swap(array_t&) with ",
type_name()),
this));
3544 swap(*(m_data.m_value.object), other);
3548 JSON_THROW(type_error::create(310, detail::concat(
"cannot use swap(object_t&) with ",
type_name()),
this));
3560 swap(*(m_data.m_value.string), other);
3564 JSON_THROW(type_error::create(310, detail::concat(
"cannot use swap(string_t&) with ",
type_name()),
this));
3576 swap(*(m_data.m_value.binary), other);
3580 JSON_THROW(type_error::create(310, detail::concat(
"cannot use swap(binary_t&) with ",
type_name()),
this));
3586 void swap(
typename binary_t::container_type& other)
3592 swap(*(m_data.m_value.binary), other);
3596 JSON_THROW(type_error::create(310, detail::concat(
"cannot use swap(binary_t::container_type&) with ",
type_name()),
this));
3611#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
3612 const auto lhs_type = lhs.type(); \
3613 const auto rhs_type = rhs.type(); \
3615 if (lhs_type == rhs_type) \
3619 case value_t::array: \
3620 return (*lhs.m_data.m_value.array) op (*rhs.m_data.m_value.array); \
3622 case value_t::object: \
3623 return (*lhs.m_data.m_value.object) op (*rhs.m_data.m_value.object); \
3625 case value_t::null: \
3626 return (null_result); \
3628 case value_t::string: \
3629 return (*lhs.m_data.m_value.string) op (*rhs.m_data.m_value.string); \
3631 case value_t::boolean: \
3632 return (lhs.m_data.m_value.boolean) op (rhs.m_data.m_value.boolean); \
3634 case value_t::number_integer: \
3635 return (lhs.m_data.m_value.number_integer) op (rhs.m_data.m_value.number_integer); \
3637 case value_t::number_unsigned: \
3638 return (lhs.m_data.m_value.number_unsigned) op (rhs.m_data.m_value.number_unsigned); \
3640 case value_t::number_float: \
3641 return (lhs.m_data.m_value.number_float) op (rhs.m_data.m_value.number_float); \
3643 case value_t::binary: \
3644 return (*lhs.m_data.m_value.binary) op (*rhs.m_data.m_value.binary); \
3646 case value_t::discarded: \
3648 return (unordered_result); \
3651 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \
3653 return static_cast<number_float_t>(lhs.m_data.m_value.number_integer) op rhs.m_data.m_value.number_float; \
3655 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \
3657 return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_integer); \
3659 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \
3661 return static_cast<number_float_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_float; \
3663 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \
3665 return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_unsigned); \
3667 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
3669 return static_cast<number_integer_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_integer; \
3671 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
3673 return lhs.m_data.m_value.number_integer op static_cast<number_integer_t>(rhs.m_data.m_value.number_unsigned); \
3675 else if(compares_unordered(lhs, rhs))\
3677 return (unordered_result);\
3680 return (default_result);
3682 JSON_PRIVATE_UNLESS_TESTED:
3688 static bool compares_unordered(const_reference lhs, const_reference rhs,
bool inverse =
false) noexcept
3690 if ((lhs.is_number_float() && std::isnan(lhs.m_data.m_value.number_float) && rhs.is_number())
3691 || (rhs.is_number_float() && std::isnan(rhs.m_data.m_value.number_float) && lhs.is_number()))
3695#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
3696 return (lhs.is_discarded() || rhs.is_discarded()) && !inverse;
3698 static_cast<void>(inverse);
3699 return lhs.is_discarded() || rhs.is_discarded();
3704 bool compares_unordered(const_reference rhs,
bool inverse =
false) const noexcept
3706 return compares_unordered(*
this, rhs, inverse);
3710#if JSON_HAS_THREE_WAY_COMPARISON
3713 bool operator==(const_reference rhs)
const noexcept
3716#pragma GCC diagnostic push
3717#pragma GCC diagnostic ignored "-Wfloat-equal"
3719 const_reference lhs = *
this;
3720 JSON_IMPLEMENT_OPERATOR( ==,
true,
false,
false)
3722#pragma GCC diagnostic pop
3728 template<
typename ScalarType>
3729 requires std::is_scalar_v<ScalarType>
3730 bool operator==(ScalarType rhs)
const noexcept
3737 bool operator!=(const_reference rhs)
const noexcept
3739 if (compares_unordered(rhs,
true))
3743 return !operator==(rhs);
3748 std::partial_ordering operator<=>(const_reference rhs)
const noexcept
3750 const_reference lhs = *
this;
3753 JSON_IMPLEMENT_OPERATOR(<=>,
3754 std::partial_ordering::equivalent,
3755 std::partial_ordering::unordered,
3756 lhs_type <=> rhs_type)
3761 template<
typename ScalarType>
3762 requires std::is_scalar_v<ScalarType>
3763 std::partial_ordering operator<=>(ScalarType rhs)
const noexcept
3768#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
3774 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON)
3775 bool operator<=(const_reference rhs)
const noexcept
3777 if (compares_unordered(rhs,
true))
3781 return !(rhs < *
this);
3786 template<
typename ScalarType>
3787 requires std::is_scalar_v<ScalarType>
3788 bool operator<=(ScalarType rhs)
const noexcept
3795 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON)
3796 bool operator>=(const_reference rhs)
const noexcept
3798 if (compares_unordered(rhs,
true))
3802 return !(*
this < rhs);
3807 template<
typename ScalarType>
3808 requires std::is_scalar_v<ScalarType>
3809 bool operator>=(ScalarType rhs)
const noexcept
3817 friend bool operator==(const_reference lhs, const_reference rhs)
noexcept
3820#pragma GCC diagnostic push
3821#pragma GCC diagnostic ignored "-Wfloat-equal"
3823 JSON_IMPLEMENT_OPERATOR( ==,
true,
false,
false)
3825#pragma GCC diagnostic pop
3831 template<
typename ScalarType,
typename std::enable_if<
3832 std::is_scalar<ScalarType>::value,
int>::type = 0>
3833 friend bool operator==(const_reference lhs, ScalarType rhs)
noexcept
3840 template<
typename ScalarType,
typename std::enable_if<
3841 std::is_scalar<ScalarType>::value,
int>::type = 0>
3842 friend bool operator==(ScalarType lhs, const_reference rhs)
noexcept
3849 friend bool operator!=(const_reference lhs, const_reference rhs)
noexcept
3851 if (compares_unordered(lhs, rhs,
true))
3855 return !(lhs == rhs);
3860 template<
typename ScalarType,
typename std::enable_if<
3861 std::is_scalar<ScalarType>::value,
int>::type = 0>
3862 friend bool operator!=(const_reference lhs, ScalarType rhs)
noexcept
3869 template<
typename ScalarType,
typename std::enable_if<
3870 std::is_scalar<ScalarType>::value,
int>::type = 0>
3871 friend bool operator!=(ScalarType lhs, const_reference rhs)
noexcept
3878 friend bool operator<(const_reference lhs, const_reference rhs)
noexcept
3883 JSON_IMPLEMENT_OPERATOR( <,
false,
false,
operator<(lhs_type, rhs_type))
3888 template<
typename ScalarType,
typename std::enable_if<
3889 std::is_scalar<ScalarType>::value,
int>::type = 0>
3890 friend bool operator<(const_reference lhs, ScalarType rhs)
noexcept
3897 template<
typename ScalarType,
typename std::enable_if<
3898 std::is_scalar<ScalarType>::value,
int>::type = 0>
3899 friend bool operator<(ScalarType lhs, const_reference rhs)
noexcept
3906 friend bool operator<=(const_reference lhs, const_reference rhs)
noexcept
3908 if (compares_unordered(lhs, rhs,
true))
3912 return !(rhs < lhs);
3917 template<
typename ScalarType,
typename std::enable_if<
3918 std::is_scalar<ScalarType>::value,
int>::type = 0>
3919 friend bool operator<=(const_reference lhs, ScalarType rhs)
noexcept
3926 template<
typename ScalarType,
typename std::enable_if<
3927 std::is_scalar<ScalarType>::value,
int>::type = 0>
3928 friend bool operator<=(ScalarType lhs, const_reference rhs)
noexcept
3935 friend bool operator>(const_reference lhs, const_reference rhs)
noexcept
3938 if (compares_unordered(lhs, rhs))
3942 return !(lhs <= rhs);
3947 template<
typename ScalarType,
typename std::enable_if<
3948 std::is_scalar<ScalarType>::value,
int>::type = 0>
3949 friend bool operator>(const_reference lhs, ScalarType rhs)
noexcept
3956 template<
typename ScalarType,
typename std::enable_if<
3957 std::is_scalar<ScalarType>::value,
int>::type = 0>
3958 friend bool operator>(ScalarType lhs, const_reference rhs)
noexcept
3965 friend bool operator>=(const_reference lhs, const_reference rhs)
noexcept
3967 if (compares_unordered(lhs, rhs,
true))
3971 return !(lhs < rhs);
3976 template<
typename ScalarType,
typename std::enable_if<
3977 std::is_scalar<ScalarType>::value,
int>::type = 0>
3978 friend bool operator>=(const_reference lhs, ScalarType rhs)
noexcept
3985 template<
typename ScalarType,
typename std::enable_if<
3986 std::is_scalar<ScalarType>::value,
int>::type = 0>
3987 friend bool operator>=(ScalarType lhs, const_reference rhs)
noexcept
3993#undef JSON_IMPLEMENT_OPERATOR
4009 const bool pretty_print = o.width() > 0;
4010 const auto indentation = pretty_print ? o.width() : 0;
4017 s.dump(j, pretty_print,
false,
static_cast<unsigned int>(indentation));
4027 JSON_HEDLEY_DEPRECATED_FOR(3.0.0,
operator<<(std::ostream&,
const basic_json&))
4028 friend std::ostream& operator>>(
const basic_json& j, std::ostream& o)
4044 template<
typename InputType>
4045 JSON_HEDLEY_WARN_UNUSED_RESULT
4047 parser_callback_t cb =
nullptr,
4048 const bool allow_exceptions =
true,
4049 const bool ignore_comments =
false,
4050 const bool ignore_trailing_commas =
false)
4053 parser(detail::input_adapter(std::forward<InputType>(i)), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas).parse(
true, result);
4059 template<
typename IteratorType>
4060 JSON_HEDLEY_WARN_UNUSED_RESULT
4063 parser_callback_t cb =
nullptr,
4064 const bool allow_exceptions =
true,
4065 const bool ignore_comments =
false,
4066 const bool ignore_trailing_commas =
false)
4069 parser(detail::input_adapter(std::move(first), std::move(last)), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas).parse(
true, result);
4073 JSON_HEDLEY_WARN_UNUSED_RESULT
4074 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
4076 parser_callback_t cb =
nullptr,
4077 const bool allow_exceptions =
true,
4078 const bool ignore_comments =
false,
4079 const bool ignore_trailing_commas =
false)
4082 parser(i.get(), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas).parse(
true, result);
4088 template<
typename InputType>
4089 static bool accept(InputType&& i,
4090 const bool ignore_comments =
false,
4091 const bool ignore_trailing_commas =
false)
4093 return parser(detail::input_adapter(std::forward<InputType>(i)),
nullptr,
false, ignore_comments, ignore_trailing_commas).accept(
true);
4098 template<
typename IteratorType>
4099 static bool accept(IteratorType first, IteratorType last,
4100 const bool ignore_comments =
false,
4101 const bool ignore_trailing_commas =
false)
4103 return parser(detail::input_adapter(std::move(first), std::move(last)),
nullptr,
false, ignore_comments, ignore_trailing_commas).accept(
true);
4106 JSON_HEDLEY_WARN_UNUSED_RESULT
4107 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
4109 const bool ignore_comments =
false,
4110 const bool ignore_trailing_commas =
false)
4112 return parser(i.get(),
nullptr,
false, ignore_comments, ignore_trailing_commas).accept(
true);
4117 template <
typename InputType,
typename SAX>
4118 JSON_HEDLEY_NON_NULL(2)
4119 static
bool sax_parse(InputType&& i, SAX* sax,
4120 input_format_t format = input_format_t::json,
4121 const
bool strict = true,
4122 const
bool ignore_comments = false,
4123 const
bool ignore_trailing_commas = false)
4125#if defined(__clang__)
4126#pragma clang diagnostic push
4127#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
4128#elif defined(__GNUC__)
4129#pragma GCC diagnostic push
4130#pragma GCC diagnostic ignored "-Wnonnull-compare"
4134 JSON_THROW(other_error::create(502,
"SAX handler must not be null",
nullptr));
4136#if defined(__clang__)
4137#pragma clang diagnostic pop
4138#elif defined(__GNUC__)
4139#pragma GCC diagnostic pop
4141 auto ia = detail::input_adapter(std::forward<InputType>(i));
4142 return format == input_format_t::json
4143 ? parser(std::move(ia),
nullptr,
true, ignore_comments, ignore_trailing_commas).sax_parse(sax, strict)
4149 template<
class IteratorType,
class SAX>
4150 JSON_HEDLEY_NON_NULL(3)
4151 static
bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
4152 input_format_t format = input_format_t::json,
4153 const
bool strict = true,
4154 const
bool ignore_comments = false,
4155 const
bool ignore_trailing_commas = false)
4157#if defined(__clang__)
4158#pragma clang diagnostic push
4159#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
4160#elif defined(__GNUC__)
4161#pragma GCC diagnostic push
4162#pragma GCC diagnostic ignored "-Wnonnull-compare"
4166 JSON_THROW(other_error::create(502,
"SAX handler must not be null",
nullptr));
4168#if defined(__clang__)
4169#pragma clang diagnostic pop
4170#elif defined(__GNUC__)
4171#pragma GCC diagnostic pop
4173 auto ia = detail::input_adapter(std::move(first), std::move(last));
4174 return format == input_format_t::json
4175 ? parser(std::move(ia),
nullptr,
true, ignore_comments, ignore_trailing_commas).sax_parse(sax, strict)
4184 template <
typename SAX>
4185 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
4186 JSON_HEDLEY_NON_NULL(2)
4187 static
bool sax_parse(
detail::span_input_adapter&& i, SAX* sax,
4188 input_format_t format = input_format_t::json,
4189 const
bool strict = true,
4190 const
bool ignore_comments = false,
4191 const
bool ignore_trailing_commas = false)
4193#if defined(__clang__)
4194#pragma clang diagnostic push
4195#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
4196#elif defined(__GNUC__)
4197#pragma GCC diagnostic push
4198#pragma GCC diagnostic ignored "-Wnonnull-compare"
4202 JSON_THROW(other_error::create(502,
"SAX handler must not be null",
nullptr));
4204#if defined(__clang__)
4205#pragma clang diagnostic pop
4206#elif defined(__GNUC__)
4207#pragma GCC diagnostic pop
4210 return format == input_format_t::json
4212 ? parser(std::move(ia),
nullptr,
true, ignore_comments, ignore_trailing_commas).sax_parse(sax, strict)
4223 JSON_HEDLEY_DEPRECATED_FOR(3.0.0,
operator>>(std::istream&,
basic_json&))
4233 parser(detail::input_adapter(i)).parse(
false, j);
4245 JSON_HEDLEY_RETURNS_NON_NULL
4248 switch (m_data.m_type)
4252 case value_t::object:
4254 case value_t::array:
4256 case value_t::string:
4258 case value_t::boolean:
4260 case value_t::binary:
4262 case value_t::discarded:
4264 case value_t::number_integer:
4265 case value_t::number_unsigned:
4266 case value_t::number_float:
4273 JSON_PRIVATE_UNLESS_TESTED:
4281 value_t m_type = value_t::null;
4286 data(
const value_t v)
4287 : m_type(v), m_value(v)
4291 data(size_type cnt,
const basic_json& val)
4294 m_value.array = create<array_t>(cnt, val);
4297 data() noexcept = default;
4298 data(data&&) noexcept = default;
4299 data(const data&) noexcept = delete;
4300 data& operator=(data&&) noexcept = delete;
4301 data& operator=(const data&) noexcept = delete;
4305 m_value.destroy(m_type);
4316#if JSON_DIAGNOSTIC_POSITIONS
4318 std::size_t start_position = std::string::npos;
4320 std::size_t end_position = std::string::npos;
4322 constexpr std::size_t start_pos() const noexcept
4324 return start_position;
4327 constexpr std::size_t end_pos() const noexcept
4329 return end_position;
4345 std::vector<std::uint8_t> result;
4354 binary_writer<std::uint8_t>(o).write_cbor(j);
4361 binary_writer<char>(o).write_cbor(j);
4368 std::vector<std::uint8_t> result;
4377 binary_writer<std::uint8_t>(o).write_msgpack(j);
4384 binary_writer<char>(o).write_msgpack(j);
4390 const bool use_size =
false,
4391 const bool use_type =
false)
4393 std::vector<std::uint8_t> result;
4394 to_ubjson(j, result, use_size, use_type);
4401 const bool use_size =
false,
const bool use_type =
false)
4403 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
4409 const bool use_size =
false,
const bool use_type =
false)
4411 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
4417 const bool use_size =
false,
4418 const bool use_type =
false,
4421 std::vector<std::uint8_t> result;
4422 to_bjdata(j, result, use_size, use_type, version);
4429 const bool use_size =
false,
const bool use_type =
false,
4432 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type,
true,
true, version);
4438 const bool use_size =
false,
const bool use_type =
false,
4441 binary_writer<char>(o).write_ubjson(j, use_size, use_type,
true,
true, version);
4448 std::vector<std::uint8_t> result;
4457 binary_writer<std::uint8_t>(o).write_bson(j);
4464 binary_writer<char>(o).write_bson(j);
4469 template<
typename InputType>
4470 JSON_HEDLEY_WARN_UNUSED_RESULT
4472 const bool strict =
true,
4473 const bool allow_exceptions =
true,
4477 auto ia = detail::input_adapter(std::forward<InputType>(i));
4479 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
4480 return res ? result :
basic_json(value_t::discarded);
4485 template<
typename IteratorType>
4486 JSON_HEDLEY_WARN_UNUSED_RESULT
4488 const bool strict =
true,
4489 const bool allow_exceptions =
true,
4493 auto ia = detail::input_adapter(std::move(first), std::move(last));
4495 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
4496 return res ? result :
basic_json(value_t::discarded);
4499 template<
typename T>
4500 JSON_HEDLEY_WARN_UNUSED_RESULT
4501 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
4502 static basic_json from_cbor(
const T* ptr, std::size_t len,
4503 const bool strict =
true,
4504 const bool allow_exceptions =
true,
4505 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
4507 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
4510 JSON_HEDLEY_WARN_UNUSED_RESULT
4511 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
4513 const bool strict =
true,
4514 const bool allow_exceptions =
true,
4515 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
4521 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
4522 return res ? result :
basic_json(value_t::discarded);
4527 template<
typename InputType>
4528 JSON_HEDLEY_WARN_UNUSED_RESULT
4530 const bool strict =
true,
4531 const bool allow_exceptions =
true)
4534 auto ia = detail::input_adapter(std::forward<InputType>(i));
4536 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
4537 return res ? result :
basic_json(value_t::discarded);
4542 template<
typename IteratorType>
4543 JSON_HEDLEY_WARN_UNUSED_RESULT
4545 const bool strict =
true,
4546 const bool allow_exceptions =
true)
4549 auto ia = detail::input_adapter(std::move(first), std::move(last));
4551 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
4552 return res ? result :
basic_json(value_t::discarded);
4555 template<
typename T>
4556 JSON_HEDLEY_WARN_UNUSED_RESULT
4557 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
4558 static basic_json from_msgpack(
const T* ptr, std::size_t len,
4559 const bool strict =
true,
4560 const bool allow_exceptions =
true)
4562 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
4565 JSON_HEDLEY_WARN_UNUSED_RESULT
4566 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
4568 const bool strict =
true,
4569 const bool allow_exceptions =
true)
4575 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
4576 return res ? result :
basic_json(value_t::discarded);
4581 template<
typename InputType>
4582 JSON_HEDLEY_WARN_UNUSED_RESULT
4584 const bool strict =
true,
4585 const bool allow_exceptions =
true)
4588 auto ia = detail::input_adapter(std::forward<InputType>(i));
4590 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
4591 return res ? result :
basic_json(value_t::discarded);
4596 template<
typename IteratorType>
4597 JSON_HEDLEY_WARN_UNUSED_RESULT
4599 const bool strict =
true,
4600 const bool allow_exceptions =
true)
4603 auto ia = detail::input_adapter(std::move(first), std::move(last));
4605 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
4606 return res ? result :
basic_json(value_t::discarded);
4609 template<
typename T>
4610 JSON_HEDLEY_WARN_UNUSED_RESULT
4611 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
4612 static basic_json from_ubjson(
const T* ptr, std::size_t len,
4613 const bool strict =
true,
4614 const bool allow_exceptions =
true)
4616 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
4619 JSON_HEDLEY_WARN_UNUSED_RESULT
4620 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
4622 const bool strict =
true,
4623 const bool allow_exceptions =
true)
4629 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
4630 return res ? result :
basic_json(value_t::discarded);
4635 template<
typename InputType>
4636 JSON_HEDLEY_WARN_UNUSED_RESULT
4638 const bool strict =
true,
4639 const bool allow_exceptions =
true)
4642 auto ia = detail::input_adapter(std::forward<InputType>(i));
4644 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
4645 return res ? result :
basic_json(value_t::discarded);
4650 template<
typename IteratorType>
4651 JSON_HEDLEY_WARN_UNUSED_RESULT
4653 const bool strict =
true,
4654 const bool allow_exceptions =
true)
4657 auto ia = detail::input_adapter(std::move(first), std::move(last));
4659 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
4660 return res ? result :
basic_json(value_t::discarded);
4665 template<
typename InputType>
4666 JSON_HEDLEY_WARN_UNUSED_RESULT
4668 const bool strict =
true,
4669 const bool allow_exceptions =
true)
4672 auto ia = detail::input_adapter(std::forward<InputType>(i));
4674 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
4675 return res ? result :
basic_json(value_t::discarded);
4680 template<
typename IteratorType>
4681 JSON_HEDLEY_WARN_UNUSED_RESULT
4683 const bool strict =
true,
4684 const bool allow_exceptions =
true)
4687 auto ia = detail::input_adapter(std::move(first), std::move(last));
4689 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
4690 return res ? result :
basic_json(value_t::discarded);
4693 template<
typename T>
4694 JSON_HEDLEY_WARN_UNUSED_RESULT
4695 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
4696 static basic_json from_bson(
const T* ptr, std::size_t len,
4697 const bool strict =
true,
4698 const bool allow_exceptions =
true)
4700 return from_bson(ptr, ptr + len, strict, allow_exceptions);
4703 JSON_HEDLEY_WARN_UNUSED_RESULT
4704 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
4706 const bool strict =
true,
4707 const bool allow_exceptions =
true)
4713 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
4714 return res ? result :
basic_json(value_t::discarded);
4729 return ptr.get_unchecked(
this);
4732 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value,
int> = 0>
4734 reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
4736 return ptr.get_unchecked(
this);
4743 return ptr.get_unchecked(
this);
4746 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value,
int> = 0>
4748 const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
const
4750 return ptr.get_unchecked(
this);
4757 return ptr.get_checked(
this);
4760 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value,
int> = 0>
4762 reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
4764 return ptr.get_checked(
this);
4771 return ptr.get_checked(
this);
4774 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value,
int> = 0>
4776 const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
const
4778 return ptr.get_checked(
this);
4786 json_pointer::flatten(
"", *
this, result);
4794 return json_pointer::unflatten(*
this);
4812 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
4814 const auto get_op = [](
const string_t& op)
4818 return patch_operations::add;
4822 return patch_operations::remove;
4824 if (op ==
"replace")
4826 return patch_operations::replace;
4830 return patch_operations::move;
4834 return patch_operations::copy;
4838 return patch_operations::test;
4841 return patch_operations::invalid;
4845 const auto operation_add = [&result](json_pointer & ptr,
const basic_json & val)
4855 json_pointer
const top_pointer = ptr.top();
4856 if (top_pointer != ptr)
4858 result.at(top_pointer);
4862 const auto last_path = ptr.
back();
4867 switch (parent.m_data.m_type)
4870 case value_t::object:
4873 parent[last_path] = val;
4877 case value_t::array:
4879 if (last_path ==
"-")
4886 const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
4887 if (JSON_HEDLEY_UNLIKELY(idx > parent.
size()))
4890 JSON_THROW(out_of_range::create(401, detail::concat(
"array index ", std::to_string(idx),
" is out of range"), &parent));
4900 case value_t::string:
4901 case value_t::boolean:
4902 case value_t::number_integer:
4903 case value_t::number_unsigned:
4904 case value_t::number_float:
4905 case value_t::binary:
4906 case value_t::discarded:
4913 const auto operation_remove = [
this, & result](json_pointer & ptr)
4916 const auto last_path = ptr.
back();
4924 auto it = parent.
find(last_path);
4925 if (JSON_HEDLEY_LIKELY(it != parent.
end()))
4931 JSON_THROW(out_of_range::create(403, detail::concat(
"key '", last_path,
"' not found"),
this));
4937 parent.
erase(json_pointer::template array_index<basic_json_t>(last_path));
4942 if (JSON_HEDLEY_UNLIKELY(!json_patch.
is_array()))
4944 JSON_THROW(
parse_error::create(104, 0,
"JSON patch must be an array of objects", &json_patch));
4948 for (
const auto& val : json_patch)
4951 const auto get_value = [&val](
const string_t& op,
4956 auto it = val.m_data.m_value.object->find(member);
4959 const auto error_msg = (op ==
"op") ?
"operation" : detail::concat(
"operation '", op,
'\'');
4962 if (JSON_HEDLEY_UNLIKELY(it == val.m_data.m_value.object->end()))
4965 JSON_THROW(
parse_error::create(105, 0, detail::concat(error_msg,
" must have member '", member,
"'"), &val));
4969 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
4972 JSON_THROW(
parse_error::create(105, 0, detail::concat(error_msg,
" must have string member '", member,
"'"), &val));
4980 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
4986 const auto op = get_value(
"op",
"op",
true).template
get<string_t>();
4987 const auto path = get_value(op,
"path",
true).template
get<string_t>();
4988 json_pointer ptr(path);
4992 case patch_operations::add:
4994 operation_add(ptr, get_value(
"add",
"value",
false));
4998 case patch_operations::remove:
5000 operation_remove(ptr);
5004 case patch_operations::replace:
5007 result.at(ptr) = get_value(
"replace",
"value",
false);
5011 case patch_operations::move:
5013 const auto from_path = get_value(
"move",
"from",
true).template
get<string_t>();
5014 json_pointer from_ptr(from_path);
5023 operation_remove(from_ptr);
5024 operation_add(ptr, v);
5028 case patch_operations::copy:
5030 const auto from_path = get_value(
"copy",
"from",
true).template
get<string_t>();
5031 const json_pointer from_ptr(from_path);
5039 operation_add(ptr, v);
5043 case patch_operations::test:
5045 bool success =
false;
5050 success = (result.at(ptr) == get_value(
"test",
"value",
false));
5052 JSON_INTERNAL_CATCH (out_of_range&)
5058 if (JSON_HEDLEY_UNLIKELY(!success))
5060 JSON_THROW(other_error::create(501, detail::concat(
"unsuccessful: ", val.dump()), &val));
5066 case patch_operations::invalid:
5071 JSON_THROW(
parse_error::create(105, 0, detail::concat(
"operation value '", op,
"' is invalid"), &val));
5082 result.patch_inplace(json_patch);
5088 JSON_HEDLEY_WARN_UNUSED_RESULT
5096 if (source == target)
5101 if (source.
type() != target.
type())
5106 {
"op",
"replace"}, {
"path", path}, {
"value", target}
5111 switch (source.
type())
5113 case value_t::array:
5117 while (i < source.
size() && i < target.
size())
5120 auto temp_diff =
diff(source[i], target[i], detail::concat<string_t>(path,
'/', detail::to_string<string_t>(i)));
5121 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
5130 while (i < source.
size())
5134 result.insert(result.begin() + end_index,
object(
5137 {
"path", detail::concat<string_t>(path,
'/', detail::to_string<string_t>(i))}
5143 while (i < target.
size())
5148 {
"path", detail::concat<string_t>(path,
"/-")},
5149 {
"value", target[i]}
5157 case value_t::object:
5160 for (
auto it = source.
cbegin(); it != source.
cend(); ++it)
5163 const auto path_key = detail::concat<string_t>(path,
'/',
detail::escape(it.key()));
5165 if (target.
find(it.key()) != target.
end())
5168 auto temp_diff =
diff(it.value(), target[it.key()], path_key);
5169 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
5174 result.push_back(
object(
5176 {
"op",
"remove"}, {
"path", path_key}
5182 for (
auto it = target.
cbegin(); it != target.
cend(); ++it)
5184 if (source.
find(it.key()) == source.
end())
5187 const auto path_key = detail::concat<string_t>(path,
'/',
detail::escape(it.key()));
5190 {
"op",
"add"}, {
"path", path_key},
5191 {
"value", it.value()}
5200 case value_t::string:
5201 case value_t::boolean:
5202 case value_t::number_integer:
5203 case value_t::number_unsigned:
5204 case value_t::number_float:
5205 case value_t::binary:
5206 case value_t::discarded:
5212 {
"op",
"replace"}, {
"path", path}, {
"value", target}
5239 for (
auto it = apply_patch.
begin(); it != apply_patch.
end(); ++it)
5241 if (it.value().is_null())
5247 operator[](it.key()).merge_patch(it.value());
5253 *
this = apply_patch;