File indexing completed on 2025-12-15 10:19:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
0019 #define INCLUDE_NLOHMANN_JSON_HPP_
0020
0021 #include <algorithm> // all_of, find, for_each
0022 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
0023 #include <functional> // hash, less
0024 #include <initializer_list> // initializer_list
0025 #ifndef JSON_NO_IO
0026 #include <iosfwd> // istream, ostream
0027 #endif
0028 #include <iterator> // random_access_iterator_tag
0029 #include <memory> // unique_ptr
0030 #include <string> // string, stoi, to_string
0031 #include <utility> // declval, forward, move, pair, swap
0032 #include <vector> // vector
0033
0034 #include <nlohmann/adl_serializer.hpp>
0035 #include <nlohmann/byte_container_with_subtype.hpp>
0036 #include <nlohmann/detail/conversions/from_json.hpp>
0037 #include <nlohmann/detail/conversions/to_json.hpp>
0038 #include <nlohmann/detail/exceptions.hpp>
0039 #include <nlohmann/detail/hash.hpp>
0040 #include <nlohmann/detail/input/binary_reader.hpp>
0041 #include <nlohmann/detail/input/input_adapters.hpp>
0042 #include <nlohmann/detail/input/lexer.hpp>
0043 #include <nlohmann/detail/input/parser.hpp>
0044 #include <nlohmann/detail/iterators/internal_iterator.hpp>
0045 #include <nlohmann/detail/iterators/iter_impl.hpp>
0046 #include <nlohmann/detail/iterators/iteration_proxy.hpp>
0047 #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
0048 #include <nlohmann/detail/iterators/primitive_iterator.hpp>
0049 #include <nlohmann/detail/json_custom_base_class.hpp>
0050 #include <nlohmann/detail/json_pointer.hpp>
0051 #include <nlohmann/detail/json_ref.hpp>
0052 #include <nlohmann/detail/macro_scope.hpp>
0053 #include <nlohmann/detail/string_concat.hpp>
0054 #include <nlohmann/detail/string_escape.hpp>
0055 #include <nlohmann/detail/meta/cpp_future.hpp>
0056 #include <nlohmann/detail/meta/type_traits.hpp>
0057 #include <nlohmann/detail/output/binary_writer.hpp>
0058 #include <nlohmann/detail/output/output_adapters.hpp>
0059 #include <nlohmann/detail/output/serializer.hpp>
0060 #include <nlohmann/detail/value_t.hpp>
0061 #include <nlohmann/json_fwd.hpp>
0062 #include <nlohmann/ordered_map.hpp>
0063
0064 #if defined(JSON_HAS_CPP_17)
0065 #if JSON_HAS_STATIC_RTTI
0066 #include <any>
0067 #endif
0068 #include <string_view>
0069 #endif
0070
0071
0072
0073
0074
0075
0076 NLOHMANN_JSON_NAMESPACE_BEGIN
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 NLOHMANN_BASIC_JSON_TPL_DECLARATION
0097 class basic_json
0098 : public ::nlohmann::detail::json_base_class<CustomBaseClass>
0099 {
0100 private:
0101 template<detail::value_t> friend struct detail::external_constructor;
0102
0103 template<typename>
0104 friend class ::nlohmann::json_pointer;
0105
0106
0107
0108 template<typename BasicJsonType, typename InputType>
0109 friend class ::nlohmann::detail::parser;
0110 friend ::nlohmann::detail::serializer<basic_json>;
0111 template<typename BasicJsonType>
0112 friend class ::nlohmann::detail::iter_impl;
0113 template<typename BasicJsonType, typename CharType>
0114 friend class ::nlohmann::detail::binary_writer;
0115 template<typename BasicJsonType, typename InputType, typename SAX>
0116 friend class ::nlohmann::detail::binary_reader;
0117 template<typename BasicJsonType>
0118 friend class ::nlohmann::detail::json_sax_dom_parser;
0119 template<typename BasicJsonType>
0120 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
0121 friend class ::nlohmann::detail::exception;
0122
0123
0124 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
0125 using json_base_class_t = ::nlohmann::detail::json_base_class<CustomBaseClass>;
0126
0127 JSON_PRIVATE_UNLESS_TESTED:
0128
0129 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
0130
0131 template<typename InputAdapterType>
0132 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
0133 InputAdapterType adapter,
0134 detail::parser_callback_t<basic_json>cb = nullptr,
0135 const bool allow_exceptions = true,
0136 const bool ignore_comments = false
0137 )
0138 {
0139 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
0140 std::move(cb), allow_exceptions, ignore_comments);
0141 }
0142
0143 private:
0144 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
0145 template<typename BasicJsonType>
0146 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
0147 template<typename BasicJsonType>
0148 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
0149 template<typename Iterator>
0150 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
0151 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
0152
0153 template<typename CharType>
0154 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
0155
0156 template<typename InputType>
0157 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
0158 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
0159
0160 JSON_PRIVATE_UNLESS_TESTED:
0161 using serializer = ::nlohmann::detail::serializer<basic_json>;
0162
0163 public:
0164 using value_t = detail::value_t;
0165
0166 using json_pointer = ::nlohmann::json_pointer<StringType>;
0167 template<typename T, typename SFINAE>
0168 using json_serializer = JSONSerializer<T, SFINAE>;
0169
0170 using error_handler_t = detail::error_handler_t;
0171
0172 using cbor_tag_handler_t = detail::cbor_tag_handler_t;
0173
0174 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
0175
0176 using input_format_t = detail::input_format_t;
0177
0178 using json_sax_t = json_sax<basic_json>;
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 using exception = detail::exception;
0189 using parse_error = detail::parse_error;
0190 using invalid_iterator = detail::invalid_iterator;
0191 using type_error = detail::type_error;
0192 using out_of_range = detail::out_of_range;
0193 using other_error = detail::other_error;
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207 using value_type = basic_json;
0208
0209
0210 using reference = value_type&;
0211
0212 using const_reference = const value_type&;
0213
0214
0215 using difference_type = std::ptrdiff_t;
0216
0217 using size_type = std::size_t;
0218
0219
0220 using allocator_type = AllocatorType<basic_json>;
0221
0222
0223 using pointer = typename std::allocator_traits<allocator_type>::pointer;
0224
0225 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
0226
0227
0228 using iterator = iter_impl<basic_json>;
0229
0230 using const_iterator = iter_impl<const basic_json>;
0231
0232 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
0233
0234 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
0235
0236
0237
0238
0239
0240 static allocator_type get_allocator()
0241 {
0242 return allocator_type();
0243 }
0244
0245
0246
0247 JSON_HEDLEY_WARN_UNUSED_RESULT
0248 static basic_json meta()
0249 {
0250 basic_json result;
0251
0252 result["copyright"] = "(C) 2013-2023 Niels Lohmann";
0253 result["name"] = "JSON for Modern C++";
0254 result["url"] = "https://github.com/nlohmann/json";
0255 result["version"]["string"] =
0256 detail::concat(std::to_string(NLOHMANN_JSON_VERSION_MAJOR), '.',
0257 std::to_string(NLOHMANN_JSON_VERSION_MINOR), '.',
0258 std::to_string(NLOHMANN_JSON_VERSION_PATCH));
0259 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
0260 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
0261 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
0262
0263 #ifdef _WIN32
0264 result["platform"] = "win32";
0265 #elif defined __linux__
0266 result["platform"] = "linux";
0267 #elif defined __APPLE__
0268 result["platform"] = "apple";
0269 #elif defined __unix__
0270 result["platform"] = "unix";
0271 #else
0272 result["platform"] = "unknown";
0273 #endif
0274
0275 #if defined(__ICC) || defined(__INTEL_COMPILER)
0276 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
0277 #elif defined(__clang__)
0278 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
0279 #elif defined(__GNUC__) || defined(__GNUG__)
0280 result["compiler"] = {{"family", "gcc"}, {"version", detail::concat(
0281 std::to_string(__GNUC__), '.',
0282 std::to_string(__GNUC_MINOR__), '.',
0283 std::to_string(__GNUC_PATCHLEVEL__))
0284 }
0285 };
0286 #elif defined(__HP_cc) || defined(__HP_aCC)
0287 result["compiler"] = "hp"
0288 #elif defined(__IBMCPP__)
0289 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
0290 #elif defined(_MSC_VER)
0291 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
0292 #elif defined(__PGI)
0293 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
0294 #elif defined(__SUNPRO_CC)
0295 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
0296 #else
0297 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
0298 #endif
0299
0300 #if defined(_MSVC_LANG)
0301 result["compiler"]["c++"] = std::to_string(_MSVC_LANG);
0302 #elif defined(__cplusplus)
0303 result["compiler"]["c++"] = std::to_string(__cplusplus);
0304 #else
0305 result["compiler"]["c++"] = "unknown";
0306 #endif
0307 return result;
0308 }
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323 #if defined(JSON_HAS_CPP_14)
0324
0325
0326 using default_object_comparator_t = std::less<>;
0327 #else
0328 using default_object_comparator_t = std::less<StringType>;
0329 #endif
0330
0331
0332
0333 using object_t = ObjectType<StringType,
0334 basic_json,
0335 default_object_comparator_t,
0336 AllocatorType<std::pair<const StringType,
0337 basic_json>>>;
0338
0339
0340
0341 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
0342
0343
0344
0345 using string_t = StringType;
0346
0347
0348
0349 using boolean_t = BooleanType;
0350
0351
0352
0353 using number_integer_t = NumberIntegerType;
0354
0355
0356
0357 using number_unsigned_t = NumberUnsignedType;
0358
0359
0360
0361 using number_float_t = NumberFloatType;
0362
0363
0364
0365 using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
0366
0367
0368
0369 using object_comparator_t = detail::actual_object_comparator_t<basic_json>;
0370
0371
0372
0373 private:
0374
0375
0376 template<typename T, typename... Args>
0377 JSON_HEDLEY_RETURNS_NON_NULL
0378 static T* create(Args&& ... args)
0379 {
0380 AllocatorType<T> alloc;
0381 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
0382
0383 auto deleter = [&](T * obj)
0384 {
0385 AllocatorTraits::deallocate(alloc, obj, 1);
0386 };
0387 std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
0388 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
0389 JSON_ASSERT(obj != nullptr);
0390 return obj.release();
0391 }
0392
0393
0394
0395
0396
0397 JSON_PRIVATE_UNLESS_TESTED:
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423 union json_value
0424 {
0425
0426 object_t* object;
0427
0428 array_t* array;
0429
0430 string_t* string;
0431
0432 binary_t* binary;
0433
0434 boolean_t boolean;
0435
0436 number_integer_t number_integer;
0437
0438 number_unsigned_t number_unsigned;
0439
0440 number_float_t number_float;
0441
0442
0443 json_value() = default;
0444
0445 json_value(boolean_t v) noexcept : boolean(v) {}
0446
0447 json_value(number_integer_t v) noexcept : number_integer(v) {}
0448
0449 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
0450
0451 json_value(number_float_t v) noexcept : number_float(v) {}
0452
0453 json_value(value_t t)
0454 {
0455 switch (t)
0456 {
0457 case value_t::object:
0458 {
0459 object = create<object_t>();
0460 break;
0461 }
0462
0463 case value_t::array:
0464 {
0465 array = create<array_t>();
0466 break;
0467 }
0468
0469 case value_t::string:
0470 {
0471 string = create<string_t>("");
0472 break;
0473 }
0474
0475 case value_t::binary:
0476 {
0477 binary = create<binary_t>();
0478 break;
0479 }
0480
0481 case value_t::boolean:
0482 {
0483 boolean = static_cast<boolean_t>(false);
0484 break;
0485 }
0486
0487 case value_t::number_integer:
0488 {
0489 number_integer = static_cast<number_integer_t>(0);
0490 break;
0491 }
0492
0493 case value_t::number_unsigned:
0494 {
0495 number_unsigned = static_cast<number_unsigned_t>(0);
0496 break;
0497 }
0498
0499 case value_t::number_float:
0500 {
0501 number_float = static_cast<number_float_t>(0.0);
0502 break;
0503 }
0504
0505 case value_t::null:
0506 {
0507 object = nullptr;
0508 break;
0509 }
0510
0511 case value_t::discarded:
0512 default:
0513 {
0514 object = nullptr;
0515 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
0516 {
0517 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.11.3", nullptr));
0518 }
0519 break;
0520 }
0521 }
0522 }
0523
0524
0525 json_value(const string_t& value) : string(create<string_t>(value)) {}
0526
0527
0528 json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
0529
0530
0531 json_value(const object_t& value) : object(create<object_t>(value)) {}
0532
0533
0534 json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
0535
0536
0537 json_value(const array_t& value) : array(create<array_t>(value)) {}
0538
0539
0540 json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
0541
0542
0543 json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
0544
0545
0546 json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
0547
0548
0549 json_value(const binary_t& value) : binary(create<binary_t>(value)) {}
0550
0551
0552 json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
0553
0554 void destroy(value_t t)
0555 {
0556 if (
0557 (t == value_t::object && object == nullptr) ||
0558 (t == value_t::array && array == nullptr) ||
0559 (t == value_t::string && string == nullptr) ||
0560 (t == value_t::binary && binary == nullptr)
0561 )
0562 {
0563
0564 return;
0565 }
0566 if (t == value_t::array || t == value_t::object)
0567 {
0568
0569 std::vector<basic_json> stack;
0570
0571
0572 if (t == value_t::array)
0573 {
0574 stack.reserve(array->size());
0575 std::move(array->begin(), array->end(), std::back_inserter(stack));
0576 }
0577 else
0578 {
0579 stack.reserve(object->size());
0580 for (auto&& it : *object)
0581 {
0582 stack.push_back(std::move(it.second));
0583 }
0584 }
0585
0586 while (!stack.empty())
0587 {
0588
0589 basic_json current_item(std::move(stack.back()));
0590 stack.pop_back();
0591
0592
0593
0594 if (current_item.is_array())
0595 {
0596 std::move(current_item.m_data.m_value.array->begin(), current_item.m_data.m_value.array->end(), std::back_inserter(stack));
0597
0598 current_item.m_data.m_value.array->clear();
0599 }
0600 else if (current_item.is_object())
0601 {
0602 for (auto&& it : *current_item.m_data.m_value.object)
0603 {
0604 stack.push_back(std::move(it.second));
0605 }
0606
0607 current_item.m_data.m_value.object->clear();
0608 }
0609
0610
0611
0612 }
0613 }
0614
0615 switch (t)
0616 {
0617 case value_t::object:
0618 {
0619 AllocatorType<object_t> alloc;
0620 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
0621 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
0622 break;
0623 }
0624
0625 case value_t::array:
0626 {
0627 AllocatorType<array_t> alloc;
0628 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
0629 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
0630 break;
0631 }
0632
0633 case value_t::string:
0634 {
0635 AllocatorType<string_t> alloc;
0636 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
0637 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
0638 break;
0639 }
0640
0641 case value_t::binary:
0642 {
0643 AllocatorType<binary_t> alloc;
0644 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
0645 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
0646 break;
0647 }
0648
0649 case value_t::null:
0650 case value_t::boolean:
0651 case value_t::number_integer:
0652 case value_t::number_unsigned:
0653 case value_t::number_float:
0654 case value_t::discarded:
0655 default:
0656 {
0657 break;
0658 }
0659 }
0660 }
0661 };
0662
0663 private:
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682 void assert_invariant(bool check_parents = true) const noexcept
0683 {
0684 JSON_ASSERT(m_data.m_type != value_t::object || m_data.m_value.object != nullptr);
0685 JSON_ASSERT(m_data.m_type != value_t::array || m_data.m_value.array != nullptr);
0686 JSON_ASSERT(m_data.m_type != value_t::string || m_data.m_value.string != nullptr);
0687 JSON_ASSERT(m_data.m_type != value_t::binary || m_data.m_value.binary != nullptr);
0688
0689 #if JSON_DIAGNOSTICS
0690 JSON_TRY
0691 {
0692
0693 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
0694 {
0695 return j.m_parent == this;
0696 }));
0697 }
0698 JSON_CATCH(...) {}
0699 #endif
0700 static_cast<void>(check_parents);
0701 }
0702
0703 void set_parents()
0704 {
0705 #if JSON_DIAGNOSTICS
0706 switch (m_data.m_type)
0707 {
0708 case value_t::array:
0709 {
0710 for (auto& element : *m_data.m_value.array)
0711 {
0712 element.m_parent = this;
0713 }
0714 break;
0715 }
0716
0717 case value_t::object:
0718 {
0719 for (auto& element : *m_data.m_value.object)
0720 {
0721 element.second.m_parent = this;
0722 }
0723 break;
0724 }
0725
0726 case value_t::null:
0727 case value_t::string:
0728 case value_t::boolean:
0729 case value_t::number_integer:
0730 case value_t::number_unsigned:
0731 case value_t::number_float:
0732 case value_t::binary:
0733 case value_t::discarded:
0734 default:
0735 break;
0736 }
0737 #endif
0738 }
0739
0740 iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
0741 {
0742 #if JSON_DIAGNOSTICS
0743 for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
0744 {
0745 (it + i)->m_parent = this;
0746 }
0747 #else
0748 static_cast<void>(count_set_parents);
0749 #endif
0750 return it;
0751 }
0752
0753 reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))
0754 {
0755 #if JSON_DIAGNOSTICS
0756 if (old_capacity != static_cast<std::size_t>(-1))
0757 {
0758
0759 JSON_ASSERT(type() == value_t::array);
0760 if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
0761 {
0762
0763 set_parents();
0764 return j;
0765 }
0766 }
0767
0768
0769
0770 #ifdef JSON_HEDLEY_MSVC_VERSION
0771 #pragma warning(push )
0772 #pragma warning(disable : 4127)
0773 #endif
0774 if (detail::is_ordered_map<object_t>::value)
0775 {
0776 set_parents();
0777 return j;
0778 }
0779 #ifdef JSON_HEDLEY_MSVC_VERSION
0780 #pragma warning( pop )
0781 #endif
0782
0783 j.m_parent = this;
0784 #else
0785 static_cast<void>(j);
0786 static_cast<void>(old_capacity);
0787 #endif
0788 return j;
0789 }
0790
0791 public:
0792
0793
0794
0795
0796
0797
0798 using parse_event_t = detail::parse_event_t;
0799
0800
0801
0802 using parser_callback_t = detail::parser_callback_t<basic_json>;
0803
0804
0805
0806
0807
0808
0809
0810
0811
0812
0813
0814
0815 basic_json(const value_t v)
0816 : m_data(v)
0817 {
0818 assert_invariant();
0819 }
0820
0821
0822
0823 basic_json(std::nullptr_t = nullptr) noexcept
0824 : basic_json(value_t::null)
0825 {
0826 assert_invariant();
0827 }
0828
0829
0830
0831 template < typename CompatibleType,
0832 typename U = detail::uncvref_t<CompatibleType>,
0833 detail::enable_if_t <
0834 !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
0835 basic_json(CompatibleType && val) noexcept(noexcept(
0836 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
0837 std::forward<CompatibleType>(val))))
0838 {
0839 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
0840 set_parents();
0841 assert_invariant();
0842 }
0843
0844
0845
0846 template < typename BasicJsonType,
0847 detail::enable_if_t <
0848 detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
0849 basic_json(const BasicJsonType& val)
0850 {
0851 using other_boolean_t = typename BasicJsonType::boolean_t;
0852 using other_number_float_t = typename BasicJsonType::number_float_t;
0853 using other_number_integer_t = typename BasicJsonType::number_integer_t;
0854 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
0855 using other_string_t = typename BasicJsonType::string_t;
0856 using other_object_t = typename BasicJsonType::object_t;
0857 using other_array_t = typename BasicJsonType::array_t;
0858 using other_binary_t = typename BasicJsonType::binary_t;
0859
0860 switch (val.type())
0861 {
0862 case value_t::boolean:
0863 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
0864 break;
0865 case value_t::number_float:
0866 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
0867 break;
0868 case value_t::number_integer:
0869 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
0870 break;
0871 case value_t::number_unsigned:
0872 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
0873 break;
0874 case value_t::string:
0875 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
0876 break;
0877 case value_t::object:
0878 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
0879 break;
0880 case value_t::array:
0881 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
0882 break;
0883 case value_t::binary:
0884 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
0885 break;
0886 case value_t::null:
0887 *this = nullptr;
0888 break;
0889 case value_t::discarded:
0890 m_data.m_type = value_t::discarded;
0891 break;
0892 default:
0893 JSON_ASSERT(false);
0894 }
0895 JSON_ASSERT(m_data.m_type == val.type());
0896 set_parents();
0897 assert_invariant();
0898 }
0899
0900
0901
0902 basic_json(initializer_list_t init,
0903 bool type_deduction = true,
0904 value_t manual_type = value_t::array)
0905 {
0906
0907
0908 bool is_an_object = std::all_of(init.begin(), init.end(),
0909 [](const detail::json_ref<basic_json>& element_ref)
0910 {
0911
0912
0913
0914 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[static_cast<size_type>(0)].is_string();
0915 });
0916
0917
0918 if (!type_deduction)
0919 {
0920
0921 if (manual_type == value_t::array)
0922 {
0923 is_an_object = false;
0924 }
0925
0926
0927 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
0928 {
0929 JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
0930 }
0931 }
0932
0933 if (is_an_object)
0934 {
0935
0936 m_data.m_type = value_t::object;
0937 m_data.m_value = value_t::object;
0938
0939 for (auto& element_ref : init)
0940 {
0941 auto element = element_ref.moved_or_copied();
0942 m_data.m_value.object->emplace(
0943 std::move(*((*element.m_data.m_value.array)[0].m_data.m_value.string)),
0944 std::move((*element.m_data.m_value.array)[1]));
0945 }
0946 }
0947 else
0948 {
0949
0950 m_data.m_type = value_t::array;
0951 m_data.m_value.array = create<array_t>(init.begin(), init.end());
0952 }
0953
0954 set_parents();
0955 assert_invariant();
0956 }
0957
0958
0959
0960 JSON_HEDLEY_WARN_UNUSED_RESULT
0961 static basic_json binary(const typename binary_t::container_type& init)
0962 {
0963 auto res = basic_json();
0964 res.m_data.m_type = value_t::binary;
0965 res.m_data.m_value = init;
0966 return res;
0967 }
0968
0969
0970
0971 JSON_HEDLEY_WARN_UNUSED_RESULT
0972 static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
0973 {
0974 auto res = basic_json();
0975 res.m_data.m_type = value_t::binary;
0976 res.m_data.m_value = binary_t(init, subtype);
0977 return res;
0978 }
0979
0980
0981
0982 JSON_HEDLEY_WARN_UNUSED_RESULT
0983 static basic_json binary(typename binary_t::container_type&& init)
0984 {
0985 auto res = basic_json();
0986 res.m_data.m_type = value_t::binary;
0987 res.m_data.m_value = std::move(init);
0988 return res;
0989 }
0990
0991
0992
0993 JSON_HEDLEY_WARN_UNUSED_RESULT
0994 static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
0995 {
0996 auto res = basic_json();
0997 res.m_data.m_type = value_t::binary;
0998 res.m_data.m_value = binary_t(std::move(init), subtype);
0999 return res;
1000 }
1001
1002
1003
1004 JSON_HEDLEY_WARN_UNUSED_RESULT
1005 static basic_json array(initializer_list_t init = {})
1006 {
1007 return basic_json(init, false, value_t::array);
1008 }
1009
1010
1011
1012 JSON_HEDLEY_WARN_UNUSED_RESULT
1013 static basic_json object(initializer_list_t init = {})
1014 {
1015 return basic_json(init, false, value_t::object);
1016 }
1017
1018
1019
1020 basic_json(size_type cnt, const basic_json& val):
1021 m_data{cnt, val}
1022 {
1023 set_parents();
1024 assert_invariant();
1025 }
1026
1027
1028
1029 template < class InputIT, typename std::enable_if <
1030 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
1031 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
1032 basic_json(InputIT first, InputIT last)
1033 {
1034 JSON_ASSERT(first.m_object != nullptr);
1035 JSON_ASSERT(last.m_object != nullptr);
1036
1037
1038 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
1039 {
1040 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
1041 }
1042
1043
1044 m_data.m_type = first.m_object->m_data.m_type;
1045
1046
1047 switch (m_data.m_type)
1048 {
1049 case value_t::boolean:
1050 case value_t::number_float:
1051 case value_t::number_integer:
1052 case value_t::number_unsigned:
1053 case value_t::string:
1054 {
1055 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
1056 || !last.m_it.primitive_iterator.is_end()))
1057 {
1058 JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
1059 }
1060 break;
1061 }
1062
1063 case value_t::null:
1064 case value_t::object:
1065 case value_t::array:
1066 case value_t::binary:
1067 case value_t::discarded:
1068 default:
1069 break;
1070 }
1071
1072 switch (m_data.m_type)
1073 {
1074 case value_t::number_integer:
1075 {
1076 m_data.m_value.number_integer = first.m_object->m_data.m_value.number_integer;
1077 break;
1078 }
1079
1080 case value_t::number_unsigned:
1081 {
1082 m_data.m_value.number_unsigned = first.m_object->m_data.m_value.number_unsigned;
1083 break;
1084 }
1085
1086 case value_t::number_float:
1087 {
1088 m_data.m_value.number_float = first.m_object->m_data.m_value.number_float;
1089 break;
1090 }
1091
1092 case value_t::boolean:
1093 {
1094 m_data.m_value.boolean = first.m_object->m_data.m_value.boolean;
1095 break;
1096 }
1097
1098 case value_t::string:
1099 {
1100 m_data.m_value = *first.m_object->m_data.m_value.string;
1101 break;
1102 }
1103
1104 case value_t::object:
1105 {
1106 m_data.m_value.object = create<object_t>(first.m_it.object_iterator,
1107 last.m_it.object_iterator);
1108 break;
1109 }
1110
1111 case value_t::array:
1112 {
1113 m_data.m_value.array = create<array_t>(first.m_it.array_iterator,
1114 last.m_it.array_iterator);
1115 break;
1116 }
1117
1118 case value_t::binary:
1119 {
1120 m_data.m_value = *first.m_object->m_data.m_value.binary;
1121 break;
1122 }
1123
1124 case value_t::null:
1125 case value_t::discarded:
1126 default:
1127 JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
1128 }
1129
1130 set_parents();
1131 assert_invariant();
1132 }
1133
1134
1135
1136
1137
1138 template<typename JsonRef,
1139 detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
1140 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
1141 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
1142
1143
1144
1145 basic_json(const basic_json& other)
1146 : json_base_class_t(other)
1147 {
1148 m_data.m_type = other.m_data.m_type;
1149
1150 other.assert_invariant();
1151
1152 switch (m_data.m_type)
1153 {
1154 case value_t::object:
1155 {
1156 m_data.m_value = *other.m_data.m_value.object;
1157 break;
1158 }
1159
1160 case value_t::array:
1161 {
1162 m_data.m_value = *other.m_data.m_value.array;
1163 break;
1164 }
1165
1166 case value_t::string:
1167 {
1168 m_data.m_value = *other.m_data.m_value.string;
1169 break;
1170 }
1171
1172 case value_t::boolean:
1173 {
1174 m_data.m_value = other.m_data.m_value.boolean;
1175 break;
1176 }
1177
1178 case value_t::number_integer:
1179 {
1180 m_data.m_value = other.m_data.m_value.number_integer;
1181 break;
1182 }
1183
1184 case value_t::number_unsigned:
1185 {
1186 m_data.m_value = other.m_data.m_value.number_unsigned;
1187 break;
1188 }
1189
1190 case value_t::number_float:
1191 {
1192 m_data.m_value = other.m_data.m_value.number_float;
1193 break;
1194 }
1195
1196 case value_t::binary:
1197 {
1198 m_data.m_value = *other.m_data.m_value.binary;
1199 break;
1200 }
1201
1202 case value_t::null:
1203 case value_t::discarded:
1204 default:
1205 break;
1206 }
1207
1208 set_parents();
1209 assert_invariant();
1210 }
1211
1212
1213
1214 basic_json(basic_json&& other) noexcept
1215 : json_base_class_t(std::forward<json_base_class_t>(other)),
1216 m_data(std::move(other.m_data))
1217 {
1218
1219 other.assert_invariant(false);
1220
1221
1222 other.m_data.m_type = value_t::null;
1223 other.m_data.m_value = {};
1224
1225 set_parents();
1226 assert_invariant();
1227 }
1228
1229
1230
1231 basic_json& operator=(basic_json other) noexcept (
1232 std::is_nothrow_move_constructible<value_t>::value&&
1233 std::is_nothrow_move_assignable<value_t>::value&&
1234 std::is_nothrow_move_constructible<json_value>::value&&
1235 std::is_nothrow_move_assignable<json_value>::value&&
1236 std::is_nothrow_move_assignable<json_base_class_t>::value
1237 )
1238 {
1239
1240 other.assert_invariant();
1241
1242 using std::swap;
1243 swap(m_data.m_type, other.m_data.m_type);
1244 swap(m_data.m_value, other.m_data.m_value);
1245 json_base_class_t::operator=(std::move(other));
1246
1247 set_parents();
1248 assert_invariant();
1249 return *this;
1250 }
1251
1252
1253
1254 ~basic_json() noexcept
1255 {
1256 assert_invariant(false);
1257 }
1258
1259
1260
1261 public:
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272 string_t dump(const int indent = -1,
1273 const char indent_char = ' ',
1274 const bool ensure_ascii = false,
1275 const error_handler_t error_handler = error_handler_t::strict) const
1276 {
1277 string_t result;
1278 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
1279
1280 if (indent >= 0)
1281 {
1282 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
1283 }
1284 else
1285 {
1286 s.dump(*this, false, ensure_ascii, 0);
1287 }
1288
1289 return result;
1290 }
1291
1292
1293
1294 constexpr value_t type() const noexcept
1295 {
1296 return m_data.m_type;
1297 }
1298
1299
1300
1301 constexpr bool is_primitive() const noexcept
1302 {
1303 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
1304 }
1305
1306
1307
1308 constexpr bool is_structured() const noexcept
1309 {
1310 return is_array() || is_object();
1311 }
1312
1313
1314
1315 constexpr bool is_null() const noexcept
1316 {
1317 return m_data.m_type == value_t::null;
1318 }
1319
1320
1321
1322 constexpr bool is_boolean() const noexcept
1323 {
1324 return m_data.m_type == value_t::boolean;
1325 }
1326
1327
1328
1329 constexpr bool is_number() const noexcept
1330 {
1331 return is_number_integer() || is_number_float();
1332 }
1333
1334
1335
1336 constexpr bool is_number_integer() const noexcept
1337 {
1338 return m_data.m_type == value_t::number_integer || m_data.m_type == value_t::number_unsigned;
1339 }
1340
1341
1342
1343 constexpr bool is_number_unsigned() const noexcept
1344 {
1345 return m_data.m_type == value_t::number_unsigned;
1346 }
1347
1348
1349
1350 constexpr bool is_number_float() const noexcept
1351 {
1352 return m_data.m_type == value_t::number_float;
1353 }
1354
1355
1356
1357 constexpr bool is_object() const noexcept
1358 {
1359 return m_data.m_type == value_t::object;
1360 }
1361
1362
1363
1364 constexpr bool is_array() const noexcept
1365 {
1366 return m_data.m_type == value_t::array;
1367 }
1368
1369
1370
1371 constexpr bool is_string() const noexcept
1372 {
1373 return m_data.m_type == value_t::string;
1374 }
1375
1376
1377
1378 constexpr bool is_binary() const noexcept
1379 {
1380 return m_data.m_type == value_t::binary;
1381 }
1382
1383
1384
1385 constexpr bool is_discarded() const noexcept
1386 {
1387 return m_data.m_type == value_t::discarded;
1388 }
1389
1390
1391
1392 constexpr operator value_t() const noexcept
1393 {
1394 return m_data.m_type;
1395 }
1396
1397
1398
1399 private:
1400
1401
1402
1403
1404
1405 boolean_t get_impl(boolean_t* ) const
1406 {
1407 if (JSON_HEDLEY_LIKELY(is_boolean()))
1408 {
1409 return m_data.m_value.boolean;
1410 }
1411
1412 JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
1413 }
1414
1415
1416 object_t* get_impl_ptr(object_t* ) noexcept
1417 {
1418 return is_object() ? m_data.m_value.object : nullptr;
1419 }
1420
1421
1422 constexpr const object_t* get_impl_ptr(const object_t* ) const noexcept
1423 {
1424 return is_object() ? m_data.m_value.object : nullptr;
1425 }
1426
1427
1428 array_t* get_impl_ptr(array_t* ) noexcept
1429 {
1430 return is_array() ? m_data.m_value.array : nullptr;
1431 }
1432
1433
1434 constexpr const array_t* get_impl_ptr(const array_t* ) const noexcept
1435 {
1436 return is_array() ? m_data.m_value.array : nullptr;
1437 }
1438
1439
1440 string_t* get_impl_ptr(string_t* ) noexcept
1441 {
1442 return is_string() ? m_data.m_value.string : nullptr;
1443 }
1444
1445
1446 constexpr const string_t* get_impl_ptr(const string_t* ) const noexcept
1447 {
1448 return is_string() ? m_data.m_value.string : nullptr;
1449 }
1450
1451
1452 boolean_t* get_impl_ptr(boolean_t* ) noexcept
1453 {
1454 return is_boolean() ? &m_data.m_value.boolean : nullptr;
1455 }
1456
1457
1458 constexpr const boolean_t* get_impl_ptr(const boolean_t* ) const noexcept
1459 {
1460 return is_boolean() ? &m_data.m_value.boolean : nullptr;
1461 }
1462
1463
1464 number_integer_t* get_impl_ptr(number_integer_t* ) noexcept
1465 {
1466 return is_number_integer() ? &m_data.m_value.number_integer : nullptr;
1467 }
1468
1469
1470 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* ) const noexcept
1471 {
1472 return is_number_integer() ? &m_data.m_value.number_integer : nullptr;
1473 }
1474
1475
1476 number_unsigned_t* get_impl_ptr(number_unsigned_t* ) noexcept
1477 {
1478 return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
1479 }
1480
1481
1482 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* ) const noexcept
1483 {
1484 return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
1485 }
1486
1487
1488 number_float_t* get_impl_ptr(number_float_t* ) noexcept
1489 {
1490 return is_number_float() ? &m_data.m_value.number_float : nullptr;
1491 }
1492
1493
1494 constexpr const number_float_t* get_impl_ptr(const number_float_t* ) const noexcept
1495 {
1496 return is_number_float() ? &m_data.m_value.number_float : nullptr;
1497 }
1498
1499
1500 binary_t* get_impl_ptr(binary_t* ) noexcept
1501 {
1502 return is_binary() ? m_data.m_value.binary : nullptr;
1503 }
1504
1505
1506 constexpr const binary_t* get_impl_ptr(const binary_t* ) const noexcept
1507 {
1508 return is_binary() ? m_data.m_value.binary : nullptr;
1509 }
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522 template<typename ReferenceType, typename ThisType>
1523 static ReferenceType get_ref_impl(ThisType& obj)
1524 {
1525
1526 auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
1527
1528 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
1529 {
1530 return *ptr;
1531 }
1532
1533 JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
1534 }
1535
1536 public:
1537
1538
1539
1540
1541
1542
1543 template<typename PointerType, typename std::enable_if<
1544 std::is_pointer<PointerType>::value, int>::type = 0>
1545 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
1546 {
1547
1548 return get_impl_ptr(static_cast<PointerType>(nullptr));
1549 }
1550
1551
1552
1553 template < typename PointerType, typename std::enable_if <
1554 std::is_pointer<PointerType>::value&&
1555 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
1556 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
1557 {
1558
1559 return get_impl_ptr(static_cast<PointerType>(nullptr));
1560 }
1561
1562 private:
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601 template < typename ValueType,
1602 detail::enable_if_t <
1603 detail::is_default_constructible<ValueType>::value&&
1604 detail::has_from_json<basic_json_t, ValueType>::value,
1605 int > = 0 >
1606 ValueType get_impl(detail::priority_tag<0> ) const noexcept(noexcept(
1607 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
1608 {
1609 auto ret = ValueType();
1610 JSONSerializer<ValueType>::from_json(*this, ret);
1611 return ret;
1612 }
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644 template < typename ValueType,
1645 detail::enable_if_t <
1646 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
1647 int > = 0 >
1648 ValueType get_impl(detail::priority_tag<1> ) const noexcept(noexcept(
1649 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
1650 {
1651 return JSONSerializer<ValueType>::from_json(*this);
1652 }
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669 template < typename BasicJsonType,
1670 detail::enable_if_t <
1671 detail::is_basic_json<BasicJsonType>::value,
1672 int > = 0 >
1673 BasicJsonType get_impl(detail::priority_tag<2> ) const
1674 {
1675 return *this;
1676 }
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692 template<typename BasicJsonType,
1693 detail::enable_if_t<
1694 std::is_same<BasicJsonType, basic_json_t>::value,
1695 int> = 0>
1696 basic_json get_impl(detail::priority_tag<3> ) const
1697 {
1698 return *this;
1699 }
1700
1701
1702
1703
1704
1705 template<typename PointerType,
1706 detail::enable_if_t<
1707 std::is_pointer<PointerType>::value,
1708 int> = 0>
1709 constexpr auto get_impl(detail::priority_tag<4> ) const noexcept
1710 -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
1711 {
1712
1713 return get_ptr<PointerType>();
1714 }
1715
1716 public:
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
1741 #if defined(JSON_HAS_CPP_14)
1742 constexpr
1743 #endif
1744 auto get() const noexcept(
1745 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
1746 -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
1747 {
1748
1749
1750
1751 static_assert(!std::is_reference<ValueTypeCV>::value,
1752 "get() cannot be used with reference types, you might want to use get_ref()");
1753 return get_impl<ValueType>(detail::priority_tag<4> {});
1754 }
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783 template<typename PointerType, typename std::enable_if<
1784 std::is_pointer<PointerType>::value, int>::type = 0>
1785 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
1786 {
1787
1788 return get_ptr<PointerType>();
1789 }
1790
1791
1792
1793 template < typename ValueType,
1794 detail::enable_if_t <
1795 !detail::is_basic_json<ValueType>::value&&
1796 detail::has_from_json<basic_json_t, ValueType>::value,
1797 int > = 0 >
1798 ValueType & get_to(ValueType& v) const noexcept(noexcept(
1799 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
1800 {
1801 JSONSerializer<ValueType>::from_json(*this, v);
1802 return v;
1803 }
1804
1805
1806
1807 template<typename ValueType,
1808 detail::enable_if_t <
1809 detail::is_basic_json<ValueType>::value,
1810 int> = 0>
1811 ValueType & get_to(ValueType& v) const
1812 {
1813 v = *this;
1814 return v;
1815 }
1816
1817 template <
1818 typename T, std::size_t N,
1819 typename Array = T (&)[N],
1820 detail::enable_if_t <
1821 detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
1822 Array get_to(T (&v)[N]) const
1823 noexcept(noexcept(JSONSerializer<Array>::from_json(
1824 std::declval<const basic_json_t&>(), v)))
1825 {
1826 JSONSerializer<Array>::from_json(*this, v);
1827 return v;
1828 }
1829
1830
1831
1832 template<typename ReferenceType, typename std::enable_if<
1833 std::is_reference<ReferenceType>::value, int>::type = 0>
1834 ReferenceType get_ref()
1835 {
1836
1837 return get_ref_impl<ReferenceType>(*this);
1838 }
1839
1840
1841
1842 template < typename ReferenceType, typename std::enable_if <
1843 std::is_reference<ReferenceType>::value&&
1844 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
1845 ReferenceType get_ref() const
1846 {
1847
1848 return get_ref_impl<ReferenceType>(*this);
1849 }
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880 template < typename ValueType, typename std::enable_if <
1881 detail::conjunction <
1882 detail::negation<std::is_pointer<ValueType>>,
1883 detail::negation<std::is_same<ValueType, std::nullptr_t>>,
1884 detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
1885 detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
1886 detail::negation<detail::is_basic_json<ValueType>>,
1887 detail::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>,
1888 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
1889 detail::negation<std::is_same<ValueType, std::string_view>>,
1890 #endif
1891 #if defined(JSON_HAS_CPP_17) && JSON_HAS_STATIC_RTTI
1892 detail::negation<std::is_same<ValueType, std::any>>,
1893 #endif
1894 detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType>
1895 >::value, int >::type = 0 >
1896 JSON_EXPLICIT operator ValueType() const
1897 {
1898
1899 return get<ValueType>();
1900 }
1901
1902
1903
1904 binary_t& get_binary()
1905 {
1906 if (!is_binary())
1907 {
1908 JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
1909 }
1910
1911 return *get_ptr<binary_t*>();
1912 }
1913
1914
1915
1916 const binary_t& get_binary() const
1917 {
1918 if (!is_binary())
1919 {
1920 JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
1921 }
1922
1923 return *get_ptr<const binary_t*>();
1924 }
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938 reference at(size_type idx)
1939 {
1940
1941 if (JSON_HEDLEY_LIKELY(is_array()))
1942 {
1943 JSON_TRY
1944 {
1945 return set_parent(m_data.m_value.array->at(idx));
1946 }
1947 JSON_CATCH (std::out_of_range&)
1948 {
1949
1950 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
1951 }
1952 }
1953 else
1954 {
1955 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
1956 }
1957 }
1958
1959
1960
1961 const_reference at(size_type idx) const
1962 {
1963
1964 if (JSON_HEDLEY_LIKELY(is_array()))
1965 {
1966 JSON_TRY
1967 {
1968 return m_data.m_value.array->at(idx);
1969 }
1970 JSON_CATCH (std::out_of_range&)
1971 {
1972
1973 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
1974 }
1975 }
1976 else
1977 {
1978 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
1979 }
1980 }
1981
1982
1983
1984 reference at(const typename object_t::key_type& key)
1985 {
1986
1987 if (JSON_HEDLEY_UNLIKELY(!is_object()))
1988 {
1989 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
1990 }
1991
1992 auto it = m_data.m_value.object->find(key);
1993 if (it == m_data.m_value.object->end())
1994 {
1995 JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
1996 }
1997 return set_parent(it->second);
1998 }
1999
2000
2001
2002 template<class KeyType, detail::enable_if_t<
2003 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
2004 reference at(KeyType && key)
2005 {
2006
2007 if (JSON_HEDLEY_UNLIKELY(!is_object()))
2008 {
2009 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
2010 }
2011
2012 auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
2013 if (it == m_data.m_value.object->end())
2014 {
2015 JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
2016 }
2017 return set_parent(it->second);
2018 }
2019
2020
2021
2022 const_reference at(const typename object_t::key_type& key) const
2023 {
2024
2025 if (JSON_HEDLEY_UNLIKELY(!is_object()))
2026 {
2027 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
2028 }
2029
2030 auto it = m_data.m_value.object->find(key);
2031 if (it == m_data.m_value.object->end())
2032 {
2033 JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
2034 }
2035 return it->second;
2036 }
2037
2038
2039
2040 template<class KeyType, detail::enable_if_t<
2041 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
2042 const_reference at(KeyType && key) const
2043 {
2044
2045 if (JSON_HEDLEY_UNLIKELY(!is_object()))
2046 {
2047 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
2048 }
2049
2050 auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
2051 if (it == m_data.m_value.object->end())
2052 {
2053 JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
2054 }
2055 return it->second;
2056 }
2057
2058
2059
2060 reference operator[](size_type idx)
2061 {
2062
2063 if (is_null())
2064 {
2065 m_data.m_type = value_t::array;
2066 m_data.m_value.array = create<array_t>();
2067 assert_invariant();
2068 }
2069
2070
2071 if (JSON_HEDLEY_LIKELY(is_array()))
2072 {
2073
2074 if (idx >= m_data.m_value.array->size())
2075 {
2076 #if JSON_DIAGNOSTICS
2077
2078 const auto old_size = m_data.m_value.array->size();
2079 const auto old_capacity = m_data.m_value.array->capacity();
2080 #endif
2081 m_data.m_value.array->resize(idx + 1);
2082
2083 #if JSON_DIAGNOSTICS
2084 if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
2085 {
2086
2087 set_parents();
2088 }
2089 else
2090 {
2091
2092 set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
2093 }
2094 #endif
2095 assert_invariant();
2096 }
2097
2098 return m_data.m_value.array->operator[](idx);
2099 }
2100
2101 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
2102 }
2103
2104
2105
2106 const_reference operator[](size_type idx) const
2107 {
2108
2109 if (JSON_HEDLEY_LIKELY(is_array()))
2110 {
2111 return m_data.m_value.array->operator[](idx);
2112 }
2113
2114 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
2115 }
2116
2117
2118
2119 reference operator[](typename object_t::key_type key)
2120 {
2121
2122 if (is_null())
2123 {
2124 m_data.m_type = value_t::object;
2125 m_data.m_value.object = create<object_t>();
2126 assert_invariant();
2127 }
2128
2129
2130 if (JSON_HEDLEY_LIKELY(is_object()))
2131 {
2132 auto result = m_data.m_value.object->emplace(std::move(key), nullptr);
2133 return set_parent(result.first->second);
2134 }
2135
2136 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
2137 }
2138
2139
2140
2141 const_reference operator[](const typename object_t::key_type& key) const
2142 {
2143
2144 if (JSON_HEDLEY_LIKELY(is_object()))
2145 {
2146 auto it = m_data.m_value.object->find(key);
2147 JSON_ASSERT(it != m_data.m_value.object->end());
2148 return it->second;
2149 }
2150
2151 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
2152 }
2153
2154
2155
2156 template<typename T>
2157 reference operator[](T* key)
2158 {
2159 return operator[](typename object_t::key_type(key));
2160 }
2161
2162 template<typename T>
2163 const_reference operator[](T* key) const
2164 {
2165 return operator[](typename object_t::key_type(key));
2166 }
2167
2168
2169
2170 template<class KeyType, detail::enable_if_t<
2171 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int > = 0 >
2172 reference operator[](KeyType && key)
2173 {
2174
2175 if (is_null())
2176 {
2177 m_data.m_type = value_t::object;
2178 m_data.m_value.object = create<object_t>();
2179 assert_invariant();
2180 }
2181
2182
2183 if (JSON_HEDLEY_LIKELY(is_object()))
2184 {
2185 auto result = m_data.m_value.object->emplace(std::forward<KeyType>(key), nullptr);
2186 return set_parent(result.first->second);
2187 }
2188
2189 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
2190 }
2191
2192
2193
2194 template<class KeyType, detail::enable_if_t<
2195 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int > = 0 >
2196 const_reference operator[](KeyType && key) const
2197 {
2198
2199 if (JSON_HEDLEY_LIKELY(is_object()))
2200 {
2201 auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
2202 JSON_ASSERT(it != m_data.m_value.object->end());
2203 return it->second;
2204 }
2205
2206 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
2207 }
2208
2209 private:
2210 template<typename KeyType>
2211 using is_comparable_with_object_key = detail::is_comparable <
2212 object_comparator_t, const typename object_t::key_type&, KeyType >;
2213
2214 template<typename ValueType>
2215 using value_return_type = std::conditional <
2216 detail::is_c_string_uncvref<ValueType>::value,
2217 string_t, typename std::decay<ValueType>::type >;
2218
2219 public:
2220
2221
2222 template < class ValueType, detail::enable_if_t <
2223 !detail::is_transparent<object_comparator_t>::value
2224 && detail::is_getable<basic_json_t, ValueType>::value
2225 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
2226 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
2227 {
2228
2229 if (JSON_HEDLEY_LIKELY(is_object()))
2230 {
2231
2232 const auto it = find(key);
2233 if (it != end())
2234 {
2235 return it->template get<ValueType>();
2236 }
2237
2238 return default_value;
2239 }
2240
2241 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
2242 }
2243
2244
2245
2246 template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
2247 detail::enable_if_t <
2248 !detail::is_transparent<object_comparator_t>::value
2249 && detail::is_getable<basic_json_t, ReturnType>::value
2250 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
2251 ReturnType value(const typename object_t::key_type& key, ValueType && default_value) const
2252 {
2253
2254 if (JSON_HEDLEY_LIKELY(is_object()))
2255 {
2256
2257 const auto it = find(key);
2258 if (it != end())
2259 {
2260 return it->template get<ReturnType>();
2261 }
2262
2263 return std::forward<ValueType>(default_value);
2264 }
2265
2266 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
2267 }
2268
2269
2270
2271 template < class ValueType, class KeyType, detail::enable_if_t <
2272 detail::is_transparent<object_comparator_t>::value
2273 && !detail::is_json_pointer<KeyType>::value
2274 && is_comparable_with_object_key<KeyType>::value
2275 && detail::is_getable<basic_json_t, ValueType>::value
2276 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
2277 ValueType value(KeyType && key, const ValueType& default_value) const
2278 {
2279
2280 if (JSON_HEDLEY_LIKELY(is_object()))
2281 {
2282
2283 const auto it = find(std::forward<KeyType>(key));
2284 if (it != end())
2285 {
2286 return it->template get<ValueType>();
2287 }
2288
2289 return default_value;
2290 }
2291
2292 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
2293 }
2294
2295
2296
2297 template < class ValueType, class KeyType, class ReturnType = typename value_return_type<ValueType>::type,
2298 detail::enable_if_t <
2299 detail::is_transparent<object_comparator_t>::value
2300 && !detail::is_json_pointer<KeyType>::value
2301 && is_comparable_with_object_key<KeyType>::value
2302 && detail::is_getable<basic_json_t, ReturnType>::value
2303 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
2304 ReturnType value(KeyType && key, ValueType && default_value) const
2305 {
2306
2307 if (JSON_HEDLEY_LIKELY(is_object()))
2308 {
2309
2310 const auto it = find(std::forward<KeyType>(key));
2311 if (it != end())
2312 {
2313 return it->template get<ReturnType>();
2314 }
2315
2316 return std::forward<ValueType>(default_value);
2317 }
2318
2319 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
2320 }
2321
2322
2323
2324 template < class ValueType, detail::enable_if_t <
2325 detail::is_getable<basic_json_t, ValueType>::value
2326 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
2327 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
2328 {
2329
2330 if (JSON_HEDLEY_LIKELY(is_object()))
2331 {
2332
2333 JSON_TRY
2334 {
2335 return ptr.get_checked(this).template get<ValueType>();
2336 }
2337 JSON_INTERNAL_CATCH (out_of_range&)
2338 {
2339 return default_value;
2340 }
2341 }
2342
2343 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
2344 }
2345
2346
2347
2348 template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
2349 detail::enable_if_t <
2350 detail::is_getable<basic_json_t, ReturnType>::value
2351 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
2352 ReturnType value(const json_pointer& ptr, ValueType && default_value) const
2353 {
2354
2355 if (JSON_HEDLEY_LIKELY(is_object()))
2356 {
2357
2358 JSON_TRY
2359 {
2360 return ptr.get_checked(this).template get<ReturnType>();
2361 }
2362 JSON_INTERNAL_CATCH (out_of_range&)
2363 {
2364 return std::forward<ValueType>(default_value);
2365 }
2366 }
2367
2368 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
2369 }
2370
2371 template < class ValueType, class BasicJsonType, detail::enable_if_t <
2372 detail::is_basic_json<BasicJsonType>::value
2373 && detail::is_getable<basic_json_t, ValueType>::value
2374 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
2375 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>)
2376 ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
2377 {
2378 return value(ptr.convert(), default_value);
2379 }
2380
2381 template < class ValueType, class BasicJsonType, class ReturnType = typename value_return_type<ValueType>::type,
2382 detail::enable_if_t <
2383 detail::is_basic_json<BasicJsonType>::value
2384 && detail::is_getable<basic_json_t, ReturnType>::value
2385 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
2386 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>)
2387 ReturnType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, ValueType && default_value) const
2388 {
2389 return value(ptr.convert(), std::forward<ValueType>(default_value));
2390 }
2391
2392
2393
2394 reference front()
2395 {
2396 return *begin();
2397 }
2398
2399
2400
2401 const_reference front() const
2402 {
2403 return *cbegin();
2404 }
2405
2406
2407
2408 reference back()
2409 {
2410 auto tmp = end();
2411 --tmp;
2412 return *tmp;
2413 }
2414
2415
2416
2417 const_reference back() const
2418 {
2419 auto tmp = cend();
2420 --tmp;
2421 return *tmp;
2422 }
2423
2424
2425
2426 template < class IteratorType, detail::enable_if_t <
2427 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
2428 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
2429 IteratorType erase(IteratorType pos)
2430 {
2431
2432 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
2433 {
2434 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
2435 }
2436
2437 IteratorType result = end();
2438
2439 switch (m_data.m_type)
2440 {
2441 case value_t::boolean:
2442 case value_t::number_float:
2443 case value_t::number_integer:
2444 case value_t::number_unsigned:
2445 case value_t::string:
2446 case value_t::binary:
2447 {
2448 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
2449 {
2450 JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
2451 }
2452
2453 if (is_string())
2454 {
2455 AllocatorType<string_t> alloc;
2456 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
2457 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
2458 m_data.m_value.string = nullptr;
2459 }
2460 else if (is_binary())
2461 {
2462 AllocatorType<binary_t> alloc;
2463 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
2464 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
2465 m_data.m_value.binary = nullptr;
2466 }
2467
2468 m_data.m_type = value_t::null;
2469 assert_invariant();
2470 break;
2471 }
2472
2473 case value_t::object:
2474 {
2475 result.m_it.object_iterator = m_data.m_value.object->erase(pos.m_it.object_iterator);
2476 break;
2477 }
2478
2479 case value_t::array:
2480 {
2481 result.m_it.array_iterator = m_data.m_value.array->erase(pos.m_it.array_iterator);
2482 break;
2483 }
2484
2485 case value_t::null:
2486 case value_t::discarded:
2487 default:
2488 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
2489 }
2490
2491 return result;
2492 }
2493
2494
2495
2496 template < class IteratorType, detail::enable_if_t <
2497 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
2498 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
2499 IteratorType erase(IteratorType first, IteratorType last)
2500 {
2501
2502 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
2503 {
2504 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
2505 }
2506
2507 IteratorType result = end();
2508
2509 switch (m_data.m_type)
2510 {
2511 case value_t::boolean:
2512 case value_t::number_float:
2513 case value_t::number_integer:
2514 case value_t::number_unsigned:
2515 case value_t::string:
2516 case value_t::binary:
2517 {
2518 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
2519 || !last.m_it.primitive_iterator.is_end()))
2520 {
2521 JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
2522 }
2523
2524 if (is_string())
2525 {
2526 AllocatorType<string_t> alloc;
2527 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
2528 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
2529 m_data.m_value.string = nullptr;
2530 }
2531 else if (is_binary())
2532 {
2533 AllocatorType<binary_t> alloc;
2534 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
2535 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
2536 m_data.m_value.binary = nullptr;
2537 }
2538
2539 m_data.m_type = value_t::null;
2540 assert_invariant();
2541 break;
2542 }
2543
2544 case value_t::object:
2545 {
2546 result.m_it.object_iterator = m_data.m_value.object->erase(first.m_it.object_iterator,
2547 last.m_it.object_iterator);
2548 break;
2549 }
2550
2551 case value_t::array:
2552 {
2553 result.m_it.array_iterator = m_data.m_value.array->erase(first.m_it.array_iterator,
2554 last.m_it.array_iterator);
2555 break;
2556 }
2557
2558 case value_t::null:
2559 case value_t::discarded:
2560 default:
2561 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
2562 }
2563
2564 return result;
2565 }
2566
2567 private:
2568 template < typename KeyType, detail::enable_if_t <
2569 detail::has_erase_with_key_type<basic_json_t, KeyType>::value, int > = 0 >
2570 size_type erase_internal(KeyType && key)
2571 {
2572
2573 if (JSON_HEDLEY_UNLIKELY(!is_object()))
2574 {
2575 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
2576 }
2577
2578 return m_data.m_value.object->erase(std::forward<KeyType>(key));
2579 }
2580
2581 template < typename KeyType, detail::enable_if_t <
2582 !detail::has_erase_with_key_type<basic_json_t, KeyType>::value, int > = 0 >
2583 size_type erase_internal(KeyType && key)
2584 {
2585
2586 if (JSON_HEDLEY_UNLIKELY(!is_object()))
2587 {
2588 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
2589 }
2590
2591 const auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
2592 if (it != m_data.m_value.object->end())
2593 {
2594 m_data.m_value.object->erase(it);
2595 return 1;
2596 }
2597 return 0;
2598 }
2599
2600 public:
2601
2602
2603
2604 size_type erase(const typename object_t::key_type& key)
2605 {
2606
2607
2608 return erase_internal(key);
2609 }
2610
2611
2612
2613 template<class KeyType, detail::enable_if_t<
2614 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
2615 size_type erase(KeyType && key)
2616 {
2617 return erase_internal(std::forward<KeyType>(key));
2618 }
2619
2620
2621
2622 void erase(const size_type idx)
2623 {
2624
2625 if (JSON_HEDLEY_LIKELY(is_array()))
2626 {
2627 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
2628 {
2629 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
2630 }
2631
2632 m_data.m_value.array->erase(m_data.m_value.array->begin() + static_cast<difference_type>(idx));
2633 }
2634 else
2635 {
2636 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
2637 }
2638 }
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651 iterator find(const typename object_t::key_type& key)
2652 {
2653 auto result = end();
2654
2655 if (is_object())
2656 {
2657 result.m_it.object_iterator = m_data.m_value.object->find(key);
2658 }
2659
2660 return result;
2661 }
2662
2663
2664
2665 const_iterator find(const typename object_t::key_type& key) const
2666 {
2667 auto result = cend();
2668
2669 if (is_object())
2670 {
2671 result.m_it.object_iterator = m_data.m_value.object->find(key);
2672 }
2673
2674 return result;
2675 }
2676
2677
2678
2679 template<class KeyType, detail::enable_if_t<
2680 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
2681 iterator find(KeyType && key)
2682 {
2683 auto result = end();
2684
2685 if (is_object())
2686 {
2687 result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
2688 }
2689
2690 return result;
2691 }
2692
2693
2694
2695 template<class KeyType, detail::enable_if_t<
2696 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
2697 const_iterator find(KeyType && key) const
2698 {
2699 auto result = cend();
2700
2701 if (is_object())
2702 {
2703 result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
2704 }
2705
2706 return result;
2707 }
2708
2709
2710
2711 size_type count(const typename object_t::key_type& key) const
2712 {
2713
2714 return is_object() ? m_data.m_value.object->count(key) : 0;
2715 }
2716
2717
2718
2719 template<class KeyType, detail::enable_if_t<
2720 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
2721 size_type count(KeyType && key) const
2722 {
2723
2724 return is_object() ? m_data.m_value.object->count(std::forward<KeyType>(key)) : 0;
2725 }
2726
2727
2728
2729 bool contains(const typename object_t::key_type& key) const
2730 {
2731 return is_object() && m_data.m_value.object->find(key) != m_data.m_value.object->end();
2732 }
2733
2734
2735
2736 template<class KeyType, detail::enable_if_t<
2737 detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
2738 bool contains(KeyType && key) const
2739 {
2740 return is_object() && m_data.m_value.object->find(std::forward<KeyType>(key)) != m_data.m_value.object->end();
2741 }
2742
2743
2744
2745 bool contains(const json_pointer& ptr) const
2746 {
2747 return ptr.contains(this);
2748 }
2749
2750 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
2751 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>)
2752 bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr) const
2753 {
2754 return ptr.contains(this);
2755 }
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768 iterator begin() noexcept
2769 {
2770 iterator result(this);
2771 result.set_begin();
2772 return result;
2773 }
2774
2775
2776
2777 const_iterator begin() const noexcept
2778 {
2779 return cbegin();
2780 }
2781
2782
2783
2784 const_iterator cbegin() const noexcept
2785 {
2786 const_iterator result(this);
2787 result.set_begin();
2788 return result;
2789 }
2790
2791
2792
2793 iterator end() noexcept
2794 {
2795 iterator result(this);
2796 result.set_end();
2797 return result;
2798 }
2799
2800
2801
2802 const_iterator end() const noexcept
2803 {
2804 return cend();
2805 }
2806
2807
2808
2809 const_iterator cend() const noexcept
2810 {
2811 const_iterator result(this);
2812 result.set_end();
2813 return result;
2814 }
2815
2816
2817
2818 reverse_iterator rbegin() noexcept
2819 {
2820 return reverse_iterator(end());
2821 }
2822
2823
2824
2825 const_reverse_iterator rbegin() const noexcept
2826 {
2827 return crbegin();
2828 }
2829
2830
2831
2832 reverse_iterator rend() noexcept
2833 {
2834 return reverse_iterator(begin());
2835 }
2836
2837
2838
2839 const_reverse_iterator rend() const noexcept
2840 {
2841 return crend();
2842 }
2843
2844
2845
2846 const_reverse_iterator crbegin() const noexcept
2847 {
2848 return const_reverse_iterator(cend());
2849 }
2850
2851
2852
2853 const_reverse_iterator crend() const noexcept
2854 {
2855 return const_reverse_iterator(cbegin());
2856 }
2857
2858 public:
2859
2860
2861
2862
2863
2864 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
2865 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
2866 {
2867 return ref.items();
2868 }
2869
2870
2871
2872
2873
2874
2875 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
2876 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
2877 {
2878 return ref.items();
2879 }
2880
2881
2882
2883 iteration_proxy<iterator> items() noexcept
2884 {
2885 return iteration_proxy<iterator>(*this);
2886 }
2887
2888
2889
2890 iteration_proxy<const_iterator> items() const noexcept
2891 {
2892 return iteration_proxy<const_iterator>(*this);
2893 }
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906 bool empty() const noexcept
2907 {
2908 switch (m_data.m_type)
2909 {
2910 case value_t::null:
2911 {
2912
2913 return true;
2914 }
2915
2916 case value_t::array:
2917 {
2918
2919 return m_data.m_value.array->empty();
2920 }
2921
2922 case value_t::object:
2923 {
2924
2925 return m_data.m_value.object->empty();
2926 }
2927
2928 case value_t::string:
2929 case value_t::boolean:
2930 case value_t::number_integer:
2931 case value_t::number_unsigned:
2932 case value_t::number_float:
2933 case value_t::binary:
2934 case value_t::discarded:
2935 default:
2936 {
2937
2938 return false;
2939 }
2940 }
2941 }
2942
2943
2944
2945 size_type size() const noexcept
2946 {
2947 switch (m_data.m_type)
2948 {
2949 case value_t::null:
2950 {
2951
2952 return 0;
2953 }
2954
2955 case value_t::array:
2956 {
2957
2958 return m_data.m_value.array->size();
2959 }
2960
2961 case value_t::object:
2962 {
2963
2964 return m_data.m_value.object->size();
2965 }
2966
2967 case value_t::string:
2968 case value_t::boolean:
2969 case value_t::number_integer:
2970 case value_t::number_unsigned:
2971 case value_t::number_float:
2972 case value_t::binary:
2973 case value_t::discarded:
2974 default:
2975 {
2976
2977 return 1;
2978 }
2979 }
2980 }
2981
2982
2983
2984 size_type max_size() const noexcept
2985 {
2986 switch (m_data.m_type)
2987 {
2988 case value_t::array:
2989 {
2990
2991 return m_data.m_value.array->max_size();
2992 }
2993
2994 case value_t::object:
2995 {
2996
2997 return m_data.m_value.object->max_size();
2998 }
2999
3000 case value_t::null:
3001 case value_t::string:
3002 case value_t::boolean:
3003 case value_t::number_integer:
3004 case value_t::number_unsigned:
3005 case value_t::number_float:
3006 case value_t::binary:
3007 case value_t::discarded:
3008 default:
3009 {
3010
3011 return size();
3012 }
3013 }
3014 }
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027 void clear() noexcept
3028 {
3029 switch (m_data.m_type)
3030 {
3031 case value_t::number_integer:
3032 {
3033 m_data.m_value.number_integer = 0;
3034 break;
3035 }
3036
3037 case value_t::number_unsigned:
3038 {
3039 m_data.m_value.number_unsigned = 0;
3040 break;
3041 }
3042
3043 case value_t::number_float:
3044 {
3045 m_data.m_value.number_float = 0.0;
3046 break;
3047 }
3048
3049 case value_t::boolean:
3050 {
3051 m_data.m_value.boolean = false;
3052 break;
3053 }
3054
3055 case value_t::string:
3056 {
3057 m_data.m_value.string->clear();
3058 break;
3059 }
3060
3061 case value_t::binary:
3062 {
3063 m_data.m_value.binary->clear();
3064 break;
3065 }
3066
3067 case value_t::array:
3068 {
3069 m_data.m_value.array->clear();
3070 break;
3071 }
3072
3073 case value_t::object:
3074 {
3075 m_data.m_value.object->clear();
3076 break;
3077 }
3078
3079 case value_t::null:
3080 case value_t::discarded:
3081 default:
3082 break;
3083 }
3084 }
3085
3086
3087
3088 void push_back(basic_json&& val)
3089 {
3090
3091 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
3092 {
3093 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
3094 }
3095
3096
3097 if (is_null())
3098 {
3099 m_data.m_type = value_t::array;
3100 m_data.m_value = value_t::array;
3101 assert_invariant();
3102 }
3103
3104
3105 const auto old_capacity = m_data.m_value.array->capacity();
3106 m_data.m_value.array->push_back(std::move(val));
3107 set_parent(m_data.m_value.array->back(), old_capacity);
3108
3109 }
3110
3111
3112
3113 reference operator+=(basic_json&& val)
3114 {
3115 push_back(std::move(val));
3116 return *this;
3117 }
3118
3119
3120
3121 void push_back(const basic_json& val)
3122 {
3123
3124 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
3125 {
3126 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
3127 }
3128
3129
3130 if (is_null())
3131 {
3132 m_data.m_type = value_t::array;
3133 m_data.m_value = value_t::array;
3134 assert_invariant();
3135 }
3136
3137
3138 const auto old_capacity = m_data.m_value.array->capacity();
3139 m_data.m_value.array->push_back(val);
3140 set_parent(m_data.m_value.array->back(), old_capacity);
3141 }
3142
3143
3144
3145 reference operator+=(const basic_json& val)
3146 {
3147 push_back(val);
3148 return *this;
3149 }
3150
3151
3152
3153 void push_back(const typename object_t::value_type& val)
3154 {
3155
3156 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
3157 {
3158 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
3159 }
3160
3161
3162 if (is_null())
3163 {
3164 m_data.m_type = value_t::object;
3165 m_data.m_value = value_t::object;
3166 assert_invariant();
3167 }
3168
3169
3170 auto res = m_data.m_value.object->insert(val);
3171 set_parent(res.first->second);
3172 }
3173
3174
3175
3176 reference operator+=(const typename object_t::value_type& val)
3177 {
3178 push_back(val);
3179 return *this;
3180 }
3181
3182
3183
3184 void push_back(initializer_list_t init)
3185 {
3186 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
3187 {
3188 basic_json&& key = init.begin()->moved_or_copied();
3189 push_back(typename object_t::value_type(
3190 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
3191 }
3192 else
3193 {
3194 push_back(basic_json(init));
3195 }
3196 }
3197
3198
3199
3200 reference operator+=(initializer_list_t init)
3201 {
3202 push_back(init);
3203 return *this;
3204 }
3205
3206
3207
3208 template<class... Args>
3209 reference emplace_back(Args&& ... args)
3210 {
3211
3212 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
3213 {
3214 JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
3215 }
3216
3217
3218 if (is_null())
3219 {
3220 m_data.m_type = value_t::array;
3221 m_data.m_value = value_t::array;
3222 assert_invariant();
3223 }
3224
3225
3226 const auto old_capacity = m_data.m_value.array->capacity();
3227 m_data.m_value.array->emplace_back(std::forward<Args>(args)...);
3228 return set_parent(m_data.m_value.array->back(), old_capacity);
3229 }
3230
3231
3232
3233 template<class... Args>
3234 std::pair<iterator, bool> emplace(Args&& ... args)
3235 {
3236
3237 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
3238 {
3239 JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
3240 }
3241
3242
3243 if (is_null())
3244 {
3245 m_data.m_type = value_t::object;
3246 m_data.m_value = value_t::object;
3247 assert_invariant();
3248 }
3249
3250
3251 auto res = m_data.m_value.object->emplace(std::forward<Args>(args)...);
3252 set_parent(res.first->second);
3253
3254
3255 auto it = begin();
3256 it.m_it.object_iterator = res.first;
3257
3258
3259 return {it, res.second};
3260 }
3261
3262
3263
3264
3265 template<typename... Args>
3266 iterator insert_iterator(const_iterator pos, Args&& ... args)
3267 {
3268 iterator result(this);
3269 JSON_ASSERT(m_data.m_value.array != nullptr);
3270
3271 auto insert_pos = std::distance(m_data.m_value.array->begin(), pos.m_it.array_iterator);
3272 m_data.m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
3273 result.m_it.array_iterator = m_data.m_value.array->begin() + insert_pos;
3274
3275
3276
3277
3278
3279 set_parents();
3280 return result;
3281 }
3282
3283
3284
3285 iterator insert(const_iterator pos, const basic_json& val)
3286 {
3287
3288 if (JSON_HEDLEY_LIKELY(is_array()))
3289 {
3290
3291 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
3292 {
3293 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
3294 }
3295
3296
3297 return insert_iterator(pos, val);
3298 }
3299
3300 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
3301 }
3302
3303
3304
3305 iterator insert(const_iterator pos, basic_json&& val)
3306 {
3307 return insert(pos, val);
3308 }
3309
3310
3311
3312 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
3313 {
3314
3315 if (JSON_HEDLEY_LIKELY(is_array()))
3316 {
3317
3318 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
3319 {
3320 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
3321 }
3322
3323
3324 return insert_iterator(pos, cnt, val);
3325 }
3326
3327 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
3328 }
3329
3330
3331
3332 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
3333 {
3334
3335 if (JSON_HEDLEY_UNLIKELY(!is_array()))
3336 {
3337 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
3338 }
3339
3340
3341 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
3342 {
3343 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
3344 }
3345
3346
3347 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
3348 {
3349 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
3350 }
3351
3352 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
3353 {
3354 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
3355 }
3356
3357
3358 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
3359 }
3360
3361
3362
3363 iterator insert(const_iterator pos, initializer_list_t ilist)
3364 {
3365
3366 if (JSON_HEDLEY_UNLIKELY(!is_array()))
3367 {
3368 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
3369 }
3370
3371
3372 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
3373 {
3374 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
3375 }
3376
3377
3378 return insert_iterator(pos, ilist.begin(), ilist.end());
3379 }
3380
3381
3382
3383 void insert(const_iterator first, const_iterator last)
3384 {
3385
3386 if (JSON_HEDLEY_UNLIKELY(!is_object()))
3387 {
3388 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
3389 }
3390
3391
3392 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
3393 {
3394 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
3395 }
3396
3397
3398 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
3399 {
3400 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
3401 }
3402
3403 m_data.m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
3404 }
3405
3406
3407
3408 void update(const_reference j, bool merge_objects = false)
3409 {
3410 update(j.begin(), j.end(), merge_objects);
3411 }
3412
3413
3414
3415 void update(const_iterator first, const_iterator last, bool merge_objects = false)
3416 {
3417
3418 if (is_null())
3419 {
3420 m_data.m_type = value_t::object;
3421 m_data.m_value.object = create<object_t>();
3422 assert_invariant();
3423 }
3424
3425 if (JSON_HEDLEY_UNLIKELY(!is_object()))
3426 {
3427 JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
3428 }
3429
3430
3431 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
3432 {
3433 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
3434 }
3435
3436
3437 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
3438 {
3439 JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
3440 }
3441
3442 for (auto it = first; it != last; ++it)
3443 {
3444 if (merge_objects && it.value().is_object())
3445 {
3446 auto it2 = m_data.m_value.object->find(it.key());
3447 if (it2 != m_data.m_value.object->end())
3448 {
3449 it2->second.update(it.value(), true);
3450 continue;
3451 }
3452 }
3453 m_data.m_value.object->operator[](it.key()) = it.value();
3454 #if JSON_DIAGNOSTICS
3455 m_data.m_value.object->operator[](it.key()).m_parent = this;
3456 #endif
3457 }
3458 }
3459
3460
3461
3462 void swap(reference other) noexcept (
3463 std::is_nothrow_move_constructible<value_t>::value&&
3464 std::is_nothrow_move_assignable<value_t>::value&&
3465 std::is_nothrow_move_constructible<json_value>::value&&
3466 std::is_nothrow_move_assignable<json_value>::value
3467 )
3468 {
3469 std::swap(m_data.m_type, other.m_data.m_type);
3470 std::swap(m_data.m_value, other.m_data.m_value);
3471
3472 set_parents();
3473 other.set_parents();
3474 assert_invariant();
3475 }
3476
3477
3478
3479 friend void swap(reference left, reference right) noexcept (
3480 std::is_nothrow_move_constructible<value_t>::value&&
3481 std::is_nothrow_move_assignable<value_t>::value&&
3482 std::is_nothrow_move_constructible<json_value>::value&&
3483 std::is_nothrow_move_assignable<json_value>::value
3484 )
3485 {
3486 left.swap(right);
3487 }
3488
3489
3490
3491 void swap(array_t& other)
3492 {
3493
3494 if (JSON_HEDLEY_LIKELY(is_array()))
3495 {
3496 using std::swap;
3497 swap(*(m_data.m_value.array), other);
3498 }
3499 else
3500 {
3501 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(array_t&) with ", type_name()), this));
3502 }
3503 }
3504
3505
3506
3507 void swap(object_t& other)
3508 {
3509
3510 if (JSON_HEDLEY_LIKELY(is_object()))
3511 {
3512 using std::swap;
3513 swap(*(m_data.m_value.object), other);
3514 }
3515 else
3516 {
3517 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(object_t&) with ", type_name()), this));
3518 }
3519 }
3520
3521
3522
3523 void swap(string_t& other)
3524 {
3525
3526 if (JSON_HEDLEY_LIKELY(is_string()))
3527 {
3528 using std::swap;
3529 swap(*(m_data.m_value.string), other);
3530 }
3531 else
3532 {
3533 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(string_t&) with ", type_name()), this));
3534 }
3535 }
3536
3537
3538
3539 void swap(binary_t& other)
3540 {
3541
3542 if (JSON_HEDLEY_LIKELY(is_binary()))
3543 {
3544 using std::swap;
3545 swap(*(m_data.m_value.binary), other);
3546 }
3547 else
3548 {
3549 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t&) with ", type_name()), this));
3550 }
3551 }
3552
3553
3554
3555 void swap(typename binary_t::container_type& other)
3556 {
3557
3558 if (JSON_HEDLEY_LIKELY(is_binary()))
3559 {
3560 using std::swap;
3561 swap(*(m_data.m_value.binary), other);
3562 }
3563 else
3564 {
3565 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t::container_type&) with ", type_name()), this));
3566 }
3567 }
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580 #define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
3581 const auto lhs_type = lhs.type(); \
3582 const auto rhs_type = rhs.type(); \
3583 \
3584 if (lhs_type == rhs_type) \
3585 { \
3586 switch (lhs_type) \
3587 { \
3588 case value_t::array: \
3589 return (*lhs.m_data.m_value.array) op (*rhs.m_data.m_value.array); \
3590 \
3591 case value_t::object: \
3592 return (*lhs.m_data.m_value.object) op (*rhs.m_data.m_value.object); \
3593 \
3594 case value_t::null: \
3595 return (null_result); \
3596 \
3597 case value_t::string: \
3598 return (*lhs.m_data.m_value.string) op (*rhs.m_data.m_value.string); \
3599 \
3600 case value_t::boolean: \
3601 return (lhs.m_data.m_value.boolean) op (rhs.m_data.m_value.boolean); \
3602 \
3603 case value_t::number_integer: \
3604 return (lhs.m_data.m_value.number_integer) op (rhs.m_data.m_value.number_integer); \
3605 \
3606 case value_t::number_unsigned: \
3607 return (lhs.m_data.m_value.number_unsigned) op (rhs.m_data.m_value.number_unsigned); \
3608 \
3609 case value_t::number_float: \
3610 return (lhs.m_data.m_value.number_float) op (rhs.m_data.m_value.number_float); \
3611 \
3612 case value_t::binary: \
3613 return (*lhs.m_data.m_value.binary) op (*rhs.m_data.m_value.binary); \
3614 \
3615 case value_t::discarded: \
3616 default: \
3617 return (unordered_result); \
3618 } \
3619 } \
3620 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \
3621 { \
3622 return static_cast<number_float_t>(lhs.m_data.m_value.number_integer) op rhs.m_data.m_value.number_float; \
3623 } \
3624 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \
3625 { \
3626 return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_integer); \
3627 } \
3628 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \
3629 { \
3630 return static_cast<number_float_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_float; \
3631 } \
3632 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \
3633 { \
3634 return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_unsigned); \
3635 } \
3636 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
3637 { \
3638 return static_cast<number_integer_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_integer; \
3639 } \
3640 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
3641 { \
3642 return lhs.m_data.m_value.number_integer op static_cast<number_integer_t>(rhs.m_data.m_value.number_unsigned); \
3643 } \
3644 else if(compares_unordered(lhs, rhs))\
3645 {\
3646 return (unordered_result);\
3647 }\
3648 \
3649 return (default_result);
3650
3651 JSON_PRIVATE_UNLESS_TESTED:
3652
3653
3654
3655
3656
3657 static bool compares_unordered(const_reference lhs, const_reference rhs, bool inverse = false) noexcept
3658 {
3659 if ((lhs.is_number_float() && std::isnan(lhs.m_data.m_value.number_float) && rhs.is_number())
3660 || (rhs.is_number_float() && std::isnan(rhs.m_data.m_value.number_float) && lhs.is_number()))
3661 {
3662 return true;
3663 }
3664 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
3665 return (lhs.is_discarded() || rhs.is_discarded()) && !inverse;
3666 #else
3667 static_cast<void>(inverse);
3668 return lhs.is_discarded() || rhs.is_discarded();
3669 #endif
3670 }
3671
3672 private:
3673 bool compares_unordered(const_reference rhs, bool inverse = false) const noexcept
3674 {
3675 return compares_unordered(*this, rhs, inverse);
3676 }
3677
3678 public:
3679 #if JSON_HAS_THREE_WAY_COMPARISON
3680
3681
3682 bool operator==(const_reference rhs) const noexcept
3683 {
3684 #ifdef __GNUC__
3685 #pragma GCC diagnostic push
3686 #pragma GCC diagnostic ignored "-Wfloat-equal"
3687 #endif
3688 const_reference lhs = *this;
3689 JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
3690 #ifdef __GNUC__
3691 #pragma GCC diagnostic pop
3692 #endif
3693 }
3694
3695
3696
3697 template<typename ScalarType>
3698 requires std::is_scalar_v<ScalarType>
3699 bool operator==(ScalarType rhs) const noexcept
3700 {
3701 return *this == basic_json(rhs);
3702 }
3703
3704
3705
3706 bool operator!=(const_reference rhs) const noexcept
3707 {
3708 if (compares_unordered(rhs, true))
3709 {
3710 return false;
3711 }
3712 return !operator==(rhs);
3713 }
3714
3715
3716
3717 std::partial_ordering operator<=>(const_reference rhs) const noexcept
3718 {
3719 const_reference lhs = *this;
3720
3721
3722 JSON_IMPLEMENT_OPERATOR(<=>,
3723 std::partial_ordering::equivalent,
3724 std::partial_ordering::unordered,
3725 lhs_type <=> rhs_type)
3726 }
3727
3728
3729
3730 template<typename ScalarType>
3731 requires std::is_scalar_v<ScalarType>
3732 std::partial_ordering operator<=>(ScalarType rhs) const noexcept
3733 {
3734 return *this <=> basic_json(rhs);
3735 }
3736
3737 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
3738
3739
3740
3741
3742
3743 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON)
3744 bool operator<=(const_reference rhs) const noexcept
3745 {
3746 if (compares_unordered(rhs, true))
3747 {
3748 return false;
3749 }
3750 return !(rhs < *this);
3751 }
3752
3753
3754
3755 template<typename ScalarType>
3756 requires std::is_scalar_v<ScalarType>
3757 bool operator<=(ScalarType rhs) const noexcept
3758 {
3759 return *this <= basic_json(rhs);
3760 }
3761
3762
3763
3764 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON)
3765 bool operator>=(const_reference rhs) const noexcept
3766 {
3767 if (compares_unordered(rhs, true))
3768 {
3769 return false;
3770 }
3771 return !(*this < rhs);
3772 }
3773
3774
3775
3776 template<typename ScalarType>
3777 requires std::is_scalar_v<ScalarType>
3778 bool operator>=(ScalarType rhs) const noexcept
3779 {
3780 return *this >= basic_json(rhs);
3781 }
3782 #endif
3783 #else
3784
3785
3786 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
3787 {
3788 #ifdef __GNUC__
3789 #pragma GCC diagnostic push
3790 #pragma GCC diagnostic ignored "-Wfloat-equal"
3791 #endif
3792 JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
3793 #ifdef __GNUC__
3794 #pragma GCC diagnostic pop
3795 #endif
3796 }
3797
3798
3799
3800 template<typename ScalarType, typename std::enable_if<
3801 std::is_scalar<ScalarType>::value, int>::type = 0>
3802 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
3803 {
3804 return lhs == basic_json(rhs);
3805 }
3806
3807
3808
3809 template<typename ScalarType, typename std::enable_if<
3810 std::is_scalar<ScalarType>::value, int>::type = 0>
3811 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
3812 {
3813 return basic_json(lhs) == rhs;
3814 }
3815
3816
3817
3818 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
3819 {
3820 if (compares_unordered(lhs, rhs, true))
3821 {
3822 return false;
3823 }
3824 return !(lhs == rhs);
3825 }
3826
3827
3828
3829 template<typename ScalarType, typename std::enable_if<
3830 std::is_scalar<ScalarType>::value, int>::type = 0>
3831 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
3832 {
3833 return lhs != basic_json(rhs);
3834 }
3835
3836
3837
3838 template<typename ScalarType, typename std::enable_if<
3839 std::is_scalar<ScalarType>::value, int>::type = 0>
3840 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
3841 {
3842 return basic_json(lhs) != rhs;
3843 }
3844
3845
3846
3847 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
3848 {
3849
3850
3851
3852 JSON_IMPLEMENT_OPERATOR( <, false, false, operator<(lhs_type, rhs_type))
3853 }
3854
3855
3856
3857 template<typename ScalarType, typename std::enable_if<
3858 std::is_scalar<ScalarType>::value, int>::type = 0>
3859 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
3860 {
3861 return lhs < basic_json(rhs);
3862 }
3863
3864
3865
3866 template<typename ScalarType, typename std::enable_if<
3867 std::is_scalar<ScalarType>::value, int>::type = 0>
3868 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
3869 {
3870 return basic_json(lhs) < rhs;
3871 }
3872
3873
3874
3875 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
3876 {
3877 if (compares_unordered(lhs, rhs, true))
3878 {
3879 return false;
3880 }
3881 return !(rhs < lhs);
3882 }
3883
3884
3885
3886 template<typename ScalarType, typename std::enable_if<
3887 std::is_scalar<ScalarType>::value, int>::type = 0>
3888 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
3889 {
3890 return lhs <= basic_json(rhs);
3891 }
3892
3893
3894
3895 template<typename ScalarType, typename std::enable_if<
3896 std::is_scalar<ScalarType>::value, int>::type = 0>
3897 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
3898 {
3899 return basic_json(lhs) <= rhs;
3900 }
3901
3902
3903
3904 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
3905 {
3906
3907 if (compares_unordered(lhs, rhs))
3908 {
3909 return false;
3910 }
3911 return !(lhs <= rhs);
3912 }
3913
3914
3915
3916 template<typename ScalarType, typename std::enable_if<
3917 std::is_scalar<ScalarType>::value, int>::type = 0>
3918 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
3919 {
3920 return lhs > basic_json(rhs);
3921 }
3922
3923
3924
3925 template<typename ScalarType, typename std::enable_if<
3926 std::is_scalar<ScalarType>::value, int>::type = 0>
3927 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
3928 {
3929 return basic_json(lhs) > rhs;
3930 }
3931
3932
3933
3934 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
3935 {
3936 if (compares_unordered(lhs, rhs, true))
3937 {
3938 return false;
3939 }
3940 return !(lhs < rhs);
3941 }
3942
3943
3944
3945 template<typename ScalarType, typename std::enable_if<
3946 std::is_scalar<ScalarType>::value, int>::type = 0>
3947 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
3948 {
3949 return lhs >= basic_json(rhs);
3950 }
3951
3952
3953
3954 template<typename ScalarType, typename std::enable_if<
3955 std::is_scalar<ScalarType>::value, int>::type = 0>
3956 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
3957 {
3958 return basic_json(lhs) >= rhs;
3959 }
3960 #endif
3961
3962 #undef JSON_IMPLEMENT_OPERATOR
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972 #ifndef JSON_NO_IO
3973
3974
3975 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
3976 {
3977
3978 const bool pretty_print = o.width() > 0;
3979 const auto indentation = pretty_print ? o.width() : 0;
3980
3981
3982 o.width(0);
3983
3984
3985 serializer s(detail::output_adapter<char>(o), o.fill());
3986 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
3987 return o;
3988 }
3989
3990
3991
3992
3993
3994
3995
3996 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
3997 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
3998 {
3999 return o << j;
4000 }
4001 #endif
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013 template<typename InputType>
4014 JSON_HEDLEY_WARN_UNUSED_RESULT
4015 static basic_json parse(InputType&& i,
4016 const parser_callback_t cb = nullptr,
4017 const bool allow_exceptions = true,
4018 const bool ignore_comments = false)
4019 {
4020 basic_json result;
4021 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
4022 return result;
4023 }
4024
4025
4026
4027 template<typename IteratorType>
4028 JSON_HEDLEY_WARN_UNUSED_RESULT
4029 static basic_json parse(IteratorType first,
4030 IteratorType last,
4031 const parser_callback_t cb = nullptr,
4032 const bool allow_exceptions = true,
4033 const bool ignore_comments = false)
4034 {
4035 basic_json result;
4036 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
4037 return result;
4038 }
4039
4040 JSON_HEDLEY_WARN_UNUSED_RESULT
4041 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
4042 static basic_json parse(detail::span_input_adapter&& i,
4043 const parser_callback_t cb = nullptr,
4044 const bool allow_exceptions = true,
4045 const bool ignore_comments = false)
4046 {
4047 basic_json result;
4048 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
4049 return result;
4050 }
4051
4052
4053
4054 template<typename InputType>
4055 static bool accept(InputType&& i,
4056 const bool ignore_comments = false)
4057 {
4058 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
4059 }
4060
4061
4062
4063 template<typename IteratorType>
4064 static bool accept(IteratorType first, IteratorType last,
4065 const bool ignore_comments = false)
4066 {
4067 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
4068 }
4069
4070 JSON_HEDLEY_WARN_UNUSED_RESULT
4071 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
4072 static bool accept(detail::span_input_adapter&& i,
4073 const bool ignore_comments = false)
4074 {
4075 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
4076 }
4077
4078
4079
4080 template <typename InputType, typename SAX>
4081 JSON_HEDLEY_NON_NULL(2)
4082 static bool sax_parse(InputType&& i, SAX* sax,
4083 input_format_t format = input_format_t::json,
4084 const bool strict = true,
4085 const bool ignore_comments = false)
4086 {
4087 auto ia = detail::input_adapter(std::forward<InputType>(i));
4088 return format == input_format_t::json
4089 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
4090 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
4091 }
4092
4093
4094
4095 template<class IteratorType, class SAX>
4096 JSON_HEDLEY_NON_NULL(3)
4097 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
4098 input_format_t format = input_format_t::json,
4099 const bool strict = true,
4100 const bool ignore_comments = false)
4101 {
4102 auto ia = detail::input_adapter(std::move(first), std::move(last));
4103 return format == input_format_t::json
4104 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
4105 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
4106 }
4107
4108
4109
4110
4111
4112
4113 template <typename SAX>
4114 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
4115 JSON_HEDLEY_NON_NULL(2)
4116 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
4117 input_format_t format = input_format_t::json,
4118 const bool strict = true,
4119 const bool ignore_comments = false)
4120 {
4121 auto ia = i.get();
4122 return format == input_format_t::json
4123
4124 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
4125
4126 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
4127 }
4128 #ifndef JSON_NO_IO
4129
4130
4131
4132
4133
4134
4135 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
4136 friend std::istream& operator<<(basic_json& j, std::istream& i)
4137 {
4138 return operator>>(i, j);
4139 }
4140
4141
4142
4143 friend std::istream& operator>>(std::istream& i, basic_json& j)
4144 {
4145 parser(detail::input_adapter(i)).parse(false, j);
4146 return i;
4147 }
4148 #endif
4149
4150
4151
4152
4153
4154
4155
4156
4157 JSON_HEDLEY_RETURNS_NON_NULL
4158 const char* type_name() const noexcept
4159 {
4160 switch (m_data.m_type)
4161 {
4162 case value_t::null:
4163 return "null";
4164 case value_t::object:
4165 return "object";
4166 case value_t::array:
4167 return "array";
4168 case value_t::string:
4169 return "string";
4170 case value_t::boolean:
4171 return "boolean";
4172 case value_t::binary:
4173 return "binary";
4174 case value_t::discarded:
4175 return "discarded";
4176 case value_t::number_integer:
4177 case value_t::number_unsigned:
4178 case value_t::number_float:
4179 default:
4180 return "number";
4181 }
4182 }
4183
4184 JSON_PRIVATE_UNLESS_TESTED:
4185
4186
4187
4188
4189 struct data
4190 {
4191
4192 value_t m_type = value_t::null;
4193
4194
4195 json_value m_value = {};
4196
4197 data(const value_t v)
4198 : m_type(v), m_value(v)
4199 {
4200 }
4201
4202 data(size_type cnt, const basic_json& val)
4203 : m_type(value_t::array)
4204 {
4205 m_value.array = create<array_t>(cnt, val);
4206 }
4207
4208 data() noexcept = default;
4209 data(data&&) noexcept = default;
4210 data(const data&) noexcept = delete;
4211 data& operator=(data&&) noexcept = delete;
4212 data& operator=(const data&) noexcept = delete;
4213
4214 ~data() noexcept
4215 {
4216 m_value.destroy(m_type);
4217 }
4218 };
4219
4220 data m_data = {};
4221
4222 #if JSON_DIAGNOSTICS
4223
4224 basic_json* m_parent = nullptr;
4225 #endif
4226
4227
4228
4229
4230
4231
4232
4233
4234 public:
4235
4236
4237 static std::vector<std::uint8_t> to_cbor(const basic_json& j)
4238 {
4239 std::vector<std::uint8_t> result;
4240 to_cbor(j, result);
4241 return result;
4242 }
4243
4244
4245
4246 static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o)
4247 {
4248 binary_writer<std::uint8_t>(o).write_cbor(j);
4249 }
4250
4251
4252
4253 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
4254 {
4255 binary_writer<char>(o).write_cbor(j);
4256 }
4257
4258
4259
4260 static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
4261 {
4262 std::vector<std::uint8_t> result;
4263 to_msgpack(j, result);
4264 return result;
4265 }
4266
4267
4268
4269 static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o)
4270 {
4271 binary_writer<std::uint8_t>(o).write_msgpack(j);
4272 }
4273
4274
4275
4276 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
4277 {
4278 binary_writer<char>(o).write_msgpack(j);
4279 }
4280
4281
4282
4283 static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
4284 const bool use_size = false,
4285 const bool use_type = false)
4286 {
4287 std::vector<std::uint8_t> result;
4288 to_ubjson(j, result, use_size, use_type);
4289 return result;
4290 }
4291
4292
4293
4294 static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,
4295 const bool use_size = false, const bool use_type = false)
4296 {
4297 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
4298 }
4299
4300
4301
4302 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
4303 const bool use_size = false, const bool use_type = false)
4304 {
4305 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
4306 }
4307
4308
4309
4310 static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
4311 const bool use_size = false,
4312 const bool use_type = false)
4313 {
4314 std::vector<std::uint8_t> result;
4315 to_bjdata(j, result, use_size, use_type);
4316 return result;
4317 }
4318
4319
4320
4321 static void to_bjdata(const basic_json& j, detail::output_adapter<std::uint8_t> o,
4322 const bool use_size = false, const bool use_type = false)
4323 {
4324 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true);
4325 }
4326
4327
4328
4329 static void to_bjdata(const basic_json& j, detail::output_adapter<char> o,
4330 const bool use_size = false, const bool use_type = false)
4331 {
4332 binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true);
4333 }
4334
4335
4336
4337 static std::vector<std::uint8_t> to_bson(const basic_json& j)
4338 {
4339 std::vector<std::uint8_t> result;
4340 to_bson(j, result);
4341 return result;
4342 }
4343
4344
4345
4346 static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o)
4347 {
4348 binary_writer<std::uint8_t>(o).write_bson(j);
4349 }
4350
4351
4352
4353 static void to_bson(const basic_json& j, detail::output_adapter<char> o)
4354 {
4355 binary_writer<char>(o).write_bson(j);
4356 }
4357
4358
4359
4360 template<typename InputType>
4361 JSON_HEDLEY_WARN_UNUSED_RESULT
4362 static basic_json from_cbor(InputType&& i,
4363 const bool strict = true,
4364 const bool allow_exceptions = true,
4365 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
4366 {
4367 basic_json result;
4368 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
4369 auto ia = detail::input_adapter(std::forward<InputType>(i));
4370 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
4371 return res ? result : basic_json(value_t::discarded);
4372 }
4373
4374
4375
4376 template<typename IteratorType>
4377 JSON_HEDLEY_WARN_UNUSED_RESULT
4378 static basic_json from_cbor(IteratorType first, IteratorType last,
4379 const bool strict = true,
4380 const bool allow_exceptions = true,
4381 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
4382 {
4383 basic_json result;
4384 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
4385 auto ia = detail::input_adapter(std::move(first), std::move(last));
4386 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
4387 return res ? result : basic_json(value_t::discarded);
4388 }
4389
4390 template<typename T>
4391 JSON_HEDLEY_WARN_UNUSED_RESULT
4392 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
4393 static basic_json from_cbor(const T* ptr, std::size_t len,
4394 const bool strict = true,
4395 const bool allow_exceptions = true,
4396 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
4397 {
4398 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
4399 }
4400
4401 JSON_HEDLEY_WARN_UNUSED_RESULT
4402 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
4403 static basic_json from_cbor(detail::span_input_adapter&& i,
4404 const bool strict = true,
4405 const bool allow_exceptions = true,
4406 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
4407 {
4408 basic_json result;
4409 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
4410 auto ia = i.get();
4411
4412 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
4413 return res ? result : basic_json(value_t::discarded);
4414 }
4415
4416
4417
4418 template<typename InputType>
4419 JSON_HEDLEY_WARN_UNUSED_RESULT
4420 static basic_json from_msgpack(InputType&& i,
4421 const bool strict = true,
4422 const bool allow_exceptions = true)
4423 {
4424 basic_json result;
4425 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
4426 auto ia = detail::input_adapter(std::forward<InputType>(i));
4427 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
4428 return res ? result : basic_json(value_t::discarded);
4429 }
4430
4431
4432
4433 template<typename IteratorType>
4434 JSON_HEDLEY_WARN_UNUSED_RESULT
4435 static basic_json from_msgpack(IteratorType first, IteratorType last,
4436 const bool strict = true,
4437 const bool allow_exceptions = true)
4438 {
4439 basic_json result;
4440 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
4441 auto ia = detail::input_adapter(std::move(first), std::move(last));
4442 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
4443 return res ? result : basic_json(value_t::discarded);
4444 }
4445
4446 template<typename T>
4447 JSON_HEDLEY_WARN_UNUSED_RESULT
4448 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
4449 static basic_json from_msgpack(const T* ptr, std::size_t len,
4450 const bool strict = true,
4451 const bool allow_exceptions = true)
4452 {
4453 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
4454 }
4455
4456 JSON_HEDLEY_WARN_UNUSED_RESULT
4457 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
4458 static basic_json from_msgpack(detail::span_input_adapter&& i,
4459 const bool strict = true,
4460 const bool allow_exceptions = true)
4461 {
4462 basic_json result;
4463 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
4464 auto ia = i.get();
4465
4466 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
4467 return res ? result : basic_json(value_t::discarded);
4468 }
4469
4470
4471
4472 template<typename InputType>
4473 JSON_HEDLEY_WARN_UNUSED_RESULT
4474 static basic_json from_ubjson(InputType&& i,
4475 const bool strict = true,
4476 const bool allow_exceptions = true)
4477 {
4478 basic_json result;
4479 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
4480 auto ia = detail::input_adapter(std::forward<InputType>(i));
4481 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
4482 return res ? result : basic_json(value_t::discarded);
4483 }
4484
4485
4486
4487 template<typename IteratorType>
4488 JSON_HEDLEY_WARN_UNUSED_RESULT
4489 static basic_json from_ubjson(IteratorType first, IteratorType last,
4490 const bool strict = true,
4491 const bool allow_exceptions = true)
4492 {
4493 basic_json result;
4494 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
4495 auto ia = detail::input_adapter(std::move(first), std::move(last));
4496 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
4497 return res ? result : basic_json(value_t::discarded);
4498 }
4499
4500 template<typename T>
4501 JSON_HEDLEY_WARN_UNUSED_RESULT
4502 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
4503 static basic_json from_ubjson(const T* ptr, std::size_t len,
4504 const bool strict = true,
4505 const bool allow_exceptions = true)
4506 {
4507 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
4508 }
4509
4510 JSON_HEDLEY_WARN_UNUSED_RESULT
4511 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
4512 static basic_json from_ubjson(detail::span_input_adapter&& i,
4513 const bool strict = true,
4514 const bool allow_exceptions = true)
4515 {
4516 basic_json result;
4517 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
4518 auto ia = i.get();
4519
4520 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
4521 return res ? result : basic_json(value_t::discarded);
4522 }
4523
4524
4525
4526 template<typename InputType>
4527 JSON_HEDLEY_WARN_UNUSED_RESULT
4528 static basic_json from_bjdata(InputType&& i,
4529 const bool strict = true,
4530 const bool allow_exceptions = true)
4531 {
4532 basic_json result;
4533 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
4534 auto ia = detail::input_adapter(std::forward<InputType>(i));
4535 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
4536 return res ? result : basic_json(value_t::discarded);
4537 }
4538
4539
4540
4541 template<typename IteratorType>
4542 JSON_HEDLEY_WARN_UNUSED_RESULT
4543 static basic_json from_bjdata(IteratorType first, IteratorType last,
4544 const bool strict = true,
4545 const bool allow_exceptions = true)
4546 {
4547 basic_json result;
4548 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
4549 auto ia = detail::input_adapter(std::move(first), std::move(last));
4550 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
4551 return res ? result : basic_json(value_t::discarded);
4552 }
4553
4554
4555
4556 template<typename InputType>
4557 JSON_HEDLEY_WARN_UNUSED_RESULT
4558 static basic_json from_bson(InputType&& i,
4559 const bool strict = true,
4560 const bool allow_exceptions = true)
4561 {
4562 basic_json result;
4563 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
4564 auto ia = detail::input_adapter(std::forward<InputType>(i));
4565 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
4566 return res ? result : basic_json(value_t::discarded);
4567 }
4568
4569
4570
4571 template<typename IteratorType>
4572 JSON_HEDLEY_WARN_UNUSED_RESULT
4573 static basic_json from_bson(IteratorType first, IteratorType last,
4574 const bool strict = true,
4575 const bool allow_exceptions = true)
4576 {
4577 basic_json result;
4578 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
4579 auto ia = detail::input_adapter(std::move(first), std::move(last));
4580 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
4581 return res ? result : basic_json(value_t::discarded);
4582 }
4583
4584 template<typename T>
4585 JSON_HEDLEY_WARN_UNUSED_RESULT
4586 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
4587 static basic_json from_bson(const T* ptr, std::size_t len,
4588 const bool strict = true,
4589 const bool allow_exceptions = true)
4590 {
4591 return from_bson(ptr, ptr + len, strict, allow_exceptions);
4592 }
4593
4594 JSON_HEDLEY_WARN_UNUSED_RESULT
4595 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
4596 static basic_json from_bson(detail::span_input_adapter&& i,
4597 const bool strict = true,
4598 const bool allow_exceptions = true)
4599 {
4600 basic_json result;
4601 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
4602 auto ia = i.get();
4603
4604 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
4605 return res ? result : basic_json(value_t::discarded);
4606 }
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618 reference operator[](const json_pointer& ptr)
4619 {
4620 return ptr.get_unchecked(this);
4621 }
4622
4623 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
4624 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>)
4625 reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
4626 {
4627 return ptr.get_unchecked(this);
4628 }
4629
4630
4631
4632 const_reference operator[](const json_pointer& ptr) const
4633 {
4634 return ptr.get_unchecked(this);
4635 }
4636
4637 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
4638 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>)
4639 const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
4640 {
4641 return ptr.get_unchecked(this);
4642 }
4643
4644
4645
4646 reference at(const json_pointer& ptr)
4647 {
4648 return ptr.get_checked(this);
4649 }
4650
4651 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
4652 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>)
4653 reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
4654 {
4655 return ptr.get_checked(this);
4656 }
4657
4658
4659
4660 const_reference at(const json_pointer& ptr) const
4661 {
4662 return ptr.get_checked(this);
4663 }
4664
4665 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
4666 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>)
4667 const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
4668 {
4669 return ptr.get_checked(this);
4670 }
4671
4672
4673
4674 basic_json flatten() const
4675 {
4676 basic_json result(value_t::object);
4677 json_pointer::flatten("", *this, result);
4678 return result;
4679 }
4680
4681
4682
4683 basic_json unflatten() const
4684 {
4685 return json_pointer::unflatten(*this);
4686 }
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699 void patch_inplace(const basic_json& json_patch)
4700 {
4701 basic_json& result = *this;
4702
4703 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
4704
4705 const auto get_op = [](const std::string & op)
4706 {
4707 if (op == "add")
4708 {
4709 return patch_operations::add;
4710 }
4711 if (op == "remove")
4712 {
4713 return patch_operations::remove;
4714 }
4715 if (op == "replace")
4716 {
4717 return patch_operations::replace;
4718 }
4719 if (op == "move")
4720 {
4721 return patch_operations::move;
4722 }
4723 if (op == "copy")
4724 {
4725 return patch_operations::copy;
4726 }
4727 if (op == "test")
4728 {
4729 return patch_operations::test;
4730 }
4731
4732 return patch_operations::invalid;
4733 };
4734
4735
4736 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
4737 {
4738
4739 if (ptr.empty())
4740 {
4741 result = val;
4742 return;
4743 }
4744
4745
4746 json_pointer const top_pointer = ptr.top();
4747 if (top_pointer != ptr)
4748 {
4749 result.at(top_pointer);
4750 }
4751
4752
4753 const auto last_path = ptr.back();
4754 ptr.pop_back();
4755
4756 basic_json& parent = result.at(ptr);
4757
4758 switch (parent.m_data.m_type)
4759 {
4760 case value_t::null:
4761 case value_t::object:
4762 {
4763
4764 parent[last_path] = val;
4765 break;
4766 }
4767
4768 case value_t::array:
4769 {
4770 if (last_path == "-")
4771 {
4772
4773 parent.push_back(val);
4774 }
4775 else
4776 {
4777 const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
4778 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
4779 {
4780
4781 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
4782 }
4783
4784
4785 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
4786 }
4787 break;
4788 }
4789
4790
4791 case value_t::string:
4792 case value_t::boolean:
4793 case value_t::number_integer:
4794 case value_t::number_unsigned:
4795 case value_t::number_float:
4796 case value_t::binary:
4797 case value_t::discarded:
4798 default:
4799 JSON_ASSERT(false);
4800 }
4801 };
4802
4803
4804 const auto operation_remove = [this, & result](json_pointer & ptr)
4805 {
4806
4807 const auto last_path = ptr.back();
4808 ptr.pop_back();
4809 basic_json& parent = result.at(ptr);
4810
4811
4812 if (parent.is_object())
4813 {
4814
4815 auto it = parent.find(last_path);
4816 if (JSON_HEDLEY_LIKELY(it != parent.end()))
4817 {
4818 parent.erase(it);
4819 }
4820 else
4821 {
4822 JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
4823 }
4824 }
4825 else if (parent.is_array())
4826 {
4827
4828 parent.erase(json_pointer::template array_index<basic_json_t>(last_path));
4829 }
4830 };
4831
4832
4833 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
4834 {
4835 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
4836 }
4837
4838
4839 for (const auto& val : json_patch)
4840 {
4841
4842 const auto get_value = [&val](const std::string & op,
4843 const std::string & member,
4844 bool string_type) -> basic_json &
4845 {
4846
4847 auto it = val.m_data.m_value.object->find(member);
4848
4849
4850 const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\'');
4851
4852
4853 if (JSON_HEDLEY_UNLIKELY(it == val.m_data.m_value.object->end()))
4854 {
4855
4856 JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
4857 }
4858
4859
4860 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
4861 {
4862
4863 JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
4864 }
4865
4866
4867 return it->second;
4868 };
4869
4870
4871 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
4872 {
4873 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
4874 }
4875
4876
4877 const auto op = get_value("op", "op", true).template get<std::string>();
4878 const auto path = get_value(op, "path", true).template get<std::string>();
4879 json_pointer ptr(path);
4880
4881 switch (get_op(op))
4882 {
4883 case patch_operations::add:
4884 {
4885 operation_add(ptr, get_value("add", "value", false));
4886 break;
4887 }
4888
4889 case patch_operations::remove:
4890 {
4891 operation_remove(ptr);
4892 break;
4893 }
4894
4895 case patch_operations::replace:
4896 {
4897
4898 result.at(ptr) = get_value("replace", "value", false);
4899 break;
4900 }
4901
4902 case patch_operations::move:
4903 {
4904 const auto from_path = get_value("move", "from", true).template get<std::string>();
4905 json_pointer from_ptr(from_path);
4906
4907
4908 basic_json const v = result.at(from_ptr);
4909
4910
4911
4912
4913
4914 operation_remove(from_ptr);
4915 operation_add(ptr, v);
4916 break;
4917 }
4918
4919 case patch_operations::copy:
4920 {
4921 const auto from_path = get_value("copy", "from", true).template get<std::string>();
4922 const json_pointer from_ptr(from_path);
4923
4924
4925 basic_json const v = result.at(from_ptr);
4926
4927
4928
4929
4930 operation_add(ptr, v);
4931 break;
4932 }
4933
4934 case patch_operations::test:
4935 {
4936 bool success = false;
4937 JSON_TRY
4938 {
4939
4940
4941 success = (result.at(ptr) == get_value("test", "value", false));
4942 }
4943 JSON_INTERNAL_CATCH (out_of_range&)
4944 {
4945
4946 }
4947
4948
4949 if (JSON_HEDLEY_UNLIKELY(!success))
4950 {
4951 JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
4952 }
4953
4954 break;
4955 }
4956
4957 case patch_operations::invalid:
4958 default:
4959 {
4960
4961
4962 JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
4963 }
4964 }
4965 }
4966 }
4967
4968
4969
4970 basic_json patch(const basic_json& json_patch) const
4971 {
4972 basic_json result = *this;
4973 result.patch_inplace(json_patch);
4974 return result;
4975 }
4976
4977
4978
4979 JSON_HEDLEY_WARN_UNUSED_RESULT
4980 static basic_json diff(const basic_json& source, const basic_json& target,
4981 const std::string& path = "")
4982 {
4983
4984 basic_json result(value_t::array);
4985
4986
4987 if (source == target)
4988 {
4989 return result;
4990 }
4991
4992 if (source.type() != target.type())
4993 {
4994
4995 result.push_back(
4996 {
4997 {"op", "replace"}, {"path", path}, {"value", target}
4998 });
4999 return result;
5000 }
5001
5002 switch (source.type())
5003 {
5004 case value_t::array:
5005 {
5006
5007 std::size_t i = 0;
5008 while (i < source.size() && i < target.size())
5009 {
5010
5011 auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
5012 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
5013 ++i;
5014 }
5015
5016
5017
5018
5019
5020 const auto end_index = static_cast<difference_type>(result.size());
5021 while (i < source.size())
5022 {
5023
5024
5025 result.insert(result.begin() + end_index, object(
5026 {
5027 {"op", "remove"},
5028 {"path", detail::concat(path, '/', std::to_string(i))}
5029 }));
5030 ++i;
5031 }
5032
5033
5034 while (i < target.size())
5035 {
5036 result.push_back(
5037 {
5038 {"op", "add"},
5039 {"path", detail::concat(path, "/-")},
5040 {"value", target[i]}
5041 });
5042 ++i;
5043 }
5044
5045 break;
5046 }
5047
5048 case value_t::object:
5049 {
5050
5051 for (auto it = source.cbegin(); it != source.cend(); ++it)
5052 {
5053
5054 const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
5055
5056 if (target.find(it.key()) != target.end())
5057 {
5058
5059 auto temp_diff = diff(it.value(), target[it.key()], path_key);
5060 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
5061 }
5062 else
5063 {
5064
5065 result.push_back(object(
5066 {
5067 {"op", "remove"}, {"path", path_key}
5068 }));
5069 }
5070 }
5071
5072
5073 for (auto it = target.cbegin(); it != target.cend(); ++it)
5074 {
5075 if (source.find(it.key()) == source.end())
5076 {
5077
5078 const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
5079 result.push_back(
5080 {
5081 {"op", "add"}, {"path", path_key},
5082 {"value", it.value()}
5083 });
5084 }
5085 }
5086
5087 break;
5088 }
5089
5090 case value_t::null:
5091 case value_t::string:
5092 case value_t::boolean:
5093 case value_t::number_integer:
5094 case value_t::number_unsigned:
5095 case value_t::number_float:
5096 case value_t::binary:
5097 case value_t::discarded:
5098 default:
5099 {
5100
5101 result.push_back(
5102 {
5103 {"op", "replace"}, {"path", path}, {"value", target}
5104 });
5105 break;
5106 }
5107 }
5108
5109 return result;
5110 }
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122 void merge_patch(const basic_json& apply_patch)
5123 {
5124 if (apply_patch.is_object())
5125 {
5126 if (!is_object())
5127 {
5128 *this = object();
5129 }
5130 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
5131 {
5132 if (it.value().is_null())
5133 {
5134 erase(it.key());
5135 }
5136 else
5137 {
5138 operator[](it.key()).merge_patch(it.value());
5139 }
5140 }
5141 }
5142 else
5143 {
5144 *this = apply_patch;
5145 }
5146 }
5147
5148
5149 };
5150
5151
5152
5153 NLOHMANN_BASIC_JSON_TPL_DECLARATION
5154 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
5155 {
5156 return j.dump();
5157 }
5158
5159 inline namespace literals
5160 {
5161 inline namespace json_literals
5162 {
5163
5164
5165
5166 JSON_HEDLEY_NON_NULL(1)
5167 #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
5168 inline nlohmann::json operator ""_json(const char* s, std::size_t n)
5169 #else
5170 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
5171 #endif
5172 {
5173 return nlohmann::json::parse(s, s + n);
5174 }
5175
5176
5177
5178 JSON_HEDLEY_NON_NULL(1)
5179 #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
5180 inline nlohmann::json::json_pointer operator ""_json_pointer(const char* s, std::size_t n)
5181 #else
5182 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
5183 #endif
5184 {
5185 return nlohmann::json::json_pointer(std::string(s, n));
5186 }
5187
5188 }
5189 }
5190 NLOHMANN_JSON_NAMESPACE_END
5191
5192
5193
5194
5195
5196 namespace std
5197 {
5198
5199
5200
5201 NLOHMANN_BASIC_JSON_TPL_DECLARATION
5202 struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL>
5203 {
5204 std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
5205 {
5206 return nlohmann::detail::hash(j);
5207 }
5208 };
5209
5210
5211 template<>
5212 struct less< ::nlohmann::detail::value_t>
5213 {
5214
5215
5216
5217
5218 bool operator()(::nlohmann::detail::value_t lhs,
5219 ::nlohmann::detail::value_t rhs) const noexcept
5220 {
5221 #if JSON_HAS_THREE_WAY_COMPARISON
5222 return std::is_lt(lhs <=> rhs);
5223 #else
5224 return ::nlohmann::detail::operator<(lhs, rhs);
5225 #endif
5226 }
5227 };
5228
5229
5230 #ifndef JSON_HAS_CPP_20
5231
5232
5233
5234 NLOHMANN_BASIC_JSON_TPL_DECLARATION
5235 inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept(
5236 is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&&
5237 is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
5238 {
5239 j1.swap(j2);
5240 }
5241
5242 #endif
5243
5244 }
5245
5246 #if JSON_USE_GLOBAL_UDLS
5247 #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
5248 using nlohmann::literals::json_literals::operator ""_json;
5249 using nlohmann::literals::json_literals::operator ""_json_pointer;
5250 #else
5251 using nlohmann::literals::json_literals::operator "" _json;
5252 using nlohmann::literals::json_literals::operator "" _json_pointer;
5253 #endif
5254 #endif
5255
5256 #include <nlohmann/detail/macro_unscope.hpp>
5257
5258 #endif