1c5f01b2fSopenharmony_ci// __ _____ _____ _____ 2c5f01b2fSopenharmony_ci// __| | __| | | | JSON for Modern C++ 3c5f01b2fSopenharmony_ci// | | |__ | | | | | | version 3.11.2 4c5f01b2fSopenharmony_ci// |_____|_____|_____|_|___| https://github.com/nlohmann/json 5c5f01b2fSopenharmony_ci// 6c5f01b2fSopenharmony_ci// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me> 7c5f01b2fSopenharmony_ci// SPDX-License-Identifier: MIT 8c5f01b2fSopenharmony_ci 9c5f01b2fSopenharmony_ci/****************************************************************************\ 10c5f01b2fSopenharmony_ci * Note on documentation: The source files contain links to the online * 11c5f01b2fSopenharmony_ci * documentation of the public API at https://json.nlohmann.me. This URL * 12c5f01b2fSopenharmony_ci * contains the most recent documentation and should also be applicable to * 13c5f01b2fSopenharmony_ci * previous versions; documentation for deprecated functions is not * 14c5f01b2fSopenharmony_ci * removed, but marked deprecated. See "Generate documentation" section in * 15c5f01b2fSopenharmony_ci * file docs/README.md. * 16c5f01b2fSopenharmony_ci\****************************************************************************/ 17c5f01b2fSopenharmony_ci 18c5f01b2fSopenharmony_ci#ifndef INCLUDE_NLOHMANN_JSON_HPP_ 19c5f01b2fSopenharmony_ci#define INCLUDE_NLOHMANN_JSON_HPP_ 20c5f01b2fSopenharmony_ci 21c5f01b2fSopenharmony_ci#include <algorithm> // all_of, find, for_each 22c5f01b2fSopenharmony_ci#include <cstddef> // nullptr_t, ptrdiff_t, size_t 23c5f01b2fSopenharmony_ci#include <functional> // hash, less 24c5f01b2fSopenharmony_ci#include <initializer_list> // initializer_list 25c5f01b2fSopenharmony_ci#ifndef JSON_NO_IO 26c5f01b2fSopenharmony_ci #include <iosfwd> // istream, ostream 27c5f01b2fSopenharmony_ci#endif // JSON_NO_IO 28c5f01b2fSopenharmony_ci#include <iterator> // random_access_iterator_tag 29c5f01b2fSopenharmony_ci#include <memory> // unique_ptr 30c5f01b2fSopenharmony_ci#include <numeric> // accumulate 31c5f01b2fSopenharmony_ci#include <string> // string, stoi, to_string 32c5f01b2fSopenharmony_ci#include <utility> // declval, forward, move, pair, swap 33c5f01b2fSopenharmony_ci#include <vector> // vector 34c5f01b2fSopenharmony_ci 35c5f01b2fSopenharmony_ci#include <nlohmann/adl_serializer.hpp> 36c5f01b2fSopenharmony_ci#include <nlohmann/byte_container_with_subtype.hpp> 37c5f01b2fSopenharmony_ci#include <nlohmann/detail/conversions/from_json.hpp> 38c5f01b2fSopenharmony_ci#include <nlohmann/detail/conversions/to_json.hpp> 39c5f01b2fSopenharmony_ci#include <nlohmann/detail/exceptions.hpp> 40c5f01b2fSopenharmony_ci#include <nlohmann/detail/hash.hpp> 41c5f01b2fSopenharmony_ci#include <nlohmann/detail/input/binary_reader.hpp> 42c5f01b2fSopenharmony_ci#include <nlohmann/detail/input/input_adapters.hpp> 43c5f01b2fSopenharmony_ci#include <nlohmann/detail/input/lexer.hpp> 44c5f01b2fSopenharmony_ci#include <nlohmann/detail/input/parser.hpp> 45c5f01b2fSopenharmony_ci#include <nlohmann/detail/iterators/internal_iterator.hpp> 46c5f01b2fSopenharmony_ci#include <nlohmann/detail/iterators/iter_impl.hpp> 47c5f01b2fSopenharmony_ci#include <nlohmann/detail/iterators/iteration_proxy.hpp> 48c5f01b2fSopenharmony_ci#include <nlohmann/detail/iterators/json_reverse_iterator.hpp> 49c5f01b2fSopenharmony_ci#include <nlohmann/detail/iterators/primitive_iterator.hpp> 50c5f01b2fSopenharmony_ci#include <nlohmann/detail/json_pointer.hpp> 51c5f01b2fSopenharmony_ci#include <nlohmann/detail/json_ref.hpp> 52c5f01b2fSopenharmony_ci#include <nlohmann/detail/macro_scope.hpp> 53c5f01b2fSopenharmony_ci#include <nlohmann/detail/string_concat.hpp> 54c5f01b2fSopenharmony_ci#include <nlohmann/detail/string_escape.hpp> 55c5f01b2fSopenharmony_ci#include <nlohmann/detail/meta/cpp_future.hpp> 56c5f01b2fSopenharmony_ci#include <nlohmann/detail/meta/type_traits.hpp> 57c5f01b2fSopenharmony_ci#include <nlohmann/detail/output/binary_writer.hpp> 58c5f01b2fSopenharmony_ci#include <nlohmann/detail/output/output_adapters.hpp> 59c5f01b2fSopenharmony_ci#include <nlohmann/detail/output/serializer.hpp> 60c5f01b2fSopenharmony_ci#include <nlohmann/detail/value_t.hpp> 61c5f01b2fSopenharmony_ci#include <nlohmann/json_fwd.hpp> 62c5f01b2fSopenharmony_ci#include <nlohmann/ordered_map.hpp> 63c5f01b2fSopenharmony_ci 64c5f01b2fSopenharmony_ci#if defined(JSON_HAS_CPP_17) 65c5f01b2fSopenharmony_ci #include <any> 66c5f01b2fSopenharmony_ci #include <string_view> 67c5f01b2fSopenharmony_ci#endif 68c5f01b2fSopenharmony_ci 69c5f01b2fSopenharmony_ci/*! 70c5f01b2fSopenharmony_ci@brief namespace for Niels Lohmann 71c5f01b2fSopenharmony_ci@see https://github.com/nlohmann 72c5f01b2fSopenharmony_ci@since version 1.0.0 73c5f01b2fSopenharmony_ci*/ 74c5f01b2fSopenharmony_ciNLOHMANN_JSON_NAMESPACE_BEGIN 75c5f01b2fSopenharmony_ci 76c5f01b2fSopenharmony_ci/*! 77c5f01b2fSopenharmony_ci@brief a class to store JSON values 78c5f01b2fSopenharmony_ci 79c5f01b2fSopenharmony_ci@internal 80c5f01b2fSopenharmony_ci@invariant The member variables @a m_value and @a m_type have the following 81c5f01b2fSopenharmony_cirelationship: 82c5f01b2fSopenharmony_ci- If `m_type == value_t::object`, then `m_value.object != nullptr`. 83c5f01b2fSopenharmony_ci- If `m_type == value_t::array`, then `m_value.array != nullptr`. 84c5f01b2fSopenharmony_ci- If `m_type == value_t::string`, then `m_value.string != nullptr`. 85c5f01b2fSopenharmony_ciThe invariants are checked by member function assert_invariant(). 86c5f01b2fSopenharmony_ci 87c5f01b2fSopenharmony_ci@note ObjectType trick from https://stackoverflow.com/a/9860911 88c5f01b2fSopenharmony_ci@endinternal 89c5f01b2fSopenharmony_ci 90c5f01b2fSopenharmony_ci@since version 1.0.0 91c5f01b2fSopenharmony_ci 92c5f01b2fSopenharmony_ci@nosubgrouping 93c5f01b2fSopenharmony_ci*/ 94c5f01b2fSopenharmony_ciNLOHMANN_BASIC_JSON_TPL_DECLARATION 95c5f01b2fSopenharmony_ciclass basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) 96c5f01b2fSopenharmony_ci{ 97c5f01b2fSopenharmony_ci private: 98c5f01b2fSopenharmony_ci template<detail::value_t> friend struct detail::external_constructor; 99c5f01b2fSopenharmony_ci 100c5f01b2fSopenharmony_ci template<typename> 101c5f01b2fSopenharmony_ci friend class ::nlohmann::json_pointer; 102c5f01b2fSopenharmony_ci // can be restored when json_pointer backwards compatibility is removed 103c5f01b2fSopenharmony_ci // friend ::nlohmann::json_pointer<StringType>; 104c5f01b2fSopenharmony_ci 105c5f01b2fSopenharmony_ci template<typename BasicJsonType, typename InputType> 106c5f01b2fSopenharmony_ci friend class ::nlohmann::detail::parser; 107c5f01b2fSopenharmony_ci friend ::nlohmann::detail::serializer<basic_json>; 108c5f01b2fSopenharmony_ci template<typename BasicJsonType> 109c5f01b2fSopenharmony_ci friend class ::nlohmann::detail::iter_impl; 110c5f01b2fSopenharmony_ci template<typename BasicJsonType, typename CharType> 111c5f01b2fSopenharmony_ci friend class ::nlohmann::detail::binary_writer; 112c5f01b2fSopenharmony_ci template<typename BasicJsonType, typename InputType, typename SAX> 113c5f01b2fSopenharmony_ci friend class ::nlohmann::detail::binary_reader; 114c5f01b2fSopenharmony_ci template<typename BasicJsonType> 115c5f01b2fSopenharmony_ci friend class ::nlohmann::detail::json_sax_dom_parser; 116c5f01b2fSopenharmony_ci template<typename BasicJsonType> 117c5f01b2fSopenharmony_ci friend class ::nlohmann::detail::json_sax_dom_callback_parser; 118c5f01b2fSopenharmony_ci friend class ::nlohmann::detail::exception; 119c5f01b2fSopenharmony_ci 120c5f01b2fSopenharmony_ci /// workaround type for MSVC 121c5f01b2fSopenharmony_ci using basic_json_t = NLOHMANN_BASIC_JSON_TPL; 122c5f01b2fSopenharmony_ci 123c5f01b2fSopenharmony_ci JSON_PRIVATE_UNLESS_TESTED: 124c5f01b2fSopenharmony_ci // convenience aliases for types residing in namespace detail; 125c5f01b2fSopenharmony_ci using lexer = ::nlohmann::detail::lexer_base<basic_json>; 126c5f01b2fSopenharmony_ci 127c5f01b2fSopenharmony_ci template<typename InputAdapterType> 128c5f01b2fSopenharmony_ci static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser( 129c5f01b2fSopenharmony_ci InputAdapterType adapter, 130c5f01b2fSopenharmony_ci detail::parser_callback_t<basic_json>cb = nullptr, 131c5f01b2fSopenharmony_ci const bool allow_exceptions = true, 132c5f01b2fSopenharmony_ci const bool ignore_comments = false 133c5f01b2fSopenharmony_ci ) 134c5f01b2fSopenharmony_ci { 135c5f01b2fSopenharmony_ci return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter), 136c5f01b2fSopenharmony_ci std::move(cb), allow_exceptions, ignore_comments); 137c5f01b2fSopenharmony_ci } 138c5f01b2fSopenharmony_ci 139c5f01b2fSopenharmony_ci private: 140c5f01b2fSopenharmony_ci using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t; 141c5f01b2fSopenharmony_ci template<typename BasicJsonType> 142c5f01b2fSopenharmony_ci using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>; 143c5f01b2fSopenharmony_ci template<typename BasicJsonType> 144c5f01b2fSopenharmony_ci using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>; 145c5f01b2fSopenharmony_ci template<typename Iterator> 146c5f01b2fSopenharmony_ci using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>; 147c5f01b2fSopenharmony_ci template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>; 148c5f01b2fSopenharmony_ci 149c5f01b2fSopenharmony_ci template<typename CharType> 150c5f01b2fSopenharmony_ci using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>; 151c5f01b2fSopenharmony_ci 152c5f01b2fSopenharmony_ci template<typename InputType> 153c5f01b2fSopenharmony_ci using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>; 154c5f01b2fSopenharmony_ci template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>; 155c5f01b2fSopenharmony_ci 156c5f01b2fSopenharmony_ci JSON_PRIVATE_UNLESS_TESTED: 157c5f01b2fSopenharmony_ci using serializer = ::nlohmann::detail::serializer<basic_json>; 158c5f01b2fSopenharmony_ci 159c5f01b2fSopenharmony_ci public: 160c5f01b2fSopenharmony_ci using value_t = detail::value_t; 161c5f01b2fSopenharmony_ci /// JSON Pointer, see @ref nlohmann::json_pointer 162c5f01b2fSopenharmony_ci using json_pointer = ::nlohmann::json_pointer<StringType>; 163c5f01b2fSopenharmony_ci template<typename T, typename SFINAE> 164c5f01b2fSopenharmony_ci using json_serializer = JSONSerializer<T, SFINAE>; 165c5f01b2fSopenharmony_ci /// how to treat decoding errors 166c5f01b2fSopenharmony_ci using error_handler_t = detail::error_handler_t; 167c5f01b2fSopenharmony_ci /// how to treat CBOR tags 168c5f01b2fSopenharmony_ci using cbor_tag_handler_t = detail::cbor_tag_handler_t; 169c5f01b2fSopenharmony_ci /// helper type for initializer lists of basic_json values 170c5f01b2fSopenharmony_ci using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>; 171c5f01b2fSopenharmony_ci 172c5f01b2fSopenharmony_ci using input_format_t = detail::input_format_t; 173c5f01b2fSopenharmony_ci /// SAX interface type, see @ref nlohmann::json_sax 174c5f01b2fSopenharmony_ci using json_sax_t = json_sax<basic_json>; 175c5f01b2fSopenharmony_ci 176c5f01b2fSopenharmony_ci //////////////// 177c5f01b2fSopenharmony_ci // exceptions // 178c5f01b2fSopenharmony_ci //////////////// 179c5f01b2fSopenharmony_ci 180c5f01b2fSopenharmony_ci /// @name exceptions 181c5f01b2fSopenharmony_ci /// Classes to implement user-defined exceptions. 182c5f01b2fSopenharmony_ci /// @{ 183c5f01b2fSopenharmony_ci 184c5f01b2fSopenharmony_ci using exception = detail::exception; 185c5f01b2fSopenharmony_ci using parse_error = detail::parse_error; 186c5f01b2fSopenharmony_ci using invalid_iterator = detail::invalid_iterator; 187c5f01b2fSopenharmony_ci using type_error = detail::type_error; 188c5f01b2fSopenharmony_ci using out_of_range = detail::out_of_range; 189c5f01b2fSopenharmony_ci using other_error = detail::other_error; 190c5f01b2fSopenharmony_ci 191c5f01b2fSopenharmony_ci /// @} 192c5f01b2fSopenharmony_ci 193c5f01b2fSopenharmony_ci 194c5f01b2fSopenharmony_ci ///////////////////// 195c5f01b2fSopenharmony_ci // container types // 196c5f01b2fSopenharmony_ci ///////////////////// 197c5f01b2fSopenharmony_ci 198c5f01b2fSopenharmony_ci /// @name container types 199c5f01b2fSopenharmony_ci /// The canonic container types to use @ref basic_json like any other STL 200c5f01b2fSopenharmony_ci /// container. 201c5f01b2fSopenharmony_ci /// @{ 202c5f01b2fSopenharmony_ci 203c5f01b2fSopenharmony_ci /// the type of elements in a basic_json container 204c5f01b2fSopenharmony_ci using value_type = basic_json; 205c5f01b2fSopenharmony_ci 206c5f01b2fSopenharmony_ci /// the type of an element reference 207c5f01b2fSopenharmony_ci using reference = value_type&; 208c5f01b2fSopenharmony_ci /// the type of an element const reference 209c5f01b2fSopenharmony_ci using const_reference = const value_type&; 210c5f01b2fSopenharmony_ci 211c5f01b2fSopenharmony_ci /// a type to represent differences between iterators 212c5f01b2fSopenharmony_ci using difference_type = std::ptrdiff_t; 213c5f01b2fSopenharmony_ci /// a type to represent container sizes 214c5f01b2fSopenharmony_ci using size_type = std::size_t; 215c5f01b2fSopenharmony_ci 216c5f01b2fSopenharmony_ci /// the allocator type 217c5f01b2fSopenharmony_ci using allocator_type = AllocatorType<basic_json>; 218c5f01b2fSopenharmony_ci 219c5f01b2fSopenharmony_ci /// the type of an element pointer 220c5f01b2fSopenharmony_ci using pointer = typename std::allocator_traits<allocator_type>::pointer; 221c5f01b2fSopenharmony_ci /// the type of an element const pointer 222c5f01b2fSopenharmony_ci using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer; 223c5f01b2fSopenharmony_ci 224c5f01b2fSopenharmony_ci /// an iterator for a basic_json container 225c5f01b2fSopenharmony_ci using iterator = iter_impl<basic_json>; 226c5f01b2fSopenharmony_ci /// a const iterator for a basic_json container 227c5f01b2fSopenharmony_ci using const_iterator = iter_impl<const basic_json>; 228c5f01b2fSopenharmony_ci /// a reverse iterator for a basic_json container 229c5f01b2fSopenharmony_ci using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>; 230c5f01b2fSopenharmony_ci /// a const reverse iterator for a basic_json container 231c5f01b2fSopenharmony_ci using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>; 232c5f01b2fSopenharmony_ci 233c5f01b2fSopenharmony_ci /// @} 234c5f01b2fSopenharmony_ci 235c5f01b2fSopenharmony_ci 236c5f01b2fSopenharmony_ci /// @brief returns the allocator associated with the container 237c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/get_allocator/ 238c5f01b2fSopenharmony_ci static allocator_type get_allocator() 239c5f01b2fSopenharmony_ci { 240c5f01b2fSopenharmony_ci return allocator_type(); 241c5f01b2fSopenharmony_ci } 242c5f01b2fSopenharmony_ci 243c5f01b2fSopenharmony_ci /// @brief returns version information on the library 244c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/meta/ 245c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 246c5f01b2fSopenharmony_ci static basic_json meta() 247c5f01b2fSopenharmony_ci { 248c5f01b2fSopenharmony_ci basic_json result; 249c5f01b2fSopenharmony_ci 250c5f01b2fSopenharmony_ci result["copyright"] = "(C) 2013-2022 Niels Lohmann"; 251c5f01b2fSopenharmony_ci result["name"] = "JSON for Modern C++"; 252c5f01b2fSopenharmony_ci result["url"] = "https://github.com/nlohmann/json"; 253c5f01b2fSopenharmony_ci result["version"]["string"] = 254c5f01b2fSopenharmony_ci detail::concat(std::to_string(NLOHMANN_JSON_VERSION_MAJOR), '.', 255c5f01b2fSopenharmony_ci std::to_string(NLOHMANN_JSON_VERSION_MINOR), '.', 256c5f01b2fSopenharmony_ci std::to_string(NLOHMANN_JSON_VERSION_PATCH)); 257c5f01b2fSopenharmony_ci result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR; 258c5f01b2fSopenharmony_ci result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR; 259c5f01b2fSopenharmony_ci result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH; 260c5f01b2fSopenharmony_ci 261c5f01b2fSopenharmony_ci#ifdef _WIN32 262c5f01b2fSopenharmony_ci result["platform"] = "win32"; 263c5f01b2fSopenharmony_ci#elif defined __linux__ 264c5f01b2fSopenharmony_ci result["platform"] = "linux"; 265c5f01b2fSopenharmony_ci#elif defined __APPLE__ 266c5f01b2fSopenharmony_ci result["platform"] = "apple"; 267c5f01b2fSopenharmony_ci#elif defined __unix__ 268c5f01b2fSopenharmony_ci result["platform"] = "unix"; 269c5f01b2fSopenharmony_ci#else 270c5f01b2fSopenharmony_ci result["platform"] = "unknown"; 271c5f01b2fSopenharmony_ci#endif 272c5f01b2fSopenharmony_ci 273c5f01b2fSopenharmony_ci#if defined(__ICC) || defined(__INTEL_COMPILER) 274c5f01b2fSopenharmony_ci result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}}; 275c5f01b2fSopenharmony_ci#elif defined(__clang__) 276c5f01b2fSopenharmony_ci result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}}; 277c5f01b2fSopenharmony_ci#elif defined(__GNUC__) || defined(__GNUG__) 278c5f01b2fSopenharmony_ci result["compiler"] = {{"family", "gcc"}, {"version", detail::concat( 279c5f01b2fSopenharmony_ci std::to_string(__GNUC__), '.', 280c5f01b2fSopenharmony_ci std::to_string(__GNUC_MINOR__), '.', 281c5f01b2fSopenharmony_ci std::to_string(__GNUC_PATCHLEVEL__)) 282c5f01b2fSopenharmony_ci } 283c5f01b2fSopenharmony_ci }; 284c5f01b2fSopenharmony_ci#elif defined(__HP_cc) || defined(__HP_aCC) 285c5f01b2fSopenharmony_ci result["compiler"] = "hp" 286c5f01b2fSopenharmony_ci#elif defined(__IBMCPP__) 287c5f01b2fSopenharmony_ci result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}}; 288c5f01b2fSopenharmony_ci#elif defined(_MSC_VER) 289c5f01b2fSopenharmony_ci result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}}; 290c5f01b2fSopenharmony_ci#elif defined(__PGI) 291c5f01b2fSopenharmony_ci result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}}; 292c5f01b2fSopenharmony_ci#elif defined(__SUNPRO_CC) 293c5f01b2fSopenharmony_ci result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}}; 294c5f01b2fSopenharmony_ci#else 295c5f01b2fSopenharmony_ci result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}}; 296c5f01b2fSopenharmony_ci#endif 297c5f01b2fSopenharmony_ci 298c5f01b2fSopenharmony_ci 299c5f01b2fSopenharmony_ci#if defined(_MSVC_LANG) 300c5f01b2fSopenharmony_ci result["compiler"]["c++"] = std::to_string(_MSVC_LANG); 301c5f01b2fSopenharmony_ci#elif defined(__cplusplus) 302c5f01b2fSopenharmony_ci result["compiler"]["c++"] = std::to_string(__cplusplus); 303c5f01b2fSopenharmony_ci#else 304c5f01b2fSopenharmony_ci result["compiler"]["c++"] = "unknown"; 305c5f01b2fSopenharmony_ci#endif 306c5f01b2fSopenharmony_ci return result; 307c5f01b2fSopenharmony_ci } 308c5f01b2fSopenharmony_ci 309c5f01b2fSopenharmony_ci 310c5f01b2fSopenharmony_ci /////////////////////////// 311c5f01b2fSopenharmony_ci // JSON value data types // 312c5f01b2fSopenharmony_ci /////////////////////////// 313c5f01b2fSopenharmony_ci 314c5f01b2fSopenharmony_ci /// @name JSON value data types 315c5f01b2fSopenharmony_ci /// The data types to store a JSON value. These types are derived from 316c5f01b2fSopenharmony_ci /// the template arguments passed to class @ref basic_json. 317c5f01b2fSopenharmony_ci /// @{ 318c5f01b2fSopenharmony_ci 319c5f01b2fSopenharmony_ci /// @brief default object key comparator type 320c5f01b2fSopenharmony_ci /// The actual object key comparator type (@ref object_comparator_t) may be 321c5f01b2fSopenharmony_ci /// different. 322c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/default_object_comparator_t/ 323c5f01b2fSopenharmony_ci#if defined(JSON_HAS_CPP_14) 324c5f01b2fSopenharmony_ci // use of transparent comparator avoids unnecessary repeated construction of temporaries 325c5f01b2fSopenharmony_ci // in functions involving lookup by key with types other than object_t::key_type (aka. StringType) 326c5f01b2fSopenharmony_ci using default_object_comparator_t = std::less<>; 327c5f01b2fSopenharmony_ci#else 328c5f01b2fSopenharmony_ci using default_object_comparator_t = std::less<StringType>; 329c5f01b2fSopenharmony_ci#endif 330c5f01b2fSopenharmony_ci 331c5f01b2fSopenharmony_ci /// @brief a type for an object 332c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/object_t/ 333c5f01b2fSopenharmony_ci using object_t = ObjectType<StringType, 334c5f01b2fSopenharmony_ci basic_json, 335c5f01b2fSopenharmony_ci default_object_comparator_t, 336c5f01b2fSopenharmony_ci AllocatorType<std::pair<const StringType, 337c5f01b2fSopenharmony_ci basic_json>>>; 338c5f01b2fSopenharmony_ci 339c5f01b2fSopenharmony_ci /// @brief a type for an array 340c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/array_t/ 341c5f01b2fSopenharmony_ci using array_t = ArrayType<basic_json, AllocatorType<basic_json>>; 342c5f01b2fSopenharmony_ci 343c5f01b2fSopenharmony_ci /// @brief a type for a string 344c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/string_t/ 345c5f01b2fSopenharmony_ci using string_t = StringType; 346c5f01b2fSopenharmony_ci 347c5f01b2fSopenharmony_ci /// @brief a type for a boolean 348c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/boolean_t/ 349c5f01b2fSopenharmony_ci using boolean_t = BooleanType; 350c5f01b2fSopenharmony_ci 351c5f01b2fSopenharmony_ci /// @brief a type for a number (integer) 352c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/number_integer_t/ 353c5f01b2fSopenharmony_ci using number_integer_t = NumberIntegerType; 354c5f01b2fSopenharmony_ci 355c5f01b2fSopenharmony_ci /// @brief a type for a number (unsigned) 356c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/number_unsigned_t/ 357c5f01b2fSopenharmony_ci using number_unsigned_t = NumberUnsignedType; 358c5f01b2fSopenharmony_ci 359c5f01b2fSopenharmony_ci /// @brief a type for a number (floating-point) 360c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/number_float_t/ 361c5f01b2fSopenharmony_ci using number_float_t = NumberFloatType; 362c5f01b2fSopenharmony_ci 363c5f01b2fSopenharmony_ci /// @brief a type for a packed binary type 364c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/binary_t/ 365c5f01b2fSopenharmony_ci using binary_t = nlohmann::byte_container_with_subtype<BinaryType>; 366c5f01b2fSopenharmony_ci 367c5f01b2fSopenharmony_ci /// @brief object key comparator type 368c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/object_comparator_t/ 369c5f01b2fSopenharmony_ci using object_comparator_t = detail::actual_object_comparator_t<basic_json>; 370c5f01b2fSopenharmony_ci 371c5f01b2fSopenharmony_ci /// @} 372c5f01b2fSopenharmony_ci 373c5f01b2fSopenharmony_ci private: 374c5f01b2fSopenharmony_ci 375c5f01b2fSopenharmony_ci /// helper for exception-safe object creation 376c5f01b2fSopenharmony_ci template<typename T, typename... Args> 377c5f01b2fSopenharmony_ci JSON_HEDLEY_RETURNS_NON_NULL 378c5f01b2fSopenharmony_ci static T* create(Args&& ... args) 379c5f01b2fSopenharmony_ci { 380c5f01b2fSopenharmony_ci AllocatorType<T> alloc; 381c5f01b2fSopenharmony_ci using AllocatorTraits = std::allocator_traits<AllocatorType<T>>; 382c5f01b2fSopenharmony_ci 383c5f01b2fSopenharmony_ci auto deleter = [&](T * obj) 384c5f01b2fSopenharmony_ci { 385c5f01b2fSopenharmony_ci AllocatorTraits::deallocate(alloc, obj, 1); 386c5f01b2fSopenharmony_ci }; 387c5f01b2fSopenharmony_ci std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter); 388c5f01b2fSopenharmony_ci AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...); 389c5f01b2fSopenharmony_ci JSON_ASSERT(obj != nullptr); 390c5f01b2fSopenharmony_ci return obj.release(); 391c5f01b2fSopenharmony_ci } 392c5f01b2fSopenharmony_ci 393c5f01b2fSopenharmony_ci //////////////////////// 394c5f01b2fSopenharmony_ci // JSON value storage // 395c5f01b2fSopenharmony_ci //////////////////////// 396c5f01b2fSopenharmony_ci 397c5f01b2fSopenharmony_ci JSON_PRIVATE_UNLESS_TESTED: 398c5f01b2fSopenharmony_ci /*! 399c5f01b2fSopenharmony_ci @brief a JSON value 400c5f01b2fSopenharmony_ci 401c5f01b2fSopenharmony_ci The actual storage for a JSON value of the @ref basic_json class. This 402c5f01b2fSopenharmony_ci union combines the different storage types for the JSON value types 403c5f01b2fSopenharmony_ci defined in @ref value_t. 404c5f01b2fSopenharmony_ci 405c5f01b2fSopenharmony_ci JSON type | value_t type | used type 406c5f01b2fSopenharmony_ci --------- | --------------- | ------------------------ 407c5f01b2fSopenharmony_ci object | object | pointer to @ref object_t 408c5f01b2fSopenharmony_ci array | array | pointer to @ref array_t 409c5f01b2fSopenharmony_ci string | string | pointer to @ref string_t 410c5f01b2fSopenharmony_ci boolean | boolean | @ref boolean_t 411c5f01b2fSopenharmony_ci number | number_integer | @ref number_integer_t 412c5f01b2fSopenharmony_ci number | number_unsigned | @ref number_unsigned_t 413c5f01b2fSopenharmony_ci number | number_float | @ref number_float_t 414c5f01b2fSopenharmony_ci binary | binary | pointer to @ref binary_t 415c5f01b2fSopenharmony_ci null | null | *no value is stored* 416c5f01b2fSopenharmony_ci 417c5f01b2fSopenharmony_ci @note Variable-length types (objects, arrays, and strings) are stored as 418c5f01b2fSopenharmony_ci pointers. The size of the union should not exceed 64 bits if the default 419c5f01b2fSopenharmony_ci value types are used. 420c5f01b2fSopenharmony_ci 421c5f01b2fSopenharmony_ci @since version 1.0.0 422c5f01b2fSopenharmony_ci */ 423c5f01b2fSopenharmony_ci union json_value 424c5f01b2fSopenharmony_ci { 425c5f01b2fSopenharmony_ci /// object (stored with pointer to save storage) 426c5f01b2fSopenharmony_ci object_t* object; 427c5f01b2fSopenharmony_ci /// array (stored with pointer to save storage) 428c5f01b2fSopenharmony_ci array_t* array; 429c5f01b2fSopenharmony_ci /// string (stored with pointer to save storage) 430c5f01b2fSopenharmony_ci string_t* string; 431c5f01b2fSopenharmony_ci /// binary (stored with pointer to save storage) 432c5f01b2fSopenharmony_ci binary_t* binary; 433c5f01b2fSopenharmony_ci /// boolean 434c5f01b2fSopenharmony_ci boolean_t boolean; 435c5f01b2fSopenharmony_ci /// number (integer) 436c5f01b2fSopenharmony_ci number_integer_t number_integer; 437c5f01b2fSopenharmony_ci /// number (unsigned integer) 438c5f01b2fSopenharmony_ci number_unsigned_t number_unsigned; 439c5f01b2fSopenharmony_ci /// number (floating-point) 440c5f01b2fSopenharmony_ci number_float_t number_float; 441c5f01b2fSopenharmony_ci 442c5f01b2fSopenharmony_ci /// default constructor (for null values) 443c5f01b2fSopenharmony_ci json_value() = default; 444c5f01b2fSopenharmony_ci /// constructor for booleans 445c5f01b2fSopenharmony_ci json_value(boolean_t v) noexcept : boolean(v) {} 446c5f01b2fSopenharmony_ci /// constructor for numbers (integer) 447c5f01b2fSopenharmony_ci json_value(number_integer_t v) noexcept : number_integer(v) {} 448c5f01b2fSopenharmony_ci /// constructor for numbers (unsigned) 449c5f01b2fSopenharmony_ci json_value(number_unsigned_t v) noexcept : number_unsigned(v) {} 450c5f01b2fSopenharmony_ci /// constructor for numbers (floating-point) 451c5f01b2fSopenharmony_ci json_value(number_float_t v) noexcept : number_float(v) {} 452c5f01b2fSopenharmony_ci /// constructor for empty values of a given type 453c5f01b2fSopenharmony_ci json_value(value_t t) 454c5f01b2fSopenharmony_ci { 455c5f01b2fSopenharmony_ci switch (t) 456c5f01b2fSopenharmony_ci { 457c5f01b2fSopenharmony_ci case value_t::object: 458c5f01b2fSopenharmony_ci { 459c5f01b2fSopenharmony_ci object = create<object_t>(); 460c5f01b2fSopenharmony_ci break; 461c5f01b2fSopenharmony_ci } 462c5f01b2fSopenharmony_ci 463c5f01b2fSopenharmony_ci case value_t::array: 464c5f01b2fSopenharmony_ci { 465c5f01b2fSopenharmony_ci array = create<array_t>(); 466c5f01b2fSopenharmony_ci break; 467c5f01b2fSopenharmony_ci } 468c5f01b2fSopenharmony_ci 469c5f01b2fSopenharmony_ci case value_t::string: 470c5f01b2fSopenharmony_ci { 471c5f01b2fSopenharmony_ci string = create<string_t>(""); 472c5f01b2fSopenharmony_ci break; 473c5f01b2fSopenharmony_ci } 474c5f01b2fSopenharmony_ci 475c5f01b2fSopenharmony_ci case value_t::binary: 476c5f01b2fSopenharmony_ci { 477c5f01b2fSopenharmony_ci binary = create<binary_t>(); 478c5f01b2fSopenharmony_ci break; 479c5f01b2fSopenharmony_ci } 480c5f01b2fSopenharmony_ci 481c5f01b2fSopenharmony_ci case value_t::boolean: 482c5f01b2fSopenharmony_ci { 483c5f01b2fSopenharmony_ci boolean = static_cast<boolean_t>(false); 484c5f01b2fSopenharmony_ci break; 485c5f01b2fSopenharmony_ci } 486c5f01b2fSopenharmony_ci 487c5f01b2fSopenharmony_ci case value_t::number_integer: 488c5f01b2fSopenharmony_ci { 489c5f01b2fSopenharmony_ci number_integer = static_cast<number_integer_t>(0); 490c5f01b2fSopenharmony_ci break; 491c5f01b2fSopenharmony_ci } 492c5f01b2fSopenharmony_ci 493c5f01b2fSopenharmony_ci case value_t::number_unsigned: 494c5f01b2fSopenharmony_ci { 495c5f01b2fSopenharmony_ci number_unsigned = static_cast<number_unsigned_t>(0); 496c5f01b2fSopenharmony_ci break; 497c5f01b2fSopenharmony_ci } 498c5f01b2fSopenharmony_ci 499c5f01b2fSopenharmony_ci case value_t::number_float: 500c5f01b2fSopenharmony_ci { 501c5f01b2fSopenharmony_ci number_float = static_cast<number_float_t>(0.0); 502c5f01b2fSopenharmony_ci break; 503c5f01b2fSopenharmony_ci } 504c5f01b2fSopenharmony_ci 505c5f01b2fSopenharmony_ci case value_t::null: 506c5f01b2fSopenharmony_ci { 507c5f01b2fSopenharmony_ci object = nullptr; // silence warning, see #821 508c5f01b2fSopenharmony_ci break; 509c5f01b2fSopenharmony_ci } 510c5f01b2fSopenharmony_ci 511c5f01b2fSopenharmony_ci case value_t::discarded: 512c5f01b2fSopenharmony_ci default: 513c5f01b2fSopenharmony_ci { 514c5f01b2fSopenharmony_ci object = nullptr; // silence warning, see #821 515c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(t == value_t::null)) 516c5f01b2fSopenharmony_ci { 517c5f01b2fSopenharmony_ci JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.11.2", nullptr)); // LCOV_EXCL_LINE 518c5f01b2fSopenharmony_ci } 519c5f01b2fSopenharmony_ci break; 520c5f01b2fSopenharmony_ci } 521c5f01b2fSopenharmony_ci } 522c5f01b2fSopenharmony_ci } 523c5f01b2fSopenharmony_ci 524c5f01b2fSopenharmony_ci /// constructor for strings 525c5f01b2fSopenharmony_ci json_value(const string_t& value) : string(create<string_t>(value)) {} 526c5f01b2fSopenharmony_ci 527c5f01b2fSopenharmony_ci /// constructor for rvalue strings 528c5f01b2fSopenharmony_ci json_value(string_t&& value) : string(create<string_t>(std::move(value))) {} 529c5f01b2fSopenharmony_ci 530c5f01b2fSopenharmony_ci /// constructor for objects 531c5f01b2fSopenharmony_ci json_value(const object_t& value) : object(create<object_t>(value)) {} 532c5f01b2fSopenharmony_ci 533c5f01b2fSopenharmony_ci /// constructor for rvalue objects 534c5f01b2fSopenharmony_ci json_value(object_t&& value) : object(create<object_t>(std::move(value))) {} 535c5f01b2fSopenharmony_ci 536c5f01b2fSopenharmony_ci /// constructor for arrays 537c5f01b2fSopenharmony_ci json_value(const array_t& value) : array(create<array_t>(value)) {} 538c5f01b2fSopenharmony_ci 539c5f01b2fSopenharmony_ci /// constructor for rvalue arrays 540c5f01b2fSopenharmony_ci json_value(array_t&& value) : array(create<array_t>(std::move(value))) {} 541c5f01b2fSopenharmony_ci 542c5f01b2fSopenharmony_ci /// constructor for binary arrays 543c5f01b2fSopenharmony_ci json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {} 544c5f01b2fSopenharmony_ci 545c5f01b2fSopenharmony_ci /// constructor for rvalue binary arrays 546c5f01b2fSopenharmony_ci json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {} 547c5f01b2fSopenharmony_ci 548c5f01b2fSopenharmony_ci /// constructor for binary arrays (internal type) 549c5f01b2fSopenharmony_ci json_value(const binary_t& value) : binary(create<binary_t>(value)) {} 550c5f01b2fSopenharmony_ci 551c5f01b2fSopenharmony_ci /// constructor for rvalue binary arrays (internal type) 552c5f01b2fSopenharmony_ci json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {} 553c5f01b2fSopenharmony_ci 554c5f01b2fSopenharmony_ci void destroy(value_t t) 555c5f01b2fSopenharmony_ci { 556c5f01b2fSopenharmony_ci if (t == value_t::array || t == value_t::object) 557c5f01b2fSopenharmony_ci { 558c5f01b2fSopenharmony_ci // flatten the current json_value to a heap-allocated stack 559c5f01b2fSopenharmony_ci std::vector<basic_json> stack; 560c5f01b2fSopenharmony_ci 561c5f01b2fSopenharmony_ci // move the top-level items to stack 562c5f01b2fSopenharmony_ci if (t == value_t::array) 563c5f01b2fSopenharmony_ci { 564c5f01b2fSopenharmony_ci stack.reserve(array->size()); 565c5f01b2fSopenharmony_ci std::move(array->begin(), array->end(), std::back_inserter(stack)); 566c5f01b2fSopenharmony_ci } 567c5f01b2fSopenharmony_ci else 568c5f01b2fSopenharmony_ci { 569c5f01b2fSopenharmony_ci stack.reserve(object->size()); 570c5f01b2fSopenharmony_ci for (auto&& it : *object) 571c5f01b2fSopenharmony_ci { 572c5f01b2fSopenharmony_ci stack.push_back(std::move(it.second)); 573c5f01b2fSopenharmony_ci } 574c5f01b2fSopenharmony_ci } 575c5f01b2fSopenharmony_ci 576c5f01b2fSopenharmony_ci while (!stack.empty()) 577c5f01b2fSopenharmony_ci { 578c5f01b2fSopenharmony_ci // move the last item to local variable to be processed 579c5f01b2fSopenharmony_ci basic_json current_item(std::move(stack.back())); 580c5f01b2fSopenharmony_ci stack.pop_back(); 581c5f01b2fSopenharmony_ci 582c5f01b2fSopenharmony_ci // if current_item is array/object, move 583c5f01b2fSopenharmony_ci // its children to the stack to be processed later 584c5f01b2fSopenharmony_ci if (current_item.is_array()) 585c5f01b2fSopenharmony_ci { 586c5f01b2fSopenharmony_ci std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack)); 587c5f01b2fSopenharmony_ci 588c5f01b2fSopenharmony_ci current_item.m_value.array->clear(); 589c5f01b2fSopenharmony_ci } 590c5f01b2fSopenharmony_ci else if (current_item.is_object()) 591c5f01b2fSopenharmony_ci { 592c5f01b2fSopenharmony_ci for (auto&& it : *current_item.m_value.object) 593c5f01b2fSopenharmony_ci { 594c5f01b2fSopenharmony_ci stack.push_back(std::move(it.second)); 595c5f01b2fSopenharmony_ci } 596c5f01b2fSopenharmony_ci 597c5f01b2fSopenharmony_ci current_item.m_value.object->clear(); 598c5f01b2fSopenharmony_ci } 599c5f01b2fSopenharmony_ci 600c5f01b2fSopenharmony_ci // it's now safe that current_item get destructed 601c5f01b2fSopenharmony_ci // since it doesn't have any children 602c5f01b2fSopenharmony_ci } 603c5f01b2fSopenharmony_ci } 604c5f01b2fSopenharmony_ci 605c5f01b2fSopenharmony_ci switch (t) 606c5f01b2fSopenharmony_ci { 607c5f01b2fSopenharmony_ci case value_t::object: 608c5f01b2fSopenharmony_ci { 609c5f01b2fSopenharmony_ci AllocatorType<object_t> alloc; 610c5f01b2fSopenharmony_ci std::allocator_traits<decltype(alloc)>::destroy(alloc, object); 611c5f01b2fSopenharmony_ci std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1); 612c5f01b2fSopenharmony_ci break; 613c5f01b2fSopenharmony_ci } 614c5f01b2fSopenharmony_ci 615c5f01b2fSopenharmony_ci case value_t::array: 616c5f01b2fSopenharmony_ci { 617c5f01b2fSopenharmony_ci AllocatorType<array_t> alloc; 618c5f01b2fSopenharmony_ci std::allocator_traits<decltype(alloc)>::destroy(alloc, array); 619c5f01b2fSopenharmony_ci std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1); 620c5f01b2fSopenharmony_ci break; 621c5f01b2fSopenharmony_ci } 622c5f01b2fSopenharmony_ci 623c5f01b2fSopenharmony_ci case value_t::string: 624c5f01b2fSopenharmony_ci { 625c5f01b2fSopenharmony_ci AllocatorType<string_t> alloc; 626c5f01b2fSopenharmony_ci std::allocator_traits<decltype(alloc)>::destroy(alloc, string); 627c5f01b2fSopenharmony_ci std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1); 628c5f01b2fSopenharmony_ci break; 629c5f01b2fSopenharmony_ci } 630c5f01b2fSopenharmony_ci 631c5f01b2fSopenharmony_ci case value_t::binary: 632c5f01b2fSopenharmony_ci { 633c5f01b2fSopenharmony_ci AllocatorType<binary_t> alloc; 634c5f01b2fSopenharmony_ci std::allocator_traits<decltype(alloc)>::destroy(alloc, binary); 635c5f01b2fSopenharmony_ci std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1); 636c5f01b2fSopenharmony_ci break; 637c5f01b2fSopenharmony_ci } 638c5f01b2fSopenharmony_ci 639c5f01b2fSopenharmony_ci case value_t::null: 640c5f01b2fSopenharmony_ci case value_t::boolean: 641c5f01b2fSopenharmony_ci case value_t::number_integer: 642c5f01b2fSopenharmony_ci case value_t::number_unsigned: 643c5f01b2fSopenharmony_ci case value_t::number_float: 644c5f01b2fSopenharmony_ci case value_t::discarded: 645c5f01b2fSopenharmony_ci default: 646c5f01b2fSopenharmony_ci { 647c5f01b2fSopenharmony_ci break; 648c5f01b2fSopenharmony_ci } 649c5f01b2fSopenharmony_ci } 650c5f01b2fSopenharmony_ci } 651c5f01b2fSopenharmony_ci }; 652c5f01b2fSopenharmony_ci 653c5f01b2fSopenharmony_ci private: 654c5f01b2fSopenharmony_ci /*! 655c5f01b2fSopenharmony_ci @brief checks the class invariants 656c5f01b2fSopenharmony_ci 657c5f01b2fSopenharmony_ci This function asserts the class invariants. It needs to be called at the 658c5f01b2fSopenharmony_ci end of every constructor to make sure that created objects respect the 659c5f01b2fSopenharmony_ci invariant. Furthermore, it has to be called each time the type of a JSON 660c5f01b2fSopenharmony_ci value is changed, because the invariant expresses a relationship between 661c5f01b2fSopenharmony_ci @a m_type and @a m_value. 662c5f01b2fSopenharmony_ci 663c5f01b2fSopenharmony_ci Furthermore, the parent relation is checked for arrays and objects: If 664c5f01b2fSopenharmony_ci @a check_parents true and the value is an array or object, then the 665c5f01b2fSopenharmony_ci container's elements must have the current value as parent. 666c5f01b2fSopenharmony_ci 667c5f01b2fSopenharmony_ci @param[in] check_parents whether the parent relation should be checked. 668c5f01b2fSopenharmony_ci The value is true by default and should only be set to false 669c5f01b2fSopenharmony_ci during destruction of objects when the invariant does not 670c5f01b2fSopenharmony_ci need to hold. 671c5f01b2fSopenharmony_ci */ 672c5f01b2fSopenharmony_ci void assert_invariant(bool check_parents = true) const noexcept 673c5f01b2fSopenharmony_ci { 674c5f01b2fSopenharmony_ci JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr); 675c5f01b2fSopenharmony_ci JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr); 676c5f01b2fSopenharmony_ci JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr); 677c5f01b2fSopenharmony_ci JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr); 678c5f01b2fSopenharmony_ci 679c5f01b2fSopenharmony_ci#if JSON_DIAGNOSTICS 680c5f01b2fSopenharmony_ci JSON_TRY 681c5f01b2fSopenharmony_ci { 682c5f01b2fSopenharmony_ci // cppcheck-suppress assertWithSideEffect 683c5f01b2fSopenharmony_ci JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j) 684c5f01b2fSopenharmony_ci { 685c5f01b2fSopenharmony_ci return j.m_parent == this; 686c5f01b2fSopenharmony_ci })); 687c5f01b2fSopenharmony_ci } 688c5f01b2fSopenharmony_ci JSON_CATCH(...) {} // LCOV_EXCL_LINE 689c5f01b2fSopenharmony_ci#endif 690c5f01b2fSopenharmony_ci static_cast<void>(check_parents); 691c5f01b2fSopenharmony_ci } 692c5f01b2fSopenharmony_ci 693c5f01b2fSopenharmony_ci void set_parents() 694c5f01b2fSopenharmony_ci { 695c5f01b2fSopenharmony_ci#if JSON_DIAGNOSTICS 696c5f01b2fSopenharmony_ci switch (m_type) 697c5f01b2fSopenharmony_ci { 698c5f01b2fSopenharmony_ci case value_t::array: 699c5f01b2fSopenharmony_ci { 700c5f01b2fSopenharmony_ci for (auto& element : *m_value.array) 701c5f01b2fSopenharmony_ci { 702c5f01b2fSopenharmony_ci element.m_parent = this; 703c5f01b2fSopenharmony_ci } 704c5f01b2fSopenharmony_ci break; 705c5f01b2fSopenharmony_ci } 706c5f01b2fSopenharmony_ci 707c5f01b2fSopenharmony_ci case value_t::object: 708c5f01b2fSopenharmony_ci { 709c5f01b2fSopenharmony_ci for (auto& element : *m_value.object) 710c5f01b2fSopenharmony_ci { 711c5f01b2fSopenharmony_ci element.second.m_parent = this; 712c5f01b2fSopenharmony_ci } 713c5f01b2fSopenharmony_ci break; 714c5f01b2fSopenharmony_ci } 715c5f01b2fSopenharmony_ci 716c5f01b2fSopenharmony_ci case value_t::null: 717c5f01b2fSopenharmony_ci case value_t::string: 718c5f01b2fSopenharmony_ci case value_t::boolean: 719c5f01b2fSopenharmony_ci case value_t::number_integer: 720c5f01b2fSopenharmony_ci case value_t::number_unsigned: 721c5f01b2fSopenharmony_ci case value_t::number_float: 722c5f01b2fSopenharmony_ci case value_t::binary: 723c5f01b2fSopenharmony_ci case value_t::discarded: 724c5f01b2fSopenharmony_ci default: 725c5f01b2fSopenharmony_ci break; 726c5f01b2fSopenharmony_ci } 727c5f01b2fSopenharmony_ci#endif 728c5f01b2fSopenharmony_ci } 729c5f01b2fSopenharmony_ci 730c5f01b2fSopenharmony_ci iterator set_parents(iterator it, typename iterator::difference_type count_set_parents) 731c5f01b2fSopenharmony_ci { 732c5f01b2fSopenharmony_ci#if JSON_DIAGNOSTICS 733c5f01b2fSopenharmony_ci for (typename iterator::difference_type i = 0; i < count_set_parents; ++i) 734c5f01b2fSopenharmony_ci { 735c5f01b2fSopenharmony_ci (it + i)->m_parent = this; 736c5f01b2fSopenharmony_ci } 737c5f01b2fSopenharmony_ci#else 738c5f01b2fSopenharmony_ci static_cast<void>(count_set_parents); 739c5f01b2fSopenharmony_ci#endif 740c5f01b2fSopenharmony_ci return it; 741c5f01b2fSopenharmony_ci } 742c5f01b2fSopenharmony_ci 743c5f01b2fSopenharmony_ci reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1)) 744c5f01b2fSopenharmony_ci { 745c5f01b2fSopenharmony_ci#if JSON_DIAGNOSTICS 746c5f01b2fSopenharmony_ci if (old_capacity != static_cast<std::size_t>(-1)) 747c5f01b2fSopenharmony_ci { 748c5f01b2fSopenharmony_ci // see https://github.com/nlohmann/json/issues/2838 749c5f01b2fSopenharmony_ci JSON_ASSERT(type() == value_t::array); 750c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity)) 751c5f01b2fSopenharmony_ci { 752c5f01b2fSopenharmony_ci // capacity has changed: update all parents 753c5f01b2fSopenharmony_ci set_parents(); 754c5f01b2fSopenharmony_ci return j; 755c5f01b2fSopenharmony_ci } 756c5f01b2fSopenharmony_ci } 757c5f01b2fSopenharmony_ci 758c5f01b2fSopenharmony_ci // ordered_json uses a vector internally, so pointers could have 759c5f01b2fSopenharmony_ci // been invalidated; see https://github.com/nlohmann/json/issues/2962 760c5f01b2fSopenharmony_ci#ifdef JSON_HEDLEY_MSVC_VERSION 761c5f01b2fSopenharmony_ci#pragma warning(push ) 762c5f01b2fSopenharmony_ci#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr 763c5f01b2fSopenharmony_ci#endif 764c5f01b2fSopenharmony_ci if (detail::is_ordered_map<object_t>::value) 765c5f01b2fSopenharmony_ci { 766c5f01b2fSopenharmony_ci set_parents(); 767c5f01b2fSopenharmony_ci return j; 768c5f01b2fSopenharmony_ci } 769c5f01b2fSopenharmony_ci#ifdef JSON_HEDLEY_MSVC_VERSION 770c5f01b2fSopenharmony_ci#pragma warning( pop ) 771c5f01b2fSopenharmony_ci#endif 772c5f01b2fSopenharmony_ci 773c5f01b2fSopenharmony_ci j.m_parent = this; 774c5f01b2fSopenharmony_ci#else 775c5f01b2fSopenharmony_ci static_cast<void>(j); 776c5f01b2fSopenharmony_ci static_cast<void>(old_capacity); 777c5f01b2fSopenharmony_ci#endif 778c5f01b2fSopenharmony_ci return j; 779c5f01b2fSopenharmony_ci } 780c5f01b2fSopenharmony_ci 781c5f01b2fSopenharmony_ci public: 782c5f01b2fSopenharmony_ci ////////////////////////// 783c5f01b2fSopenharmony_ci // JSON parser callback // 784c5f01b2fSopenharmony_ci ////////////////////////// 785c5f01b2fSopenharmony_ci 786c5f01b2fSopenharmony_ci /// @brief parser event types 787c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/parse_event_t/ 788c5f01b2fSopenharmony_ci using parse_event_t = detail::parse_event_t; 789c5f01b2fSopenharmony_ci 790c5f01b2fSopenharmony_ci /// @brief per-element parser callback type 791c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/parser_callback_t/ 792c5f01b2fSopenharmony_ci using parser_callback_t = detail::parser_callback_t<basic_json>; 793c5f01b2fSopenharmony_ci 794c5f01b2fSopenharmony_ci ////////////////// 795c5f01b2fSopenharmony_ci // constructors // 796c5f01b2fSopenharmony_ci ////////////////// 797c5f01b2fSopenharmony_ci 798c5f01b2fSopenharmony_ci /// @name constructors and destructors 799c5f01b2fSopenharmony_ci /// Constructors of class @ref basic_json, copy/move constructor, copy 800c5f01b2fSopenharmony_ci /// assignment, static functions creating objects, and the destructor. 801c5f01b2fSopenharmony_ci /// @{ 802c5f01b2fSopenharmony_ci 803c5f01b2fSopenharmony_ci /// @brief create an empty value with a given type 804c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ 805c5f01b2fSopenharmony_ci basic_json(const value_t v) 806c5f01b2fSopenharmony_ci : m_type(v), m_value(v) 807c5f01b2fSopenharmony_ci { 808c5f01b2fSopenharmony_ci assert_invariant(); 809c5f01b2fSopenharmony_ci } 810c5f01b2fSopenharmony_ci 811c5f01b2fSopenharmony_ci /// @brief create a null object 812c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ 813c5f01b2fSopenharmony_ci basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape) 814c5f01b2fSopenharmony_ci : basic_json(value_t::null) 815c5f01b2fSopenharmony_ci { 816c5f01b2fSopenharmony_ci assert_invariant(); 817c5f01b2fSopenharmony_ci } 818c5f01b2fSopenharmony_ci 819c5f01b2fSopenharmony_ci /// @brief create a JSON value from compatible types 820c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ 821c5f01b2fSopenharmony_ci template < typename CompatibleType, 822c5f01b2fSopenharmony_ci typename U = detail::uncvref_t<CompatibleType>, 823c5f01b2fSopenharmony_ci detail::enable_if_t < 824c5f01b2fSopenharmony_ci !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 > 825c5f01b2fSopenharmony_ci basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape) 826c5f01b2fSopenharmony_ci JSONSerializer<U>::to_json(std::declval<basic_json_t&>(), 827c5f01b2fSopenharmony_ci std::forward<CompatibleType>(val)))) 828c5f01b2fSopenharmony_ci { 829c5f01b2fSopenharmony_ci JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val)); 830c5f01b2fSopenharmony_ci set_parents(); 831c5f01b2fSopenharmony_ci assert_invariant(); 832c5f01b2fSopenharmony_ci } 833c5f01b2fSopenharmony_ci 834c5f01b2fSopenharmony_ci /// @brief create a JSON value from an existing one 835c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ 836c5f01b2fSopenharmony_ci template < typename BasicJsonType, 837c5f01b2fSopenharmony_ci detail::enable_if_t < 838c5f01b2fSopenharmony_ci detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 > 839c5f01b2fSopenharmony_ci basic_json(const BasicJsonType& val) 840c5f01b2fSopenharmony_ci { 841c5f01b2fSopenharmony_ci using other_boolean_t = typename BasicJsonType::boolean_t; 842c5f01b2fSopenharmony_ci using other_number_float_t = typename BasicJsonType::number_float_t; 843c5f01b2fSopenharmony_ci using other_number_integer_t = typename BasicJsonType::number_integer_t; 844c5f01b2fSopenharmony_ci using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t; 845c5f01b2fSopenharmony_ci using other_string_t = typename BasicJsonType::string_t; 846c5f01b2fSopenharmony_ci using other_object_t = typename BasicJsonType::object_t; 847c5f01b2fSopenharmony_ci using other_array_t = typename BasicJsonType::array_t; 848c5f01b2fSopenharmony_ci using other_binary_t = typename BasicJsonType::binary_t; 849c5f01b2fSopenharmony_ci 850c5f01b2fSopenharmony_ci switch (val.type()) 851c5f01b2fSopenharmony_ci { 852c5f01b2fSopenharmony_ci case value_t::boolean: 853c5f01b2fSopenharmony_ci JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>()); 854c5f01b2fSopenharmony_ci break; 855c5f01b2fSopenharmony_ci case value_t::number_float: 856c5f01b2fSopenharmony_ci JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>()); 857c5f01b2fSopenharmony_ci break; 858c5f01b2fSopenharmony_ci case value_t::number_integer: 859c5f01b2fSopenharmony_ci JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>()); 860c5f01b2fSopenharmony_ci break; 861c5f01b2fSopenharmony_ci case value_t::number_unsigned: 862c5f01b2fSopenharmony_ci JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>()); 863c5f01b2fSopenharmony_ci break; 864c5f01b2fSopenharmony_ci case value_t::string: 865c5f01b2fSopenharmony_ci JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>()); 866c5f01b2fSopenharmony_ci break; 867c5f01b2fSopenharmony_ci case value_t::object: 868c5f01b2fSopenharmony_ci JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>()); 869c5f01b2fSopenharmony_ci break; 870c5f01b2fSopenharmony_ci case value_t::array: 871c5f01b2fSopenharmony_ci JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>()); 872c5f01b2fSopenharmony_ci break; 873c5f01b2fSopenharmony_ci case value_t::binary: 874c5f01b2fSopenharmony_ci JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>()); 875c5f01b2fSopenharmony_ci break; 876c5f01b2fSopenharmony_ci case value_t::null: 877c5f01b2fSopenharmony_ci *this = nullptr; 878c5f01b2fSopenharmony_ci break; 879c5f01b2fSopenharmony_ci case value_t::discarded: 880c5f01b2fSopenharmony_ci m_type = value_t::discarded; 881c5f01b2fSopenharmony_ci break; 882c5f01b2fSopenharmony_ci default: // LCOV_EXCL_LINE 883c5f01b2fSopenharmony_ci JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE 884c5f01b2fSopenharmony_ci } 885c5f01b2fSopenharmony_ci JSON_ASSERT(m_type == val.type()); 886c5f01b2fSopenharmony_ci set_parents(); 887c5f01b2fSopenharmony_ci assert_invariant(); 888c5f01b2fSopenharmony_ci } 889c5f01b2fSopenharmony_ci 890c5f01b2fSopenharmony_ci /// @brief create a container (array or object) from an initializer list 891c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ 892c5f01b2fSopenharmony_ci basic_json(initializer_list_t init, 893c5f01b2fSopenharmony_ci bool type_deduction = true, 894c5f01b2fSopenharmony_ci value_t manual_type = value_t::array) 895c5f01b2fSopenharmony_ci { 896c5f01b2fSopenharmony_ci // check if each element is an array with two elements whose first 897c5f01b2fSopenharmony_ci // element is a string 898c5f01b2fSopenharmony_ci bool is_an_object = std::all_of(init.begin(), init.end(), 899c5f01b2fSopenharmony_ci [](const detail::json_ref<basic_json>& element_ref) 900c5f01b2fSopenharmony_ci { 901c5f01b2fSopenharmony_ci return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string(); 902c5f01b2fSopenharmony_ci }); 903c5f01b2fSopenharmony_ci 904c5f01b2fSopenharmony_ci // adjust type if type deduction is not wanted 905c5f01b2fSopenharmony_ci if (!type_deduction) 906c5f01b2fSopenharmony_ci { 907c5f01b2fSopenharmony_ci // if array is wanted, do not create an object though possible 908c5f01b2fSopenharmony_ci if (manual_type == value_t::array) 909c5f01b2fSopenharmony_ci { 910c5f01b2fSopenharmony_ci is_an_object = false; 911c5f01b2fSopenharmony_ci } 912c5f01b2fSopenharmony_ci 913c5f01b2fSopenharmony_ci // if object is wanted but impossible, throw an exception 914c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object)) 915c5f01b2fSopenharmony_ci { 916c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr)); 917c5f01b2fSopenharmony_ci } 918c5f01b2fSopenharmony_ci } 919c5f01b2fSopenharmony_ci 920c5f01b2fSopenharmony_ci if (is_an_object) 921c5f01b2fSopenharmony_ci { 922c5f01b2fSopenharmony_ci // the initializer list is a list of pairs -> create object 923c5f01b2fSopenharmony_ci m_type = value_t::object; 924c5f01b2fSopenharmony_ci m_value = value_t::object; 925c5f01b2fSopenharmony_ci 926c5f01b2fSopenharmony_ci for (auto& element_ref : init) 927c5f01b2fSopenharmony_ci { 928c5f01b2fSopenharmony_ci auto element = element_ref.moved_or_copied(); 929c5f01b2fSopenharmony_ci m_value.object->emplace( 930c5f01b2fSopenharmony_ci std::move(*((*element.m_value.array)[0].m_value.string)), 931c5f01b2fSopenharmony_ci std::move((*element.m_value.array)[1])); 932c5f01b2fSopenharmony_ci } 933c5f01b2fSopenharmony_ci } 934c5f01b2fSopenharmony_ci else 935c5f01b2fSopenharmony_ci { 936c5f01b2fSopenharmony_ci // the initializer list describes an array -> create array 937c5f01b2fSopenharmony_ci m_type = value_t::array; 938c5f01b2fSopenharmony_ci m_value.array = create<array_t>(init.begin(), init.end()); 939c5f01b2fSopenharmony_ci } 940c5f01b2fSopenharmony_ci 941c5f01b2fSopenharmony_ci set_parents(); 942c5f01b2fSopenharmony_ci assert_invariant(); 943c5f01b2fSopenharmony_ci } 944c5f01b2fSopenharmony_ci 945c5f01b2fSopenharmony_ci /// @brief explicitly create a binary array (without subtype) 946c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/binary/ 947c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 948c5f01b2fSopenharmony_ci static basic_json binary(const typename binary_t::container_type& init) 949c5f01b2fSopenharmony_ci { 950c5f01b2fSopenharmony_ci auto res = basic_json(); 951c5f01b2fSopenharmony_ci res.m_type = value_t::binary; 952c5f01b2fSopenharmony_ci res.m_value = init; 953c5f01b2fSopenharmony_ci return res; 954c5f01b2fSopenharmony_ci } 955c5f01b2fSopenharmony_ci 956c5f01b2fSopenharmony_ci /// @brief explicitly create a binary array (with subtype) 957c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/binary/ 958c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 959c5f01b2fSopenharmony_ci static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype) 960c5f01b2fSopenharmony_ci { 961c5f01b2fSopenharmony_ci auto res = basic_json(); 962c5f01b2fSopenharmony_ci res.m_type = value_t::binary; 963c5f01b2fSopenharmony_ci res.m_value = binary_t(init, subtype); 964c5f01b2fSopenharmony_ci return res; 965c5f01b2fSopenharmony_ci } 966c5f01b2fSopenharmony_ci 967c5f01b2fSopenharmony_ci /// @brief explicitly create a binary array 968c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/binary/ 969c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 970c5f01b2fSopenharmony_ci static basic_json binary(typename binary_t::container_type&& init) 971c5f01b2fSopenharmony_ci { 972c5f01b2fSopenharmony_ci auto res = basic_json(); 973c5f01b2fSopenharmony_ci res.m_type = value_t::binary; 974c5f01b2fSopenharmony_ci res.m_value = std::move(init); 975c5f01b2fSopenharmony_ci return res; 976c5f01b2fSopenharmony_ci } 977c5f01b2fSopenharmony_ci 978c5f01b2fSopenharmony_ci /// @brief explicitly create a binary array (with subtype) 979c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/binary/ 980c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 981c5f01b2fSopenharmony_ci static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype) 982c5f01b2fSopenharmony_ci { 983c5f01b2fSopenharmony_ci auto res = basic_json(); 984c5f01b2fSopenharmony_ci res.m_type = value_t::binary; 985c5f01b2fSopenharmony_ci res.m_value = binary_t(std::move(init), subtype); 986c5f01b2fSopenharmony_ci return res; 987c5f01b2fSopenharmony_ci } 988c5f01b2fSopenharmony_ci 989c5f01b2fSopenharmony_ci /// @brief explicitly create an array from an initializer list 990c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/array/ 991c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 992c5f01b2fSopenharmony_ci static basic_json array(initializer_list_t init = {}) 993c5f01b2fSopenharmony_ci { 994c5f01b2fSopenharmony_ci return basic_json(init, false, value_t::array); 995c5f01b2fSopenharmony_ci } 996c5f01b2fSopenharmony_ci 997c5f01b2fSopenharmony_ci /// @brief explicitly create an object from an initializer list 998c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/object/ 999c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 1000c5f01b2fSopenharmony_ci static basic_json object(initializer_list_t init = {}) 1001c5f01b2fSopenharmony_ci { 1002c5f01b2fSopenharmony_ci return basic_json(init, false, value_t::object); 1003c5f01b2fSopenharmony_ci } 1004c5f01b2fSopenharmony_ci 1005c5f01b2fSopenharmony_ci /// @brief construct an array with count copies of given value 1006c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ 1007c5f01b2fSopenharmony_ci basic_json(size_type cnt, const basic_json& val) 1008c5f01b2fSopenharmony_ci : m_type(value_t::array) 1009c5f01b2fSopenharmony_ci { 1010c5f01b2fSopenharmony_ci m_value.array = create<array_t>(cnt, val); 1011c5f01b2fSopenharmony_ci set_parents(); 1012c5f01b2fSopenharmony_ci assert_invariant(); 1013c5f01b2fSopenharmony_ci } 1014c5f01b2fSopenharmony_ci 1015c5f01b2fSopenharmony_ci /// @brief construct a JSON container given an iterator range 1016c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ 1017c5f01b2fSopenharmony_ci template < class InputIT, typename std::enable_if < 1018c5f01b2fSopenharmony_ci std::is_same<InputIT, typename basic_json_t::iterator>::value || 1019c5f01b2fSopenharmony_ci std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 > 1020c5f01b2fSopenharmony_ci basic_json(InputIT first, InputIT last) 1021c5f01b2fSopenharmony_ci { 1022c5f01b2fSopenharmony_ci JSON_ASSERT(first.m_object != nullptr); 1023c5f01b2fSopenharmony_ci JSON_ASSERT(last.m_object != nullptr); 1024c5f01b2fSopenharmony_ci 1025c5f01b2fSopenharmony_ci // make sure iterator fits the current value 1026c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) 1027c5f01b2fSopenharmony_ci { 1028c5f01b2fSopenharmony_ci JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr)); 1029c5f01b2fSopenharmony_ci } 1030c5f01b2fSopenharmony_ci 1031c5f01b2fSopenharmony_ci // copy type from first iterator 1032c5f01b2fSopenharmony_ci m_type = first.m_object->m_type; 1033c5f01b2fSopenharmony_ci 1034c5f01b2fSopenharmony_ci // check if iterator range is complete for primitive values 1035c5f01b2fSopenharmony_ci switch (m_type) 1036c5f01b2fSopenharmony_ci { 1037c5f01b2fSopenharmony_ci case value_t::boolean: 1038c5f01b2fSopenharmony_ci case value_t::number_float: 1039c5f01b2fSopenharmony_ci case value_t::number_integer: 1040c5f01b2fSopenharmony_ci case value_t::number_unsigned: 1041c5f01b2fSopenharmony_ci case value_t::string: 1042c5f01b2fSopenharmony_ci { 1043c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin() 1044c5f01b2fSopenharmony_ci || !last.m_it.primitive_iterator.is_end())) 1045c5f01b2fSopenharmony_ci { 1046c5f01b2fSopenharmony_ci JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object)); 1047c5f01b2fSopenharmony_ci } 1048c5f01b2fSopenharmony_ci break; 1049c5f01b2fSopenharmony_ci } 1050c5f01b2fSopenharmony_ci 1051c5f01b2fSopenharmony_ci case value_t::null: 1052c5f01b2fSopenharmony_ci case value_t::object: 1053c5f01b2fSopenharmony_ci case value_t::array: 1054c5f01b2fSopenharmony_ci case value_t::binary: 1055c5f01b2fSopenharmony_ci case value_t::discarded: 1056c5f01b2fSopenharmony_ci default: 1057c5f01b2fSopenharmony_ci break; 1058c5f01b2fSopenharmony_ci } 1059c5f01b2fSopenharmony_ci 1060c5f01b2fSopenharmony_ci switch (m_type) 1061c5f01b2fSopenharmony_ci { 1062c5f01b2fSopenharmony_ci case value_t::number_integer: 1063c5f01b2fSopenharmony_ci { 1064c5f01b2fSopenharmony_ci m_value.number_integer = first.m_object->m_value.number_integer; 1065c5f01b2fSopenharmony_ci break; 1066c5f01b2fSopenharmony_ci } 1067c5f01b2fSopenharmony_ci 1068c5f01b2fSopenharmony_ci case value_t::number_unsigned: 1069c5f01b2fSopenharmony_ci { 1070c5f01b2fSopenharmony_ci m_value.number_unsigned = first.m_object->m_value.number_unsigned; 1071c5f01b2fSopenharmony_ci break; 1072c5f01b2fSopenharmony_ci } 1073c5f01b2fSopenharmony_ci 1074c5f01b2fSopenharmony_ci case value_t::number_float: 1075c5f01b2fSopenharmony_ci { 1076c5f01b2fSopenharmony_ci m_value.number_float = first.m_object->m_value.number_float; 1077c5f01b2fSopenharmony_ci break; 1078c5f01b2fSopenharmony_ci } 1079c5f01b2fSopenharmony_ci 1080c5f01b2fSopenharmony_ci case value_t::boolean: 1081c5f01b2fSopenharmony_ci { 1082c5f01b2fSopenharmony_ci m_value.boolean = first.m_object->m_value.boolean; 1083c5f01b2fSopenharmony_ci break; 1084c5f01b2fSopenharmony_ci } 1085c5f01b2fSopenharmony_ci 1086c5f01b2fSopenharmony_ci case value_t::string: 1087c5f01b2fSopenharmony_ci { 1088c5f01b2fSopenharmony_ci m_value = *first.m_object->m_value.string; 1089c5f01b2fSopenharmony_ci break; 1090c5f01b2fSopenharmony_ci } 1091c5f01b2fSopenharmony_ci 1092c5f01b2fSopenharmony_ci case value_t::object: 1093c5f01b2fSopenharmony_ci { 1094c5f01b2fSopenharmony_ci m_value.object = create<object_t>(first.m_it.object_iterator, 1095c5f01b2fSopenharmony_ci last.m_it.object_iterator); 1096c5f01b2fSopenharmony_ci break; 1097c5f01b2fSopenharmony_ci } 1098c5f01b2fSopenharmony_ci 1099c5f01b2fSopenharmony_ci case value_t::array: 1100c5f01b2fSopenharmony_ci { 1101c5f01b2fSopenharmony_ci m_value.array = create<array_t>(first.m_it.array_iterator, 1102c5f01b2fSopenharmony_ci last.m_it.array_iterator); 1103c5f01b2fSopenharmony_ci break; 1104c5f01b2fSopenharmony_ci } 1105c5f01b2fSopenharmony_ci 1106c5f01b2fSopenharmony_ci case value_t::binary: 1107c5f01b2fSopenharmony_ci { 1108c5f01b2fSopenharmony_ci m_value = *first.m_object->m_value.binary; 1109c5f01b2fSopenharmony_ci break; 1110c5f01b2fSopenharmony_ci } 1111c5f01b2fSopenharmony_ci 1112c5f01b2fSopenharmony_ci case value_t::null: 1113c5f01b2fSopenharmony_ci case value_t::discarded: 1114c5f01b2fSopenharmony_ci default: 1115c5f01b2fSopenharmony_ci JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object)); 1116c5f01b2fSopenharmony_ci } 1117c5f01b2fSopenharmony_ci 1118c5f01b2fSopenharmony_ci set_parents(); 1119c5f01b2fSopenharmony_ci assert_invariant(); 1120c5f01b2fSopenharmony_ci } 1121c5f01b2fSopenharmony_ci 1122c5f01b2fSopenharmony_ci 1123c5f01b2fSopenharmony_ci /////////////////////////////////////// 1124c5f01b2fSopenharmony_ci // other constructors and destructor // 1125c5f01b2fSopenharmony_ci /////////////////////////////////////// 1126c5f01b2fSopenharmony_ci 1127c5f01b2fSopenharmony_ci template<typename JsonRef, 1128c5f01b2fSopenharmony_ci detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>, 1129c5f01b2fSopenharmony_ci std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 > 1130c5f01b2fSopenharmony_ci basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {} 1131c5f01b2fSopenharmony_ci 1132c5f01b2fSopenharmony_ci /// @brief copy constructor 1133c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ 1134c5f01b2fSopenharmony_ci basic_json(const basic_json& other) 1135c5f01b2fSopenharmony_ci : m_type(other.m_type) 1136c5f01b2fSopenharmony_ci { 1137c5f01b2fSopenharmony_ci // check of passed value is valid 1138c5f01b2fSopenharmony_ci other.assert_invariant(); 1139c5f01b2fSopenharmony_ci 1140c5f01b2fSopenharmony_ci switch (m_type) 1141c5f01b2fSopenharmony_ci { 1142c5f01b2fSopenharmony_ci case value_t::object: 1143c5f01b2fSopenharmony_ci { 1144c5f01b2fSopenharmony_ci m_value = *other.m_value.object; 1145c5f01b2fSopenharmony_ci break; 1146c5f01b2fSopenharmony_ci } 1147c5f01b2fSopenharmony_ci 1148c5f01b2fSopenharmony_ci case value_t::array: 1149c5f01b2fSopenharmony_ci { 1150c5f01b2fSopenharmony_ci m_value = *other.m_value.array; 1151c5f01b2fSopenharmony_ci break; 1152c5f01b2fSopenharmony_ci } 1153c5f01b2fSopenharmony_ci 1154c5f01b2fSopenharmony_ci case value_t::string: 1155c5f01b2fSopenharmony_ci { 1156c5f01b2fSopenharmony_ci m_value = *other.m_value.string; 1157c5f01b2fSopenharmony_ci break; 1158c5f01b2fSopenharmony_ci } 1159c5f01b2fSopenharmony_ci 1160c5f01b2fSopenharmony_ci case value_t::boolean: 1161c5f01b2fSopenharmony_ci { 1162c5f01b2fSopenharmony_ci m_value = other.m_value.boolean; 1163c5f01b2fSopenharmony_ci break; 1164c5f01b2fSopenharmony_ci } 1165c5f01b2fSopenharmony_ci 1166c5f01b2fSopenharmony_ci case value_t::number_integer: 1167c5f01b2fSopenharmony_ci { 1168c5f01b2fSopenharmony_ci m_value = other.m_value.number_integer; 1169c5f01b2fSopenharmony_ci break; 1170c5f01b2fSopenharmony_ci } 1171c5f01b2fSopenharmony_ci 1172c5f01b2fSopenharmony_ci case value_t::number_unsigned: 1173c5f01b2fSopenharmony_ci { 1174c5f01b2fSopenharmony_ci m_value = other.m_value.number_unsigned; 1175c5f01b2fSopenharmony_ci break; 1176c5f01b2fSopenharmony_ci } 1177c5f01b2fSopenharmony_ci 1178c5f01b2fSopenharmony_ci case value_t::number_float: 1179c5f01b2fSopenharmony_ci { 1180c5f01b2fSopenharmony_ci m_value = other.m_value.number_float; 1181c5f01b2fSopenharmony_ci break; 1182c5f01b2fSopenharmony_ci } 1183c5f01b2fSopenharmony_ci 1184c5f01b2fSopenharmony_ci case value_t::binary: 1185c5f01b2fSopenharmony_ci { 1186c5f01b2fSopenharmony_ci m_value = *other.m_value.binary; 1187c5f01b2fSopenharmony_ci break; 1188c5f01b2fSopenharmony_ci } 1189c5f01b2fSopenharmony_ci 1190c5f01b2fSopenharmony_ci case value_t::null: 1191c5f01b2fSopenharmony_ci case value_t::discarded: 1192c5f01b2fSopenharmony_ci default: 1193c5f01b2fSopenharmony_ci break; 1194c5f01b2fSopenharmony_ci } 1195c5f01b2fSopenharmony_ci 1196c5f01b2fSopenharmony_ci set_parents(); 1197c5f01b2fSopenharmony_ci assert_invariant(); 1198c5f01b2fSopenharmony_ci } 1199c5f01b2fSopenharmony_ci 1200c5f01b2fSopenharmony_ci /// @brief move constructor 1201c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ 1202c5f01b2fSopenharmony_ci basic_json(basic_json&& other) noexcept 1203c5f01b2fSopenharmony_ci : m_type(std::move(other.m_type)), 1204c5f01b2fSopenharmony_ci m_value(std::move(other.m_value)) 1205c5f01b2fSopenharmony_ci { 1206c5f01b2fSopenharmony_ci // check that passed value is valid 1207c5f01b2fSopenharmony_ci other.assert_invariant(false); 1208c5f01b2fSopenharmony_ci 1209c5f01b2fSopenharmony_ci // invalidate payload 1210c5f01b2fSopenharmony_ci other.m_type = value_t::null; 1211c5f01b2fSopenharmony_ci other.m_value = {}; 1212c5f01b2fSopenharmony_ci 1213c5f01b2fSopenharmony_ci set_parents(); 1214c5f01b2fSopenharmony_ci assert_invariant(); 1215c5f01b2fSopenharmony_ci } 1216c5f01b2fSopenharmony_ci 1217c5f01b2fSopenharmony_ci /// @brief copy assignment 1218c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator=/ 1219c5f01b2fSopenharmony_ci basic_json& operator=(basic_json other) noexcept ( 1220c5f01b2fSopenharmony_ci std::is_nothrow_move_constructible<value_t>::value&& 1221c5f01b2fSopenharmony_ci std::is_nothrow_move_assignable<value_t>::value&& 1222c5f01b2fSopenharmony_ci std::is_nothrow_move_constructible<json_value>::value&& 1223c5f01b2fSopenharmony_ci std::is_nothrow_move_assignable<json_value>::value 1224c5f01b2fSopenharmony_ci ) 1225c5f01b2fSopenharmony_ci { 1226c5f01b2fSopenharmony_ci // check that passed value is valid 1227c5f01b2fSopenharmony_ci other.assert_invariant(); 1228c5f01b2fSopenharmony_ci 1229c5f01b2fSopenharmony_ci using std::swap; 1230c5f01b2fSopenharmony_ci swap(m_type, other.m_type); 1231c5f01b2fSopenharmony_ci swap(m_value, other.m_value); 1232c5f01b2fSopenharmony_ci 1233c5f01b2fSopenharmony_ci set_parents(); 1234c5f01b2fSopenharmony_ci assert_invariant(); 1235c5f01b2fSopenharmony_ci return *this; 1236c5f01b2fSopenharmony_ci } 1237c5f01b2fSopenharmony_ci 1238c5f01b2fSopenharmony_ci /// @brief destructor 1239c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/~basic_json/ 1240c5f01b2fSopenharmony_ci ~basic_json() noexcept 1241c5f01b2fSopenharmony_ci { 1242c5f01b2fSopenharmony_ci assert_invariant(false); 1243c5f01b2fSopenharmony_ci m_value.destroy(m_type); 1244c5f01b2fSopenharmony_ci } 1245c5f01b2fSopenharmony_ci 1246c5f01b2fSopenharmony_ci /// @} 1247c5f01b2fSopenharmony_ci 1248c5f01b2fSopenharmony_ci public: 1249c5f01b2fSopenharmony_ci /////////////////////// 1250c5f01b2fSopenharmony_ci // object inspection // 1251c5f01b2fSopenharmony_ci /////////////////////// 1252c5f01b2fSopenharmony_ci 1253c5f01b2fSopenharmony_ci /// @name object inspection 1254c5f01b2fSopenharmony_ci /// Functions to inspect the type of a JSON value. 1255c5f01b2fSopenharmony_ci /// @{ 1256c5f01b2fSopenharmony_ci 1257c5f01b2fSopenharmony_ci /// @brief serialization 1258c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/dump/ 1259c5f01b2fSopenharmony_ci string_t dump(const int indent = -1, 1260c5f01b2fSopenharmony_ci const char indent_char = ' ', 1261c5f01b2fSopenharmony_ci const bool ensure_ascii = false, 1262c5f01b2fSopenharmony_ci const error_handler_t error_handler = error_handler_t::strict) const 1263c5f01b2fSopenharmony_ci { 1264c5f01b2fSopenharmony_ci string_t result; 1265c5f01b2fSopenharmony_ci serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler); 1266c5f01b2fSopenharmony_ci 1267c5f01b2fSopenharmony_ci if (indent >= 0) 1268c5f01b2fSopenharmony_ci { 1269c5f01b2fSopenharmony_ci s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent)); 1270c5f01b2fSopenharmony_ci } 1271c5f01b2fSopenharmony_ci else 1272c5f01b2fSopenharmony_ci { 1273c5f01b2fSopenharmony_ci s.dump(*this, false, ensure_ascii, 0); 1274c5f01b2fSopenharmony_ci } 1275c5f01b2fSopenharmony_ci 1276c5f01b2fSopenharmony_ci return result; 1277c5f01b2fSopenharmony_ci } 1278c5f01b2fSopenharmony_ci 1279c5f01b2fSopenharmony_ci /// @brief return the type of the JSON value (explicit) 1280c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/type/ 1281c5f01b2fSopenharmony_ci constexpr value_t type() const noexcept 1282c5f01b2fSopenharmony_ci { 1283c5f01b2fSopenharmony_ci return m_type; 1284c5f01b2fSopenharmony_ci } 1285c5f01b2fSopenharmony_ci 1286c5f01b2fSopenharmony_ci /// @brief return whether type is primitive 1287c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/is_primitive/ 1288c5f01b2fSopenharmony_ci constexpr bool is_primitive() const noexcept 1289c5f01b2fSopenharmony_ci { 1290c5f01b2fSopenharmony_ci return is_null() || is_string() || is_boolean() || is_number() || is_binary(); 1291c5f01b2fSopenharmony_ci } 1292c5f01b2fSopenharmony_ci 1293c5f01b2fSopenharmony_ci /// @brief return whether type is structured 1294c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/is_structured/ 1295c5f01b2fSopenharmony_ci constexpr bool is_structured() const noexcept 1296c5f01b2fSopenharmony_ci { 1297c5f01b2fSopenharmony_ci return is_array() || is_object(); 1298c5f01b2fSopenharmony_ci } 1299c5f01b2fSopenharmony_ci 1300c5f01b2fSopenharmony_ci /// @brief return whether value is null 1301c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/is_null/ 1302c5f01b2fSopenharmony_ci constexpr bool is_null() const noexcept 1303c5f01b2fSopenharmony_ci { 1304c5f01b2fSopenharmony_ci return m_type == value_t::null; 1305c5f01b2fSopenharmony_ci } 1306c5f01b2fSopenharmony_ci 1307c5f01b2fSopenharmony_ci /// @brief return whether value is a boolean 1308c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/is_boolean/ 1309c5f01b2fSopenharmony_ci constexpr bool is_boolean() const noexcept 1310c5f01b2fSopenharmony_ci { 1311c5f01b2fSopenharmony_ci return m_type == value_t::boolean; 1312c5f01b2fSopenharmony_ci } 1313c5f01b2fSopenharmony_ci 1314c5f01b2fSopenharmony_ci /// @brief return whether value is a number 1315c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/is_number/ 1316c5f01b2fSopenharmony_ci constexpr bool is_number() const noexcept 1317c5f01b2fSopenharmony_ci { 1318c5f01b2fSopenharmony_ci return is_number_integer() || is_number_float(); 1319c5f01b2fSopenharmony_ci } 1320c5f01b2fSopenharmony_ci 1321c5f01b2fSopenharmony_ci /// @brief return whether value is an integer number 1322c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/is_number_integer/ 1323c5f01b2fSopenharmony_ci constexpr bool is_number_integer() const noexcept 1324c5f01b2fSopenharmony_ci { 1325c5f01b2fSopenharmony_ci return m_type == value_t::number_integer || m_type == value_t::number_unsigned; 1326c5f01b2fSopenharmony_ci } 1327c5f01b2fSopenharmony_ci 1328c5f01b2fSopenharmony_ci /// @brief return whether value is an unsigned integer number 1329c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/is_number_unsigned/ 1330c5f01b2fSopenharmony_ci constexpr bool is_number_unsigned() const noexcept 1331c5f01b2fSopenharmony_ci { 1332c5f01b2fSopenharmony_ci return m_type == value_t::number_unsigned; 1333c5f01b2fSopenharmony_ci } 1334c5f01b2fSopenharmony_ci 1335c5f01b2fSopenharmony_ci /// @brief return whether value is a floating-point number 1336c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/is_number_float/ 1337c5f01b2fSopenharmony_ci constexpr bool is_number_float() const noexcept 1338c5f01b2fSopenharmony_ci { 1339c5f01b2fSopenharmony_ci return m_type == value_t::number_float; 1340c5f01b2fSopenharmony_ci } 1341c5f01b2fSopenharmony_ci 1342c5f01b2fSopenharmony_ci /// @brief return whether value is an object 1343c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/is_object/ 1344c5f01b2fSopenharmony_ci constexpr bool is_object() const noexcept 1345c5f01b2fSopenharmony_ci { 1346c5f01b2fSopenharmony_ci return m_type == value_t::object; 1347c5f01b2fSopenharmony_ci } 1348c5f01b2fSopenharmony_ci 1349c5f01b2fSopenharmony_ci /// @brief return whether value is an array 1350c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/is_array/ 1351c5f01b2fSopenharmony_ci constexpr bool is_array() const noexcept 1352c5f01b2fSopenharmony_ci { 1353c5f01b2fSopenharmony_ci return m_type == value_t::array; 1354c5f01b2fSopenharmony_ci } 1355c5f01b2fSopenharmony_ci 1356c5f01b2fSopenharmony_ci /// @brief return whether value is a string 1357c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/is_string/ 1358c5f01b2fSopenharmony_ci constexpr bool is_string() const noexcept 1359c5f01b2fSopenharmony_ci { 1360c5f01b2fSopenharmony_ci return m_type == value_t::string; 1361c5f01b2fSopenharmony_ci } 1362c5f01b2fSopenharmony_ci 1363c5f01b2fSopenharmony_ci /// @brief return whether value is a binary array 1364c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/is_binary/ 1365c5f01b2fSopenharmony_ci constexpr bool is_binary() const noexcept 1366c5f01b2fSopenharmony_ci { 1367c5f01b2fSopenharmony_ci return m_type == value_t::binary; 1368c5f01b2fSopenharmony_ci } 1369c5f01b2fSopenharmony_ci 1370c5f01b2fSopenharmony_ci /// @brief return whether value is discarded 1371c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/is_discarded/ 1372c5f01b2fSopenharmony_ci constexpr bool is_discarded() const noexcept 1373c5f01b2fSopenharmony_ci { 1374c5f01b2fSopenharmony_ci return m_type == value_t::discarded; 1375c5f01b2fSopenharmony_ci } 1376c5f01b2fSopenharmony_ci 1377c5f01b2fSopenharmony_ci /// @brief return the type of the JSON value (implicit) 1378c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_value_t/ 1379c5f01b2fSopenharmony_ci constexpr operator value_t() const noexcept 1380c5f01b2fSopenharmony_ci { 1381c5f01b2fSopenharmony_ci return m_type; 1382c5f01b2fSopenharmony_ci } 1383c5f01b2fSopenharmony_ci 1384c5f01b2fSopenharmony_ci /// @} 1385c5f01b2fSopenharmony_ci 1386c5f01b2fSopenharmony_ci private: 1387c5f01b2fSopenharmony_ci ////////////////// 1388c5f01b2fSopenharmony_ci // value access // 1389c5f01b2fSopenharmony_ci ////////////////// 1390c5f01b2fSopenharmony_ci 1391c5f01b2fSopenharmony_ci /// get a boolean (explicit) 1392c5f01b2fSopenharmony_ci boolean_t get_impl(boolean_t* /*unused*/) const 1393c5f01b2fSopenharmony_ci { 1394c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_boolean())) 1395c5f01b2fSopenharmony_ci { 1396c5f01b2fSopenharmony_ci return m_value.boolean; 1397c5f01b2fSopenharmony_ci } 1398c5f01b2fSopenharmony_ci 1399c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this)); 1400c5f01b2fSopenharmony_ci } 1401c5f01b2fSopenharmony_ci 1402c5f01b2fSopenharmony_ci /// get a pointer to the value (object) 1403c5f01b2fSopenharmony_ci object_t* get_impl_ptr(object_t* /*unused*/) noexcept 1404c5f01b2fSopenharmony_ci { 1405c5f01b2fSopenharmony_ci return is_object() ? m_value.object : nullptr; 1406c5f01b2fSopenharmony_ci } 1407c5f01b2fSopenharmony_ci 1408c5f01b2fSopenharmony_ci /// get a pointer to the value (object) 1409c5f01b2fSopenharmony_ci constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept 1410c5f01b2fSopenharmony_ci { 1411c5f01b2fSopenharmony_ci return is_object() ? m_value.object : nullptr; 1412c5f01b2fSopenharmony_ci } 1413c5f01b2fSopenharmony_ci 1414c5f01b2fSopenharmony_ci /// get a pointer to the value (array) 1415c5f01b2fSopenharmony_ci array_t* get_impl_ptr(array_t* /*unused*/) noexcept 1416c5f01b2fSopenharmony_ci { 1417c5f01b2fSopenharmony_ci return is_array() ? m_value.array : nullptr; 1418c5f01b2fSopenharmony_ci } 1419c5f01b2fSopenharmony_ci 1420c5f01b2fSopenharmony_ci /// get a pointer to the value (array) 1421c5f01b2fSopenharmony_ci constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept 1422c5f01b2fSopenharmony_ci { 1423c5f01b2fSopenharmony_ci return is_array() ? m_value.array : nullptr; 1424c5f01b2fSopenharmony_ci } 1425c5f01b2fSopenharmony_ci 1426c5f01b2fSopenharmony_ci /// get a pointer to the value (string) 1427c5f01b2fSopenharmony_ci string_t* get_impl_ptr(string_t* /*unused*/) noexcept 1428c5f01b2fSopenharmony_ci { 1429c5f01b2fSopenharmony_ci return is_string() ? m_value.string : nullptr; 1430c5f01b2fSopenharmony_ci } 1431c5f01b2fSopenharmony_ci 1432c5f01b2fSopenharmony_ci /// get a pointer to the value (string) 1433c5f01b2fSopenharmony_ci constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept 1434c5f01b2fSopenharmony_ci { 1435c5f01b2fSopenharmony_ci return is_string() ? m_value.string : nullptr; 1436c5f01b2fSopenharmony_ci } 1437c5f01b2fSopenharmony_ci 1438c5f01b2fSopenharmony_ci /// get a pointer to the value (boolean) 1439c5f01b2fSopenharmony_ci boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept 1440c5f01b2fSopenharmony_ci { 1441c5f01b2fSopenharmony_ci return is_boolean() ? &m_value.boolean : nullptr; 1442c5f01b2fSopenharmony_ci } 1443c5f01b2fSopenharmony_ci 1444c5f01b2fSopenharmony_ci /// get a pointer to the value (boolean) 1445c5f01b2fSopenharmony_ci constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept 1446c5f01b2fSopenharmony_ci { 1447c5f01b2fSopenharmony_ci return is_boolean() ? &m_value.boolean : nullptr; 1448c5f01b2fSopenharmony_ci } 1449c5f01b2fSopenharmony_ci 1450c5f01b2fSopenharmony_ci /// get a pointer to the value (integer number) 1451c5f01b2fSopenharmony_ci number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept 1452c5f01b2fSopenharmony_ci { 1453c5f01b2fSopenharmony_ci return is_number_integer() ? &m_value.number_integer : nullptr; 1454c5f01b2fSopenharmony_ci } 1455c5f01b2fSopenharmony_ci 1456c5f01b2fSopenharmony_ci /// get a pointer to the value (integer number) 1457c5f01b2fSopenharmony_ci constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept 1458c5f01b2fSopenharmony_ci { 1459c5f01b2fSopenharmony_ci return is_number_integer() ? &m_value.number_integer : nullptr; 1460c5f01b2fSopenharmony_ci } 1461c5f01b2fSopenharmony_ci 1462c5f01b2fSopenharmony_ci /// get a pointer to the value (unsigned number) 1463c5f01b2fSopenharmony_ci number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept 1464c5f01b2fSopenharmony_ci { 1465c5f01b2fSopenharmony_ci return is_number_unsigned() ? &m_value.number_unsigned : nullptr; 1466c5f01b2fSopenharmony_ci } 1467c5f01b2fSopenharmony_ci 1468c5f01b2fSopenharmony_ci /// get a pointer to the value (unsigned number) 1469c5f01b2fSopenharmony_ci constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept 1470c5f01b2fSopenharmony_ci { 1471c5f01b2fSopenharmony_ci return is_number_unsigned() ? &m_value.number_unsigned : nullptr; 1472c5f01b2fSopenharmony_ci } 1473c5f01b2fSopenharmony_ci 1474c5f01b2fSopenharmony_ci /// get a pointer to the value (floating-point number) 1475c5f01b2fSopenharmony_ci number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept 1476c5f01b2fSopenharmony_ci { 1477c5f01b2fSopenharmony_ci return is_number_float() ? &m_value.number_float : nullptr; 1478c5f01b2fSopenharmony_ci } 1479c5f01b2fSopenharmony_ci 1480c5f01b2fSopenharmony_ci /// get a pointer to the value (floating-point number) 1481c5f01b2fSopenharmony_ci constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept 1482c5f01b2fSopenharmony_ci { 1483c5f01b2fSopenharmony_ci return is_number_float() ? &m_value.number_float : nullptr; 1484c5f01b2fSopenharmony_ci } 1485c5f01b2fSopenharmony_ci 1486c5f01b2fSopenharmony_ci /// get a pointer to the value (binary) 1487c5f01b2fSopenharmony_ci binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept 1488c5f01b2fSopenharmony_ci { 1489c5f01b2fSopenharmony_ci return is_binary() ? m_value.binary : nullptr; 1490c5f01b2fSopenharmony_ci } 1491c5f01b2fSopenharmony_ci 1492c5f01b2fSopenharmony_ci /// get a pointer to the value (binary) 1493c5f01b2fSopenharmony_ci constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept 1494c5f01b2fSopenharmony_ci { 1495c5f01b2fSopenharmony_ci return is_binary() ? m_value.binary : nullptr; 1496c5f01b2fSopenharmony_ci } 1497c5f01b2fSopenharmony_ci 1498c5f01b2fSopenharmony_ci /*! 1499c5f01b2fSopenharmony_ci @brief helper function to implement get_ref() 1500c5f01b2fSopenharmony_ci 1501c5f01b2fSopenharmony_ci This function helps to implement get_ref() without code duplication for 1502c5f01b2fSopenharmony_ci const and non-const overloads 1503c5f01b2fSopenharmony_ci 1504c5f01b2fSopenharmony_ci @tparam ThisType will be deduced as `basic_json` or `const basic_json` 1505c5f01b2fSopenharmony_ci 1506c5f01b2fSopenharmony_ci @throw type_error.303 if ReferenceType does not match underlying value 1507c5f01b2fSopenharmony_ci type of the current JSON 1508c5f01b2fSopenharmony_ci */ 1509c5f01b2fSopenharmony_ci template<typename ReferenceType, typename ThisType> 1510c5f01b2fSopenharmony_ci static ReferenceType get_ref_impl(ThisType& obj) 1511c5f01b2fSopenharmony_ci { 1512c5f01b2fSopenharmony_ci // delegate the call to get_ptr<>() 1513c5f01b2fSopenharmony_ci auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>(); 1514c5f01b2fSopenharmony_ci 1515c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(ptr != nullptr)) 1516c5f01b2fSopenharmony_ci { 1517c5f01b2fSopenharmony_ci return *ptr; 1518c5f01b2fSopenharmony_ci } 1519c5f01b2fSopenharmony_ci 1520c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj)); 1521c5f01b2fSopenharmony_ci } 1522c5f01b2fSopenharmony_ci 1523c5f01b2fSopenharmony_ci public: 1524c5f01b2fSopenharmony_ci /// @name value access 1525c5f01b2fSopenharmony_ci /// Direct access to the stored value of a JSON value. 1526c5f01b2fSopenharmony_ci /// @{ 1527c5f01b2fSopenharmony_ci 1528c5f01b2fSopenharmony_ci /// @brief get a pointer value (implicit) 1529c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/get_ptr/ 1530c5f01b2fSopenharmony_ci template<typename PointerType, typename std::enable_if< 1531c5f01b2fSopenharmony_ci std::is_pointer<PointerType>::value, int>::type = 0> 1532c5f01b2fSopenharmony_ci auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>())) 1533c5f01b2fSopenharmony_ci { 1534c5f01b2fSopenharmony_ci // delegate the call to get_impl_ptr<>() 1535c5f01b2fSopenharmony_ci return get_impl_ptr(static_cast<PointerType>(nullptr)); 1536c5f01b2fSopenharmony_ci } 1537c5f01b2fSopenharmony_ci 1538c5f01b2fSopenharmony_ci /// @brief get a pointer value (implicit) 1539c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/get_ptr/ 1540c5f01b2fSopenharmony_ci template < typename PointerType, typename std::enable_if < 1541c5f01b2fSopenharmony_ci std::is_pointer<PointerType>::value&& 1542c5f01b2fSopenharmony_ci std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 > 1543c5f01b2fSopenharmony_ci constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>())) 1544c5f01b2fSopenharmony_ci { 1545c5f01b2fSopenharmony_ci // delegate the call to get_impl_ptr<>() const 1546c5f01b2fSopenharmony_ci return get_impl_ptr(static_cast<PointerType>(nullptr)); 1547c5f01b2fSopenharmony_ci } 1548c5f01b2fSopenharmony_ci 1549c5f01b2fSopenharmony_ci private: 1550c5f01b2fSopenharmony_ci /*! 1551c5f01b2fSopenharmony_ci @brief get a value (explicit) 1552c5f01b2fSopenharmony_ci 1553c5f01b2fSopenharmony_ci Explicit type conversion between the JSON value and a compatible value 1554c5f01b2fSopenharmony_ci which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) 1555c5f01b2fSopenharmony_ci and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). 1556c5f01b2fSopenharmony_ci The value is converted by calling the @ref json_serializer<ValueType> 1557c5f01b2fSopenharmony_ci `from_json()` method. 1558c5f01b2fSopenharmony_ci 1559c5f01b2fSopenharmony_ci The function is equivalent to executing 1560c5f01b2fSopenharmony_ci @code {.cpp} 1561c5f01b2fSopenharmony_ci ValueType ret; 1562c5f01b2fSopenharmony_ci JSONSerializer<ValueType>::from_json(*this, ret); 1563c5f01b2fSopenharmony_ci return ret; 1564c5f01b2fSopenharmony_ci @endcode 1565c5f01b2fSopenharmony_ci 1566c5f01b2fSopenharmony_ci This overloads is chosen if: 1567c5f01b2fSopenharmony_ci - @a ValueType is not @ref basic_json, 1568c5f01b2fSopenharmony_ci - @ref json_serializer<ValueType> has a `from_json()` method of the form 1569c5f01b2fSopenharmony_ci `void from_json(const basic_json&, ValueType&)`, and 1570c5f01b2fSopenharmony_ci - @ref json_serializer<ValueType> does not have a `from_json()` method of 1571c5f01b2fSopenharmony_ci the form `ValueType from_json(const basic_json&)` 1572c5f01b2fSopenharmony_ci 1573c5f01b2fSopenharmony_ci @tparam ValueType the returned value type 1574c5f01b2fSopenharmony_ci 1575c5f01b2fSopenharmony_ci @return copy of the JSON value, converted to @a ValueType 1576c5f01b2fSopenharmony_ci 1577c5f01b2fSopenharmony_ci @throw what @ref json_serializer<ValueType> `from_json()` method throws 1578c5f01b2fSopenharmony_ci 1579c5f01b2fSopenharmony_ci @liveexample{The example below shows several conversions from JSON values 1580c5f01b2fSopenharmony_ci to other types. There a few things to note: (1) Floating-point numbers can 1581c5f01b2fSopenharmony_ci be converted to integers\, (2) A JSON array can be converted to a standard 1582c5f01b2fSopenharmony_ci `std::vector<short>`\, (3) A JSON object can be converted to C++ 1583c5f01b2fSopenharmony_ci associative containers such as `std::unordered_map<std::string\, 1584c5f01b2fSopenharmony_ci json>`.,get__ValueType_const} 1585c5f01b2fSopenharmony_ci 1586c5f01b2fSopenharmony_ci @since version 2.1.0 1587c5f01b2fSopenharmony_ci */ 1588c5f01b2fSopenharmony_ci template < typename ValueType, 1589c5f01b2fSopenharmony_ci detail::enable_if_t < 1590c5f01b2fSopenharmony_ci detail::is_default_constructible<ValueType>::value&& 1591c5f01b2fSopenharmony_ci detail::has_from_json<basic_json_t, ValueType>::value, 1592c5f01b2fSopenharmony_ci int > = 0 > 1593c5f01b2fSopenharmony_ci ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept( 1594c5f01b2fSopenharmony_ci JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>()))) 1595c5f01b2fSopenharmony_ci { 1596c5f01b2fSopenharmony_ci auto ret = ValueType(); 1597c5f01b2fSopenharmony_ci JSONSerializer<ValueType>::from_json(*this, ret); 1598c5f01b2fSopenharmony_ci return ret; 1599c5f01b2fSopenharmony_ci } 1600c5f01b2fSopenharmony_ci 1601c5f01b2fSopenharmony_ci /*! 1602c5f01b2fSopenharmony_ci @brief get a value (explicit); special case 1603c5f01b2fSopenharmony_ci 1604c5f01b2fSopenharmony_ci Explicit type conversion between the JSON value and a compatible value 1605c5f01b2fSopenharmony_ci which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) 1606c5f01b2fSopenharmony_ci and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). 1607c5f01b2fSopenharmony_ci The value is converted by calling the @ref json_serializer<ValueType> 1608c5f01b2fSopenharmony_ci `from_json()` method. 1609c5f01b2fSopenharmony_ci 1610c5f01b2fSopenharmony_ci The function is equivalent to executing 1611c5f01b2fSopenharmony_ci @code {.cpp} 1612c5f01b2fSopenharmony_ci return JSONSerializer<ValueType>::from_json(*this); 1613c5f01b2fSopenharmony_ci @endcode 1614c5f01b2fSopenharmony_ci 1615c5f01b2fSopenharmony_ci This overloads is chosen if: 1616c5f01b2fSopenharmony_ci - @a ValueType is not @ref basic_json and 1617c5f01b2fSopenharmony_ci - @ref json_serializer<ValueType> has a `from_json()` method of the form 1618c5f01b2fSopenharmony_ci `ValueType from_json(const basic_json&)` 1619c5f01b2fSopenharmony_ci 1620c5f01b2fSopenharmony_ci @note If @ref json_serializer<ValueType> has both overloads of 1621c5f01b2fSopenharmony_ci `from_json()`, this one is chosen. 1622c5f01b2fSopenharmony_ci 1623c5f01b2fSopenharmony_ci @tparam ValueType the returned value type 1624c5f01b2fSopenharmony_ci 1625c5f01b2fSopenharmony_ci @return copy of the JSON value, converted to @a ValueType 1626c5f01b2fSopenharmony_ci 1627c5f01b2fSopenharmony_ci @throw what @ref json_serializer<ValueType> `from_json()` method throws 1628c5f01b2fSopenharmony_ci 1629c5f01b2fSopenharmony_ci @since version 2.1.0 1630c5f01b2fSopenharmony_ci */ 1631c5f01b2fSopenharmony_ci template < typename ValueType, 1632c5f01b2fSopenharmony_ci detail::enable_if_t < 1633c5f01b2fSopenharmony_ci detail::has_non_default_from_json<basic_json_t, ValueType>::value, 1634c5f01b2fSopenharmony_ci int > = 0 > 1635c5f01b2fSopenharmony_ci ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept( 1636c5f01b2fSopenharmony_ci JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>()))) 1637c5f01b2fSopenharmony_ci { 1638c5f01b2fSopenharmony_ci return JSONSerializer<ValueType>::from_json(*this); 1639c5f01b2fSopenharmony_ci } 1640c5f01b2fSopenharmony_ci 1641c5f01b2fSopenharmony_ci /*! 1642c5f01b2fSopenharmony_ci @brief get special-case overload 1643c5f01b2fSopenharmony_ci 1644c5f01b2fSopenharmony_ci This overloads converts the current @ref basic_json in a different 1645c5f01b2fSopenharmony_ci @ref basic_json type 1646c5f01b2fSopenharmony_ci 1647c5f01b2fSopenharmony_ci @tparam BasicJsonType == @ref basic_json 1648c5f01b2fSopenharmony_ci 1649c5f01b2fSopenharmony_ci @return a copy of *this, converted into @a BasicJsonType 1650c5f01b2fSopenharmony_ci 1651c5f01b2fSopenharmony_ci @complexity Depending on the implementation of the called `from_json()` 1652c5f01b2fSopenharmony_ci method. 1653c5f01b2fSopenharmony_ci 1654c5f01b2fSopenharmony_ci @since version 3.2.0 1655c5f01b2fSopenharmony_ci */ 1656c5f01b2fSopenharmony_ci template < typename BasicJsonType, 1657c5f01b2fSopenharmony_ci detail::enable_if_t < 1658c5f01b2fSopenharmony_ci detail::is_basic_json<BasicJsonType>::value, 1659c5f01b2fSopenharmony_ci int > = 0 > 1660c5f01b2fSopenharmony_ci BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const 1661c5f01b2fSopenharmony_ci { 1662c5f01b2fSopenharmony_ci return *this; 1663c5f01b2fSopenharmony_ci } 1664c5f01b2fSopenharmony_ci 1665c5f01b2fSopenharmony_ci /*! 1666c5f01b2fSopenharmony_ci @brief get special-case overload 1667c5f01b2fSopenharmony_ci 1668c5f01b2fSopenharmony_ci This overloads avoids a lot of template boilerplate, it can be seen as the 1669c5f01b2fSopenharmony_ci identity method 1670c5f01b2fSopenharmony_ci 1671c5f01b2fSopenharmony_ci @tparam BasicJsonType == @ref basic_json 1672c5f01b2fSopenharmony_ci 1673c5f01b2fSopenharmony_ci @return a copy of *this 1674c5f01b2fSopenharmony_ci 1675c5f01b2fSopenharmony_ci @complexity Constant. 1676c5f01b2fSopenharmony_ci 1677c5f01b2fSopenharmony_ci @since version 2.1.0 1678c5f01b2fSopenharmony_ci */ 1679c5f01b2fSopenharmony_ci template<typename BasicJsonType, 1680c5f01b2fSopenharmony_ci detail::enable_if_t< 1681c5f01b2fSopenharmony_ci std::is_same<BasicJsonType, basic_json_t>::value, 1682c5f01b2fSopenharmony_ci int> = 0> 1683c5f01b2fSopenharmony_ci basic_json get_impl(detail::priority_tag<3> /*unused*/) const 1684c5f01b2fSopenharmony_ci { 1685c5f01b2fSopenharmony_ci return *this; 1686c5f01b2fSopenharmony_ci } 1687c5f01b2fSopenharmony_ci 1688c5f01b2fSopenharmony_ci /*! 1689c5f01b2fSopenharmony_ci @brief get a pointer value (explicit) 1690c5f01b2fSopenharmony_ci @copydoc get() 1691c5f01b2fSopenharmony_ci */ 1692c5f01b2fSopenharmony_ci template<typename PointerType, 1693c5f01b2fSopenharmony_ci detail::enable_if_t< 1694c5f01b2fSopenharmony_ci std::is_pointer<PointerType>::value, 1695c5f01b2fSopenharmony_ci int> = 0> 1696c5f01b2fSopenharmony_ci constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept 1697c5f01b2fSopenharmony_ci -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>()) 1698c5f01b2fSopenharmony_ci { 1699c5f01b2fSopenharmony_ci // delegate the call to get_ptr 1700c5f01b2fSopenharmony_ci return get_ptr<PointerType>(); 1701c5f01b2fSopenharmony_ci } 1702c5f01b2fSopenharmony_ci 1703c5f01b2fSopenharmony_ci public: 1704c5f01b2fSopenharmony_ci /*! 1705c5f01b2fSopenharmony_ci @brief get a (pointer) value (explicit) 1706c5f01b2fSopenharmony_ci 1707c5f01b2fSopenharmony_ci Performs explicit type conversion between the JSON value and a compatible value if required. 1708c5f01b2fSopenharmony_ci 1709c5f01b2fSopenharmony_ci - If the requested type is a pointer to the internally stored JSON value that pointer is returned. 1710c5f01b2fSopenharmony_ci No copies are made. 1711c5f01b2fSopenharmony_ci 1712c5f01b2fSopenharmony_ci - If the requested type is the current @ref basic_json, or a different @ref basic_json convertible 1713c5f01b2fSopenharmony_ci from the current @ref basic_json. 1714c5f01b2fSopenharmony_ci 1715c5f01b2fSopenharmony_ci - Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()` 1716c5f01b2fSopenharmony_ci method. 1717c5f01b2fSopenharmony_ci 1718c5f01b2fSopenharmony_ci @tparam ValueTypeCV the provided value type 1719c5f01b2fSopenharmony_ci @tparam ValueType the returned value type 1720c5f01b2fSopenharmony_ci 1721c5f01b2fSopenharmony_ci @return copy of the JSON value, converted to @tparam ValueType if necessary 1722c5f01b2fSopenharmony_ci 1723c5f01b2fSopenharmony_ci @throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required 1724c5f01b2fSopenharmony_ci 1725c5f01b2fSopenharmony_ci @since version 2.1.0 1726c5f01b2fSopenharmony_ci */ 1727c5f01b2fSopenharmony_ci template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>> 1728c5f01b2fSopenharmony_ci#if defined(JSON_HAS_CPP_14) 1729c5f01b2fSopenharmony_ci constexpr 1730c5f01b2fSopenharmony_ci#endif 1731c5f01b2fSopenharmony_ci auto get() const noexcept( 1732c5f01b2fSopenharmony_ci noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))) 1733c5f01b2fSopenharmony_ci -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})) 1734c5f01b2fSopenharmony_ci { 1735c5f01b2fSopenharmony_ci // we cannot static_assert on ValueTypeCV being non-const, because 1736c5f01b2fSopenharmony_ci // there is support for get<const basic_json_t>(), which is why we 1737c5f01b2fSopenharmony_ci // still need the uncvref 1738c5f01b2fSopenharmony_ci static_assert(!std::is_reference<ValueTypeCV>::value, 1739c5f01b2fSopenharmony_ci "get() cannot be used with reference types, you might want to use get_ref()"); 1740c5f01b2fSopenharmony_ci return get_impl<ValueType>(detail::priority_tag<4> {}); 1741c5f01b2fSopenharmony_ci } 1742c5f01b2fSopenharmony_ci 1743c5f01b2fSopenharmony_ci /*! 1744c5f01b2fSopenharmony_ci @brief get a pointer value (explicit) 1745c5f01b2fSopenharmony_ci 1746c5f01b2fSopenharmony_ci Explicit pointer access to the internally stored JSON value. No copies are 1747c5f01b2fSopenharmony_ci made. 1748c5f01b2fSopenharmony_ci 1749c5f01b2fSopenharmony_ci @warning The pointer becomes invalid if the underlying JSON object 1750c5f01b2fSopenharmony_ci changes. 1751c5f01b2fSopenharmony_ci 1752c5f01b2fSopenharmony_ci @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref 1753c5f01b2fSopenharmony_ci object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, 1754c5f01b2fSopenharmony_ci @ref number_unsigned_t, or @ref number_float_t. 1755c5f01b2fSopenharmony_ci 1756c5f01b2fSopenharmony_ci @return pointer to the internally stored JSON value if the requested 1757c5f01b2fSopenharmony_ci pointer type @a PointerType fits to the JSON value; `nullptr` otherwise 1758c5f01b2fSopenharmony_ci 1759c5f01b2fSopenharmony_ci @complexity Constant. 1760c5f01b2fSopenharmony_ci 1761c5f01b2fSopenharmony_ci @liveexample{The example below shows how pointers to internal values of a 1762c5f01b2fSopenharmony_ci JSON value can be requested. Note that no type conversions are made and a 1763c5f01b2fSopenharmony_ci `nullptr` is returned if the value and the requested pointer type does not 1764c5f01b2fSopenharmony_ci match.,get__PointerType} 1765c5f01b2fSopenharmony_ci 1766c5f01b2fSopenharmony_ci @sa see @ref get_ptr() for explicit pointer-member access 1767c5f01b2fSopenharmony_ci 1768c5f01b2fSopenharmony_ci @since version 1.0.0 1769c5f01b2fSopenharmony_ci */ 1770c5f01b2fSopenharmony_ci template<typename PointerType, typename std::enable_if< 1771c5f01b2fSopenharmony_ci std::is_pointer<PointerType>::value, int>::type = 0> 1772c5f01b2fSopenharmony_ci auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>()) 1773c5f01b2fSopenharmony_ci { 1774c5f01b2fSopenharmony_ci // delegate the call to get_ptr 1775c5f01b2fSopenharmony_ci return get_ptr<PointerType>(); 1776c5f01b2fSopenharmony_ci } 1777c5f01b2fSopenharmony_ci 1778c5f01b2fSopenharmony_ci /// @brief get a value (explicit) 1779c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/get_to/ 1780c5f01b2fSopenharmony_ci template < typename ValueType, 1781c5f01b2fSopenharmony_ci detail::enable_if_t < 1782c5f01b2fSopenharmony_ci !detail::is_basic_json<ValueType>::value&& 1783c5f01b2fSopenharmony_ci detail::has_from_json<basic_json_t, ValueType>::value, 1784c5f01b2fSopenharmony_ci int > = 0 > 1785c5f01b2fSopenharmony_ci ValueType & get_to(ValueType& v) const noexcept(noexcept( 1786c5f01b2fSopenharmony_ci JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v))) 1787c5f01b2fSopenharmony_ci { 1788c5f01b2fSopenharmony_ci JSONSerializer<ValueType>::from_json(*this, v); 1789c5f01b2fSopenharmony_ci return v; 1790c5f01b2fSopenharmony_ci } 1791c5f01b2fSopenharmony_ci 1792c5f01b2fSopenharmony_ci // specialization to allow calling get_to with a basic_json value 1793c5f01b2fSopenharmony_ci // see https://github.com/nlohmann/json/issues/2175 1794c5f01b2fSopenharmony_ci template<typename ValueType, 1795c5f01b2fSopenharmony_ci detail::enable_if_t < 1796c5f01b2fSopenharmony_ci detail::is_basic_json<ValueType>::value, 1797c5f01b2fSopenharmony_ci int> = 0> 1798c5f01b2fSopenharmony_ci ValueType & get_to(ValueType& v) const 1799c5f01b2fSopenharmony_ci { 1800c5f01b2fSopenharmony_ci v = *this; 1801c5f01b2fSopenharmony_ci return v; 1802c5f01b2fSopenharmony_ci } 1803c5f01b2fSopenharmony_ci 1804c5f01b2fSopenharmony_ci template < 1805c5f01b2fSopenharmony_ci typename T, std::size_t N, 1806c5f01b2fSopenharmony_ci typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) 1807c5f01b2fSopenharmony_ci detail::enable_if_t < 1808c5f01b2fSopenharmony_ci detail::has_from_json<basic_json_t, Array>::value, int > = 0 > 1809c5f01b2fSopenharmony_ci Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) 1810c5f01b2fSopenharmony_ci noexcept(noexcept(JSONSerializer<Array>::from_json( 1811c5f01b2fSopenharmony_ci std::declval<const basic_json_t&>(), v))) 1812c5f01b2fSopenharmony_ci { 1813c5f01b2fSopenharmony_ci JSONSerializer<Array>::from_json(*this, v); 1814c5f01b2fSopenharmony_ci return v; 1815c5f01b2fSopenharmony_ci } 1816c5f01b2fSopenharmony_ci 1817c5f01b2fSopenharmony_ci /// @brief get a reference value (implicit) 1818c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/get_ref/ 1819c5f01b2fSopenharmony_ci template<typename ReferenceType, typename std::enable_if< 1820c5f01b2fSopenharmony_ci std::is_reference<ReferenceType>::value, int>::type = 0> 1821c5f01b2fSopenharmony_ci ReferenceType get_ref() 1822c5f01b2fSopenharmony_ci { 1823c5f01b2fSopenharmony_ci // delegate call to get_ref_impl 1824c5f01b2fSopenharmony_ci return get_ref_impl<ReferenceType>(*this); 1825c5f01b2fSopenharmony_ci } 1826c5f01b2fSopenharmony_ci 1827c5f01b2fSopenharmony_ci /// @brief get a reference value (implicit) 1828c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/get_ref/ 1829c5f01b2fSopenharmony_ci template < typename ReferenceType, typename std::enable_if < 1830c5f01b2fSopenharmony_ci std::is_reference<ReferenceType>::value&& 1831c5f01b2fSopenharmony_ci std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 > 1832c5f01b2fSopenharmony_ci ReferenceType get_ref() const 1833c5f01b2fSopenharmony_ci { 1834c5f01b2fSopenharmony_ci // delegate call to get_ref_impl 1835c5f01b2fSopenharmony_ci return get_ref_impl<ReferenceType>(*this); 1836c5f01b2fSopenharmony_ci } 1837c5f01b2fSopenharmony_ci 1838c5f01b2fSopenharmony_ci /*! 1839c5f01b2fSopenharmony_ci @brief get a value (implicit) 1840c5f01b2fSopenharmony_ci 1841c5f01b2fSopenharmony_ci Implicit type conversion between the JSON value and a compatible value. 1842c5f01b2fSopenharmony_ci The call is realized by calling @ref get() const. 1843c5f01b2fSopenharmony_ci 1844c5f01b2fSopenharmony_ci @tparam ValueType non-pointer type compatible to the JSON value, for 1845c5f01b2fSopenharmony_ci instance `int` for JSON integer numbers, `bool` for JSON booleans, or 1846c5f01b2fSopenharmony_ci `std::vector` types for JSON arrays. The character type of @ref string_t 1847c5f01b2fSopenharmony_ci as well as an initializer list of this type is excluded to avoid 1848c5f01b2fSopenharmony_ci ambiguities as these types implicitly convert to `std::string`. 1849c5f01b2fSopenharmony_ci 1850c5f01b2fSopenharmony_ci @return copy of the JSON value, converted to type @a ValueType 1851c5f01b2fSopenharmony_ci 1852c5f01b2fSopenharmony_ci @throw type_error.302 in case passed type @a ValueType is incompatible 1853c5f01b2fSopenharmony_ci to the JSON value type (e.g., the JSON value is of type boolean, but a 1854c5f01b2fSopenharmony_ci string is requested); see example below 1855c5f01b2fSopenharmony_ci 1856c5f01b2fSopenharmony_ci @complexity Linear in the size of the JSON value. 1857c5f01b2fSopenharmony_ci 1858c5f01b2fSopenharmony_ci @liveexample{The example below shows several conversions from JSON values 1859c5f01b2fSopenharmony_ci to other types. There a few things to note: (1) Floating-point numbers can 1860c5f01b2fSopenharmony_ci be converted to integers\, (2) A JSON array can be converted to a standard 1861c5f01b2fSopenharmony_ci `std::vector<short>`\, (3) A JSON object can be converted to C++ 1862c5f01b2fSopenharmony_ci associative containers such as `std::unordered_map<std::string\, 1863c5f01b2fSopenharmony_ci json>`.,operator__ValueType} 1864c5f01b2fSopenharmony_ci 1865c5f01b2fSopenharmony_ci @since version 1.0.0 1866c5f01b2fSopenharmony_ci */ 1867c5f01b2fSopenharmony_ci template < typename ValueType, typename std::enable_if < 1868c5f01b2fSopenharmony_ci detail::conjunction < 1869c5f01b2fSopenharmony_ci detail::negation<std::is_pointer<ValueType>>, 1870c5f01b2fSopenharmony_ci detail::negation<std::is_same<ValueType, std::nullptr_t>>, 1871c5f01b2fSopenharmony_ci detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>, 1872c5f01b2fSopenharmony_ci detail::negation<std::is_same<ValueType, typename string_t::value_type>>, 1873c5f01b2fSopenharmony_ci detail::negation<detail::is_basic_json<ValueType>>, 1874c5f01b2fSopenharmony_ci detail::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>, 1875c5f01b2fSopenharmony_ci#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914)) 1876c5f01b2fSopenharmony_ci detail::negation<std::is_same<ValueType, std::string_view>>, 1877c5f01b2fSopenharmony_ci#endif 1878c5f01b2fSopenharmony_ci#if defined(JSON_HAS_CPP_17) 1879c5f01b2fSopenharmony_ci detail::negation<std::is_same<ValueType, std::any>>, 1880c5f01b2fSopenharmony_ci#endif 1881c5f01b2fSopenharmony_ci detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType> 1882c5f01b2fSopenharmony_ci >::value, int >::type = 0 > 1883c5f01b2fSopenharmony_ci JSON_EXPLICIT operator ValueType() const 1884c5f01b2fSopenharmony_ci { 1885c5f01b2fSopenharmony_ci // delegate the call to get<>() const 1886c5f01b2fSopenharmony_ci return get<ValueType>(); 1887c5f01b2fSopenharmony_ci } 1888c5f01b2fSopenharmony_ci 1889c5f01b2fSopenharmony_ci /// @brief get a binary value 1890c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/get_binary/ 1891c5f01b2fSopenharmony_ci binary_t& get_binary() 1892c5f01b2fSopenharmony_ci { 1893c5f01b2fSopenharmony_ci if (!is_binary()) 1894c5f01b2fSopenharmony_ci { 1895c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this)); 1896c5f01b2fSopenharmony_ci } 1897c5f01b2fSopenharmony_ci 1898c5f01b2fSopenharmony_ci return *get_ptr<binary_t*>(); 1899c5f01b2fSopenharmony_ci } 1900c5f01b2fSopenharmony_ci 1901c5f01b2fSopenharmony_ci /// @brief get a binary value 1902c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/get_binary/ 1903c5f01b2fSopenharmony_ci const binary_t& get_binary() const 1904c5f01b2fSopenharmony_ci { 1905c5f01b2fSopenharmony_ci if (!is_binary()) 1906c5f01b2fSopenharmony_ci { 1907c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this)); 1908c5f01b2fSopenharmony_ci } 1909c5f01b2fSopenharmony_ci 1910c5f01b2fSopenharmony_ci return *get_ptr<const binary_t*>(); 1911c5f01b2fSopenharmony_ci } 1912c5f01b2fSopenharmony_ci 1913c5f01b2fSopenharmony_ci /// @} 1914c5f01b2fSopenharmony_ci 1915c5f01b2fSopenharmony_ci 1916c5f01b2fSopenharmony_ci //////////////////// 1917c5f01b2fSopenharmony_ci // element access // 1918c5f01b2fSopenharmony_ci //////////////////// 1919c5f01b2fSopenharmony_ci 1920c5f01b2fSopenharmony_ci /// @name element access 1921c5f01b2fSopenharmony_ci /// Access to the JSON value. 1922c5f01b2fSopenharmony_ci /// @{ 1923c5f01b2fSopenharmony_ci 1924c5f01b2fSopenharmony_ci /// @brief access specified array element with bounds checking 1925c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/at/ 1926c5f01b2fSopenharmony_ci reference at(size_type idx) 1927c5f01b2fSopenharmony_ci { 1928c5f01b2fSopenharmony_ci // at only works for arrays 1929c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_array())) 1930c5f01b2fSopenharmony_ci { 1931c5f01b2fSopenharmony_ci JSON_TRY 1932c5f01b2fSopenharmony_ci { 1933c5f01b2fSopenharmony_ci return set_parent(m_value.array->at(idx)); 1934c5f01b2fSopenharmony_ci } 1935c5f01b2fSopenharmony_ci JSON_CATCH (std::out_of_range&) 1936c5f01b2fSopenharmony_ci { 1937c5f01b2fSopenharmony_ci // create better exception explanation 1938c5f01b2fSopenharmony_ci JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this)); 1939c5f01b2fSopenharmony_ci } 1940c5f01b2fSopenharmony_ci } 1941c5f01b2fSopenharmony_ci else 1942c5f01b2fSopenharmony_ci { 1943c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this)); 1944c5f01b2fSopenharmony_ci } 1945c5f01b2fSopenharmony_ci } 1946c5f01b2fSopenharmony_ci 1947c5f01b2fSopenharmony_ci /// @brief access specified array element with bounds checking 1948c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/at/ 1949c5f01b2fSopenharmony_ci const_reference at(size_type idx) const 1950c5f01b2fSopenharmony_ci { 1951c5f01b2fSopenharmony_ci // at only works for arrays 1952c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_array())) 1953c5f01b2fSopenharmony_ci { 1954c5f01b2fSopenharmony_ci JSON_TRY 1955c5f01b2fSopenharmony_ci { 1956c5f01b2fSopenharmony_ci return m_value.array->at(idx); 1957c5f01b2fSopenharmony_ci } 1958c5f01b2fSopenharmony_ci JSON_CATCH (std::out_of_range&) 1959c5f01b2fSopenharmony_ci { 1960c5f01b2fSopenharmony_ci // create better exception explanation 1961c5f01b2fSopenharmony_ci JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this)); 1962c5f01b2fSopenharmony_ci } 1963c5f01b2fSopenharmony_ci } 1964c5f01b2fSopenharmony_ci else 1965c5f01b2fSopenharmony_ci { 1966c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this)); 1967c5f01b2fSopenharmony_ci } 1968c5f01b2fSopenharmony_ci } 1969c5f01b2fSopenharmony_ci 1970c5f01b2fSopenharmony_ci /// @brief access specified object element with bounds checking 1971c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/at/ 1972c5f01b2fSopenharmony_ci reference at(const typename object_t::key_type& key) 1973c5f01b2fSopenharmony_ci { 1974c5f01b2fSopenharmony_ci // at only works for objects 1975c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!is_object())) 1976c5f01b2fSopenharmony_ci { 1977c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this)); 1978c5f01b2fSopenharmony_ci } 1979c5f01b2fSopenharmony_ci 1980c5f01b2fSopenharmony_ci auto it = m_value.object->find(key); 1981c5f01b2fSopenharmony_ci if (it == m_value.object->end()) 1982c5f01b2fSopenharmony_ci { 1983c5f01b2fSopenharmony_ci JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this)); 1984c5f01b2fSopenharmony_ci } 1985c5f01b2fSopenharmony_ci return set_parent(it->second); 1986c5f01b2fSopenharmony_ci } 1987c5f01b2fSopenharmony_ci 1988c5f01b2fSopenharmony_ci /// @brief access specified object element with bounds checking 1989c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/at/ 1990c5f01b2fSopenharmony_ci template<class KeyType, detail::enable_if_t< 1991c5f01b2fSopenharmony_ci detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0> 1992c5f01b2fSopenharmony_ci reference at(KeyType && key) 1993c5f01b2fSopenharmony_ci { 1994c5f01b2fSopenharmony_ci // at only works for objects 1995c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!is_object())) 1996c5f01b2fSopenharmony_ci { 1997c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this)); 1998c5f01b2fSopenharmony_ci } 1999c5f01b2fSopenharmony_ci 2000c5f01b2fSopenharmony_ci auto it = m_value.object->find(std::forward<KeyType>(key)); 2001c5f01b2fSopenharmony_ci if (it == m_value.object->end()) 2002c5f01b2fSopenharmony_ci { 2003c5f01b2fSopenharmony_ci JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this)); 2004c5f01b2fSopenharmony_ci } 2005c5f01b2fSopenharmony_ci return set_parent(it->second); 2006c5f01b2fSopenharmony_ci } 2007c5f01b2fSopenharmony_ci 2008c5f01b2fSopenharmony_ci /// @brief access specified object element with bounds checking 2009c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/at/ 2010c5f01b2fSopenharmony_ci const_reference at(const typename object_t::key_type& key) const 2011c5f01b2fSopenharmony_ci { 2012c5f01b2fSopenharmony_ci // at only works for objects 2013c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!is_object())) 2014c5f01b2fSopenharmony_ci { 2015c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this)); 2016c5f01b2fSopenharmony_ci } 2017c5f01b2fSopenharmony_ci 2018c5f01b2fSopenharmony_ci auto it = m_value.object->find(key); 2019c5f01b2fSopenharmony_ci if (it == m_value.object->end()) 2020c5f01b2fSopenharmony_ci { 2021c5f01b2fSopenharmony_ci JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this)); 2022c5f01b2fSopenharmony_ci } 2023c5f01b2fSopenharmony_ci return it->second; 2024c5f01b2fSopenharmony_ci } 2025c5f01b2fSopenharmony_ci 2026c5f01b2fSopenharmony_ci /// @brief access specified object element with bounds checking 2027c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/at/ 2028c5f01b2fSopenharmony_ci template<class KeyType, detail::enable_if_t< 2029c5f01b2fSopenharmony_ci detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0> 2030c5f01b2fSopenharmony_ci const_reference at(KeyType && key) const 2031c5f01b2fSopenharmony_ci { 2032c5f01b2fSopenharmony_ci // at only works for objects 2033c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!is_object())) 2034c5f01b2fSopenharmony_ci { 2035c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this)); 2036c5f01b2fSopenharmony_ci } 2037c5f01b2fSopenharmony_ci 2038c5f01b2fSopenharmony_ci auto it = m_value.object->find(std::forward<KeyType>(key)); 2039c5f01b2fSopenharmony_ci if (it == m_value.object->end()) 2040c5f01b2fSopenharmony_ci { 2041c5f01b2fSopenharmony_ci JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this)); 2042c5f01b2fSopenharmony_ci } 2043c5f01b2fSopenharmony_ci return it->second; 2044c5f01b2fSopenharmony_ci } 2045c5f01b2fSopenharmony_ci 2046c5f01b2fSopenharmony_ci /// @brief access specified array element 2047c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ 2048c5f01b2fSopenharmony_ci reference operator[](size_type idx) 2049c5f01b2fSopenharmony_ci { 2050c5f01b2fSopenharmony_ci // implicitly convert null value to an empty array 2051c5f01b2fSopenharmony_ci if (is_null()) 2052c5f01b2fSopenharmony_ci { 2053c5f01b2fSopenharmony_ci m_type = value_t::array; 2054c5f01b2fSopenharmony_ci m_value.array = create<array_t>(); 2055c5f01b2fSopenharmony_ci assert_invariant(); 2056c5f01b2fSopenharmony_ci } 2057c5f01b2fSopenharmony_ci 2058c5f01b2fSopenharmony_ci // operator[] only works for arrays 2059c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_array())) 2060c5f01b2fSopenharmony_ci { 2061c5f01b2fSopenharmony_ci // fill up array with null values if given idx is outside range 2062c5f01b2fSopenharmony_ci if (idx >= m_value.array->size()) 2063c5f01b2fSopenharmony_ci { 2064c5f01b2fSopenharmony_ci#if JSON_DIAGNOSTICS 2065c5f01b2fSopenharmony_ci // remember array size & capacity before resizing 2066c5f01b2fSopenharmony_ci const auto old_size = m_value.array->size(); 2067c5f01b2fSopenharmony_ci const auto old_capacity = m_value.array->capacity(); 2068c5f01b2fSopenharmony_ci#endif 2069c5f01b2fSopenharmony_ci m_value.array->resize(idx + 1); 2070c5f01b2fSopenharmony_ci 2071c5f01b2fSopenharmony_ci#if JSON_DIAGNOSTICS 2072c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity)) 2073c5f01b2fSopenharmony_ci { 2074c5f01b2fSopenharmony_ci // capacity has changed: update all parents 2075c5f01b2fSopenharmony_ci set_parents(); 2076c5f01b2fSopenharmony_ci } 2077c5f01b2fSopenharmony_ci else 2078c5f01b2fSopenharmony_ci { 2079c5f01b2fSopenharmony_ci // set parent for values added above 2080c5f01b2fSopenharmony_ci set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size)); 2081c5f01b2fSopenharmony_ci } 2082c5f01b2fSopenharmony_ci#endif 2083c5f01b2fSopenharmony_ci assert_invariant(); 2084c5f01b2fSopenharmony_ci } 2085c5f01b2fSopenharmony_ci 2086c5f01b2fSopenharmony_ci return m_value.array->operator[](idx); 2087c5f01b2fSopenharmony_ci } 2088c5f01b2fSopenharmony_ci 2089c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this)); 2090c5f01b2fSopenharmony_ci } 2091c5f01b2fSopenharmony_ci 2092c5f01b2fSopenharmony_ci /// @brief access specified array element 2093c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ 2094c5f01b2fSopenharmony_ci const_reference operator[](size_type idx) const 2095c5f01b2fSopenharmony_ci { 2096c5f01b2fSopenharmony_ci // const operator[] only works for arrays 2097c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_array())) 2098c5f01b2fSopenharmony_ci { 2099c5f01b2fSopenharmony_ci return m_value.array->operator[](idx); 2100c5f01b2fSopenharmony_ci } 2101c5f01b2fSopenharmony_ci 2102c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this)); 2103c5f01b2fSopenharmony_ci } 2104c5f01b2fSopenharmony_ci 2105c5f01b2fSopenharmony_ci /// @brief access specified object element 2106c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ 2107c5f01b2fSopenharmony_ci reference operator[](typename object_t::key_type key) 2108c5f01b2fSopenharmony_ci { 2109c5f01b2fSopenharmony_ci // implicitly convert null value to an empty object 2110c5f01b2fSopenharmony_ci if (is_null()) 2111c5f01b2fSopenharmony_ci { 2112c5f01b2fSopenharmony_ci m_type = value_t::object; 2113c5f01b2fSopenharmony_ci m_value.object = create<object_t>(); 2114c5f01b2fSopenharmony_ci assert_invariant(); 2115c5f01b2fSopenharmony_ci } 2116c5f01b2fSopenharmony_ci 2117c5f01b2fSopenharmony_ci // operator[] only works for objects 2118c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_object())) 2119c5f01b2fSopenharmony_ci { 2120c5f01b2fSopenharmony_ci auto result = m_value.object->emplace(std::move(key), nullptr); 2121c5f01b2fSopenharmony_ci return set_parent(result.first->second); 2122c5f01b2fSopenharmony_ci } 2123c5f01b2fSopenharmony_ci 2124c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this)); 2125c5f01b2fSopenharmony_ci } 2126c5f01b2fSopenharmony_ci 2127c5f01b2fSopenharmony_ci /// @brief access specified object element 2128c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ 2129c5f01b2fSopenharmony_ci const_reference operator[](const typename object_t::key_type& key) const 2130c5f01b2fSopenharmony_ci { 2131c5f01b2fSopenharmony_ci // const operator[] only works for objects 2132c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_object())) 2133c5f01b2fSopenharmony_ci { 2134c5f01b2fSopenharmony_ci auto it = m_value.object->find(key); 2135c5f01b2fSopenharmony_ci JSON_ASSERT(it != m_value.object->end()); 2136c5f01b2fSopenharmony_ci return it->second; 2137c5f01b2fSopenharmony_ci } 2138c5f01b2fSopenharmony_ci 2139c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this)); 2140c5f01b2fSopenharmony_ci } 2141c5f01b2fSopenharmony_ci 2142c5f01b2fSopenharmony_ci // these two functions resolve a (const) char * ambiguity affecting Clang and MSVC 2143c5f01b2fSopenharmony_ci // (they seemingly cannot be constrained to resolve the ambiguity) 2144c5f01b2fSopenharmony_ci template<typename T> 2145c5f01b2fSopenharmony_ci reference operator[](T* key) 2146c5f01b2fSopenharmony_ci { 2147c5f01b2fSopenharmony_ci return operator[](typename object_t::key_type(key)); 2148c5f01b2fSopenharmony_ci } 2149c5f01b2fSopenharmony_ci 2150c5f01b2fSopenharmony_ci template<typename T> 2151c5f01b2fSopenharmony_ci const_reference operator[](T* key) const 2152c5f01b2fSopenharmony_ci { 2153c5f01b2fSopenharmony_ci return operator[](typename object_t::key_type(key)); 2154c5f01b2fSopenharmony_ci } 2155c5f01b2fSopenharmony_ci 2156c5f01b2fSopenharmony_ci /// @brief access specified object element 2157c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ 2158c5f01b2fSopenharmony_ci template<class KeyType, detail::enable_if_t< 2159c5f01b2fSopenharmony_ci detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int > = 0 > 2160c5f01b2fSopenharmony_ci reference operator[](KeyType && key) 2161c5f01b2fSopenharmony_ci { 2162c5f01b2fSopenharmony_ci // implicitly convert null value to an empty object 2163c5f01b2fSopenharmony_ci if (is_null()) 2164c5f01b2fSopenharmony_ci { 2165c5f01b2fSopenharmony_ci m_type = value_t::object; 2166c5f01b2fSopenharmony_ci m_value.object = create<object_t>(); 2167c5f01b2fSopenharmony_ci assert_invariant(); 2168c5f01b2fSopenharmony_ci } 2169c5f01b2fSopenharmony_ci 2170c5f01b2fSopenharmony_ci // operator[] only works for objects 2171c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_object())) 2172c5f01b2fSopenharmony_ci { 2173c5f01b2fSopenharmony_ci auto result = m_value.object->emplace(std::forward<KeyType>(key), nullptr); 2174c5f01b2fSopenharmony_ci return set_parent(result.first->second); 2175c5f01b2fSopenharmony_ci } 2176c5f01b2fSopenharmony_ci 2177c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this)); 2178c5f01b2fSopenharmony_ci } 2179c5f01b2fSopenharmony_ci 2180c5f01b2fSopenharmony_ci /// @brief access specified object element 2181c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ 2182c5f01b2fSopenharmony_ci template<class KeyType, detail::enable_if_t< 2183c5f01b2fSopenharmony_ci detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int > = 0 > 2184c5f01b2fSopenharmony_ci const_reference operator[](KeyType && key) const 2185c5f01b2fSopenharmony_ci { 2186c5f01b2fSopenharmony_ci // const operator[] only works for objects 2187c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_object())) 2188c5f01b2fSopenharmony_ci { 2189c5f01b2fSopenharmony_ci auto it = m_value.object->find(std::forward<KeyType>(key)); 2190c5f01b2fSopenharmony_ci JSON_ASSERT(it != m_value.object->end()); 2191c5f01b2fSopenharmony_ci return it->second; 2192c5f01b2fSopenharmony_ci } 2193c5f01b2fSopenharmony_ci 2194c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this)); 2195c5f01b2fSopenharmony_ci } 2196c5f01b2fSopenharmony_ci 2197c5f01b2fSopenharmony_ci private: 2198c5f01b2fSopenharmony_ci template<typename KeyType> 2199c5f01b2fSopenharmony_ci using is_comparable_with_object_key = detail::is_comparable < 2200c5f01b2fSopenharmony_ci object_comparator_t, const typename object_t::key_type&, KeyType >; 2201c5f01b2fSopenharmony_ci 2202c5f01b2fSopenharmony_ci template<typename ValueType> 2203c5f01b2fSopenharmony_ci using value_return_type = std::conditional < 2204c5f01b2fSopenharmony_ci detail::is_c_string_uncvref<ValueType>::value, 2205c5f01b2fSopenharmony_ci string_t, typename std::decay<ValueType>::type >; 2206c5f01b2fSopenharmony_ci 2207c5f01b2fSopenharmony_ci public: 2208c5f01b2fSopenharmony_ci /// @brief access specified object element with default value 2209c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/value/ 2210c5f01b2fSopenharmony_ci template < class ValueType, detail::enable_if_t < 2211c5f01b2fSopenharmony_ci !detail::is_transparent<object_comparator_t>::value 2212c5f01b2fSopenharmony_ci && detail::is_getable<basic_json_t, ValueType>::value 2213c5f01b2fSopenharmony_ci && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 > 2214c5f01b2fSopenharmony_ci ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const 2215c5f01b2fSopenharmony_ci { 2216c5f01b2fSopenharmony_ci // value only works for objects 2217c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_object())) 2218c5f01b2fSopenharmony_ci { 2219c5f01b2fSopenharmony_ci // if key is found, return value and given default value otherwise 2220c5f01b2fSopenharmony_ci const auto it = find(key); 2221c5f01b2fSopenharmony_ci if (it != end()) 2222c5f01b2fSopenharmony_ci { 2223c5f01b2fSopenharmony_ci return it->template get<ValueType>(); 2224c5f01b2fSopenharmony_ci } 2225c5f01b2fSopenharmony_ci 2226c5f01b2fSopenharmony_ci return default_value; 2227c5f01b2fSopenharmony_ci } 2228c5f01b2fSopenharmony_ci 2229c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this)); 2230c5f01b2fSopenharmony_ci } 2231c5f01b2fSopenharmony_ci 2232c5f01b2fSopenharmony_ci /// @brief access specified object element with default value 2233c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/value/ 2234c5f01b2fSopenharmony_ci template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type, 2235c5f01b2fSopenharmony_ci detail::enable_if_t < 2236c5f01b2fSopenharmony_ci !detail::is_transparent<object_comparator_t>::value 2237c5f01b2fSopenharmony_ci && detail::is_getable<basic_json_t, ReturnType>::value 2238c5f01b2fSopenharmony_ci && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 > 2239c5f01b2fSopenharmony_ci ReturnType value(const typename object_t::key_type& key, ValueType && default_value) const 2240c5f01b2fSopenharmony_ci { 2241c5f01b2fSopenharmony_ci // value only works for objects 2242c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_object())) 2243c5f01b2fSopenharmony_ci { 2244c5f01b2fSopenharmony_ci // if key is found, return value and given default value otherwise 2245c5f01b2fSopenharmony_ci const auto it = find(key); 2246c5f01b2fSopenharmony_ci if (it != end()) 2247c5f01b2fSopenharmony_ci { 2248c5f01b2fSopenharmony_ci return it->template get<ReturnType>(); 2249c5f01b2fSopenharmony_ci } 2250c5f01b2fSopenharmony_ci 2251c5f01b2fSopenharmony_ci return std::forward<ValueType>(default_value); 2252c5f01b2fSopenharmony_ci } 2253c5f01b2fSopenharmony_ci 2254c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this)); 2255c5f01b2fSopenharmony_ci } 2256c5f01b2fSopenharmony_ci 2257c5f01b2fSopenharmony_ci /// @brief access specified object element with default value 2258c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/value/ 2259c5f01b2fSopenharmony_ci template < class ValueType, class KeyType, detail::enable_if_t < 2260c5f01b2fSopenharmony_ci detail::is_transparent<object_comparator_t>::value 2261c5f01b2fSopenharmony_ci && !detail::is_json_pointer<KeyType>::value 2262c5f01b2fSopenharmony_ci && is_comparable_with_object_key<KeyType>::value 2263c5f01b2fSopenharmony_ci && detail::is_getable<basic_json_t, ValueType>::value 2264c5f01b2fSopenharmony_ci && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 > 2265c5f01b2fSopenharmony_ci ValueType value(KeyType && key, const ValueType& default_value) const 2266c5f01b2fSopenharmony_ci { 2267c5f01b2fSopenharmony_ci // value only works for objects 2268c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_object())) 2269c5f01b2fSopenharmony_ci { 2270c5f01b2fSopenharmony_ci // if key is found, return value and given default value otherwise 2271c5f01b2fSopenharmony_ci const auto it = find(std::forward<KeyType>(key)); 2272c5f01b2fSopenharmony_ci if (it != end()) 2273c5f01b2fSopenharmony_ci { 2274c5f01b2fSopenharmony_ci return it->template get<ValueType>(); 2275c5f01b2fSopenharmony_ci } 2276c5f01b2fSopenharmony_ci 2277c5f01b2fSopenharmony_ci return default_value; 2278c5f01b2fSopenharmony_ci } 2279c5f01b2fSopenharmony_ci 2280c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this)); 2281c5f01b2fSopenharmony_ci } 2282c5f01b2fSopenharmony_ci 2283c5f01b2fSopenharmony_ci /// @brief access specified object element via JSON Pointer with default value 2284c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/value/ 2285c5f01b2fSopenharmony_ci template < class ValueType, class KeyType, class ReturnType = typename value_return_type<ValueType>::type, 2286c5f01b2fSopenharmony_ci detail::enable_if_t < 2287c5f01b2fSopenharmony_ci detail::is_transparent<object_comparator_t>::value 2288c5f01b2fSopenharmony_ci && !detail::is_json_pointer<KeyType>::value 2289c5f01b2fSopenharmony_ci && is_comparable_with_object_key<KeyType>::value 2290c5f01b2fSopenharmony_ci && detail::is_getable<basic_json_t, ReturnType>::value 2291c5f01b2fSopenharmony_ci && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 > 2292c5f01b2fSopenharmony_ci ReturnType value(KeyType && key, ValueType && default_value) const 2293c5f01b2fSopenharmony_ci { 2294c5f01b2fSopenharmony_ci // value only works for objects 2295c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_object())) 2296c5f01b2fSopenharmony_ci { 2297c5f01b2fSopenharmony_ci // if key is found, return value and given default value otherwise 2298c5f01b2fSopenharmony_ci const auto it = find(std::forward<KeyType>(key)); 2299c5f01b2fSopenharmony_ci if (it != end()) 2300c5f01b2fSopenharmony_ci { 2301c5f01b2fSopenharmony_ci return it->template get<ReturnType>(); 2302c5f01b2fSopenharmony_ci } 2303c5f01b2fSopenharmony_ci 2304c5f01b2fSopenharmony_ci return std::forward<ValueType>(default_value); 2305c5f01b2fSopenharmony_ci } 2306c5f01b2fSopenharmony_ci 2307c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this)); 2308c5f01b2fSopenharmony_ci } 2309c5f01b2fSopenharmony_ci 2310c5f01b2fSopenharmony_ci /// @brief access specified object element via JSON Pointer with default value 2311c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/value/ 2312c5f01b2fSopenharmony_ci template < class ValueType, detail::enable_if_t < 2313c5f01b2fSopenharmony_ci detail::is_getable<basic_json_t, ValueType>::value 2314c5f01b2fSopenharmony_ci && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 > 2315c5f01b2fSopenharmony_ci ValueType value(const json_pointer& ptr, const ValueType& default_value) const 2316c5f01b2fSopenharmony_ci { 2317c5f01b2fSopenharmony_ci // value only works for objects 2318c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_object())) 2319c5f01b2fSopenharmony_ci { 2320c5f01b2fSopenharmony_ci // if pointer resolves a value, return it or use default value 2321c5f01b2fSopenharmony_ci JSON_TRY 2322c5f01b2fSopenharmony_ci { 2323c5f01b2fSopenharmony_ci return ptr.get_checked(this).template get<ValueType>(); 2324c5f01b2fSopenharmony_ci } 2325c5f01b2fSopenharmony_ci JSON_INTERNAL_CATCH (out_of_range&) 2326c5f01b2fSopenharmony_ci { 2327c5f01b2fSopenharmony_ci return default_value; 2328c5f01b2fSopenharmony_ci } 2329c5f01b2fSopenharmony_ci } 2330c5f01b2fSopenharmony_ci 2331c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this)); 2332c5f01b2fSopenharmony_ci } 2333c5f01b2fSopenharmony_ci 2334c5f01b2fSopenharmony_ci /// @brief access specified object element via JSON Pointer with default value 2335c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/value/ 2336c5f01b2fSopenharmony_ci template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type, 2337c5f01b2fSopenharmony_ci detail::enable_if_t < 2338c5f01b2fSopenharmony_ci detail::is_getable<basic_json_t, ReturnType>::value 2339c5f01b2fSopenharmony_ci && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 > 2340c5f01b2fSopenharmony_ci ReturnType value(const json_pointer& ptr, ValueType && default_value) const 2341c5f01b2fSopenharmony_ci { 2342c5f01b2fSopenharmony_ci // value only works for objects 2343c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_object())) 2344c5f01b2fSopenharmony_ci { 2345c5f01b2fSopenharmony_ci // if pointer resolves a value, return it or use default value 2346c5f01b2fSopenharmony_ci JSON_TRY 2347c5f01b2fSopenharmony_ci { 2348c5f01b2fSopenharmony_ci return ptr.get_checked(this).template get<ReturnType>(); 2349c5f01b2fSopenharmony_ci } 2350c5f01b2fSopenharmony_ci JSON_INTERNAL_CATCH (out_of_range&) 2351c5f01b2fSopenharmony_ci { 2352c5f01b2fSopenharmony_ci return std::forward<ValueType>(default_value); 2353c5f01b2fSopenharmony_ci } 2354c5f01b2fSopenharmony_ci } 2355c5f01b2fSopenharmony_ci 2356c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this)); 2357c5f01b2fSopenharmony_ci } 2358c5f01b2fSopenharmony_ci 2359c5f01b2fSopenharmony_ci template < class ValueType, class BasicJsonType, detail::enable_if_t < 2360c5f01b2fSopenharmony_ci detail::is_basic_json<BasicJsonType>::value 2361c5f01b2fSopenharmony_ci && detail::is_getable<basic_json_t, ValueType>::value 2362c5f01b2fSopenharmony_ci && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 > 2363c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens) 2364c5f01b2fSopenharmony_ci ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const 2365c5f01b2fSopenharmony_ci { 2366c5f01b2fSopenharmony_ci return value(ptr.convert(), default_value); 2367c5f01b2fSopenharmony_ci } 2368c5f01b2fSopenharmony_ci 2369c5f01b2fSopenharmony_ci template < class ValueType, class BasicJsonType, class ReturnType = typename value_return_type<ValueType>::type, 2370c5f01b2fSopenharmony_ci detail::enable_if_t < 2371c5f01b2fSopenharmony_ci detail::is_basic_json<BasicJsonType>::value 2372c5f01b2fSopenharmony_ci && detail::is_getable<basic_json_t, ReturnType>::value 2373c5f01b2fSopenharmony_ci && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 > 2374c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens) 2375c5f01b2fSopenharmony_ci ReturnType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, ValueType && default_value) const 2376c5f01b2fSopenharmony_ci { 2377c5f01b2fSopenharmony_ci return value(ptr.convert(), std::forward<ValueType>(default_value)); 2378c5f01b2fSopenharmony_ci } 2379c5f01b2fSopenharmony_ci 2380c5f01b2fSopenharmony_ci /// @brief access the first element 2381c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/front/ 2382c5f01b2fSopenharmony_ci reference front() 2383c5f01b2fSopenharmony_ci { 2384c5f01b2fSopenharmony_ci return *begin(); 2385c5f01b2fSopenharmony_ci } 2386c5f01b2fSopenharmony_ci 2387c5f01b2fSopenharmony_ci /// @brief access the first element 2388c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/front/ 2389c5f01b2fSopenharmony_ci const_reference front() const 2390c5f01b2fSopenharmony_ci { 2391c5f01b2fSopenharmony_ci return *cbegin(); 2392c5f01b2fSopenharmony_ci } 2393c5f01b2fSopenharmony_ci 2394c5f01b2fSopenharmony_ci /// @brief access the last element 2395c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/back/ 2396c5f01b2fSopenharmony_ci reference back() 2397c5f01b2fSopenharmony_ci { 2398c5f01b2fSopenharmony_ci auto tmp = end(); 2399c5f01b2fSopenharmony_ci --tmp; 2400c5f01b2fSopenharmony_ci return *tmp; 2401c5f01b2fSopenharmony_ci } 2402c5f01b2fSopenharmony_ci 2403c5f01b2fSopenharmony_ci /// @brief access the last element 2404c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/back/ 2405c5f01b2fSopenharmony_ci const_reference back() const 2406c5f01b2fSopenharmony_ci { 2407c5f01b2fSopenharmony_ci auto tmp = cend(); 2408c5f01b2fSopenharmony_ci --tmp; 2409c5f01b2fSopenharmony_ci return *tmp; 2410c5f01b2fSopenharmony_ci } 2411c5f01b2fSopenharmony_ci 2412c5f01b2fSopenharmony_ci /// @brief remove element given an iterator 2413c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/erase/ 2414c5f01b2fSopenharmony_ci template < class IteratorType, detail::enable_if_t < 2415c5f01b2fSopenharmony_ci std::is_same<IteratorType, typename basic_json_t::iterator>::value || 2416c5f01b2fSopenharmony_ci std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 > 2417c5f01b2fSopenharmony_ci IteratorType erase(IteratorType pos) 2418c5f01b2fSopenharmony_ci { 2419c5f01b2fSopenharmony_ci // make sure iterator fits the current value 2420c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(this != pos.m_object)) 2421c5f01b2fSopenharmony_ci { 2422c5f01b2fSopenharmony_ci JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this)); 2423c5f01b2fSopenharmony_ci } 2424c5f01b2fSopenharmony_ci 2425c5f01b2fSopenharmony_ci IteratorType result = end(); 2426c5f01b2fSopenharmony_ci 2427c5f01b2fSopenharmony_ci switch (m_type) 2428c5f01b2fSopenharmony_ci { 2429c5f01b2fSopenharmony_ci case value_t::boolean: 2430c5f01b2fSopenharmony_ci case value_t::number_float: 2431c5f01b2fSopenharmony_ci case value_t::number_integer: 2432c5f01b2fSopenharmony_ci case value_t::number_unsigned: 2433c5f01b2fSopenharmony_ci case value_t::string: 2434c5f01b2fSopenharmony_ci case value_t::binary: 2435c5f01b2fSopenharmony_ci { 2436c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin())) 2437c5f01b2fSopenharmony_ci { 2438c5f01b2fSopenharmony_ci JSON_THROW(invalid_iterator::create(205, "iterator out of range", this)); 2439c5f01b2fSopenharmony_ci } 2440c5f01b2fSopenharmony_ci 2441c5f01b2fSopenharmony_ci if (is_string()) 2442c5f01b2fSopenharmony_ci { 2443c5f01b2fSopenharmony_ci AllocatorType<string_t> alloc; 2444c5f01b2fSopenharmony_ci std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string); 2445c5f01b2fSopenharmony_ci std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1); 2446c5f01b2fSopenharmony_ci m_value.string = nullptr; 2447c5f01b2fSopenharmony_ci } 2448c5f01b2fSopenharmony_ci else if (is_binary()) 2449c5f01b2fSopenharmony_ci { 2450c5f01b2fSopenharmony_ci AllocatorType<binary_t> alloc; 2451c5f01b2fSopenharmony_ci std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary); 2452c5f01b2fSopenharmony_ci std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1); 2453c5f01b2fSopenharmony_ci m_value.binary = nullptr; 2454c5f01b2fSopenharmony_ci } 2455c5f01b2fSopenharmony_ci 2456c5f01b2fSopenharmony_ci m_type = value_t::null; 2457c5f01b2fSopenharmony_ci assert_invariant(); 2458c5f01b2fSopenharmony_ci break; 2459c5f01b2fSopenharmony_ci } 2460c5f01b2fSopenharmony_ci 2461c5f01b2fSopenharmony_ci case value_t::object: 2462c5f01b2fSopenharmony_ci { 2463c5f01b2fSopenharmony_ci result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator); 2464c5f01b2fSopenharmony_ci break; 2465c5f01b2fSopenharmony_ci } 2466c5f01b2fSopenharmony_ci 2467c5f01b2fSopenharmony_ci case value_t::array: 2468c5f01b2fSopenharmony_ci { 2469c5f01b2fSopenharmony_ci result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator); 2470c5f01b2fSopenharmony_ci break; 2471c5f01b2fSopenharmony_ci } 2472c5f01b2fSopenharmony_ci 2473c5f01b2fSopenharmony_ci case value_t::null: 2474c5f01b2fSopenharmony_ci case value_t::discarded: 2475c5f01b2fSopenharmony_ci default: 2476c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this)); 2477c5f01b2fSopenharmony_ci } 2478c5f01b2fSopenharmony_ci 2479c5f01b2fSopenharmony_ci return result; 2480c5f01b2fSopenharmony_ci } 2481c5f01b2fSopenharmony_ci 2482c5f01b2fSopenharmony_ci /// @brief remove elements given an iterator range 2483c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/erase/ 2484c5f01b2fSopenharmony_ci template < class IteratorType, detail::enable_if_t < 2485c5f01b2fSopenharmony_ci std::is_same<IteratorType, typename basic_json_t::iterator>::value || 2486c5f01b2fSopenharmony_ci std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 > 2487c5f01b2fSopenharmony_ci IteratorType erase(IteratorType first, IteratorType last) 2488c5f01b2fSopenharmony_ci { 2489c5f01b2fSopenharmony_ci // make sure iterator fits the current value 2490c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object)) 2491c5f01b2fSopenharmony_ci { 2492c5f01b2fSopenharmony_ci JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this)); 2493c5f01b2fSopenharmony_ci } 2494c5f01b2fSopenharmony_ci 2495c5f01b2fSopenharmony_ci IteratorType result = end(); 2496c5f01b2fSopenharmony_ci 2497c5f01b2fSopenharmony_ci switch (m_type) 2498c5f01b2fSopenharmony_ci { 2499c5f01b2fSopenharmony_ci case value_t::boolean: 2500c5f01b2fSopenharmony_ci case value_t::number_float: 2501c5f01b2fSopenharmony_ci case value_t::number_integer: 2502c5f01b2fSopenharmony_ci case value_t::number_unsigned: 2503c5f01b2fSopenharmony_ci case value_t::string: 2504c5f01b2fSopenharmony_ci case value_t::binary: 2505c5f01b2fSopenharmony_ci { 2506c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin() 2507c5f01b2fSopenharmony_ci || !last.m_it.primitive_iterator.is_end())) 2508c5f01b2fSopenharmony_ci { 2509c5f01b2fSopenharmony_ci JSON_THROW(invalid_iterator::create(204, "iterators out of range", this)); 2510c5f01b2fSopenharmony_ci } 2511c5f01b2fSopenharmony_ci 2512c5f01b2fSopenharmony_ci if (is_string()) 2513c5f01b2fSopenharmony_ci { 2514c5f01b2fSopenharmony_ci AllocatorType<string_t> alloc; 2515c5f01b2fSopenharmony_ci std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string); 2516c5f01b2fSopenharmony_ci std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1); 2517c5f01b2fSopenharmony_ci m_value.string = nullptr; 2518c5f01b2fSopenharmony_ci } 2519c5f01b2fSopenharmony_ci else if (is_binary()) 2520c5f01b2fSopenharmony_ci { 2521c5f01b2fSopenharmony_ci AllocatorType<binary_t> alloc; 2522c5f01b2fSopenharmony_ci std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary); 2523c5f01b2fSopenharmony_ci std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1); 2524c5f01b2fSopenharmony_ci m_value.binary = nullptr; 2525c5f01b2fSopenharmony_ci } 2526c5f01b2fSopenharmony_ci 2527c5f01b2fSopenharmony_ci m_type = value_t::null; 2528c5f01b2fSopenharmony_ci assert_invariant(); 2529c5f01b2fSopenharmony_ci break; 2530c5f01b2fSopenharmony_ci } 2531c5f01b2fSopenharmony_ci 2532c5f01b2fSopenharmony_ci case value_t::object: 2533c5f01b2fSopenharmony_ci { 2534c5f01b2fSopenharmony_ci result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator, 2535c5f01b2fSopenharmony_ci last.m_it.object_iterator); 2536c5f01b2fSopenharmony_ci break; 2537c5f01b2fSopenharmony_ci } 2538c5f01b2fSopenharmony_ci 2539c5f01b2fSopenharmony_ci case value_t::array: 2540c5f01b2fSopenharmony_ci { 2541c5f01b2fSopenharmony_ci result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator, 2542c5f01b2fSopenharmony_ci last.m_it.array_iterator); 2543c5f01b2fSopenharmony_ci break; 2544c5f01b2fSopenharmony_ci } 2545c5f01b2fSopenharmony_ci 2546c5f01b2fSopenharmony_ci case value_t::null: 2547c5f01b2fSopenharmony_ci case value_t::discarded: 2548c5f01b2fSopenharmony_ci default: 2549c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this)); 2550c5f01b2fSopenharmony_ci } 2551c5f01b2fSopenharmony_ci 2552c5f01b2fSopenharmony_ci return result; 2553c5f01b2fSopenharmony_ci } 2554c5f01b2fSopenharmony_ci 2555c5f01b2fSopenharmony_ci private: 2556c5f01b2fSopenharmony_ci template < typename KeyType, detail::enable_if_t < 2557c5f01b2fSopenharmony_ci detail::has_erase_with_key_type<basic_json_t, KeyType>::value, int > = 0 > 2558c5f01b2fSopenharmony_ci size_type erase_internal(KeyType && key) 2559c5f01b2fSopenharmony_ci { 2560c5f01b2fSopenharmony_ci // this erase only works for objects 2561c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!is_object())) 2562c5f01b2fSopenharmony_ci { 2563c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this)); 2564c5f01b2fSopenharmony_ci } 2565c5f01b2fSopenharmony_ci 2566c5f01b2fSopenharmony_ci return m_value.object->erase(std::forward<KeyType>(key)); 2567c5f01b2fSopenharmony_ci } 2568c5f01b2fSopenharmony_ci 2569c5f01b2fSopenharmony_ci template < typename KeyType, detail::enable_if_t < 2570c5f01b2fSopenharmony_ci !detail::has_erase_with_key_type<basic_json_t, KeyType>::value, int > = 0 > 2571c5f01b2fSopenharmony_ci size_type erase_internal(KeyType && key) 2572c5f01b2fSopenharmony_ci { 2573c5f01b2fSopenharmony_ci // this erase only works for objects 2574c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!is_object())) 2575c5f01b2fSopenharmony_ci { 2576c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this)); 2577c5f01b2fSopenharmony_ci } 2578c5f01b2fSopenharmony_ci 2579c5f01b2fSopenharmony_ci const auto it = m_value.object->find(std::forward<KeyType>(key)); 2580c5f01b2fSopenharmony_ci if (it != m_value.object->end()) 2581c5f01b2fSopenharmony_ci { 2582c5f01b2fSopenharmony_ci m_value.object->erase(it); 2583c5f01b2fSopenharmony_ci return 1; 2584c5f01b2fSopenharmony_ci } 2585c5f01b2fSopenharmony_ci return 0; 2586c5f01b2fSopenharmony_ci } 2587c5f01b2fSopenharmony_ci 2588c5f01b2fSopenharmony_ci public: 2589c5f01b2fSopenharmony_ci 2590c5f01b2fSopenharmony_ci /// @brief remove element from a JSON object given a key 2591c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/erase/ 2592c5f01b2fSopenharmony_ci size_type erase(const typename object_t::key_type& key) 2593c5f01b2fSopenharmony_ci { 2594c5f01b2fSopenharmony_ci // the indirection via erase_internal() is added to avoid making this 2595c5f01b2fSopenharmony_ci // function a template and thus de-rank it during overload resolution 2596c5f01b2fSopenharmony_ci return erase_internal(key); 2597c5f01b2fSopenharmony_ci } 2598c5f01b2fSopenharmony_ci 2599c5f01b2fSopenharmony_ci /// @brief remove element from a JSON object given a key 2600c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/erase/ 2601c5f01b2fSopenharmony_ci template<class KeyType, detail::enable_if_t< 2602c5f01b2fSopenharmony_ci detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0> 2603c5f01b2fSopenharmony_ci size_type erase(KeyType && key) 2604c5f01b2fSopenharmony_ci { 2605c5f01b2fSopenharmony_ci return erase_internal(std::forward<KeyType>(key)); 2606c5f01b2fSopenharmony_ci } 2607c5f01b2fSopenharmony_ci 2608c5f01b2fSopenharmony_ci /// @brief remove element from a JSON array given an index 2609c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/erase/ 2610c5f01b2fSopenharmony_ci void erase(const size_type idx) 2611c5f01b2fSopenharmony_ci { 2612c5f01b2fSopenharmony_ci // this erase only works for arrays 2613c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_array())) 2614c5f01b2fSopenharmony_ci { 2615c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(idx >= size())) 2616c5f01b2fSopenharmony_ci { 2617c5f01b2fSopenharmony_ci JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this)); 2618c5f01b2fSopenharmony_ci } 2619c5f01b2fSopenharmony_ci 2620c5f01b2fSopenharmony_ci m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx)); 2621c5f01b2fSopenharmony_ci } 2622c5f01b2fSopenharmony_ci else 2623c5f01b2fSopenharmony_ci { 2624c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this)); 2625c5f01b2fSopenharmony_ci } 2626c5f01b2fSopenharmony_ci } 2627c5f01b2fSopenharmony_ci 2628c5f01b2fSopenharmony_ci /// @} 2629c5f01b2fSopenharmony_ci 2630c5f01b2fSopenharmony_ci 2631c5f01b2fSopenharmony_ci //////////// 2632c5f01b2fSopenharmony_ci // lookup // 2633c5f01b2fSopenharmony_ci //////////// 2634c5f01b2fSopenharmony_ci 2635c5f01b2fSopenharmony_ci /// @name lookup 2636c5f01b2fSopenharmony_ci /// @{ 2637c5f01b2fSopenharmony_ci 2638c5f01b2fSopenharmony_ci /// @brief find an element in a JSON object 2639c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/find/ 2640c5f01b2fSopenharmony_ci iterator find(const typename object_t::key_type& key) 2641c5f01b2fSopenharmony_ci { 2642c5f01b2fSopenharmony_ci auto result = end(); 2643c5f01b2fSopenharmony_ci 2644c5f01b2fSopenharmony_ci if (is_object()) 2645c5f01b2fSopenharmony_ci { 2646c5f01b2fSopenharmony_ci result.m_it.object_iterator = m_value.object->find(key); 2647c5f01b2fSopenharmony_ci } 2648c5f01b2fSopenharmony_ci 2649c5f01b2fSopenharmony_ci return result; 2650c5f01b2fSopenharmony_ci } 2651c5f01b2fSopenharmony_ci 2652c5f01b2fSopenharmony_ci /// @brief find an element in a JSON object 2653c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/find/ 2654c5f01b2fSopenharmony_ci const_iterator find(const typename object_t::key_type& key) const 2655c5f01b2fSopenharmony_ci { 2656c5f01b2fSopenharmony_ci auto result = cend(); 2657c5f01b2fSopenharmony_ci 2658c5f01b2fSopenharmony_ci if (is_object()) 2659c5f01b2fSopenharmony_ci { 2660c5f01b2fSopenharmony_ci result.m_it.object_iterator = m_value.object->find(key); 2661c5f01b2fSopenharmony_ci } 2662c5f01b2fSopenharmony_ci 2663c5f01b2fSopenharmony_ci return result; 2664c5f01b2fSopenharmony_ci } 2665c5f01b2fSopenharmony_ci 2666c5f01b2fSopenharmony_ci /// @brief find an element in a JSON object 2667c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/find/ 2668c5f01b2fSopenharmony_ci template<class KeyType, detail::enable_if_t< 2669c5f01b2fSopenharmony_ci detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0> 2670c5f01b2fSopenharmony_ci iterator find(KeyType && key) 2671c5f01b2fSopenharmony_ci { 2672c5f01b2fSopenharmony_ci auto result = end(); 2673c5f01b2fSopenharmony_ci 2674c5f01b2fSopenharmony_ci if (is_object()) 2675c5f01b2fSopenharmony_ci { 2676c5f01b2fSopenharmony_ci result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key)); 2677c5f01b2fSopenharmony_ci } 2678c5f01b2fSopenharmony_ci 2679c5f01b2fSopenharmony_ci return result; 2680c5f01b2fSopenharmony_ci } 2681c5f01b2fSopenharmony_ci 2682c5f01b2fSopenharmony_ci /// @brief find an element in a JSON object 2683c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/find/ 2684c5f01b2fSopenharmony_ci template<class KeyType, detail::enable_if_t< 2685c5f01b2fSopenharmony_ci detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0> 2686c5f01b2fSopenharmony_ci const_iterator find(KeyType && key) const 2687c5f01b2fSopenharmony_ci { 2688c5f01b2fSopenharmony_ci auto result = cend(); 2689c5f01b2fSopenharmony_ci 2690c5f01b2fSopenharmony_ci if (is_object()) 2691c5f01b2fSopenharmony_ci { 2692c5f01b2fSopenharmony_ci result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key)); 2693c5f01b2fSopenharmony_ci } 2694c5f01b2fSopenharmony_ci 2695c5f01b2fSopenharmony_ci return result; 2696c5f01b2fSopenharmony_ci } 2697c5f01b2fSopenharmony_ci 2698c5f01b2fSopenharmony_ci /// @brief returns the number of occurrences of a key in a JSON object 2699c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/count/ 2700c5f01b2fSopenharmony_ci size_type count(const typename object_t::key_type& key) const 2701c5f01b2fSopenharmony_ci { 2702c5f01b2fSopenharmony_ci // return 0 for all nonobject types 2703c5f01b2fSopenharmony_ci return is_object() ? m_value.object->count(key) : 0; 2704c5f01b2fSopenharmony_ci } 2705c5f01b2fSopenharmony_ci 2706c5f01b2fSopenharmony_ci /// @brief returns the number of occurrences of a key in a JSON object 2707c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/count/ 2708c5f01b2fSopenharmony_ci template<class KeyType, detail::enable_if_t< 2709c5f01b2fSopenharmony_ci detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0> 2710c5f01b2fSopenharmony_ci size_type count(KeyType && key) const 2711c5f01b2fSopenharmony_ci { 2712c5f01b2fSopenharmony_ci // return 0 for all nonobject types 2713c5f01b2fSopenharmony_ci return is_object() ? m_value.object->count(std::forward<KeyType>(key)) : 0; 2714c5f01b2fSopenharmony_ci } 2715c5f01b2fSopenharmony_ci 2716c5f01b2fSopenharmony_ci /// @brief check the existence of an element in a JSON object 2717c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/contains/ 2718c5f01b2fSopenharmony_ci bool contains(const typename object_t::key_type& key) const 2719c5f01b2fSopenharmony_ci { 2720c5f01b2fSopenharmony_ci return is_object() && m_value.object->find(key) != m_value.object->end(); 2721c5f01b2fSopenharmony_ci } 2722c5f01b2fSopenharmony_ci 2723c5f01b2fSopenharmony_ci /// @brief check the existence of an element in a JSON object 2724c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/contains/ 2725c5f01b2fSopenharmony_ci template<class KeyType, detail::enable_if_t< 2726c5f01b2fSopenharmony_ci detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0> 2727c5f01b2fSopenharmony_ci bool contains(KeyType && key) const 2728c5f01b2fSopenharmony_ci { 2729c5f01b2fSopenharmony_ci return is_object() && m_value.object->find(std::forward<KeyType>(key)) != m_value.object->end(); 2730c5f01b2fSopenharmony_ci } 2731c5f01b2fSopenharmony_ci 2732c5f01b2fSopenharmony_ci /// @brief check the existence of an element in a JSON object given a JSON pointer 2733c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/contains/ 2734c5f01b2fSopenharmony_ci bool contains(const json_pointer& ptr) const 2735c5f01b2fSopenharmony_ci { 2736c5f01b2fSopenharmony_ci return ptr.contains(this); 2737c5f01b2fSopenharmony_ci } 2738c5f01b2fSopenharmony_ci 2739c5f01b2fSopenharmony_ci template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0> 2740c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens) 2741c5f01b2fSopenharmony_ci bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr) const 2742c5f01b2fSopenharmony_ci { 2743c5f01b2fSopenharmony_ci return ptr.contains(this); 2744c5f01b2fSopenharmony_ci } 2745c5f01b2fSopenharmony_ci 2746c5f01b2fSopenharmony_ci /// @} 2747c5f01b2fSopenharmony_ci 2748c5f01b2fSopenharmony_ci 2749c5f01b2fSopenharmony_ci /////////////// 2750c5f01b2fSopenharmony_ci // iterators // 2751c5f01b2fSopenharmony_ci /////////////// 2752c5f01b2fSopenharmony_ci 2753c5f01b2fSopenharmony_ci /// @name iterators 2754c5f01b2fSopenharmony_ci /// @{ 2755c5f01b2fSopenharmony_ci 2756c5f01b2fSopenharmony_ci /// @brief returns an iterator to the first element 2757c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/begin/ 2758c5f01b2fSopenharmony_ci iterator begin() noexcept 2759c5f01b2fSopenharmony_ci { 2760c5f01b2fSopenharmony_ci iterator result(this); 2761c5f01b2fSopenharmony_ci result.set_begin(); 2762c5f01b2fSopenharmony_ci return result; 2763c5f01b2fSopenharmony_ci } 2764c5f01b2fSopenharmony_ci 2765c5f01b2fSopenharmony_ci /// @brief returns an iterator to the first element 2766c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/begin/ 2767c5f01b2fSopenharmony_ci const_iterator begin() const noexcept 2768c5f01b2fSopenharmony_ci { 2769c5f01b2fSopenharmony_ci return cbegin(); 2770c5f01b2fSopenharmony_ci } 2771c5f01b2fSopenharmony_ci 2772c5f01b2fSopenharmony_ci /// @brief returns a const iterator to the first element 2773c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/cbegin/ 2774c5f01b2fSopenharmony_ci const_iterator cbegin() const noexcept 2775c5f01b2fSopenharmony_ci { 2776c5f01b2fSopenharmony_ci const_iterator result(this); 2777c5f01b2fSopenharmony_ci result.set_begin(); 2778c5f01b2fSopenharmony_ci return result; 2779c5f01b2fSopenharmony_ci } 2780c5f01b2fSopenharmony_ci 2781c5f01b2fSopenharmony_ci /// @brief returns an iterator to one past the last element 2782c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/end/ 2783c5f01b2fSopenharmony_ci iterator end() noexcept 2784c5f01b2fSopenharmony_ci { 2785c5f01b2fSopenharmony_ci iterator result(this); 2786c5f01b2fSopenharmony_ci result.set_end(); 2787c5f01b2fSopenharmony_ci return result; 2788c5f01b2fSopenharmony_ci } 2789c5f01b2fSopenharmony_ci 2790c5f01b2fSopenharmony_ci /// @brief returns an iterator to one past the last element 2791c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/end/ 2792c5f01b2fSopenharmony_ci const_iterator end() const noexcept 2793c5f01b2fSopenharmony_ci { 2794c5f01b2fSopenharmony_ci return cend(); 2795c5f01b2fSopenharmony_ci } 2796c5f01b2fSopenharmony_ci 2797c5f01b2fSopenharmony_ci /// @brief returns an iterator to one past the last element 2798c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/cend/ 2799c5f01b2fSopenharmony_ci const_iterator cend() const noexcept 2800c5f01b2fSopenharmony_ci { 2801c5f01b2fSopenharmony_ci const_iterator result(this); 2802c5f01b2fSopenharmony_ci result.set_end(); 2803c5f01b2fSopenharmony_ci return result; 2804c5f01b2fSopenharmony_ci } 2805c5f01b2fSopenharmony_ci 2806c5f01b2fSopenharmony_ci /// @brief returns an iterator to the reverse-beginning 2807c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/rbegin/ 2808c5f01b2fSopenharmony_ci reverse_iterator rbegin() noexcept 2809c5f01b2fSopenharmony_ci { 2810c5f01b2fSopenharmony_ci return reverse_iterator(end()); 2811c5f01b2fSopenharmony_ci } 2812c5f01b2fSopenharmony_ci 2813c5f01b2fSopenharmony_ci /// @brief returns an iterator to the reverse-beginning 2814c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/rbegin/ 2815c5f01b2fSopenharmony_ci const_reverse_iterator rbegin() const noexcept 2816c5f01b2fSopenharmony_ci { 2817c5f01b2fSopenharmony_ci return crbegin(); 2818c5f01b2fSopenharmony_ci } 2819c5f01b2fSopenharmony_ci 2820c5f01b2fSopenharmony_ci /// @brief returns an iterator to the reverse-end 2821c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/rend/ 2822c5f01b2fSopenharmony_ci reverse_iterator rend() noexcept 2823c5f01b2fSopenharmony_ci { 2824c5f01b2fSopenharmony_ci return reverse_iterator(begin()); 2825c5f01b2fSopenharmony_ci } 2826c5f01b2fSopenharmony_ci 2827c5f01b2fSopenharmony_ci /// @brief returns an iterator to the reverse-end 2828c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/rend/ 2829c5f01b2fSopenharmony_ci const_reverse_iterator rend() const noexcept 2830c5f01b2fSopenharmony_ci { 2831c5f01b2fSopenharmony_ci return crend(); 2832c5f01b2fSopenharmony_ci } 2833c5f01b2fSopenharmony_ci 2834c5f01b2fSopenharmony_ci /// @brief returns a const reverse iterator to the last element 2835c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/crbegin/ 2836c5f01b2fSopenharmony_ci const_reverse_iterator crbegin() const noexcept 2837c5f01b2fSopenharmony_ci { 2838c5f01b2fSopenharmony_ci return const_reverse_iterator(cend()); 2839c5f01b2fSopenharmony_ci } 2840c5f01b2fSopenharmony_ci 2841c5f01b2fSopenharmony_ci /// @brief returns a const reverse iterator to one before the first 2842c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/crend/ 2843c5f01b2fSopenharmony_ci const_reverse_iterator crend() const noexcept 2844c5f01b2fSopenharmony_ci { 2845c5f01b2fSopenharmony_ci return const_reverse_iterator(cbegin()); 2846c5f01b2fSopenharmony_ci } 2847c5f01b2fSopenharmony_ci 2848c5f01b2fSopenharmony_ci public: 2849c5f01b2fSopenharmony_ci /// @brief wrapper to access iterator member functions in range-based for 2850c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/items/ 2851c5f01b2fSopenharmony_ci /// @deprecated This function is deprecated since 3.1.0 and will be removed in 2852c5f01b2fSopenharmony_ci /// version 4.0.0 of the library. Please use @ref items() instead; 2853c5f01b2fSopenharmony_ci /// that is, replace `json::iterator_wrapper(j)` with `j.items()`. 2854c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items()) 2855c5f01b2fSopenharmony_ci static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept 2856c5f01b2fSopenharmony_ci { 2857c5f01b2fSopenharmony_ci return ref.items(); 2858c5f01b2fSopenharmony_ci } 2859c5f01b2fSopenharmony_ci 2860c5f01b2fSopenharmony_ci /// @brief wrapper to access iterator member functions in range-based for 2861c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/items/ 2862c5f01b2fSopenharmony_ci /// @deprecated This function is deprecated since 3.1.0 and will be removed in 2863c5f01b2fSopenharmony_ci /// version 4.0.0 of the library. Please use @ref items() instead; 2864c5f01b2fSopenharmony_ci /// that is, replace `json::iterator_wrapper(j)` with `j.items()`. 2865c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items()) 2866c5f01b2fSopenharmony_ci static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept 2867c5f01b2fSopenharmony_ci { 2868c5f01b2fSopenharmony_ci return ref.items(); 2869c5f01b2fSopenharmony_ci } 2870c5f01b2fSopenharmony_ci 2871c5f01b2fSopenharmony_ci /// @brief helper to access iterator member functions in range-based for 2872c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/items/ 2873c5f01b2fSopenharmony_ci iteration_proxy<iterator> items() noexcept 2874c5f01b2fSopenharmony_ci { 2875c5f01b2fSopenharmony_ci return iteration_proxy<iterator>(*this); 2876c5f01b2fSopenharmony_ci } 2877c5f01b2fSopenharmony_ci 2878c5f01b2fSopenharmony_ci /// @brief helper to access iterator member functions in range-based for 2879c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/items/ 2880c5f01b2fSopenharmony_ci iteration_proxy<const_iterator> items() const noexcept 2881c5f01b2fSopenharmony_ci { 2882c5f01b2fSopenharmony_ci return iteration_proxy<const_iterator>(*this); 2883c5f01b2fSopenharmony_ci } 2884c5f01b2fSopenharmony_ci 2885c5f01b2fSopenharmony_ci /// @} 2886c5f01b2fSopenharmony_ci 2887c5f01b2fSopenharmony_ci 2888c5f01b2fSopenharmony_ci ////////////// 2889c5f01b2fSopenharmony_ci // capacity // 2890c5f01b2fSopenharmony_ci ////////////// 2891c5f01b2fSopenharmony_ci 2892c5f01b2fSopenharmony_ci /// @name capacity 2893c5f01b2fSopenharmony_ci /// @{ 2894c5f01b2fSopenharmony_ci 2895c5f01b2fSopenharmony_ci /// @brief checks whether the container is empty. 2896c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/empty/ 2897c5f01b2fSopenharmony_ci bool empty() const noexcept 2898c5f01b2fSopenharmony_ci { 2899c5f01b2fSopenharmony_ci switch (m_type) 2900c5f01b2fSopenharmony_ci { 2901c5f01b2fSopenharmony_ci case value_t::null: 2902c5f01b2fSopenharmony_ci { 2903c5f01b2fSopenharmony_ci // null values are empty 2904c5f01b2fSopenharmony_ci return true; 2905c5f01b2fSopenharmony_ci } 2906c5f01b2fSopenharmony_ci 2907c5f01b2fSopenharmony_ci case value_t::array: 2908c5f01b2fSopenharmony_ci { 2909c5f01b2fSopenharmony_ci // delegate call to array_t::empty() 2910c5f01b2fSopenharmony_ci return m_value.array->empty(); 2911c5f01b2fSopenharmony_ci } 2912c5f01b2fSopenharmony_ci 2913c5f01b2fSopenharmony_ci case value_t::object: 2914c5f01b2fSopenharmony_ci { 2915c5f01b2fSopenharmony_ci // delegate call to object_t::empty() 2916c5f01b2fSopenharmony_ci return m_value.object->empty(); 2917c5f01b2fSopenharmony_ci } 2918c5f01b2fSopenharmony_ci 2919c5f01b2fSopenharmony_ci case value_t::string: 2920c5f01b2fSopenharmony_ci case value_t::boolean: 2921c5f01b2fSopenharmony_ci case value_t::number_integer: 2922c5f01b2fSopenharmony_ci case value_t::number_unsigned: 2923c5f01b2fSopenharmony_ci case value_t::number_float: 2924c5f01b2fSopenharmony_ci case value_t::binary: 2925c5f01b2fSopenharmony_ci case value_t::discarded: 2926c5f01b2fSopenharmony_ci default: 2927c5f01b2fSopenharmony_ci { 2928c5f01b2fSopenharmony_ci // all other types are nonempty 2929c5f01b2fSopenharmony_ci return false; 2930c5f01b2fSopenharmony_ci } 2931c5f01b2fSopenharmony_ci } 2932c5f01b2fSopenharmony_ci } 2933c5f01b2fSopenharmony_ci 2934c5f01b2fSopenharmony_ci /// @brief returns the number of elements 2935c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/size/ 2936c5f01b2fSopenharmony_ci size_type size() const noexcept 2937c5f01b2fSopenharmony_ci { 2938c5f01b2fSopenharmony_ci switch (m_type) 2939c5f01b2fSopenharmony_ci { 2940c5f01b2fSopenharmony_ci case value_t::null: 2941c5f01b2fSopenharmony_ci { 2942c5f01b2fSopenharmony_ci // null values are empty 2943c5f01b2fSopenharmony_ci return 0; 2944c5f01b2fSopenharmony_ci } 2945c5f01b2fSopenharmony_ci 2946c5f01b2fSopenharmony_ci case value_t::array: 2947c5f01b2fSopenharmony_ci { 2948c5f01b2fSopenharmony_ci // delegate call to array_t::size() 2949c5f01b2fSopenharmony_ci return m_value.array->size(); 2950c5f01b2fSopenharmony_ci } 2951c5f01b2fSopenharmony_ci 2952c5f01b2fSopenharmony_ci case value_t::object: 2953c5f01b2fSopenharmony_ci { 2954c5f01b2fSopenharmony_ci // delegate call to object_t::size() 2955c5f01b2fSopenharmony_ci return m_value.object->size(); 2956c5f01b2fSopenharmony_ci } 2957c5f01b2fSopenharmony_ci 2958c5f01b2fSopenharmony_ci case value_t::string: 2959c5f01b2fSopenharmony_ci case value_t::boolean: 2960c5f01b2fSopenharmony_ci case value_t::number_integer: 2961c5f01b2fSopenharmony_ci case value_t::number_unsigned: 2962c5f01b2fSopenharmony_ci case value_t::number_float: 2963c5f01b2fSopenharmony_ci case value_t::binary: 2964c5f01b2fSopenharmony_ci case value_t::discarded: 2965c5f01b2fSopenharmony_ci default: 2966c5f01b2fSopenharmony_ci { 2967c5f01b2fSopenharmony_ci // all other types have size 1 2968c5f01b2fSopenharmony_ci return 1; 2969c5f01b2fSopenharmony_ci } 2970c5f01b2fSopenharmony_ci } 2971c5f01b2fSopenharmony_ci } 2972c5f01b2fSopenharmony_ci 2973c5f01b2fSopenharmony_ci /// @brief returns the maximum possible number of elements 2974c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/max_size/ 2975c5f01b2fSopenharmony_ci size_type max_size() const noexcept 2976c5f01b2fSopenharmony_ci { 2977c5f01b2fSopenharmony_ci switch (m_type) 2978c5f01b2fSopenharmony_ci { 2979c5f01b2fSopenharmony_ci case value_t::array: 2980c5f01b2fSopenharmony_ci { 2981c5f01b2fSopenharmony_ci // delegate call to array_t::max_size() 2982c5f01b2fSopenharmony_ci return m_value.array->max_size(); 2983c5f01b2fSopenharmony_ci } 2984c5f01b2fSopenharmony_ci 2985c5f01b2fSopenharmony_ci case value_t::object: 2986c5f01b2fSopenharmony_ci { 2987c5f01b2fSopenharmony_ci // delegate call to object_t::max_size() 2988c5f01b2fSopenharmony_ci return m_value.object->max_size(); 2989c5f01b2fSopenharmony_ci } 2990c5f01b2fSopenharmony_ci 2991c5f01b2fSopenharmony_ci case value_t::null: 2992c5f01b2fSopenharmony_ci case value_t::string: 2993c5f01b2fSopenharmony_ci case value_t::boolean: 2994c5f01b2fSopenharmony_ci case value_t::number_integer: 2995c5f01b2fSopenharmony_ci case value_t::number_unsigned: 2996c5f01b2fSopenharmony_ci case value_t::number_float: 2997c5f01b2fSopenharmony_ci case value_t::binary: 2998c5f01b2fSopenharmony_ci case value_t::discarded: 2999c5f01b2fSopenharmony_ci default: 3000c5f01b2fSopenharmony_ci { 3001c5f01b2fSopenharmony_ci // all other types have max_size() == size() 3002c5f01b2fSopenharmony_ci return size(); 3003c5f01b2fSopenharmony_ci } 3004c5f01b2fSopenharmony_ci } 3005c5f01b2fSopenharmony_ci } 3006c5f01b2fSopenharmony_ci 3007c5f01b2fSopenharmony_ci /// @} 3008c5f01b2fSopenharmony_ci 3009c5f01b2fSopenharmony_ci 3010c5f01b2fSopenharmony_ci /////////////// 3011c5f01b2fSopenharmony_ci // modifiers // 3012c5f01b2fSopenharmony_ci /////////////// 3013c5f01b2fSopenharmony_ci 3014c5f01b2fSopenharmony_ci /// @name modifiers 3015c5f01b2fSopenharmony_ci /// @{ 3016c5f01b2fSopenharmony_ci 3017c5f01b2fSopenharmony_ci /// @brief clears the contents 3018c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/clear/ 3019c5f01b2fSopenharmony_ci void clear() noexcept 3020c5f01b2fSopenharmony_ci { 3021c5f01b2fSopenharmony_ci switch (m_type) 3022c5f01b2fSopenharmony_ci { 3023c5f01b2fSopenharmony_ci case value_t::number_integer: 3024c5f01b2fSopenharmony_ci { 3025c5f01b2fSopenharmony_ci m_value.number_integer = 0; 3026c5f01b2fSopenharmony_ci break; 3027c5f01b2fSopenharmony_ci } 3028c5f01b2fSopenharmony_ci 3029c5f01b2fSopenharmony_ci case value_t::number_unsigned: 3030c5f01b2fSopenharmony_ci { 3031c5f01b2fSopenharmony_ci m_value.number_unsigned = 0; 3032c5f01b2fSopenharmony_ci break; 3033c5f01b2fSopenharmony_ci } 3034c5f01b2fSopenharmony_ci 3035c5f01b2fSopenharmony_ci case value_t::number_float: 3036c5f01b2fSopenharmony_ci { 3037c5f01b2fSopenharmony_ci m_value.number_float = 0.0; 3038c5f01b2fSopenharmony_ci break; 3039c5f01b2fSopenharmony_ci } 3040c5f01b2fSopenharmony_ci 3041c5f01b2fSopenharmony_ci case value_t::boolean: 3042c5f01b2fSopenharmony_ci { 3043c5f01b2fSopenharmony_ci m_value.boolean = false; 3044c5f01b2fSopenharmony_ci break; 3045c5f01b2fSopenharmony_ci } 3046c5f01b2fSopenharmony_ci 3047c5f01b2fSopenharmony_ci case value_t::string: 3048c5f01b2fSopenharmony_ci { 3049c5f01b2fSopenharmony_ci m_value.string->clear(); 3050c5f01b2fSopenharmony_ci break; 3051c5f01b2fSopenharmony_ci } 3052c5f01b2fSopenharmony_ci 3053c5f01b2fSopenharmony_ci case value_t::binary: 3054c5f01b2fSopenharmony_ci { 3055c5f01b2fSopenharmony_ci m_value.binary->clear(); 3056c5f01b2fSopenharmony_ci break; 3057c5f01b2fSopenharmony_ci } 3058c5f01b2fSopenharmony_ci 3059c5f01b2fSopenharmony_ci case value_t::array: 3060c5f01b2fSopenharmony_ci { 3061c5f01b2fSopenharmony_ci m_value.array->clear(); 3062c5f01b2fSopenharmony_ci break; 3063c5f01b2fSopenharmony_ci } 3064c5f01b2fSopenharmony_ci 3065c5f01b2fSopenharmony_ci case value_t::object: 3066c5f01b2fSopenharmony_ci { 3067c5f01b2fSopenharmony_ci m_value.object->clear(); 3068c5f01b2fSopenharmony_ci break; 3069c5f01b2fSopenharmony_ci } 3070c5f01b2fSopenharmony_ci 3071c5f01b2fSopenharmony_ci case value_t::null: 3072c5f01b2fSopenharmony_ci case value_t::discarded: 3073c5f01b2fSopenharmony_ci default: 3074c5f01b2fSopenharmony_ci break; 3075c5f01b2fSopenharmony_ci } 3076c5f01b2fSopenharmony_ci } 3077c5f01b2fSopenharmony_ci 3078c5f01b2fSopenharmony_ci /// @brief add an object to an array 3079c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/push_back/ 3080c5f01b2fSopenharmony_ci void push_back(basic_json&& val) 3081c5f01b2fSopenharmony_ci { 3082c5f01b2fSopenharmony_ci // push_back only works for null objects or arrays 3083c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array()))) 3084c5f01b2fSopenharmony_ci { 3085c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this)); 3086c5f01b2fSopenharmony_ci } 3087c5f01b2fSopenharmony_ci 3088c5f01b2fSopenharmony_ci // transform null object into an array 3089c5f01b2fSopenharmony_ci if (is_null()) 3090c5f01b2fSopenharmony_ci { 3091c5f01b2fSopenharmony_ci m_type = value_t::array; 3092c5f01b2fSopenharmony_ci m_value = value_t::array; 3093c5f01b2fSopenharmony_ci assert_invariant(); 3094c5f01b2fSopenharmony_ci } 3095c5f01b2fSopenharmony_ci 3096c5f01b2fSopenharmony_ci // add element to array (move semantics) 3097c5f01b2fSopenharmony_ci const auto old_capacity = m_value.array->capacity(); 3098c5f01b2fSopenharmony_ci m_value.array->push_back(std::move(val)); 3099c5f01b2fSopenharmony_ci set_parent(m_value.array->back(), old_capacity); 3100c5f01b2fSopenharmony_ci // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor 3101c5f01b2fSopenharmony_ci } 3102c5f01b2fSopenharmony_ci 3103c5f01b2fSopenharmony_ci /// @brief add an object to an array 3104c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator+=/ 3105c5f01b2fSopenharmony_ci reference operator+=(basic_json&& val) 3106c5f01b2fSopenharmony_ci { 3107c5f01b2fSopenharmony_ci push_back(std::move(val)); 3108c5f01b2fSopenharmony_ci return *this; 3109c5f01b2fSopenharmony_ci } 3110c5f01b2fSopenharmony_ci 3111c5f01b2fSopenharmony_ci /// @brief add an object to an array 3112c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/push_back/ 3113c5f01b2fSopenharmony_ci void push_back(const basic_json& val) 3114c5f01b2fSopenharmony_ci { 3115c5f01b2fSopenharmony_ci // push_back only works for null objects or arrays 3116c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array()))) 3117c5f01b2fSopenharmony_ci { 3118c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this)); 3119c5f01b2fSopenharmony_ci } 3120c5f01b2fSopenharmony_ci 3121c5f01b2fSopenharmony_ci // transform null object into an array 3122c5f01b2fSopenharmony_ci if (is_null()) 3123c5f01b2fSopenharmony_ci { 3124c5f01b2fSopenharmony_ci m_type = value_t::array; 3125c5f01b2fSopenharmony_ci m_value = value_t::array; 3126c5f01b2fSopenharmony_ci assert_invariant(); 3127c5f01b2fSopenharmony_ci } 3128c5f01b2fSopenharmony_ci 3129c5f01b2fSopenharmony_ci // add element to array 3130c5f01b2fSopenharmony_ci const auto old_capacity = m_value.array->capacity(); 3131c5f01b2fSopenharmony_ci m_value.array->push_back(val); 3132c5f01b2fSopenharmony_ci set_parent(m_value.array->back(), old_capacity); 3133c5f01b2fSopenharmony_ci } 3134c5f01b2fSopenharmony_ci 3135c5f01b2fSopenharmony_ci /// @brief add an object to an array 3136c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator+=/ 3137c5f01b2fSopenharmony_ci reference operator+=(const basic_json& val) 3138c5f01b2fSopenharmony_ci { 3139c5f01b2fSopenharmony_ci push_back(val); 3140c5f01b2fSopenharmony_ci return *this; 3141c5f01b2fSopenharmony_ci } 3142c5f01b2fSopenharmony_ci 3143c5f01b2fSopenharmony_ci /// @brief add an object to an object 3144c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/push_back/ 3145c5f01b2fSopenharmony_ci void push_back(const typename object_t::value_type& val) 3146c5f01b2fSopenharmony_ci { 3147c5f01b2fSopenharmony_ci // push_back only works for null objects or objects 3148c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object()))) 3149c5f01b2fSopenharmony_ci { 3150c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this)); 3151c5f01b2fSopenharmony_ci } 3152c5f01b2fSopenharmony_ci 3153c5f01b2fSopenharmony_ci // transform null object into an object 3154c5f01b2fSopenharmony_ci if (is_null()) 3155c5f01b2fSopenharmony_ci { 3156c5f01b2fSopenharmony_ci m_type = value_t::object; 3157c5f01b2fSopenharmony_ci m_value = value_t::object; 3158c5f01b2fSopenharmony_ci assert_invariant(); 3159c5f01b2fSopenharmony_ci } 3160c5f01b2fSopenharmony_ci 3161c5f01b2fSopenharmony_ci // add element to object 3162c5f01b2fSopenharmony_ci auto res = m_value.object->insert(val); 3163c5f01b2fSopenharmony_ci set_parent(res.first->second); 3164c5f01b2fSopenharmony_ci } 3165c5f01b2fSopenharmony_ci 3166c5f01b2fSopenharmony_ci /// @brief add an object to an object 3167c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator+=/ 3168c5f01b2fSopenharmony_ci reference operator+=(const typename object_t::value_type& val) 3169c5f01b2fSopenharmony_ci { 3170c5f01b2fSopenharmony_ci push_back(val); 3171c5f01b2fSopenharmony_ci return *this; 3172c5f01b2fSopenharmony_ci } 3173c5f01b2fSopenharmony_ci 3174c5f01b2fSopenharmony_ci /// @brief add an object to an object 3175c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/push_back/ 3176c5f01b2fSopenharmony_ci void push_back(initializer_list_t init) 3177c5f01b2fSopenharmony_ci { 3178c5f01b2fSopenharmony_ci if (is_object() && init.size() == 2 && (*init.begin())->is_string()) 3179c5f01b2fSopenharmony_ci { 3180c5f01b2fSopenharmony_ci basic_json&& key = init.begin()->moved_or_copied(); 3181c5f01b2fSopenharmony_ci push_back(typename object_t::value_type( 3182c5f01b2fSopenharmony_ci std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied())); 3183c5f01b2fSopenharmony_ci } 3184c5f01b2fSopenharmony_ci else 3185c5f01b2fSopenharmony_ci { 3186c5f01b2fSopenharmony_ci push_back(basic_json(init)); 3187c5f01b2fSopenharmony_ci } 3188c5f01b2fSopenharmony_ci } 3189c5f01b2fSopenharmony_ci 3190c5f01b2fSopenharmony_ci /// @brief add an object to an object 3191c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator+=/ 3192c5f01b2fSopenharmony_ci reference operator+=(initializer_list_t init) 3193c5f01b2fSopenharmony_ci { 3194c5f01b2fSopenharmony_ci push_back(init); 3195c5f01b2fSopenharmony_ci return *this; 3196c5f01b2fSopenharmony_ci } 3197c5f01b2fSopenharmony_ci 3198c5f01b2fSopenharmony_ci /// @brief add an object to an array 3199c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/emplace_back/ 3200c5f01b2fSopenharmony_ci template<class... Args> 3201c5f01b2fSopenharmony_ci reference emplace_back(Args&& ... args) 3202c5f01b2fSopenharmony_ci { 3203c5f01b2fSopenharmony_ci // emplace_back only works for null objects or arrays 3204c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array()))) 3205c5f01b2fSopenharmony_ci { 3206c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this)); 3207c5f01b2fSopenharmony_ci } 3208c5f01b2fSopenharmony_ci 3209c5f01b2fSopenharmony_ci // transform null object into an array 3210c5f01b2fSopenharmony_ci if (is_null()) 3211c5f01b2fSopenharmony_ci { 3212c5f01b2fSopenharmony_ci m_type = value_t::array; 3213c5f01b2fSopenharmony_ci m_value = value_t::array; 3214c5f01b2fSopenharmony_ci assert_invariant(); 3215c5f01b2fSopenharmony_ci } 3216c5f01b2fSopenharmony_ci 3217c5f01b2fSopenharmony_ci // add element to array (perfect forwarding) 3218c5f01b2fSopenharmony_ci const auto old_capacity = m_value.array->capacity(); 3219c5f01b2fSopenharmony_ci m_value.array->emplace_back(std::forward<Args>(args)...); 3220c5f01b2fSopenharmony_ci return set_parent(m_value.array->back(), old_capacity); 3221c5f01b2fSopenharmony_ci } 3222c5f01b2fSopenharmony_ci 3223c5f01b2fSopenharmony_ci /// @brief add an object to an object if key does not exist 3224c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/emplace/ 3225c5f01b2fSopenharmony_ci template<class... Args> 3226c5f01b2fSopenharmony_ci std::pair<iterator, bool> emplace(Args&& ... args) 3227c5f01b2fSopenharmony_ci { 3228c5f01b2fSopenharmony_ci // emplace only works for null objects or arrays 3229c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object()))) 3230c5f01b2fSopenharmony_ci { 3231c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this)); 3232c5f01b2fSopenharmony_ci } 3233c5f01b2fSopenharmony_ci 3234c5f01b2fSopenharmony_ci // transform null object into an object 3235c5f01b2fSopenharmony_ci if (is_null()) 3236c5f01b2fSopenharmony_ci { 3237c5f01b2fSopenharmony_ci m_type = value_t::object; 3238c5f01b2fSopenharmony_ci m_value = value_t::object; 3239c5f01b2fSopenharmony_ci assert_invariant(); 3240c5f01b2fSopenharmony_ci } 3241c5f01b2fSopenharmony_ci 3242c5f01b2fSopenharmony_ci // add element to array (perfect forwarding) 3243c5f01b2fSopenharmony_ci auto res = m_value.object->emplace(std::forward<Args>(args)...); 3244c5f01b2fSopenharmony_ci set_parent(res.first->second); 3245c5f01b2fSopenharmony_ci 3246c5f01b2fSopenharmony_ci // create result iterator and set iterator to the result of emplace 3247c5f01b2fSopenharmony_ci auto it = begin(); 3248c5f01b2fSopenharmony_ci it.m_it.object_iterator = res.first; 3249c5f01b2fSopenharmony_ci 3250c5f01b2fSopenharmony_ci // return pair of iterator and boolean 3251c5f01b2fSopenharmony_ci return {it, res.second}; 3252c5f01b2fSopenharmony_ci } 3253c5f01b2fSopenharmony_ci 3254c5f01b2fSopenharmony_ci /// Helper for insertion of an iterator 3255c5f01b2fSopenharmony_ci /// @note: This uses std::distance to support GCC 4.8, 3256c5f01b2fSopenharmony_ci /// see https://github.com/nlohmann/json/pull/1257 3257c5f01b2fSopenharmony_ci template<typename... Args> 3258c5f01b2fSopenharmony_ci iterator insert_iterator(const_iterator pos, Args&& ... args) 3259c5f01b2fSopenharmony_ci { 3260c5f01b2fSopenharmony_ci iterator result(this); 3261c5f01b2fSopenharmony_ci JSON_ASSERT(m_value.array != nullptr); 3262c5f01b2fSopenharmony_ci 3263c5f01b2fSopenharmony_ci auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator); 3264c5f01b2fSopenharmony_ci m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...); 3265c5f01b2fSopenharmony_ci result.m_it.array_iterator = m_value.array->begin() + insert_pos; 3266c5f01b2fSopenharmony_ci 3267c5f01b2fSopenharmony_ci // This could have been written as: 3268c5f01b2fSopenharmony_ci // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val); 3269c5f01b2fSopenharmony_ci // but the return value of insert is missing in GCC 4.8, so it is written this way instead. 3270c5f01b2fSopenharmony_ci 3271c5f01b2fSopenharmony_ci set_parents(); 3272c5f01b2fSopenharmony_ci return result; 3273c5f01b2fSopenharmony_ci } 3274c5f01b2fSopenharmony_ci 3275c5f01b2fSopenharmony_ci /// @brief inserts element into array 3276c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/insert/ 3277c5f01b2fSopenharmony_ci iterator insert(const_iterator pos, const basic_json& val) 3278c5f01b2fSopenharmony_ci { 3279c5f01b2fSopenharmony_ci // insert only works for arrays 3280c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_array())) 3281c5f01b2fSopenharmony_ci { 3282c5f01b2fSopenharmony_ci // check if iterator pos fits to this JSON value 3283c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) 3284c5f01b2fSopenharmony_ci { 3285c5f01b2fSopenharmony_ci JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this)); 3286c5f01b2fSopenharmony_ci } 3287c5f01b2fSopenharmony_ci 3288c5f01b2fSopenharmony_ci // insert to array and return iterator 3289c5f01b2fSopenharmony_ci return insert_iterator(pos, val); 3290c5f01b2fSopenharmony_ci } 3291c5f01b2fSopenharmony_ci 3292c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this)); 3293c5f01b2fSopenharmony_ci } 3294c5f01b2fSopenharmony_ci 3295c5f01b2fSopenharmony_ci /// @brief inserts element into array 3296c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/insert/ 3297c5f01b2fSopenharmony_ci iterator insert(const_iterator pos, basic_json&& val) 3298c5f01b2fSopenharmony_ci { 3299c5f01b2fSopenharmony_ci return insert(pos, val); 3300c5f01b2fSopenharmony_ci } 3301c5f01b2fSopenharmony_ci 3302c5f01b2fSopenharmony_ci /// @brief inserts copies of element into array 3303c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/insert/ 3304c5f01b2fSopenharmony_ci iterator insert(const_iterator pos, size_type cnt, const basic_json& val) 3305c5f01b2fSopenharmony_ci { 3306c5f01b2fSopenharmony_ci // insert only works for arrays 3307c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_array())) 3308c5f01b2fSopenharmony_ci { 3309c5f01b2fSopenharmony_ci // check if iterator pos fits to this JSON value 3310c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) 3311c5f01b2fSopenharmony_ci { 3312c5f01b2fSopenharmony_ci JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this)); 3313c5f01b2fSopenharmony_ci } 3314c5f01b2fSopenharmony_ci 3315c5f01b2fSopenharmony_ci // insert to array and return iterator 3316c5f01b2fSopenharmony_ci return insert_iterator(pos, cnt, val); 3317c5f01b2fSopenharmony_ci } 3318c5f01b2fSopenharmony_ci 3319c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this)); 3320c5f01b2fSopenharmony_ci } 3321c5f01b2fSopenharmony_ci 3322c5f01b2fSopenharmony_ci /// @brief inserts range of elements into array 3323c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/insert/ 3324c5f01b2fSopenharmony_ci iterator insert(const_iterator pos, const_iterator first, const_iterator last) 3325c5f01b2fSopenharmony_ci { 3326c5f01b2fSopenharmony_ci // insert only works for arrays 3327c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!is_array())) 3328c5f01b2fSopenharmony_ci { 3329c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this)); 3330c5f01b2fSopenharmony_ci } 3331c5f01b2fSopenharmony_ci 3332c5f01b2fSopenharmony_ci // check if iterator pos fits to this JSON value 3333c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) 3334c5f01b2fSopenharmony_ci { 3335c5f01b2fSopenharmony_ci JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this)); 3336c5f01b2fSopenharmony_ci } 3337c5f01b2fSopenharmony_ci 3338c5f01b2fSopenharmony_ci // check if range iterators belong to the same JSON object 3339c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) 3340c5f01b2fSopenharmony_ci { 3341c5f01b2fSopenharmony_ci JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this)); 3342c5f01b2fSopenharmony_ci } 3343c5f01b2fSopenharmony_ci 3344c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(first.m_object == this)) 3345c5f01b2fSopenharmony_ci { 3346c5f01b2fSopenharmony_ci JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this)); 3347c5f01b2fSopenharmony_ci } 3348c5f01b2fSopenharmony_ci 3349c5f01b2fSopenharmony_ci // insert to array and return iterator 3350c5f01b2fSopenharmony_ci return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator); 3351c5f01b2fSopenharmony_ci } 3352c5f01b2fSopenharmony_ci 3353c5f01b2fSopenharmony_ci /// @brief inserts elements from initializer list into array 3354c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/insert/ 3355c5f01b2fSopenharmony_ci iterator insert(const_iterator pos, initializer_list_t ilist) 3356c5f01b2fSopenharmony_ci { 3357c5f01b2fSopenharmony_ci // insert only works for arrays 3358c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!is_array())) 3359c5f01b2fSopenharmony_ci { 3360c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this)); 3361c5f01b2fSopenharmony_ci } 3362c5f01b2fSopenharmony_ci 3363c5f01b2fSopenharmony_ci // check if iterator pos fits to this JSON value 3364c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) 3365c5f01b2fSopenharmony_ci { 3366c5f01b2fSopenharmony_ci JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this)); 3367c5f01b2fSopenharmony_ci } 3368c5f01b2fSopenharmony_ci 3369c5f01b2fSopenharmony_ci // insert to array and return iterator 3370c5f01b2fSopenharmony_ci return insert_iterator(pos, ilist.begin(), ilist.end()); 3371c5f01b2fSopenharmony_ci } 3372c5f01b2fSopenharmony_ci 3373c5f01b2fSopenharmony_ci /// @brief inserts range of elements into object 3374c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/insert/ 3375c5f01b2fSopenharmony_ci void insert(const_iterator first, const_iterator last) 3376c5f01b2fSopenharmony_ci { 3377c5f01b2fSopenharmony_ci // insert only works for objects 3378c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!is_object())) 3379c5f01b2fSopenharmony_ci { 3380c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this)); 3381c5f01b2fSopenharmony_ci } 3382c5f01b2fSopenharmony_ci 3383c5f01b2fSopenharmony_ci // check if range iterators belong to the same JSON object 3384c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) 3385c5f01b2fSopenharmony_ci { 3386c5f01b2fSopenharmony_ci JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this)); 3387c5f01b2fSopenharmony_ci } 3388c5f01b2fSopenharmony_ci 3389c5f01b2fSopenharmony_ci // passed iterators must belong to objects 3390c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object())) 3391c5f01b2fSopenharmony_ci { 3392c5f01b2fSopenharmony_ci JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this)); 3393c5f01b2fSopenharmony_ci } 3394c5f01b2fSopenharmony_ci 3395c5f01b2fSopenharmony_ci m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator); 3396c5f01b2fSopenharmony_ci } 3397c5f01b2fSopenharmony_ci 3398c5f01b2fSopenharmony_ci /// @brief updates a JSON object from another object, overwriting existing keys 3399c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/update/ 3400c5f01b2fSopenharmony_ci void update(const_reference j, bool merge_objects = false) 3401c5f01b2fSopenharmony_ci { 3402c5f01b2fSopenharmony_ci update(j.begin(), j.end(), merge_objects); 3403c5f01b2fSopenharmony_ci } 3404c5f01b2fSopenharmony_ci 3405c5f01b2fSopenharmony_ci /// @brief updates a JSON object from another object, overwriting existing keys 3406c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/update/ 3407c5f01b2fSopenharmony_ci void update(const_iterator first, const_iterator last, bool merge_objects = false) 3408c5f01b2fSopenharmony_ci { 3409c5f01b2fSopenharmony_ci // implicitly convert null value to an empty object 3410c5f01b2fSopenharmony_ci if (is_null()) 3411c5f01b2fSopenharmony_ci { 3412c5f01b2fSopenharmony_ci m_type = value_t::object; 3413c5f01b2fSopenharmony_ci m_value.object = create<object_t>(); 3414c5f01b2fSopenharmony_ci assert_invariant(); 3415c5f01b2fSopenharmony_ci } 3416c5f01b2fSopenharmony_ci 3417c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!is_object())) 3418c5f01b2fSopenharmony_ci { 3419c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this)); 3420c5f01b2fSopenharmony_ci } 3421c5f01b2fSopenharmony_ci 3422c5f01b2fSopenharmony_ci // check if range iterators belong to the same JSON object 3423c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) 3424c5f01b2fSopenharmony_ci { 3425c5f01b2fSopenharmony_ci JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this)); 3426c5f01b2fSopenharmony_ci } 3427c5f01b2fSopenharmony_ci 3428c5f01b2fSopenharmony_ci // passed iterators must belong to objects 3429c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object())) 3430c5f01b2fSopenharmony_ci { 3431c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object)); 3432c5f01b2fSopenharmony_ci } 3433c5f01b2fSopenharmony_ci 3434c5f01b2fSopenharmony_ci for (auto it = first; it != last; ++it) 3435c5f01b2fSopenharmony_ci { 3436c5f01b2fSopenharmony_ci if (merge_objects && it.value().is_object()) 3437c5f01b2fSopenharmony_ci { 3438c5f01b2fSopenharmony_ci auto it2 = m_value.object->find(it.key()); 3439c5f01b2fSopenharmony_ci if (it2 != m_value.object->end()) 3440c5f01b2fSopenharmony_ci { 3441c5f01b2fSopenharmony_ci it2->second.update(it.value(), true); 3442c5f01b2fSopenharmony_ci continue; 3443c5f01b2fSopenharmony_ci } 3444c5f01b2fSopenharmony_ci } 3445c5f01b2fSopenharmony_ci m_value.object->operator[](it.key()) = it.value(); 3446c5f01b2fSopenharmony_ci#if JSON_DIAGNOSTICS 3447c5f01b2fSopenharmony_ci m_value.object->operator[](it.key()).m_parent = this; 3448c5f01b2fSopenharmony_ci#endif 3449c5f01b2fSopenharmony_ci } 3450c5f01b2fSopenharmony_ci } 3451c5f01b2fSopenharmony_ci 3452c5f01b2fSopenharmony_ci /// @brief exchanges the values 3453c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/swap/ 3454c5f01b2fSopenharmony_ci void swap(reference other) noexcept ( 3455c5f01b2fSopenharmony_ci std::is_nothrow_move_constructible<value_t>::value&& 3456c5f01b2fSopenharmony_ci std::is_nothrow_move_assignable<value_t>::value&& 3457c5f01b2fSopenharmony_ci std::is_nothrow_move_constructible<json_value>::value&& 3458c5f01b2fSopenharmony_ci std::is_nothrow_move_assignable<json_value>::value 3459c5f01b2fSopenharmony_ci ) 3460c5f01b2fSopenharmony_ci { 3461c5f01b2fSopenharmony_ci std::swap(m_type, other.m_type); 3462c5f01b2fSopenharmony_ci std::swap(m_value, other.m_value); 3463c5f01b2fSopenharmony_ci 3464c5f01b2fSopenharmony_ci set_parents(); 3465c5f01b2fSopenharmony_ci other.set_parents(); 3466c5f01b2fSopenharmony_ci assert_invariant(); 3467c5f01b2fSopenharmony_ci } 3468c5f01b2fSopenharmony_ci 3469c5f01b2fSopenharmony_ci /// @brief exchanges the values 3470c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/swap/ 3471c5f01b2fSopenharmony_ci friend void swap(reference left, reference right) noexcept ( 3472c5f01b2fSopenharmony_ci std::is_nothrow_move_constructible<value_t>::value&& 3473c5f01b2fSopenharmony_ci std::is_nothrow_move_assignable<value_t>::value&& 3474c5f01b2fSopenharmony_ci std::is_nothrow_move_constructible<json_value>::value&& 3475c5f01b2fSopenharmony_ci std::is_nothrow_move_assignable<json_value>::value 3476c5f01b2fSopenharmony_ci ) 3477c5f01b2fSopenharmony_ci { 3478c5f01b2fSopenharmony_ci left.swap(right); 3479c5f01b2fSopenharmony_ci } 3480c5f01b2fSopenharmony_ci 3481c5f01b2fSopenharmony_ci /// @brief exchanges the values 3482c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/swap/ 3483c5f01b2fSopenharmony_ci void swap(array_t& other) // NOLINT(bugprone-exception-escape) 3484c5f01b2fSopenharmony_ci { 3485c5f01b2fSopenharmony_ci // swap only works for arrays 3486c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_array())) 3487c5f01b2fSopenharmony_ci { 3488c5f01b2fSopenharmony_ci using std::swap; 3489c5f01b2fSopenharmony_ci swap(*(m_value.array), other); 3490c5f01b2fSopenharmony_ci } 3491c5f01b2fSopenharmony_ci else 3492c5f01b2fSopenharmony_ci { 3493c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(310, detail::concat("cannot use swap(array_t&) with ", type_name()), this)); 3494c5f01b2fSopenharmony_ci } 3495c5f01b2fSopenharmony_ci } 3496c5f01b2fSopenharmony_ci 3497c5f01b2fSopenharmony_ci /// @brief exchanges the values 3498c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/swap/ 3499c5f01b2fSopenharmony_ci void swap(object_t& other) // NOLINT(bugprone-exception-escape) 3500c5f01b2fSopenharmony_ci { 3501c5f01b2fSopenharmony_ci // swap only works for objects 3502c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_object())) 3503c5f01b2fSopenharmony_ci { 3504c5f01b2fSopenharmony_ci using std::swap; 3505c5f01b2fSopenharmony_ci swap(*(m_value.object), other); 3506c5f01b2fSopenharmony_ci } 3507c5f01b2fSopenharmony_ci else 3508c5f01b2fSopenharmony_ci { 3509c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(310, detail::concat("cannot use swap(object_t&) with ", type_name()), this)); 3510c5f01b2fSopenharmony_ci } 3511c5f01b2fSopenharmony_ci } 3512c5f01b2fSopenharmony_ci 3513c5f01b2fSopenharmony_ci /// @brief exchanges the values 3514c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/swap/ 3515c5f01b2fSopenharmony_ci void swap(string_t& other) // NOLINT(bugprone-exception-escape) 3516c5f01b2fSopenharmony_ci { 3517c5f01b2fSopenharmony_ci // swap only works for strings 3518c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_string())) 3519c5f01b2fSopenharmony_ci { 3520c5f01b2fSopenharmony_ci using std::swap; 3521c5f01b2fSopenharmony_ci swap(*(m_value.string), other); 3522c5f01b2fSopenharmony_ci } 3523c5f01b2fSopenharmony_ci else 3524c5f01b2fSopenharmony_ci { 3525c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(310, detail::concat("cannot use swap(string_t&) with ", type_name()), this)); 3526c5f01b2fSopenharmony_ci } 3527c5f01b2fSopenharmony_ci } 3528c5f01b2fSopenharmony_ci 3529c5f01b2fSopenharmony_ci /// @brief exchanges the values 3530c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/swap/ 3531c5f01b2fSopenharmony_ci void swap(binary_t& other) // NOLINT(bugprone-exception-escape) 3532c5f01b2fSopenharmony_ci { 3533c5f01b2fSopenharmony_ci // swap only works for strings 3534c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_binary())) 3535c5f01b2fSopenharmony_ci { 3536c5f01b2fSopenharmony_ci using std::swap; 3537c5f01b2fSopenharmony_ci swap(*(m_value.binary), other); 3538c5f01b2fSopenharmony_ci } 3539c5f01b2fSopenharmony_ci else 3540c5f01b2fSopenharmony_ci { 3541c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t&) with ", type_name()), this)); 3542c5f01b2fSopenharmony_ci } 3543c5f01b2fSopenharmony_ci } 3544c5f01b2fSopenharmony_ci 3545c5f01b2fSopenharmony_ci /// @brief exchanges the values 3546c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/swap/ 3547c5f01b2fSopenharmony_ci void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape) 3548c5f01b2fSopenharmony_ci { 3549c5f01b2fSopenharmony_ci // swap only works for strings 3550c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(is_binary())) 3551c5f01b2fSopenharmony_ci { 3552c5f01b2fSopenharmony_ci using std::swap; 3553c5f01b2fSopenharmony_ci swap(*(m_value.binary), other); 3554c5f01b2fSopenharmony_ci } 3555c5f01b2fSopenharmony_ci else 3556c5f01b2fSopenharmony_ci { 3557c5f01b2fSopenharmony_ci JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t::container_type&) with ", type_name()), this)); 3558c5f01b2fSopenharmony_ci } 3559c5f01b2fSopenharmony_ci } 3560c5f01b2fSopenharmony_ci 3561c5f01b2fSopenharmony_ci /// @} 3562c5f01b2fSopenharmony_ci 3563c5f01b2fSopenharmony_ci ////////////////////////////////////////// 3564c5f01b2fSopenharmony_ci // lexicographical comparison operators // 3565c5f01b2fSopenharmony_ci ////////////////////////////////////////// 3566c5f01b2fSopenharmony_ci 3567c5f01b2fSopenharmony_ci /// @name lexicographical comparison operators 3568c5f01b2fSopenharmony_ci /// @{ 3569c5f01b2fSopenharmony_ci 3570c5f01b2fSopenharmony_ci // note parentheses around operands are necessary; see 3571c5f01b2fSopenharmony_ci // https://github.com/nlohmann/json/issues/1530 3572c5f01b2fSopenharmony_ci#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \ 3573c5f01b2fSopenharmony_ci const auto lhs_type = lhs.type(); \ 3574c5f01b2fSopenharmony_ci const auto rhs_type = rhs.type(); \ 3575c5f01b2fSopenharmony_ci \ 3576c5f01b2fSopenharmony_ci if (lhs_type == rhs_type) /* NOLINT(readability/braces) */ \ 3577c5f01b2fSopenharmony_ci { \ 3578c5f01b2fSopenharmony_ci switch (lhs_type) \ 3579c5f01b2fSopenharmony_ci { \ 3580c5f01b2fSopenharmony_ci case value_t::array: \ 3581c5f01b2fSopenharmony_ci return (*lhs.m_value.array) op (*rhs.m_value.array); \ 3582c5f01b2fSopenharmony_ci \ 3583c5f01b2fSopenharmony_ci case value_t::object: \ 3584c5f01b2fSopenharmony_ci return (*lhs.m_value.object) op (*rhs.m_value.object); \ 3585c5f01b2fSopenharmony_ci \ 3586c5f01b2fSopenharmony_ci case value_t::null: \ 3587c5f01b2fSopenharmony_ci return (null_result); \ 3588c5f01b2fSopenharmony_ci \ 3589c5f01b2fSopenharmony_ci case value_t::string: \ 3590c5f01b2fSopenharmony_ci return (*lhs.m_value.string) op (*rhs.m_value.string); \ 3591c5f01b2fSopenharmony_ci \ 3592c5f01b2fSopenharmony_ci case value_t::boolean: \ 3593c5f01b2fSopenharmony_ci return (lhs.m_value.boolean) op (rhs.m_value.boolean); \ 3594c5f01b2fSopenharmony_ci \ 3595c5f01b2fSopenharmony_ci case value_t::number_integer: \ 3596c5f01b2fSopenharmony_ci return (lhs.m_value.number_integer) op (rhs.m_value.number_integer); \ 3597c5f01b2fSopenharmony_ci \ 3598c5f01b2fSopenharmony_ci case value_t::number_unsigned: \ 3599c5f01b2fSopenharmony_ci return (lhs.m_value.number_unsigned) op (rhs.m_value.number_unsigned); \ 3600c5f01b2fSopenharmony_ci \ 3601c5f01b2fSopenharmony_ci case value_t::number_float: \ 3602c5f01b2fSopenharmony_ci return (lhs.m_value.number_float) op (rhs.m_value.number_float); \ 3603c5f01b2fSopenharmony_ci \ 3604c5f01b2fSopenharmony_ci case value_t::binary: \ 3605c5f01b2fSopenharmony_ci return (*lhs.m_value.binary) op (*rhs.m_value.binary); \ 3606c5f01b2fSopenharmony_ci \ 3607c5f01b2fSopenharmony_ci case value_t::discarded: \ 3608c5f01b2fSopenharmony_ci default: \ 3609c5f01b2fSopenharmony_ci return (unordered_result); \ 3610c5f01b2fSopenharmony_ci } \ 3611c5f01b2fSopenharmony_ci } \ 3612c5f01b2fSopenharmony_ci else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \ 3613c5f01b2fSopenharmony_ci { \ 3614c5f01b2fSopenharmony_ci return static_cast<number_float_t>(lhs.m_value.number_integer) op rhs.m_value.number_float; \ 3615c5f01b2fSopenharmony_ci } \ 3616c5f01b2fSopenharmony_ci else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \ 3617c5f01b2fSopenharmony_ci { \ 3618c5f01b2fSopenharmony_ci return lhs.m_value.number_float op static_cast<number_float_t>(rhs.m_value.number_integer); \ 3619c5f01b2fSopenharmony_ci } \ 3620c5f01b2fSopenharmony_ci else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \ 3621c5f01b2fSopenharmony_ci { \ 3622c5f01b2fSopenharmony_ci return static_cast<number_float_t>(lhs.m_value.number_unsigned) op rhs.m_value.number_float; \ 3623c5f01b2fSopenharmony_ci } \ 3624c5f01b2fSopenharmony_ci else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \ 3625c5f01b2fSopenharmony_ci { \ 3626c5f01b2fSopenharmony_ci return lhs.m_value.number_float op static_cast<number_float_t>(rhs.m_value.number_unsigned); \ 3627c5f01b2fSopenharmony_ci } \ 3628c5f01b2fSopenharmony_ci else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \ 3629c5f01b2fSopenharmony_ci { \ 3630c5f01b2fSopenharmony_ci return static_cast<number_integer_t>(lhs.m_value.number_unsigned) op rhs.m_value.number_integer; \ 3631c5f01b2fSopenharmony_ci } \ 3632c5f01b2fSopenharmony_ci else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \ 3633c5f01b2fSopenharmony_ci { \ 3634c5f01b2fSopenharmony_ci return lhs.m_value.number_integer op static_cast<number_integer_t>(rhs.m_value.number_unsigned); \ 3635c5f01b2fSopenharmony_ci } \ 3636c5f01b2fSopenharmony_ci else if(compares_unordered(lhs, rhs))\ 3637c5f01b2fSopenharmony_ci {\ 3638c5f01b2fSopenharmony_ci return (unordered_result);\ 3639c5f01b2fSopenharmony_ci }\ 3640c5f01b2fSopenharmony_ci \ 3641c5f01b2fSopenharmony_ci return (default_result); 3642c5f01b2fSopenharmony_ci 3643c5f01b2fSopenharmony_ci JSON_PRIVATE_UNLESS_TESTED: 3644c5f01b2fSopenharmony_ci // returns true if: 3645c5f01b2fSopenharmony_ci // - any operand is NaN and the other operand is of number type 3646c5f01b2fSopenharmony_ci // - any operand is discarded 3647c5f01b2fSopenharmony_ci // in legacy mode, discarded values are considered ordered if 3648c5f01b2fSopenharmony_ci // an operation is computed as an odd number of inverses of others 3649c5f01b2fSopenharmony_ci static bool compares_unordered(const_reference lhs, const_reference rhs, bool inverse = false) noexcept 3650c5f01b2fSopenharmony_ci { 3651c5f01b2fSopenharmony_ci if ((lhs.is_number_float() && std::isnan(lhs.m_value.number_float) && rhs.is_number()) 3652c5f01b2fSopenharmony_ci || (rhs.is_number_float() && std::isnan(rhs.m_value.number_float) && lhs.is_number())) 3653c5f01b2fSopenharmony_ci { 3654c5f01b2fSopenharmony_ci return true; 3655c5f01b2fSopenharmony_ci } 3656c5f01b2fSopenharmony_ci#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 3657c5f01b2fSopenharmony_ci return (lhs.is_discarded() || rhs.is_discarded()) && !inverse; 3658c5f01b2fSopenharmony_ci#else 3659c5f01b2fSopenharmony_ci static_cast<void>(inverse); 3660c5f01b2fSopenharmony_ci return lhs.is_discarded() || rhs.is_discarded(); 3661c5f01b2fSopenharmony_ci#endif 3662c5f01b2fSopenharmony_ci } 3663c5f01b2fSopenharmony_ci 3664c5f01b2fSopenharmony_ci private: 3665c5f01b2fSopenharmony_ci bool compares_unordered(const_reference rhs, bool inverse = false) const noexcept 3666c5f01b2fSopenharmony_ci { 3667c5f01b2fSopenharmony_ci return compares_unordered(*this, rhs, inverse); 3668c5f01b2fSopenharmony_ci } 3669c5f01b2fSopenharmony_ci 3670c5f01b2fSopenharmony_ci public: 3671c5f01b2fSopenharmony_ci#if JSON_HAS_THREE_WAY_COMPARISON 3672c5f01b2fSopenharmony_ci /// @brief comparison: equal 3673c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/ 3674c5f01b2fSopenharmony_ci bool operator==(const_reference rhs) const noexcept 3675c5f01b2fSopenharmony_ci { 3676c5f01b2fSopenharmony_ci#ifdef __GNUC__ 3677c5f01b2fSopenharmony_ci#pragma GCC diagnostic push 3678c5f01b2fSopenharmony_ci#pragma GCC diagnostic ignored "-Wfloat-equal" 3679c5f01b2fSopenharmony_ci#endif 3680c5f01b2fSopenharmony_ci const_reference lhs = *this; 3681c5f01b2fSopenharmony_ci JSON_IMPLEMENT_OPERATOR( ==, true, false, false) 3682c5f01b2fSopenharmony_ci#ifdef __GNUC__ 3683c5f01b2fSopenharmony_ci#pragma GCC diagnostic pop 3684c5f01b2fSopenharmony_ci#endif 3685c5f01b2fSopenharmony_ci } 3686c5f01b2fSopenharmony_ci 3687c5f01b2fSopenharmony_ci /// @brief comparison: equal 3688c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/ 3689c5f01b2fSopenharmony_ci template<typename ScalarType> 3690c5f01b2fSopenharmony_ci requires std::is_scalar_v<ScalarType> 3691c5f01b2fSopenharmony_ci bool operator==(ScalarType rhs) const noexcept 3692c5f01b2fSopenharmony_ci { 3693c5f01b2fSopenharmony_ci return *this == basic_json(rhs); 3694c5f01b2fSopenharmony_ci } 3695c5f01b2fSopenharmony_ci 3696c5f01b2fSopenharmony_ci /// @brief comparison: not equal 3697c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/ 3698c5f01b2fSopenharmony_ci bool operator!=(const_reference rhs) const noexcept 3699c5f01b2fSopenharmony_ci { 3700c5f01b2fSopenharmony_ci if (compares_unordered(rhs, true)) 3701c5f01b2fSopenharmony_ci { 3702c5f01b2fSopenharmony_ci return false; 3703c5f01b2fSopenharmony_ci } 3704c5f01b2fSopenharmony_ci return !operator==(rhs); 3705c5f01b2fSopenharmony_ci } 3706c5f01b2fSopenharmony_ci 3707c5f01b2fSopenharmony_ci /// @brief comparison: 3-way 3708c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_spaceship/ 3709c5f01b2fSopenharmony_ci std::partial_ordering operator<=>(const_reference rhs) const noexcept // *NOPAD* 3710c5f01b2fSopenharmony_ci { 3711c5f01b2fSopenharmony_ci const_reference lhs = *this; 3712c5f01b2fSopenharmony_ci // default_result is used if we cannot compare values. In that case, 3713c5f01b2fSopenharmony_ci // we compare types. 3714c5f01b2fSopenharmony_ci JSON_IMPLEMENT_OPERATOR(<=>, // *NOPAD* 3715c5f01b2fSopenharmony_ci std::partial_ordering::equivalent, 3716c5f01b2fSopenharmony_ci std::partial_ordering::unordered, 3717c5f01b2fSopenharmony_ci lhs_type <=> rhs_type) // *NOPAD* 3718c5f01b2fSopenharmony_ci } 3719c5f01b2fSopenharmony_ci 3720c5f01b2fSopenharmony_ci /// @brief comparison: 3-way 3721c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_spaceship/ 3722c5f01b2fSopenharmony_ci template<typename ScalarType> 3723c5f01b2fSopenharmony_ci requires std::is_scalar_v<ScalarType> 3724c5f01b2fSopenharmony_ci std::partial_ordering operator<=>(ScalarType rhs) const noexcept // *NOPAD* 3725c5f01b2fSopenharmony_ci { 3726c5f01b2fSopenharmony_ci return *this <=> basic_json(rhs); // *NOPAD* 3727c5f01b2fSopenharmony_ci } 3728c5f01b2fSopenharmony_ci 3729c5f01b2fSopenharmony_ci#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 3730c5f01b2fSopenharmony_ci // all operators that are computed as an odd number of inverses of others 3731c5f01b2fSopenharmony_ci // need to be overloaded to emulate the legacy comparison behavior 3732c5f01b2fSopenharmony_ci 3733c5f01b2fSopenharmony_ci /// @brief comparison: less than or equal 3734c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_le/ 3735c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.11.0, undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON) 3736c5f01b2fSopenharmony_ci bool operator<=(const_reference rhs) const noexcept 3737c5f01b2fSopenharmony_ci { 3738c5f01b2fSopenharmony_ci if (compares_unordered(rhs, true)) 3739c5f01b2fSopenharmony_ci { 3740c5f01b2fSopenharmony_ci return false; 3741c5f01b2fSopenharmony_ci } 3742c5f01b2fSopenharmony_ci return !(rhs < *this); 3743c5f01b2fSopenharmony_ci } 3744c5f01b2fSopenharmony_ci 3745c5f01b2fSopenharmony_ci /// @brief comparison: less than or equal 3746c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_le/ 3747c5f01b2fSopenharmony_ci template<typename ScalarType> 3748c5f01b2fSopenharmony_ci requires std::is_scalar_v<ScalarType> 3749c5f01b2fSopenharmony_ci bool operator<=(ScalarType rhs) const noexcept 3750c5f01b2fSopenharmony_ci { 3751c5f01b2fSopenharmony_ci return *this <= basic_json(rhs); 3752c5f01b2fSopenharmony_ci } 3753c5f01b2fSopenharmony_ci 3754c5f01b2fSopenharmony_ci /// @brief comparison: greater than or equal 3755c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/ 3756c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.11.0, undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON) 3757c5f01b2fSopenharmony_ci bool operator>=(const_reference rhs) const noexcept 3758c5f01b2fSopenharmony_ci { 3759c5f01b2fSopenharmony_ci if (compares_unordered(rhs, true)) 3760c5f01b2fSopenharmony_ci { 3761c5f01b2fSopenharmony_ci return false; 3762c5f01b2fSopenharmony_ci } 3763c5f01b2fSopenharmony_ci return !(*this < rhs); 3764c5f01b2fSopenharmony_ci } 3765c5f01b2fSopenharmony_ci 3766c5f01b2fSopenharmony_ci /// @brief comparison: greater than or equal 3767c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/ 3768c5f01b2fSopenharmony_ci template<typename ScalarType> 3769c5f01b2fSopenharmony_ci requires std::is_scalar_v<ScalarType> 3770c5f01b2fSopenharmony_ci bool operator>=(ScalarType rhs) const noexcept 3771c5f01b2fSopenharmony_ci { 3772c5f01b2fSopenharmony_ci return *this >= basic_json(rhs); 3773c5f01b2fSopenharmony_ci } 3774c5f01b2fSopenharmony_ci#endif 3775c5f01b2fSopenharmony_ci#else 3776c5f01b2fSopenharmony_ci /// @brief comparison: equal 3777c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/ 3778c5f01b2fSopenharmony_ci friend bool operator==(const_reference lhs, const_reference rhs) noexcept 3779c5f01b2fSopenharmony_ci { 3780c5f01b2fSopenharmony_ci#ifdef __GNUC__ 3781c5f01b2fSopenharmony_ci#pragma GCC diagnostic push 3782c5f01b2fSopenharmony_ci#pragma GCC diagnostic ignored "-Wfloat-equal" 3783c5f01b2fSopenharmony_ci#endif 3784c5f01b2fSopenharmony_ci JSON_IMPLEMENT_OPERATOR( ==, true, false, false) 3785c5f01b2fSopenharmony_ci#ifdef __GNUC__ 3786c5f01b2fSopenharmony_ci#pragma GCC diagnostic pop 3787c5f01b2fSopenharmony_ci#endif 3788c5f01b2fSopenharmony_ci } 3789c5f01b2fSopenharmony_ci 3790c5f01b2fSopenharmony_ci /// @brief comparison: equal 3791c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/ 3792c5f01b2fSopenharmony_ci template<typename ScalarType, typename std::enable_if< 3793c5f01b2fSopenharmony_ci std::is_scalar<ScalarType>::value, int>::type = 0> 3794c5f01b2fSopenharmony_ci friend bool operator==(const_reference lhs, ScalarType rhs) noexcept 3795c5f01b2fSopenharmony_ci { 3796c5f01b2fSopenharmony_ci return lhs == basic_json(rhs); 3797c5f01b2fSopenharmony_ci } 3798c5f01b2fSopenharmony_ci 3799c5f01b2fSopenharmony_ci /// @brief comparison: equal 3800c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/ 3801c5f01b2fSopenharmony_ci template<typename ScalarType, typename std::enable_if< 3802c5f01b2fSopenharmony_ci std::is_scalar<ScalarType>::value, int>::type = 0> 3803c5f01b2fSopenharmony_ci friend bool operator==(ScalarType lhs, const_reference rhs) noexcept 3804c5f01b2fSopenharmony_ci { 3805c5f01b2fSopenharmony_ci return basic_json(lhs) == rhs; 3806c5f01b2fSopenharmony_ci } 3807c5f01b2fSopenharmony_ci 3808c5f01b2fSopenharmony_ci /// @brief comparison: not equal 3809c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/ 3810c5f01b2fSopenharmony_ci friend bool operator!=(const_reference lhs, const_reference rhs) noexcept 3811c5f01b2fSopenharmony_ci { 3812c5f01b2fSopenharmony_ci if (compares_unordered(lhs, rhs, true)) 3813c5f01b2fSopenharmony_ci { 3814c5f01b2fSopenharmony_ci return false; 3815c5f01b2fSopenharmony_ci } 3816c5f01b2fSopenharmony_ci return !(lhs == rhs); 3817c5f01b2fSopenharmony_ci } 3818c5f01b2fSopenharmony_ci 3819c5f01b2fSopenharmony_ci /// @brief comparison: not equal 3820c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/ 3821c5f01b2fSopenharmony_ci template<typename ScalarType, typename std::enable_if< 3822c5f01b2fSopenharmony_ci std::is_scalar<ScalarType>::value, int>::type = 0> 3823c5f01b2fSopenharmony_ci friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept 3824c5f01b2fSopenharmony_ci { 3825c5f01b2fSopenharmony_ci return lhs != basic_json(rhs); 3826c5f01b2fSopenharmony_ci } 3827c5f01b2fSopenharmony_ci 3828c5f01b2fSopenharmony_ci /// @brief comparison: not equal 3829c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/ 3830c5f01b2fSopenharmony_ci template<typename ScalarType, typename std::enable_if< 3831c5f01b2fSopenharmony_ci std::is_scalar<ScalarType>::value, int>::type = 0> 3832c5f01b2fSopenharmony_ci friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept 3833c5f01b2fSopenharmony_ci { 3834c5f01b2fSopenharmony_ci return basic_json(lhs) != rhs; 3835c5f01b2fSopenharmony_ci } 3836c5f01b2fSopenharmony_ci 3837c5f01b2fSopenharmony_ci /// @brief comparison: less than 3838c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/ 3839c5f01b2fSopenharmony_ci friend bool operator<(const_reference lhs, const_reference rhs) noexcept 3840c5f01b2fSopenharmony_ci { 3841c5f01b2fSopenharmony_ci // default_result is used if we cannot compare values. In that case, 3842c5f01b2fSopenharmony_ci // we compare types. Note we have to call the operator explicitly, 3843c5f01b2fSopenharmony_ci // because MSVC has problems otherwise. 3844c5f01b2fSopenharmony_ci JSON_IMPLEMENT_OPERATOR( <, false, false, operator<(lhs_type, rhs_type)) 3845c5f01b2fSopenharmony_ci } 3846c5f01b2fSopenharmony_ci 3847c5f01b2fSopenharmony_ci /// @brief comparison: less than 3848c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/ 3849c5f01b2fSopenharmony_ci template<typename ScalarType, typename std::enable_if< 3850c5f01b2fSopenharmony_ci std::is_scalar<ScalarType>::value, int>::type = 0> 3851c5f01b2fSopenharmony_ci friend bool operator<(const_reference lhs, ScalarType rhs) noexcept 3852c5f01b2fSopenharmony_ci { 3853c5f01b2fSopenharmony_ci return lhs < basic_json(rhs); 3854c5f01b2fSopenharmony_ci } 3855c5f01b2fSopenharmony_ci 3856c5f01b2fSopenharmony_ci /// @brief comparison: less than 3857c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/ 3858c5f01b2fSopenharmony_ci template<typename ScalarType, typename std::enable_if< 3859c5f01b2fSopenharmony_ci std::is_scalar<ScalarType>::value, int>::type = 0> 3860c5f01b2fSopenharmony_ci friend bool operator<(ScalarType lhs, const_reference rhs) noexcept 3861c5f01b2fSopenharmony_ci { 3862c5f01b2fSopenharmony_ci return basic_json(lhs) < rhs; 3863c5f01b2fSopenharmony_ci } 3864c5f01b2fSopenharmony_ci 3865c5f01b2fSopenharmony_ci /// @brief comparison: less than or equal 3866c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_le/ 3867c5f01b2fSopenharmony_ci friend bool operator<=(const_reference lhs, const_reference rhs) noexcept 3868c5f01b2fSopenharmony_ci { 3869c5f01b2fSopenharmony_ci if (compares_unordered(lhs, rhs, true)) 3870c5f01b2fSopenharmony_ci { 3871c5f01b2fSopenharmony_ci return false; 3872c5f01b2fSopenharmony_ci } 3873c5f01b2fSopenharmony_ci return !(rhs < lhs); 3874c5f01b2fSopenharmony_ci } 3875c5f01b2fSopenharmony_ci 3876c5f01b2fSopenharmony_ci /// @brief comparison: less than or equal 3877c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_le/ 3878c5f01b2fSopenharmony_ci template<typename ScalarType, typename std::enable_if< 3879c5f01b2fSopenharmony_ci std::is_scalar<ScalarType>::value, int>::type = 0> 3880c5f01b2fSopenharmony_ci friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept 3881c5f01b2fSopenharmony_ci { 3882c5f01b2fSopenharmony_ci return lhs <= basic_json(rhs); 3883c5f01b2fSopenharmony_ci } 3884c5f01b2fSopenharmony_ci 3885c5f01b2fSopenharmony_ci /// @brief comparison: less than or equal 3886c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_le/ 3887c5f01b2fSopenharmony_ci template<typename ScalarType, typename std::enable_if< 3888c5f01b2fSopenharmony_ci std::is_scalar<ScalarType>::value, int>::type = 0> 3889c5f01b2fSopenharmony_ci friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept 3890c5f01b2fSopenharmony_ci { 3891c5f01b2fSopenharmony_ci return basic_json(lhs) <= rhs; 3892c5f01b2fSopenharmony_ci } 3893c5f01b2fSopenharmony_ci 3894c5f01b2fSopenharmony_ci /// @brief comparison: greater than 3895c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/ 3896c5f01b2fSopenharmony_ci friend bool operator>(const_reference lhs, const_reference rhs) noexcept 3897c5f01b2fSopenharmony_ci { 3898c5f01b2fSopenharmony_ci // double inverse 3899c5f01b2fSopenharmony_ci if (compares_unordered(lhs, rhs)) 3900c5f01b2fSopenharmony_ci { 3901c5f01b2fSopenharmony_ci return false; 3902c5f01b2fSopenharmony_ci } 3903c5f01b2fSopenharmony_ci return !(lhs <= rhs); 3904c5f01b2fSopenharmony_ci } 3905c5f01b2fSopenharmony_ci 3906c5f01b2fSopenharmony_ci /// @brief comparison: greater than 3907c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/ 3908c5f01b2fSopenharmony_ci template<typename ScalarType, typename std::enable_if< 3909c5f01b2fSopenharmony_ci std::is_scalar<ScalarType>::value, int>::type = 0> 3910c5f01b2fSopenharmony_ci friend bool operator>(const_reference lhs, ScalarType rhs) noexcept 3911c5f01b2fSopenharmony_ci { 3912c5f01b2fSopenharmony_ci return lhs > basic_json(rhs); 3913c5f01b2fSopenharmony_ci } 3914c5f01b2fSopenharmony_ci 3915c5f01b2fSopenharmony_ci /// @brief comparison: greater than 3916c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/ 3917c5f01b2fSopenharmony_ci template<typename ScalarType, typename std::enable_if< 3918c5f01b2fSopenharmony_ci std::is_scalar<ScalarType>::value, int>::type = 0> 3919c5f01b2fSopenharmony_ci friend bool operator>(ScalarType lhs, const_reference rhs) noexcept 3920c5f01b2fSopenharmony_ci { 3921c5f01b2fSopenharmony_ci return basic_json(lhs) > rhs; 3922c5f01b2fSopenharmony_ci } 3923c5f01b2fSopenharmony_ci 3924c5f01b2fSopenharmony_ci /// @brief comparison: greater than or equal 3925c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/ 3926c5f01b2fSopenharmony_ci friend bool operator>=(const_reference lhs, const_reference rhs) noexcept 3927c5f01b2fSopenharmony_ci { 3928c5f01b2fSopenharmony_ci if (compares_unordered(lhs, rhs, true)) 3929c5f01b2fSopenharmony_ci { 3930c5f01b2fSopenharmony_ci return false; 3931c5f01b2fSopenharmony_ci } 3932c5f01b2fSopenharmony_ci return !(lhs < rhs); 3933c5f01b2fSopenharmony_ci } 3934c5f01b2fSopenharmony_ci 3935c5f01b2fSopenharmony_ci /// @brief comparison: greater than or equal 3936c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/ 3937c5f01b2fSopenharmony_ci template<typename ScalarType, typename std::enable_if< 3938c5f01b2fSopenharmony_ci std::is_scalar<ScalarType>::value, int>::type = 0> 3939c5f01b2fSopenharmony_ci friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept 3940c5f01b2fSopenharmony_ci { 3941c5f01b2fSopenharmony_ci return lhs >= basic_json(rhs); 3942c5f01b2fSopenharmony_ci } 3943c5f01b2fSopenharmony_ci 3944c5f01b2fSopenharmony_ci /// @brief comparison: greater than or equal 3945c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/ 3946c5f01b2fSopenharmony_ci template<typename ScalarType, typename std::enable_if< 3947c5f01b2fSopenharmony_ci std::is_scalar<ScalarType>::value, int>::type = 0> 3948c5f01b2fSopenharmony_ci friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept 3949c5f01b2fSopenharmony_ci { 3950c5f01b2fSopenharmony_ci return basic_json(lhs) >= rhs; 3951c5f01b2fSopenharmony_ci } 3952c5f01b2fSopenharmony_ci#endif 3953c5f01b2fSopenharmony_ci 3954c5f01b2fSopenharmony_ci#undef JSON_IMPLEMENT_OPERATOR 3955c5f01b2fSopenharmony_ci 3956c5f01b2fSopenharmony_ci /// @} 3957c5f01b2fSopenharmony_ci 3958c5f01b2fSopenharmony_ci /////////////////// 3959c5f01b2fSopenharmony_ci // serialization // 3960c5f01b2fSopenharmony_ci /////////////////// 3961c5f01b2fSopenharmony_ci 3962c5f01b2fSopenharmony_ci /// @name serialization 3963c5f01b2fSopenharmony_ci /// @{ 3964c5f01b2fSopenharmony_ci#ifndef JSON_NO_IO 3965c5f01b2fSopenharmony_ci /// @brief serialize to stream 3966c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/ 3967c5f01b2fSopenharmony_ci friend std::ostream& operator<<(std::ostream& o, const basic_json& j) 3968c5f01b2fSopenharmony_ci { 3969c5f01b2fSopenharmony_ci // read width member and use it as indentation parameter if nonzero 3970c5f01b2fSopenharmony_ci const bool pretty_print = o.width() > 0; 3971c5f01b2fSopenharmony_ci const auto indentation = pretty_print ? o.width() : 0; 3972c5f01b2fSopenharmony_ci 3973c5f01b2fSopenharmony_ci // reset width to 0 for subsequent calls to this stream 3974c5f01b2fSopenharmony_ci o.width(0); 3975c5f01b2fSopenharmony_ci 3976c5f01b2fSopenharmony_ci // do the actual serialization 3977c5f01b2fSopenharmony_ci serializer s(detail::output_adapter<char>(o), o.fill()); 3978c5f01b2fSopenharmony_ci s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation)); 3979c5f01b2fSopenharmony_ci return o; 3980c5f01b2fSopenharmony_ci } 3981c5f01b2fSopenharmony_ci 3982c5f01b2fSopenharmony_ci /// @brief serialize to stream 3983c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/ 3984c5f01b2fSopenharmony_ci /// @deprecated This function is deprecated since 3.0.0 and will be removed in 3985c5f01b2fSopenharmony_ci /// version 4.0.0 of the library. Please use 3986c5f01b2fSopenharmony_ci /// operator<<(std::ostream&, const basic_json&) instead; that is, 3987c5f01b2fSopenharmony_ci /// replace calls like `j >> o;` with `o << j;`. 3988c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&)) 3989c5f01b2fSopenharmony_ci friend std::ostream& operator>>(const basic_json& j, std::ostream& o) 3990c5f01b2fSopenharmony_ci { 3991c5f01b2fSopenharmony_ci return o << j; 3992c5f01b2fSopenharmony_ci } 3993c5f01b2fSopenharmony_ci#endif // JSON_NO_IO 3994c5f01b2fSopenharmony_ci /// @} 3995c5f01b2fSopenharmony_ci 3996c5f01b2fSopenharmony_ci 3997c5f01b2fSopenharmony_ci ///////////////////// 3998c5f01b2fSopenharmony_ci // deserialization // 3999c5f01b2fSopenharmony_ci ///////////////////// 4000c5f01b2fSopenharmony_ci 4001c5f01b2fSopenharmony_ci /// @name deserialization 4002c5f01b2fSopenharmony_ci /// @{ 4003c5f01b2fSopenharmony_ci 4004c5f01b2fSopenharmony_ci /// @brief deserialize from a compatible input 4005c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/parse/ 4006c5f01b2fSopenharmony_ci template<typename InputType> 4007c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4008c5f01b2fSopenharmony_ci static basic_json parse(InputType&& i, 4009c5f01b2fSopenharmony_ci const parser_callback_t cb = nullptr, 4010c5f01b2fSopenharmony_ci const bool allow_exceptions = true, 4011c5f01b2fSopenharmony_ci const bool ignore_comments = false) 4012c5f01b2fSopenharmony_ci { 4013c5f01b2fSopenharmony_ci basic_json result; 4014c5f01b2fSopenharmony_ci parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result); 4015c5f01b2fSopenharmony_ci return result; 4016c5f01b2fSopenharmony_ci } 4017c5f01b2fSopenharmony_ci 4018c5f01b2fSopenharmony_ci /// @brief deserialize from a pair of character iterators 4019c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/parse/ 4020c5f01b2fSopenharmony_ci template<typename IteratorType> 4021c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4022c5f01b2fSopenharmony_ci static basic_json parse(IteratorType first, 4023c5f01b2fSopenharmony_ci IteratorType last, 4024c5f01b2fSopenharmony_ci const parser_callback_t cb = nullptr, 4025c5f01b2fSopenharmony_ci const bool allow_exceptions = true, 4026c5f01b2fSopenharmony_ci const bool ignore_comments = false) 4027c5f01b2fSopenharmony_ci { 4028c5f01b2fSopenharmony_ci basic_json result; 4029c5f01b2fSopenharmony_ci parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result); 4030c5f01b2fSopenharmony_ci return result; 4031c5f01b2fSopenharmony_ci } 4032c5f01b2fSopenharmony_ci 4033c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4034c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len)) 4035c5f01b2fSopenharmony_ci static basic_json parse(detail::span_input_adapter&& i, 4036c5f01b2fSopenharmony_ci const parser_callback_t cb = nullptr, 4037c5f01b2fSopenharmony_ci const bool allow_exceptions = true, 4038c5f01b2fSopenharmony_ci const bool ignore_comments = false) 4039c5f01b2fSopenharmony_ci { 4040c5f01b2fSopenharmony_ci basic_json result; 4041c5f01b2fSopenharmony_ci parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result); 4042c5f01b2fSopenharmony_ci return result; 4043c5f01b2fSopenharmony_ci } 4044c5f01b2fSopenharmony_ci 4045c5f01b2fSopenharmony_ci /// @brief check if the input is valid JSON 4046c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/accept/ 4047c5f01b2fSopenharmony_ci template<typename InputType> 4048c5f01b2fSopenharmony_ci static bool accept(InputType&& i, 4049c5f01b2fSopenharmony_ci const bool ignore_comments = false) 4050c5f01b2fSopenharmony_ci { 4051c5f01b2fSopenharmony_ci return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true); 4052c5f01b2fSopenharmony_ci } 4053c5f01b2fSopenharmony_ci 4054c5f01b2fSopenharmony_ci /// @brief check if the input is valid JSON 4055c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/accept/ 4056c5f01b2fSopenharmony_ci template<typename IteratorType> 4057c5f01b2fSopenharmony_ci static bool accept(IteratorType first, IteratorType last, 4058c5f01b2fSopenharmony_ci const bool ignore_comments = false) 4059c5f01b2fSopenharmony_ci { 4060c5f01b2fSopenharmony_ci return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true); 4061c5f01b2fSopenharmony_ci } 4062c5f01b2fSopenharmony_ci 4063c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4064c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len)) 4065c5f01b2fSopenharmony_ci static bool accept(detail::span_input_adapter&& i, 4066c5f01b2fSopenharmony_ci const bool ignore_comments = false) 4067c5f01b2fSopenharmony_ci { 4068c5f01b2fSopenharmony_ci return parser(i.get(), nullptr, false, ignore_comments).accept(true); 4069c5f01b2fSopenharmony_ci } 4070c5f01b2fSopenharmony_ci 4071c5f01b2fSopenharmony_ci /// @brief generate SAX events 4072c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/ 4073c5f01b2fSopenharmony_ci template <typename InputType, typename SAX> 4074c5f01b2fSopenharmony_ci JSON_HEDLEY_NON_NULL(2) 4075c5f01b2fSopenharmony_ci static bool sax_parse(InputType&& i, SAX* sax, 4076c5f01b2fSopenharmony_ci input_format_t format = input_format_t::json, 4077c5f01b2fSopenharmony_ci const bool strict = true, 4078c5f01b2fSopenharmony_ci const bool ignore_comments = false) 4079c5f01b2fSopenharmony_ci { 4080c5f01b2fSopenharmony_ci auto ia = detail::input_adapter(std::forward<InputType>(i)); 4081c5f01b2fSopenharmony_ci return format == input_format_t::json 4082c5f01b2fSopenharmony_ci ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) 4083c5f01b2fSopenharmony_ci : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict); 4084c5f01b2fSopenharmony_ci } 4085c5f01b2fSopenharmony_ci 4086c5f01b2fSopenharmony_ci /// @brief generate SAX events 4087c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/ 4088c5f01b2fSopenharmony_ci template<class IteratorType, class SAX> 4089c5f01b2fSopenharmony_ci JSON_HEDLEY_NON_NULL(3) 4090c5f01b2fSopenharmony_ci static bool sax_parse(IteratorType first, IteratorType last, SAX* sax, 4091c5f01b2fSopenharmony_ci input_format_t format = input_format_t::json, 4092c5f01b2fSopenharmony_ci const bool strict = true, 4093c5f01b2fSopenharmony_ci const bool ignore_comments = false) 4094c5f01b2fSopenharmony_ci { 4095c5f01b2fSopenharmony_ci auto ia = detail::input_adapter(std::move(first), std::move(last)); 4096c5f01b2fSopenharmony_ci return format == input_format_t::json 4097c5f01b2fSopenharmony_ci ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) 4098c5f01b2fSopenharmony_ci : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict); 4099c5f01b2fSopenharmony_ci } 4100c5f01b2fSopenharmony_ci 4101c5f01b2fSopenharmony_ci /// @brief generate SAX events 4102c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/ 4103c5f01b2fSopenharmony_ci /// @deprecated This function is deprecated since 3.8.0 and will be removed in 4104c5f01b2fSopenharmony_ci /// version 4.0.0 of the library. Please use 4105c5f01b2fSopenharmony_ci /// sax_parse(ptr, ptr + len) instead. 4106c5f01b2fSopenharmony_ci template <typename SAX> 4107c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...)) 4108c5f01b2fSopenharmony_ci JSON_HEDLEY_NON_NULL(2) 4109c5f01b2fSopenharmony_ci static bool sax_parse(detail::span_input_adapter&& i, SAX* sax, 4110c5f01b2fSopenharmony_ci input_format_t format = input_format_t::json, 4111c5f01b2fSopenharmony_ci const bool strict = true, 4112c5f01b2fSopenharmony_ci const bool ignore_comments = false) 4113c5f01b2fSopenharmony_ci { 4114c5f01b2fSopenharmony_ci auto ia = i.get(); 4115c5f01b2fSopenharmony_ci return format == input_format_t::json 4116c5f01b2fSopenharmony_ci // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) 4117c5f01b2fSopenharmony_ci ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) 4118c5f01b2fSopenharmony_ci // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) 4119c5f01b2fSopenharmony_ci : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict); 4120c5f01b2fSopenharmony_ci } 4121c5f01b2fSopenharmony_ci#ifndef JSON_NO_IO 4122c5f01b2fSopenharmony_ci /// @brief deserialize from stream 4123c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/ 4124c5f01b2fSopenharmony_ci /// @deprecated This stream operator is deprecated since 3.0.0 and will be removed in 4125c5f01b2fSopenharmony_ci /// version 4.0.0 of the library. Please use 4126c5f01b2fSopenharmony_ci /// operator>>(std::istream&, basic_json&) instead; that is, 4127c5f01b2fSopenharmony_ci /// replace calls like `j << i;` with `i >> j;`. 4128c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&)) 4129c5f01b2fSopenharmony_ci friend std::istream& operator<<(basic_json& j, std::istream& i) 4130c5f01b2fSopenharmony_ci { 4131c5f01b2fSopenharmony_ci return operator>>(i, j); 4132c5f01b2fSopenharmony_ci } 4133c5f01b2fSopenharmony_ci 4134c5f01b2fSopenharmony_ci /// @brief deserialize from stream 4135c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/ 4136c5f01b2fSopenharmony_ci friend std::istream& operator>>(std::istream& i, basic_json& j) 4137c5f01b2fSopenharmony_ci { 4138c5f01b2fSopenharmony_ci parser(detail::input_adapter(i)).parse(false, j); 4139c5f01b2fSopenharmony_ci return i; 4140c5f01b2fSopenharmony_ci } 4141c5f01b2fSopenharmony_ci#endif // JSON_NO_IO 4142c5f01b2fSopenharmony_ci /// @} 4143c5f01b2fSopenharmony_ci 4144c5f01b2fSopenharmony_ci /////////////////////////// 4145c5f01b2fSopenharmony_ci // convenience functions // 4146c5f01b2fSopenharmony_ci /////////////////////////// 4147c5f01b2fSopenharmony_ci 4148c5f01b2fSopenharmony_ci /// @brief return the type as string 4149c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/type_name/ 4150c5f01b2fSopenharmony_ci JSON_HEDLEY_RETURNS_NON_NULL 4151c5f01b2fSopenharmony_ci const char* type_name() const noexcept 4152c5f01b2fSopenharmony_ci { 4153c5f01b2fSopenharmony_ci switch (m_type) 4154c5f01b2fSopenharmony_ci { 4155c5f01b2fSopenharmony_ci case value_t::null: 4156c5f01b2fSopenharmony_ci return "null"; 4157c5f01b2fSopenharmony_ci case value_t::object: 4158c5f01b2fSopenharmony_ci return "object"; 4159c5f01b2fSopenharmony_ci case value_t::array: 4160c5f01b2fSopenharmony_ci return "array"; 4161c5f01b2fSopenharmony_ci case value_t::string: 4162c5f01b2fSopenharmony_ci return "string"; 4163c5f01b2fSopenharmony_ci case value_t::boolean: 4164c5f01b2fSopenharmony_ci return "boolean"; 4165c5f01b2fSopenharmony_ci case value_t::binary: 4166c5f01b2fSopenharmony_ci return "binary"; 4167c5f01b2fSopenharmony_ci case value_t::discarded: 4168c5f01b2fSopenharmony_ci return "discarded"; 4169c5f01b2fSopenharmony_ci case value_t::number_integer: 4170c5f01b2fSopenharmony_ci case value_t::number_unsigned: 4171c5f01b2fSopenharmony_ci case value_t::number_float: 4172c5f01b2fSopenharmony_ci default: 4173c5f01b2fSopenharmony_ci return "number"; 4174c5f01b2fSopenharmony_ci } 4175c5f01b2fSopenharmony_ci } 4176c5f01b2fSopenharmony_ci 4177c5f01b2fSopenharmony_ci 4178c5f01b2fSopenharmony_ci JSON_PRIVATE_UNLESS_TESTED: 4179c5f01b2fSopenharmony_ci ////////////////////// 4180c5f01b2fSopenharmony_ci // member variables // 4181c5f01b2fSopenharmony_ci ////////////////////// 4182c5f01b2fSopenharmony_ci 4183c5f01b2fSopenharmony_ci /// the type of the current element 4184c5f01b2fSopenharmony_ci value_t m_type = value_t::null; 4185c5f01b2fSopenharmony_ci 4186c5f01b2fSopenharmony_ci /// the value of the current element 4187c5f01b2fSopenharmony_ci json_value m_value = {}; 4188c5f01b2fSopenharmony_ci 4189c5f01b2fSopenharmony_ci#if JSON_DIAGNOSTICS 4190c5f01b2fSopenharmony_ci /// a pointer to a parent value (for debugging purposes) 4191c5f01b2fSopenharmony_ci basic_json* m_parent = nullptr; 4192c5f01b2fSopenharmony_ci#endif 4193c5f01b2fSopenharmony_ci 4194c5f01b2fSopenharmony_ci ////////////////////////////////////////// 4195c5f01b2fSopenharmony_ci // binary serialization/deserialization // 4196c5f01b2fSopenharmony_ci ////////////////////////////////////////// 4197c5f01b2fSopenharmony_ci 4198c5f01b2fSopenharmony_ci /// @name binary serialization/deserialization support 4199c5f01b2fSopenharmony_ci /// @{ 4200c5f01b2fSopenharmony_ci 4201c5f01b2fSopenharmony_ci public: 4202c5f01b2fSopenharmony_ci /// @brief create a CBOR serialization of a given JSON value 4203c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/ 4204c5f01b2fSopenharmony_ci static std::vector<std::uint8_t> to_cbor(const basic_json& j) 4205c5f01b2fSopenharmony_ci { 4206c5f01b2fSopenharmony_ci std::vector<std::uint8_t> result; 4207c5f01b2fSopenharmony_ci to_cbor(j, result); 4208c5f01b2fSopenharmony_ci return result; 4209c5f01b2fSopenharmony_ci } 4210c5f01b2fSopenharmony_ci 4211c5f01b2fSopenharmony_ci /// @brief create a CBOR serialization of a given JSON value 4212c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/ 4213c5f01b2fSopenharmony_ci static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o) 4214c5f01b2fSopenharmony_ci { 4215c5f01b2fSopenharmony_ci binary_writer<std::uint8_t>(o).write_cbor(j); 4216c5f01b2fSopenharmony_ci } 4217c5f01b2fSopenharmony_ci 4218c5f01b2fSopenharmony_ci /// @brief create a CBOR serialization of a given JSON value 4219c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/ 4220c5f01b2fSopenharmony_ci static void to_cbor(const basic_json& j, detail::output_adapter<char> o) 4221c5f01b2fSopenharmony_ci { 4222c5f01b2fSopenharmony_ci binary_writer<char>(o).write_cbor(j); 4223c5f01b2fSopenharmony_ci } 4224c5f01b2fSopenharmony_ci 4225c5f01b2fSopenharmony_ci /// @brief create a MessagePack serialization of a given JSON value 4226c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/ 4227c5f01b2fSopenharmony_ci static std::vector<std::uint8_t> to_msgpack(const basic_json& j) 4228c5f01b2fSopenharmony_ci { 4229c5f01b2fSopenharmony_ci std::vector<std::uint8_t> result; 4230c5f01b2fSopenharmony_ci to_msgpack(j, result); 4231c5f01b2fSopenharmony_ci return result; 4232c5f01b2fSopenharmony_ci } 4233c5f01b2fSopenharmony_ci 4234c5f01b2fSopenharmony_ci /// @brief create a MessagePack serialization of a given JSON value 4235c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/ 4236c5f01b2fSopenharmony_ci static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o) 4237c5f01b2fSopenharmony_ci { 4238c5f01b2fSopenharmony_ci binary_writer<std::uint8_t>(o).write_msgpack(j); 4239c5f01b2fSopenharmony_ci } 4240c5f01b2fSopenharmony_ci 4241c5f01b2fSopenharmony_ci /// @brief create a MessagePack serialization of a given JSON value 4242c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/ 4243c5f01b2fSopenharmony_ci static void to_msgpack(const basic_json& j, detail::output_adapter<char> o) 4244c5f01b2fSopenharmony_ci { 4245c5f01b2fSopenharmony_ci binary_writer<char>(o).write_msgpack(j); 4246c5f01b2fSopenharmony_ci } 4247c5f01b2fSopenharmony_ci 4248c5f01b2fSopenharmony_ci /// @brief create a UBJSON serialization of a given JSON value 4249c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/ 4250c5f01b2fSopenharmony_ci static std::vector<std::uint8_t> to_ubjson(const basic_json& j, 4251c5f01b2fSopenharmony_ci const bool use_size = false, 4252c5f01b2fSopenharmony_ci const bool use_type = false) 4253c5f01b2fSopenharmony_ci { 4254c5f01b2fSopenharmony_ci std::vector<std::uint8_t> result; 4255c5f01b2fSopenharmony_ci to_ubjson(j, result, use_size, use_type); 4256c5f01b2fSopenharmony_ci return result; 4257c5f01b2fSopenharmony_ci } 4258c5f01b2fSopenharmony_ci 4259c5f01b2fSopenharmony_ci /// @brief create a UBJSON serialization of a given JSON value 4260c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/ 4261c5f01b2fSopenharmony_ci static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o, 4262c5f01b2fSopenharmony_ci const bool use_size = false, const bool use_type = false) 4263c5f01b2fSopenharmony_ci { 4264c5f01b2fSopenharmony_ci binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type); 4265c5f01b2fSopenharmony_ci } 4266c5f01b2fSopenharmony_ci 4267c5f01b2fSopenharmony_ci /// @brief create a UBJSON serialization of a given JSON value 4268c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/ 4269c5f01b2fSopenharmony_ci static void to_ubjson(const basic_json& j, detail::output_adapter<char> o, 4270c5f01b2fSopenharmony_ci const bool use_size = false, const bool use_type = false) 4271c5f01b2fSopenharmony_ci { 4272c5f01b2fSopenharmony_ci binary_writer<char>(o).write_ubjson(j, use_size, use_type); 4273c5f01b2fSopenharmony_ci } 4274c5f01b2fSopenharmony_ci 4275c5f01b2fSopenharmony_ci /// @brief create a BJData serialization of a given JSON value 4276c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/to_bjdata/ 4277c5f01b2fSopenharmony_ci static std::vector<std::uint8_t> to_bjdata(const basic_json& j, 4278c5f01b2fSopenharmony_ci const bool use_size = false, 4279c5f01b2fSopenharmony_ci const bool use_type = false) 4280c5f01b2fSopenharmony_ci { 4281c5f01b2fSopenharmony_ci std::vector<std::uint8_t> result; 4282c5f01b2fSopenharmony_ci to_bjdata(j, result, use_size, use_type); 4283c5f01b2fSopenharmony_ci return result; 4284c5f01b2fSopenharmony_ci } 4285c5f01b2fSopenharmony_ci 4286c5f01b2fSopenharmony_ci /// @brief create a BJData serialization of a given JSON value 4287c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/to_bjdata/ 4288c5f01b2fSopenharmony_ci static void to_bjdata(const basic_json& j, detail::output_adapter<std::uint8_t> o, 4289c5f01b2fSopenharmony_ci const bool use_size = false, const bool use_type = false) 4290c5f01b2fSopenharmony_ci { 4291c5f01b2fSopenharmony_ci binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true); 4292c5f01b2fSopenharmony_ci } 4293c5f01b2fSopenharmony_ci 4294c5f01b2fSopenharmony_ci /// @brief create a BJData serialization of a given JSON value 4295c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/to_bjdata/ 4296c5f01b2fSopenharmony_ci static void to_bjdata(const basic_json& j, detail::output_adapter<char> o, 4297c5f01b2fSopenharmony_ci const bool use_size = false, const bool use_type = false) 4298c5f01b2fSopenharmony_ci { 4299c5f01b2fSopenharmony_ci binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true); 4300c5f01b2fSopenharmony_ci } 4301c5f01b2fSopenharmony_ci 4302c5f01b2fSopenharmony_ci /// @brief create a BSON serialization of a given JSON value 4303c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/to_bson/ 4304c5f01b2fSopenharmony_ci static std::vector<std::uint8_t> to_bson(const basic_json& j) 4305c5f01b2fSopenharmony_ci { 4306c5f01b2fSopenharmony_ci std::vector<std::uint8_t> result; 4307c5f01b2fSopenharmony_ci to_bson(j, result); 4308c5f01b2fSopenharmony_ci return result; 4309c5f01b2fSopenharmony_ci } 4310c5f01b2fSopenharmony_ci 4311c5f01b2fSopenharmony_ci /// @brief create a BSON serialization of a given JSON value 4312c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/to_bson/ 4313c5f01b2fSopenharmony_ci static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o) 4314c5f01b2fSopenharmony_ci { 4315c5f01b2fSopenharmony_ci binary_writer<std::uint8_t>(o).write_bson(j); 4316c5f01b2fSopenharmony_ci } 4317c5f01b2fSopenharmony_ci 4318c5f01b2fSopenharmony_ci /// @brief create a BSON serialization of a given JSON value 4319c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/to_bson/ 4320c5f01b2fSopenharmony_ci static void to_bson(const basic_json& j, detail::output_adapter<char> o) 4321c5f01b2fSopenharmony_ci { 4322c5f01b2fSopenharmony_ci binary_writer<char>(o).write_bson(j); 4323c5f01b2fSopenharmony_ci } 4324c5f01b2fSopenharmony_ci 4325c5f01b2fSopenharmony_ci /// @brief create a JSON value from an input in CBOR format 4326c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/ 4327c5f01b2fSopenharmony_ci template<typename InputType> 4328c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4329c5f01b2fSopenharmony_ci static basic_json from_cbor(InputType&& i, 4330c5f01b2fSopenharmony_ci const bool strict = true, 4331c5f01b2fSopenharmony_ci const bool allow_exceptions = true, 4332c5f01b2fSopenharmony_ci const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) 4333c5f01b2fSopenharmony_ci { 4334c5f01b2fSopenharmony_ci basic_json result; 4335c5f01b2fSopenharmony_ci detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 4336c5f01b2fSopenharmony_ci auto ia = detail::input_adapter(std::forward<InputType>(i)); 4337c5f01b2fSopenharmony_ci const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); 4338c5f01b2fSopenharmony_ci return res ? result : basic_json(value_t::discarded); 4339c5f01b2fSopenharmony_ci } 4340c5f01b2fSopenharmony_ci 4341c5f01b2fSopenharmony_ci /// @brief create a JSON value from an input in CBOR format 4342c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/ 4343c5f01b2fSopenharmony_ci template<typename IteratorType> 4344c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4345c5f01b2fSopenharmony_ci static basic_json from_cbor(IteratorType first, IteratorType last, 4346c5f01b2fSopenharmony_ci const bool strict = true, 4347c5f01b2fSopenharmony_ci const bool allow_exceptions = true, 4348c5f01b2fSopenharmony_ci const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) 4349c5f01b2fSopenharmony_ci { 4350c5f01b2fSopenharmony_ci basic_json result; 4351c5f01b2fSopenharmony_ci detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 4352c5f01b2fSopenharmony_ci auto ia = detail::input_adapter(std::move(first), std::move(last)); 4353c5f01b2fSopenharmony_ci const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); 4354c5f01b2fSopenharmony_ci return res ? result : basic_json(value_t::discarded); 4355c5f01b2fSopenharmony_ci } 4356c5f01b2fSopenharmony_ci 4357c5f01b2fSopenharmony_ci template<typename T> 4358c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4359c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len)) 4360c5f01b2fSopenharmony_ci static basic_json from_cbor(const T* ptr, std::size_t len, 4361c5f01b2fSopenharmony_ci const bool strict = true, 4362c5f01b2fSopenharmony_ci const bool allow_exceptions = true, 4363c5f01b2fSopenharmony_ci const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) 4364c5f01b2fSopenharmony_ci { 4365c5f01b2fSopenharmony_ci return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler); 4366c5f01b2fSopenharmony_ci } 4367c5f01b2fSopenharmony_ci 4368c5f01b2fSopenharmony_ci 4369c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4370c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len)) 4371c5f01b2fSopenharmony_ci static basic_json from_cbor(detail::span_input_adapter&& i, 4372c5f01b2fSopenharmony_ci const bool strict = true, 4373c5f01b2fSopenharmony_ci const bool allow_exceptions = true, 4374c5f01b2fSopenharmony_ci const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) 4375c5f01b2fSopenharmony_ci { 4376c5f01b2fSopenharmony_ci basic_json result; 4377c5f01b2fSopenharmony_ci detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 4378c5f01b2fSopenharmony_ci auto ia = i.get(); 4379c5f01b2fSopenharmony_ci // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) 4380c5f01b2fSopenharmony_ci const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); 4381c5f01b2fSopenharmony_ci return res ? result : basic_json(value_t::discarded); 4382c5f01b2fSopenharmony_ci } 4383c5f01b2fSopenharmony_ci 4384c5f01b2fSopenharmony_ci /// @brief create a JSON value from an input in MessagePack format 4385c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/ 4386c5f01b2fSopenharmony_ci template<typename InputType> 4387c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4388c5f01b2fSopenharmony_ci static basic_json from_msgpack(InputType&& i, 4389c5f01b2fSopenharmony_ci const bool strict = true, 4390c5f01b2fSopenharmony_ci const bool allow_exceptions = true) 4391c5f01b2fSopenharmony_ci { 4392c5f01b2fSopenharmony_ci basic_json result; 4393c5f01b2fSopenharmony_ci detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 4394c5f01b2fSopenharmony_ci auto ia = detail::input_adapter(std::forward<InputType>(i)); 4395c5f01b2fSopenharmony_ci const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); 4396c5f01b2fSopenharmony_ci return res ? result : basic_json(value_t::discarded); 4397c5f01b2fSopenharmony_ci } 4398c5f01b2fSopenharmony_ci 4399c5f01b2fSopenharmony_ci /// @brief create a JSON value from an input in MessagePack format 4400c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/ 4401c5f01b2fSopenharmony_ci template<typename IteratorType> 4402c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4403c5f01b2fSopenharmony_ci static basic_json from_msgpack(IteratorType first, IteratorType last, 4404c5f01b2fSopenharmony_ci const bool strict = true, 4405c5f01b2fSopenharmony_ci const bool allow_exceptions = true) 4406c5f01b2fSopenharmony_ci { 4407c5f01b2fSopenharmony_ci basic_json result; 4408c5f01b2fSopenharmony_ci detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 4409c5f01b2fSopenharmony_ci auto ia = detail::input_adapter(std::move(first), std::move(last)); 4410c5f01b2fSopenharmony_ci const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); 4411c5f01b2fSopenharmony_ci return res ? result : basic_json(value_t::discarded); 4412c5f01b2fSopenharmony_ci } 4413c5f01b2fSopenharmony_ci 4414c5f01b2fSopenharmony_ci template<typename T> 4415c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4416c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len)) 4417c5f01b2fSopenharmony_ci static basic_json from_msgpack(const T* ptr, std::size_t len, 4418c5f01b2fSopenharmony_ci const bool strict = true, 4419c5f01b2fSopenharmony_ci const bool allow_exceptions = true) 4420c5f01b2fSopenharmony_ci { 4421c5f01b2fSopenharmony_ci return from_msgpack(ptr, ptr + len, strict, allow_exceptions); 4422c5f01b2fSopenharmony_ci } 4423c5f01b2fSopenharmony_ci 4424c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4425c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len)) 4426c5f01b2fSopenharmony_ci static basic_json from_msgpack(detail::span_input_adapter&& i, 4427c5f01b2fSopenharmony_ci const bool strict = true, 4428c5f01b2fSopenharmony_ci const bool allow_exceptions = true) 4429c5f01b2fSopenharmony_ci { 4430c5f01b2fSopenharmony_ci basic_json result; 4431c5f01b2fSopenharmony_ci detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 4432c5f01b2fSopenharmony_ci auto ia = i.get(); 4433c5f01b2fSopenharmony_ci // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) 4434c5f01b2fSopenharmony_ci const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); 4435c5f01b2fSopenharmony_ci return res ? result : basic_json(value_t::discarded); 4436c5f01b2fSopenharmony_ci } 4437c5f01b2fSopenharmony_ci 4438c5f01b2fSopenharmony_ci /// @brief create a JSON value from an input in UBJSON format 4439c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/ 4440c5f01b2fSopenharmony_ci template<typename InputType> 4441c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4442c5f01b2fSopenharmony_ci static basic_json from_ubjson(InputType&& i, 4443c5f01b2fSopenharmony_ci const bool strict = true, 4444c5f01b2fSopenharmony_ci const bool allow_exceptions = true) 4445c5f01b2fSopenharmony_ci { 4446c5f01b2fSopenharmony_ci basic_json result; 4447c5f01b2fSopenharmony_ci detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 4448c5f01b2fSopenharmony_ci auto ia = detail::input_adapter(std::forward<InputType>(i)); 4449c5f01b2fSopenharmony_ci const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); 4450c5f01b2fSopenharmony_ci return res ? result : basic_json(value_t::discarded); 4451c5f01b2fSopenharmony_ci } 4452c5f01b2fSopenharmony_ci 4453c5f01b2fSopenharmony_ci /// @brief create a JSON value from an input in UBJSON format 4454c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/ 4455c5f01b2fSopenharmony_ci template<typename IteratorType> 4456c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4457c5f01b2fSopenharmony_ci static basic_json from_ubjson(IteratorType first, IteratorType last, 4458c5f01b2fSopenharmony_ci const bool strict = true, 4459c5f01b2fSopenharmony_ci const bool allow_exceptions = true) 4460c5f01b2fSopenharmony_ci { 4461c5f01b2fSopenharmony_ci basic_json result; 4462c5f01b2fSopenharmony_ci detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 4463c5f01b2fSopenharmony_ci auto ia = detail::input_adapter(std::move(first), std::move(last)); 4464c5f01b2fSopenharmony_ci const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); 4465c5f01b2fSopenharmony_ci return res ? result : basic_json(value_t::discarded); 4466c5f01b2fSopenharmony_ci } 4467c5f01b2fSopenharmony_ci 4468c5f01b2fSopenharmony_ci template<typename T> 4469c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4470c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len)) 4471c5f01b2fSopenharmony_ci static basic_json from_ubjson(const T* ptr, std::size_t len, 4472c5f01b2fSopenharmony_ci const bool strict = true, 4473c5f01b2fSopenharmony_ci const bool allow_exceptions = true) 4474c5f01b2fSopenharmony_ci { 4475c5f01b2fSopenharmony_ci return from_ubjson(ptr, ptr + len, strict, allow_exceptions); 4476c5f01b2fSopenharmony_ci } 4477c5f01b2fSopenharmony_ci 4478c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4479c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len)) 4480c5f01b2fSopenharmony_ci static basic_json from_ubjson(detail::span_input_adapter&& i, 4481c5f01b2fSopenharmony_ci const bool strict = true, 4482c5f01b2fSopenharmony_ci const bool allow_exceptions = true) 4483c5f01b2fSopenharmony_ci { 4484c5f01b2fSopenharmony_ci basic_json result; 4485c5f01b2fSopenharmony_ci detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 4486c5f01b2fSopenharmony_ci auto ia = i.get(); 4487c5f01b2fSopenharmony_ci // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) 4488c5f01b2fSopenharmony_ci const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); 4489c5f01b2fSopenharmony_ci return res ? result : basic_json(value_t::discarded); 4490c5f01b2fSopenharmony_ci } 4491c5f01b2fSopenharmony_ci 4492c5f01b2fSopenharmony_ci 4493c5f01b2fSopenharmony_ci /// @brief create a JSON value from an input in BJData format 4494c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/from_bjdata/ 4495c5f01b2fSopenharmony_ci template<typename InputType> 4496c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4497c5f01b2fSopenharmony_ci static basic_json from_bjdata(InputType&& i, 4498c5f01b2fSopenharmony_ci const bool strict = true, 4499c5f01b2fSopenharmony_ci const bool allow_exceptions = true) 4500c5f01b2fSopenharmony_ci { 4501c5f01b2fSopenharmony_ci basic_json result; 4502c5f01b2fSopenharmony_ci detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 4503c5f01b2fSopenharmony_ci auto ia = detail::input_adapter(std::forward<InputType>(i)); 4504c5f01b2fSopenharmony_ci const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict); 4505c5f01b2fSopenharmony_ci return res ? result : basic_json(value_t::discarded); 4506c5f01b2fSopenharmony_ci } 4507c5f01b2fSopenharmony_ci 4508c5f01b2fSopenharmony_ci /// @brief create a JSON value from an input in BJData format 4509c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/from_bjdata/ 4510c5f01b2fSopenharmony_ci template<typename IteratorType> 4511c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4512c5f01b2fSopenharmony_ci static basic_json from_bjdata(IteratorType first, IteratorType last, 4513c5f01b2fSopenharmony_ci const bool strict = true, 4514c5f01b2fSopenharmony_ci const bool allow_exceptions = true) 4515c5f01b2fSopenharmony_ci { 4516c5f01b2fSopenharmony_ci basic_json result; 4517c5f01b2fSopenharmony_ci detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 4518c5f01b2fSopenharmony_ci auto ia = detail::input_adapter(std::move(first), std::move(last)); 4519c5f01b2fSopenharmony_ci const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict); 4520c5f01b2fSopenharmony_ci return res ? result : basic_json(value_t::discarded); 4521c5f01b2fSopenharmony_ci } 4522c5f01b2fSopenharmony_ci 4523c5f01b2fSopenharmony_ci /// @brief create a JSON value from an input in BSON format 4524c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/from_bson/ 4525c5f01b2fSopenharmony_ci template<typename InputType> 4526c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4527c5f01b2fSopenharmony_ci static basic_json from_bson(InputType&& i, 4528c5f01b2fSopenharmony_ci const bool strict = true, 4529c5f01b2fSopenharmony_ci const bool allow_exceptions = true) 4530c5f01b2fSopenharmony_ci { 4531c5f01b2fSopenharmony_ci basic_json result; 4532c5f01b2fSopenharmony_ci detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 4533c5f01b2fSopenharmony_ci auto ia = detail::input_adapter(std::forward<InputType>(i)); 4534c5f01b2fSopenharmony_ci const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); 4535c5f01b2fSopenharmony_ci return res ? result : basic_json(value_t::discarded); 4536c5f01b2fSopenharmony_ci } 4537c5f01b2fSopenharmony_ci 4538c5f01b2fSopenharmony_ci /// @brief create a JSON value from an input in BSON format 4539c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/from_bson/ 4540c5f01b2fSopenharmony_ci template<typename IteratorType> 4541c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4542c5f01b2fSopenharmony_ci static basic_json from_bson(IteratorType first, IteratorType last, 4543c5f01b2fSopenharmony_ci const bool strict = true, 4544c5f01b2fSopenharmony_ci const bool allow_exceptions = true) 4545c5f01b2fSopenharmony_ci { 4546c5f01b2fSopenharmony_ci basic_json result; 4547c5f01b2fSopenharmony_ci detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 4548c5f01b2fSopenharmony_ci auto ia = detail::input_adapter(std::move(first), std::move(last)); 4549c5f01b2fSopenharmony_ci const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); 4550c5f01b2fSopenharmony_ci return res ? result : basic_json(value_t::discarded); 4551c5f01b2fSopenharmony_ci } 4552c5f01b2fSopenharmony_ci 4553c5f01b2fSopenharmony_ci template<typename T> 4554c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4555c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len)) 4556c5f01b2fSopenharmony_ci static basic_json from_bson(const T* ptr, std::size_t len, 4557c5f01b2fSopenharmony_ci const bool strict = true, 4558c5f01b2fSopenharmony_ci const bool allow_exceptions = true) 4559c5f01b2fSopenharmony_ci { 4560c5f01b2fSopenharmony_ci return from_bson(ptr, ptr + len, strict, allow_exceptions); 4561c5f01b2fSopenharmony_ci } 4562c5f01b2fSopenharmony_ci 4563c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4564c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len)) 4565c5f01b2fSopenharmony_ci static basic_json from_bson(detail::span_input_adapter&& i, 4566c5f01b2fSopenharmony_ci const bool strict = true, 4567c5f01b2fSopenharmony_ci const bool allow_exceptions = true) 4568c5f01b2fSopenharmony_ci { 4569c5f01b2fSopenharmony_ci basic_json result; 4570c5f01b2fSopenharmony_ci detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 4571c5f01b2fSopenharmony_ci auto ia = i.get(); 4572c5f01b2fSopenharmony_ci // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) 4573c5f01b2fSopenharmony_ci const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); 4574c5f01b2fSopenharmony_ci return res ? result : basic_json(value_t::discarded); 4575c5f01b2fSopenharmony_ci } 4576c5f01b2fSopenharmony_ci /// @} 4577c5f01b2fSopenharmony_ci 4578c5f01b2fSopenharmony_ci ////////////////////////// 4579c5f01b2fSopenharmony_ci // JSON Pointer support // 4580c5f01b2fSopenharmony_ci ////////////////////////// 4581c5f01b2fSopenharmony_ci 4582c5f01b2fSopenharmony_ci /// @name JSON Pointer functions 4583c5f01b2fSopenharmony_ci /// @{ 4584c5f01b2fSopenharmony_ci 4585c5f01b2fSopenharmony_ci /// @brief access specified element via JSON Pointer 4586c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ 4587c5f01b2fSopenharmony_ci reference operator[](const json_pointer& ptr) 4588c5f01b2fSopenharmony_ci { 4589c5f01b2fSopenharmony_ci return ptr.get_unchecked(this); 4590c5f01b2fSopenharmony_ci } 4591c5f01b2fSopenharmony_ci 4592c5f01b2fSopenharmony_ci template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0> 4593c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens) 4594c5f01b2fSopenharmony_ci reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) 4595c5f01b2fSopenharmony_ci { 4596c5f01b2fSopenharmony_ci return ptr.get_unchecked(this); 4597c5f01b2fSopenharmony_ci } 4598c5f01b2fSopenharmony_ci 4599c5f01b2fSopenharmony_ci /// @brief access specified element via JSON Pointer 4600c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ 4601c5f01b2fSopenharmony_ci const_reference operator[](const json_pointer& ptr) const 4602c5f01b2fSopenharmony_ci { 4603c5f01b2fSopenharmony_ci return ptr.get_unchecked(this); 4604c5f01b2fSopenharmony_ci } 4605c5f01b2fSopenharmony_ci 4606c5f01b2fSopenharmony_ci template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0> 4607c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens) 4608c5f01b2fSopenharmony_ci const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const 4609c5f01b2fSopenharmony_ci { 4610c5f01b2fSopenharmony_ci return ptr.get_unchecked(this); 4611c5f01b2fSopenharmony_ci } 4612c5f01b2fSopenharmony_ci 4613c5f01b2fSopenharmony_ci /// @brief access specified element via JSON Pointer 4614c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/at/ 4615c5f01b2fSopenharmony_ci reference at(const json_pointer& ptr) 4616c5f01b2fSopenharmony_ci { 4617c5f01b2fSopenharmony_ci return ptr.get_checked(this); 4618c5f01b2fSopenharmony_ci } 4619c5f01b2fSopenharmony_ci 4620c5f01b2fSopenharmony_ci template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0> 4621c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens) 4622c5f01b2fSopenharmony_ci reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) 4623c5f01b2fSopenharmony_ci { 4624c5f01b2fSopenharmony_ci return ptr.get_checked(this); 4625c5f01b2fSopenharmony_ci } 4626c5f01b2fSopenharmony_ci 4627c5f01b2fSopenharmony_ci /// @brief access specified element via JSON Pointer 4628c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/at/ 4629c5f01b2fSopenharmony_ci const_reference at(const json_pointer& ptr) const 4630c5f01b2fSopenharmony_ci { 4631c5f01b2fSopenharmony_ci return ptr.get_checked(this); 4632c5f01b2fSopenharmony_ci } 4633c5f01b2fSopenharmony_ci 4634c5f01b2fSopenharmony_ci template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0> 4635c5f01b2fSopenharmony_ci JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens) 4636c5f01b2fSopenharmony_ci const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const 4637c5f01b2fSopenharmony_ci { 4638c5f01b2fSopenharmony_ci return ptr.get_checked(this); 4639c5f01b2fSopenharmony_ci } 4640c5f01b2fSopenharmony_ci 4641c5f01b2fSopenharmony_ci /// @brief return flattened JSON value 4642c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/flatten/ 4643c5f01b2fSopenharmony_ci basic_json flatten() const 4644c5f01b2fSopenharmony_ci { 4645c5f01b2fSopenharmony_ci basic_json result(value_t::object); 4646c5f01b2fSopenharmony_ci json_pointer::flatten("", *this, result); 4647c5f01b2fSopenharmony_ci return result; 4648c5f01b2fSopenharmony_ci } 4649c5f01b2fSopenharmony_ci 4650c5f01b2fSopenharmony_ci /// @brief unflatten a previously flattened JSON value 4651c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/unflatten/ 4652c5f01b2fSopenharmony_ci basic_json unflatten() const 4653c5f01b2fSopenharmony_ci { 4654c5f01b2fSopenharmony_ci return json_pointer::unflatten(*this); 4655c5f01b2fSopenharmony_ci } 4656c5f01b2fSopenharmony_ci 4657c5f01b2fSopenharmony_ci /// @} 4658c5f01b2fSopenharmony_ci 4659c5f01b2fSopenharmony_ci ////////////////////////// 4660c5f01b2fSopenharmony_ci // JSON Patch functions // 4661c5f01b2fSopenharmony_ci ////////////////////////// 4662c5f01b2fSopenharmony_ci 4663c5f01b2fSopenharmony_ci /// @name JSON Patch functions 4664c5f01b2fSopenharmony_ci /// @{ 4665c5f01b2fSopenharmony_ci 4666c5f01b2fSopenharmony_ci /// @brief applies a JSON patch in-place without copying the object 4667c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/patch/ 4668c5f01b2fSopenharmony_ci void patch_inplace(const basic_json& json_patch) 4669c5f01b2fSopenharmony_ci { 4670c5f01b2fSopenharmony_ci basic_json& result = *this; 4671c5f01b2fSopenharmony_ci // the valid JSON Patch operations 4672c5f01b2fSopenharmony_ci enum class patch_operations {add, remove, replace, move, copy, test, invalid}; 4673c5f01b2fSopenharmony_ci 4674c5f01b2fSopenharmony_ci const auto get_op = [](const std::string & op) 4675c5f01b2fSopenharmony_ci { 4676c5f01b2fSopenharmony_ci if (op == "add") 4677c5f01b2fSopenharmony_ci { 4678c5f01b2fSopenharmony_ci return patch_operations::add; 4679c5f01b2fSopenharmony_ci } 4680c5f01b2fSopenharmony_ci if (op == "remove") 4681c5f01b2fSopenharmony_ci { 4682c5f01b2fSopenharmony_ci return patch_operations::remove; 4683c5f01b2fSopenharmony_ci } 4684c5f01b2fSopenharmony_ci if (op == "replace") 4685c5f01b2fSopenharmony_ci { 4686c5f01b2fSopenharmony_ci return patch_operations::replace; 4687c5f01b2fSopenharmony_ci } 4688c5f01b2fSopenharmony_ci if (op == "move") 4689c5f01b2fSopenharmony_ci { 4690c5f01b2fSopenharmony_ci return patch_operations::move; 4691c5f01b2fSopenharmony_ci } 4692c5f01b2fSopenharmony_ci if (op == "copy") 4693c5f01b2fSopenharmony_ci { 4694c5f01b2fSopenharmony_ci return patch_operations::copy; 4695c5f01b2fSopenharmony_ci } 4696c5f01b2fSopenharmony_ci if (op == "test") 4697c5f01b2fSopenharmony_ci { 4698c5f01b2fSopenharmony_ci return patch_operations::test; 4699c5f01b2fSopenharmony_ci } 4700c5f01b2fSopenharmony_ci 4701c5f01b2fSopenharmony_ci return patch_operations::invalid; 4702c5f01b2fSopenharmony_ci }; 4703c5f01b2fSopenharmony_ci 4704c5f01b2fSopenharmony_ci // wrapper for "add" operation; add value at ptr 4705c5f01b2fSopenharmony_ci const auto operation_add = [&result](json_pointer & ptr, basic_json val) 4706c5f01b2fSopenharmony_ci { 4707c5f01b2fSopenharmony_ci // adding to the root of the target document means replacing it 4708c5f01b2fSopenharmony_ci if (ptr.empty()) 4709c5f01b2fSopenharmony_ci { 4710c5f01b2fSopenharmony_ci result = val; 4711c5f01b2fSopenharmony_ci return; 4712c5f01b2fSopenharmony_ci } 4713c5f01b2fSopenharmony_ci 4714c5f01b2fSopenharmony_ci // make sure the top element of the pointer exists 4715c5f01b2fSopenharmony_ci json_pointer top_pointer = ptr.top(); 4716c5f01b2fSopenharmony_ci if (top_pointer != ptr) 4717c5f01b2fSopenharmony_ci { 4718c5f01b2fSopenharmony_ci result.at(top_pointer); 4719c5f01b2fSopenharmony_ci } 4720c5f01b2fSopenharmony_ci 4721c5f01b2fSopenharmony_ci // get reference to parent of JSON pointer ptr 4722c5f01b2fSopenharmony_ci const auto last_path = ptr.back(); 4723c5f01b2fSopenharmony_ci ptr.pop_back(); 4724c5f01b2fSopenharmony_ci // parent must exist when performing patch add per RFC6902 specs 4725c5f01b2fSopenharmony_ci basic_json& parent = result.at(ptr); 4726c5f01b2fSopenharmony_ci 4727c5f01b2fSopenharmony_ci switch (parent.m_type) 4728c5f01b2fSopenharmony_ci { 4729c5f01b2fSopenharmony_ci case value_t::null: 4730c5f01b2fSopenharmony_ci case value_t::object: 4731c5f01b2fSopenharmony_ci { 4732c5f01b2fSopenharmony_ci // use operator[] to add value 4733c5f01b2fSopenharmony_ci parent[last_path] = val; 4734c5f01b2fSopenharmony_ci break; 4735c5f01b2fSopenharmony_ci } 4736c5f01b2fSopenharmony_ci 4737c5f01b2fSopenharmony_ci case value_t::array: 4738c5f01b2fSopenharmony_ci { 4739c5f01b2fSopenharmony_ci if (last_path == "-") 4740c5f01b2fSopenharmony_ci { 4741c5f01b2fSopenharmony_ci // special case: append to back 4742c5f01b2fSopenharmony_ci parent.push_back(val); 4743c5f01b2fSopenharmony_ci } 4744c5f01b2fSopenharmony_ci else 4745c5f01b2fSopenharmony_ci { 4746c5f01b2fSopenharmony_ci const auto idx = json_pointer::template array_index<basic_json_t>(last_path); 4747c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(idx > parent.size())) 4748c5f01b2fSopenharmony_ci { 4749c5f01b2fSopenharmony_ci // avoid undefined behavior 4750c5f01b2fSopenharmony_ci JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent)); 4751c5f01b2fSopenharmony_ci } 4752c5f01b2fSopenharmony_ci 4753c5f01b2fSopenharmony_ci // default case: insert add offset 4754c5f01b2fSopenharmony_ci parent.insert(parent.begin() + static_cast<difference_type>(idx), val); 4755c5f01b2fSopenharmony_ci } 4756c5f01b2fSopenharmony_ci break; 4757c5f01b2fSopenharmony_ci } 4758c5f01b2fSopenharmony_ci 4759c5f01b2fSopenharmony_ci // if there exists a parent it cannot be primitive 4760c5f01b2fSopenharmony_ci case value_t::string: // LCOV_EXCL_LINE 4761c5f01b2fSopenharmony_ci case value_t::boolean: // LCOV_EXCL_LINE 4762c5f01b2fSopenharmony_ci case value_t::number_integer: // LCOV_EXCL_LINE 4763c5f01b2fSopenharmony_ci case value_t::number_unsigned: // LCOV_EXCL_LINE 4764c5f01b2fSopenharmony_ci case value_t::number_float: // LCOV_EXCL_LINE 4765c5f01b2fSopenharmony_ci case value_t::binary: // LCOV_EXCL_LINE 4766c5f01b2fSopenharmony_ci case value_t::discarded: // LCOV_EXCL_LINE 4767c5f01b2fSopenharmony_ci default: // LCOV_EXCL_LINE 4768c5f01b2fSopenharmony_ci JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE 4769c5f01b2fSopenharmony_ci } 4770c5f01b2fSopenharmony_ci }; 4771c5f01b2fSopenharmony_ci 4772c5f01b2fSopenharmony_ci // wrapper for "remove" operation; remove value at ptr 4773c5f01b2fSopenharmony_ci const auto operation_remove = [this, &result](json_pointer & ptr) 4774c5f01b2fSopenharmony_ci { 4775c5f01b2fSopenharmony_ci // get reference to parent of JSON pointer ptr 4776c5f01b2fSopenharmony_ci const auto last_path = ptr.back(); 4777c5f01b2fSopenharmony_ci ptr.pop_back(); 4778c5f01b2fSopenharmony_ci basic_json& parent = result.at(ptr); 4779c5f01b2fSopenharmony_ci 4780c5f01b2fSopenharmony_ci // remove child 4781c5f01b2fSopenharmony_ci if (parent.is_object()) 4782c5f01b2fSopenharmony_ci { 4783c5f01b2fSopenharmony_ci // perform range check 4784c5f01b2fSopenharmony_ci auto it = parent.find(last_path); 4785c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(it != parent.end())) 4786c5f01b2fSopenharmony_ci { 4787c5f01b2fSopenharmony_ci parent.erase(it); 4788c5f01b2fSopenharmony_ci } 4789c5f01b2fSopenharmony_ci else 4790c5f01b2fSopenharmony_ci { 4791c5f01b2fSopenharmony_ci JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this)); 4792c5f01b2fSopenharmony_ci } 4793c5f01b2fSopenharmony_ci } 4794c5f01b2fSopenharmony_ci else if (parent.is_array()) 4795c5f01b2fSopenharmony_ci { 4796c5f01b2fSopenharmony_ci // note erase performs range check 4797c5f01b2fSopenharmony_ci parent.erase(json_pointer::template array_index<basic_json_t>(last_path)); 4798c5f01b2fSopenharmony_ci } 4799c5f01b2fSopenharmony_ci }; 4800c5f01b2fSopenharmony_ci 4801c5f01b2fSopenharmony_ci // type check: top level value must be an array 4802c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array())) 4803c5f01b2fSopenharmony_ci { 4804c5f01b2fSopenharmony_ci JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch)); 4805c5f01b2fSopenharmony_ci } 4806c5f01b2fSopenharmony_ci 4807c5f01b2fSopenharmony_ci // iterate and apply the operations 4808c5f01b2fSopenharmony_ci for (const auto& val : json_patch) 4809c5f01b2fSopenharmony_ci { 4810c5f01b2fSopenharmony_ci // wrapper to get a value for an operation 4811c5f01b2fSopenharmony_ci const auto get_value = [&val](const std::string & op, 4812c5f01b2fSopenharmony_ci const std::string & member, 4813c5f01b2fSopenharmony_ci bool string_type) -> basic_json & 4814c5f01b2fSopenharmony_ci { 4815c5f01b2fSopenharmony_ci // find value 4816c5f01b2fSopenharmony_ci auto it = val.m_value.object->find(member); 4817c5f01b2fSopenharmony_ci 4818c5f01b2fSopenharmony_ci // context-sensitive error message 4819c5f01b2fSopenharmony_ci const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\''); 4820c5f01b2fSopenharmony_ci 4821c5f01b2fSopenharmony_ci // check if desired value is present 4822c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end())) 4823c5f01b2fSopenharmony_ci { 4824c5f01b2fSopenharmony_ci // NOLINTNEXTLINE(performance-inefficient-string-concatenation) 4825c5f01b2fSopenharmony_ci JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val)); 4826c5f01b2fSopenharmony_ci } 4827c5f01b2fSopenharmony_ci 4828c5f01b2fSopenharmony_ci // check if result is of type string 4829c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string())) 4830c5f01b2fSopenharmony_ci { 4831c5f01b2fSopenharmony_ci // NOLINTNEXTLINE(performance-inefficient-string-concatenation) 4832c5f01b2fSopenharmony_ci JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val)); 4833c5f01b2fSopenharmony_ci } 4834c5f01b2fSopenharmony_ci 4835c5f01b2fSopenharmony_ci // no error: return value 4836c5f01b2fSopenharmony_ci return it->second; 4837c5f01b2fSopenharmony_ci }; 4838c5f01b2fSopenharmony_ci 4839c5f01b2fSopenharmony_ci // type check: every element of the array must be an object 4840c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!val.is_object())) 4841c5f01b2fSopenharmony_ci { 4842c5f01b2fSopenharmony_ci JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val)); 4843c5f01b2fSopenharmony_ci } 4844c5f01b2fSopenharmony_ci 4845c5f01b2fSopenharmony_ci // collect mandatory members 4846c5f01b2fSopenharmony_ci const auto op = get_value("op", "op", true).template get<std::string>(); 4847c5f01b2fSopenharmony_ci const auto path = get_value(op, "path", true).template get<std::string>(); 4848c5f01b2fSopenharmony_ci json_pointer ptr(path); 4849c5f01b2fSopenharmony_ci 4850c5f01b2fSopenharmony_ci switch (get_op(op)) 4851c5f01b2fSopenharmony_ci { 4852c5f01b2fSopenharmony_ci case patch_operations::add: 4853c5f01b2fSopenharmony_ci { 4854c5f01b2fSopenharmony_ci operation_add(ptr, get_value("add", "value", false)); 4855c5f01b2fSopenharmony_ci break; 4856c5f01b2fSopenharmony_ci } 4857c5f01b2fSopenharmony_ci 4858c5f01b2fSopenharmony_ci case patch_operations::remove: 4859c5f01b2fSopenharmony_ci { 4860c5f01b2fSopenharmony_ci operation_remove(ptr); 4861c5f01b2fSopenharmony_ci break; 4862c5f01b2fSopenharmony_ci } 4863c5f01b2fSopenharmony_ci 4864c5f01b2fSopenharmony_ci case patch_operations::replace: 4865c5f01b2fSopenharmony_ci { 4866c5f01b2fSopenharmony_ci // the "path" location must exist - use at() 4867c5f01b2fSopenharmony_ci result.at(ptr) = get_value("replace", "value", false); 4868c5f01b2fSopenharmony_ci break; 4869c5f01b2fSopenharmony_ci } 4870c5f01b2fSopenharmony_ci 4871c5f01b2fSopenharmony_ci case patch_operations::move: 4872c5f01b2fSopenharmony_ci { 4873c5f01b2fSopenharmony_ci const auto from_path = get_value("move", "from", true).template get<std::string>(); 4874c5f01b2fSopenharmony_ci json_pointer from_ptr(from_path); 4875c5f01b2fSopenharmony_ci 4876c5f01b2fSopenharmony_ci // the "from" location must exist - use at() 4877c5f01b2fSopenharmony_ci basic_json v = result.at(from_ptr); 4878c5f01b2fSopenharmony_ci 4879c5f01b2fSopenharmony_ci // The move operation is functionally identical to a 4880c5f01b2fSopenharmony_ci // "remove" operation on the "from" location, followed 4881c5f01b2fSopenharmony_ci // immediately by an "add" operation at the target 4882c5f01b2fSopenharmony_ci // location with the value that was just removed. 4883c5f01b2fSopenharmony_ci operation_remove(from_ptr); 4884c5f01b2fSopenharmony_ci operation_add(ptr, v); 4885c5f01b2fSopenharmony_ci break; 4886c5f01b2fSopenharmony_ci } 4887c5f01b2fSopenharmony_ci 4888c5f01b2fSopenharmony_ci case patch_operations::copy: 4889c5f01b2fSopenharmony_ci { 4890c5f01b2fSopenharmony_ci const auto from_path = get_value("copy", "from", true).template get<std::string>(); 4891c5f01b2fSopenharmony_ci const json_pointer from_ptr(from_path); 4892c5f01b2fSopenharmony_ci 4893c5f01b2fSopenharmony_ci // the "from" location must exist - use at() 4894c5f01b2fSopenharmony_ci basic_json v = result.at(from_ptr); 4895c5f01b2fSopenharmony_ci 4896c5f01b2fSopenharmony_ci // The copy is functionally identical to an "add" 4897c5f01b2fSopenharmony_ci // operation at the target location using the value 4898c5f01b2fSopenharmony_ci // specified in the "from" member. 4899c5f01b2fSopenharmony_ci operation_add(ptr, v); 4900c5f01b2fSopenharmony_ci break; 4901c5f01b2fSopenharmony_ci } 4902c5f01b2fSopenharmony_ci 4903c5f01b2fSopenharmony_ci case patch_operations::test: 4904c5f01b2fSopenharmony_ci { 4905c5f01b2fSopenharmony_ci bool success = false; 4906c5f01b2fSopenharmony_ci JSON_TRY 4907c5f01b2fSopenharmony_ci { 4908c5f01b2fSopenharmony_ci // check if "value" matches the one at "path" 4909c5f01b2fSopenharmony_ci // the "path" location must exist - use at() 4910c5f01b2fSopenharmony_ci success = (result.at(ptr) == get_value("test", "value", false)); 4911c5f01b2fSopenharmony_ci } 4912c5f01b2fSopenharmony_ci JSON_INTERNAL_CATCH (out_of_range&) 4913c5f01b2fSopenharmony_ci { 4914c5f01b2fSopenharmony_ci // ignore out of range errors: success remains false 4915c5f01b2fSopenharmony_ci } 4916c5f01b2fSopenharmony_ci 4917c5f01b2fSopenharmony_ci // throw an exception if test fails 4918c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!success)) 4919c5f01b2fSopenharmony_ci { 4920c5f01b2fSopenharmony_ci JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val)); 4921c5f01b2fSopenharmony_ci } 4922c5f01b2fSopenharmony_ci 4923c5f01b2fSopenharmony_ci break; 4924c5f01b2fSopenharmony_ci } 4925c5f01b2fSopenharmony_ci 4926c5f01b2fSopenharmony_ci case patch_operations::invalid: 4927c5f01b2fSopenharmony_ci default: 4928c5f01b2fSopenharmony_ci { 4929c5f01b2fSopenharmony_ci // op must be "add", "remove", "replace", "move", "copy", or 4930c5f01b2fSopenharmony_ci // "test" 4931c5f01b2fSopenharmony_ci JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val)); 4932c5f01b2fSopenharmony_ci } 4933c5f01b2fSopenharmony_ci } 4934c5f01b2fSopenharmony_ci } 4935c5f01b2fSopenharmony_ci } 4936c5f01b2fSopenharmony_ci 4937c5f01b2fSopenharmony_ci /// @brief applies a JSON patch to a copy of the current object 4938c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/patch/ 4939c5f01b2fSopenharmony_ci basic_json patch(const basic_json& json_patch) const 4940c5f01b2fSopenharmony_ci { 4941c5f01b2fSopenharmony_ci basic_json result = *this; 4942c5f01b2fSopenharmony_ci result.patch_inplace(json_patch); 4943c5f01b2fSopenharmony_ci return result; 4944c5f01b2fSopenharmony_ci } 4945c5f01b2fSopenharmony_ci 4946c5f01b2fSopenharmony_ci /// @brief creates a diff as a JSON patch 4947c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/diff/ 4948c5f01b2fSopenharmony_ci JSON_HEDLEY_WARN_UNUSED_RESULT 4949c5f01b2fSopenharmony_ci static basic_json diff(const basic_json& source, const basic_json& target, 4950c5f01b2fSopenharmony_ci const std::string& path = "") 4951c5f01b2fSopenharmony_ci { 4952c5f01b2fSopenharmony_ci // the patch 4953c5f01b2fSopenharmony_ci basic_json result(value_t::array); 4954c5f01b2fSopenharmony_ci 4955c5f01b2fSopenharmony_ci // if the values are the same, return empty patch 4956c5f01b2fSopenharmony_ci if (source == target) 4957c5f01b2fSopenharmony_ci { 4958c5f01b2fSopenharmony_ci return result; 4959c5f01b2fSopenharmony_ci } 4960c5f01b2fSopenharmony_ci 4961c5f01b2fSopenharmony_ci if (source.type() != target.type()) 4962c5f01b2fSopenharmony_ci { 4963c5f01b2fSopenharmony_ci // different types: replace value 4964c5f01b2fSopenharmony_ci result.push_back( 4965c5f01b2fSopenharmony_ci { 4966c5f01b2fSopenharmony_ci {"op", "replace"}, {"path", path}, {"value", target} 4967c5f01b2fSopenharmony_ci }); 4968c5f01b2fSopenharmony_ci return result; 4969c5f01b2fSopenharmony_ci } 4970c5f01b2fSopenharmony_ci 4971c5f01b2fSopenharmony_ci switch (source.type()) 4972c5f01b2fSopenharmony_ci { 4973c5f01b2fSopenharmony_ci case value_t::array: 4974c5f01b2fSopenharmony_ci { 4975c5f01b2fSopenharmony_ci // first pass: traverse common elements 4976c5f01b2fSopenharmony_ci std::size_t i = 0; 4977c5f01b2fSopenharmony_ci while (i < source.size() && i < target.size()) 4978c5f01b2fSopenharmony_ci { 4979c5f01b2fSopenharmony_ci // recursive call to compare array values at index i 4980c5f01b2fSopenharmony_ci auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i))); 4981c5f01b2fSopenharmony_ci result.insert(result.end(), temp_diff.begin(), temp_diff.end()); 4982c5f01b2fSopenharmony_ci ++i; 4983c5f01b2fSopenharmony_ci } 4984c5f01b2fSopenharmony_ci 4985c5f01b2fSopenharmony_ci // We now reached the end of at least one array 4986c5f01b2fSopenharmony_ci // in a second pass, traverse the remaining elements 4987c5f01b2fSopenharmony_ci 4988c5f01b2fSopenharmony_ci // remove my remaining elements 4989c5f01b2fSopenharmony_ci const auto end_index = static_cast<difference_type>(result.size()); 4990c5f01b2fSopenharmony_ci while (i < source.size()) 4991c5f01b2fSopenharmony_ci { 4992c5f01b2fSopenharmony_ci // add operations in reverse order to avoid invalid 4993c5f01b2fSopenharmony_ci // indices 4994c5f01b2fSopenharmony_ci result.insert(result.begin() + end_index, object( 4995c5f01b2fSopenharmony_ci { 4996c5f01b2fSopenharmony_ci {"op", "remove"}, 4997c5f01b2fSopenharmony_ci {"path", detail::concat(path, '/', std::to_string(i))} 4998c5f01b2fSopenharmony_ci })); 4999c5f01b2fSopenharmony_ci ++i; 5000c5f01b2fSopenharmony_ci } 5001c5f01b2fSopenharmony_ci 5002c5f01b2fSopenharmony_ci // add other remaining elements 5003c5f01b2fSopenharmony_ci while (i < target.size()) 5004c5f01b2fSopenharmony_ci { 5005c5f01b2fSopenharmony_ci result.push_back( 5006c5f01b2fSopenharmony_ci { 5007c5f01b2fSopenharmony_ci {"op", "add"}, 5008c5f01b2fSopenharmony_ci {"path", detail::concat(path, "/-")}, 5009c5f01b2fSopenharmony_ci {"value", target[i]} 5010c5f01b2fSopenharmony_ci }); 5011c5f01b2fSopenharmony_ci ++i; 5012c5f01b2fSopenharmony_ci } 5013c5f01b2fSopenharmony_ci 5014c5f01b2fSopenharmony_ci break; 5015c5f01b2fSopenharmony_ci } 5016c5f01b2fSopenharmony_ci 5017c5f01b2fSopenharmony_ci case value_t::object: 5018c5f01b2fSopenharmony_ci { 5019c5f01b2fSopenharmony_ci // first pass: traverse this object's elements 5020c5f01b2fSopenharmony_ci for (auto it = source.cbegin(); it != source.cend(); ++it) 5021c5f01b2fSopenharmony_ci { 5022c5f01b2fSopenharmony_ci // escape the key name to be used in a JSON patch 5023c5f01b2fSopenharmony_ci const auto path_key = detail::concat(path, '/', detail::escape(it.key())); 5024c5f01b2fSopenharmony_ci 5025c5f01b2fSopenharmony_ci if (target.find(it.key()) != target.end()) 5026c5f01b2fSopenharmony_ci { 5027c5f01b2fSopenharmony_ci // recursive call to compare object values at key it 5028c5f01b2fSopenharmony_ci auto temp_diff = diff(it.value(), target[it.key()], path_key); 5029c5f01b2fSopenharmony_ci result.insert(result.end(), temp_diff.begin(), temp_diff.end()); 5030c5f01b2fSopenharmony_ci } 5031c5f01b2fSopenharmony_ci else 5032c5f01b2fSopenharmony_ci { 5033c5f01b2fSopenharmony_ci // found a key that is not in o -> remove it 5034c5f01b2fSopenharmony_ci result.push_back(object( 5035c5f01b2fSopenharmony_ci { 5036c5f01b2fSopenharmony_ci {"op", "remove"}, {"path", path_key} 5037c5f01b2fSopenharmony_ci })); 5038c5f01b2fSopenharmony_ci } 5039c5f01b2fSopenharmony_ci } 5040c5f01b2fSopenharmony_ci 5041c5f01b2fSopenharmony_ci // second pass: traverse other object's elements 5042c5f01b2fSopenharmony_ci for (auto it = target.cbegin(); it != target.cend(); ++it) 5043c5f01b2fSopenharmony_ci { 5044c5f01b2fSopenharmony_ci if (source.find(it.key()) == source.end()) 5045c5f01b2fSopenharmony_ci { 5046c5f01b2fSopenharmony_ci // found a key that is not in this -> add it 5047c5f01b2fSopenharmony_ci const auto path_key = detail::concat(path, '/', detail::escape(it.key())); 5048c5f01b2fSopenharmony_ci result.push_back( 5049c5f01b2fSopenharmony_ci { 5050c5f01b2fSopenharmony_ci {"op", "add"}, {"path", path_key}, 5051c5f01b2fSopenharmony_ci {"value", it.value()} 5052c5f01b2fSopenharmony_ci }); 5053c5f01b2fSopenharmony_ci } 5054c5f01b2fSopenharmony_ci } 5055c5f01b2fSopenharmony_ci 5056c5f01b2fSopenharmony_ci break; 5057c5f01b2fSopenharmony_ci } 5058c5f01b2fSopenharmony_ci 5059c5f01b2fSopenharmony_ci case value_t::null: 5060c5f01b2fSopenharmony_ci case value_t::string: 5061c5f01b2fSopenharmony_ci case value_t::boolean: 5062c5f01b2fSopenharmony_ci case value_t::number_integer: 5063c5f01b2fSopenharmony_ci case value_t::number_unsigned: 5064c5f01b2fSopenharmony_ci case value_t::number_float: 5065c5f01b2fSopenharmony_ci case value_t::binary: 5066c5f01b2fSopenharmony_ci case value_t::discarded: 5067c5f01b2fSopenharmony_ci default: 5068c5f01b2fSopenharmony_ci { 5069c5f01b2fSopenharmony_ci // both primitive type: replace value 5070c5f01b2fSopenharmony_ci result.push_back( 5071c5f01b2fSopenharmony_ci { 5072c5f01b2fSopenharmony_ci {"op", "replace"}, {"path", path}, {"value", target} 5073c5f01b2fSopenharmony_ci }); 5074c5f01b2fSopenharmony_ci break; 5075c5f01b2fSopenharmony_ci } 5076c5f01b2fSopenharmony_ci } 5077c5f01b2fSopenharmony_ci 5078c5f01b2fSopenharmony_ci return result; 5079c5f01b2fSopenharmony_ci } 5080c5f01b2fSopenharmony_ci /// @} 5081c5f01b2fSopenharmony_ci 5082c5f01b2fSopenharmony_ci //////////////////////////////// 5083c5f01b2fSopenharmony_ci // JSON Merge Patch functions // 5084c5f01b2fSopenharmony_ci //////////////////////////////// 5085c5f01b2fSopenharmony_ci 5086c5f01b2fSopenharmony_ci /// @name JSON Merge Patch functions 5087c5f01b2fSopenharmony_ci /// @{ 5088c5f01b2fSopenharmony_ci 5089c5f01b2fSopenharmony_ci /// @brief applies a JSON Merge Patch 5090c5f01b2fSopenharmony_ci /// @sa https://json.nlohmann.me/api/basic_json/merge_patch/ 5091c5f01b2fSopenharmony_ci void merge_patch(const basic_json& apply_patch) 5092c5f01b2fSopenharmony_ci { 5093c5f01b2fSopenharmony_ci if (apply_patch.is_object()) 5094c5f01b2fSopenharmony_ci { 5095c5f01b2fSopenharmony_ci if (!is_object()) 5096c5f01b2fSopenharmony_ci { 5097c5f01b2fSopenharmony_ci *this = object(); 5098c5f01b2fSopenharmony_ci } 5099c5f01b2fSopenharmony_ci for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it) 5100c5f01b2fSopenharmony_ci { 5101c5f01b2fSopenharmony_ci if (it.value().is_null()) 5102c5f01b2fSopenharmony_ci { 5103c5f01b2fSopenharmony_ci erase(it.key()); 5104c5f01b2fSopenharmony_ci } 5105c5f01b2fSopenharmony_ci else 5106c5f01b2fSopenharmony_ci { 5107c5f01b2fSopenharmony_ci operator[](it.key()).merge_patch(it.value()); 5108c5f01b2fSopenharmony_ci } 5109c5f01b2fSopenharmony_ci } 5110c5f01b2fSopenharmony_ci } 5111c5f01b2fSopenharmony_ci else 5112c5f01b2fSopenharmony_ci { 5113c5f01b2fSopenharmony_ci *this = apply_patch; 5114c5f01b2fSopenharmony_ci } 5115c5f01b2fSopenharmony_ci } 5116c5f01b2fSopenharmony_ci 5117c5f01b2fSopenharmony_ci /// @} 5118c5f01b2fSopenharmony_ci}; 5119c5f01b2fSopenharmony_ci 5120c5f01b2fSopenharmony_ci/// @brief user-defined to_string function for JSON values 5121c5f01b2fSopenharmony_ci/// @sa https://json.nlohmann.me/api/basic_json/to_string/ 5122c5f01b2fSopenharmony_ciNLOHMANN_BASIC_JSON_TPL_DECLARATION 5123c5f01b2fSopenharmony_cistd::string to_string(const NLOHMANN_BASIC_JSON_TPL& j) 5124c5f01b2fSopenharmony_ci{ 5125c5f01b2fSopenharmony_ci return j.dump(); 5126c5f01b2fSopenharmony_ci} 5127c5f01b2fSopenharmony_ci 5128c5f01b2fSopenharmony_ciinline namespace literals 5129c5f01b2fSopenharmony_ci{ 5130c5f01b2fSopenharmony_ciinline namespace json_literals 5131c5f01b2fSopenharmony_ci{ 5132c5f01b2fSopenharmony_ci 5133c5f01b2fSopenharmony_ci/// @brief user-defined string literal for JSON values 5134c5f01b2fSopenharmony_ci/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json/ 5135c5f01b2fSopenharmony_ciJSON_HEDLEY_NON_NULL(1) 5136c5f01b2fSopenharmony_ciinline nlohmann::json operator "" _json(const char* s, std::size_t n) 5137c5f01b2fSopenharmony_ci{ 5138c5f01b2fSopenharmony_ci return nlohmann::json::parse(s, s + n); 5139c5f01b2fSopenharmony_ci} 5140c5f01b2fSopenharmony_ci 5141c5f01b2fSopenharmony_ci/// @brief user-defined string literal for JSON pointer 5142c5f01b2fSopenharmony_ci/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json_pointer/ 5143c5f01b2fSopenharmony_ciJSON_HEDLEY_NON_NULL(1) 5144c5f01b2fSopenharmony_ciinline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n) 5145c5f01b2fSopenharmony_ci{ 5146c5f01b2fSopenharmony_ci return nlohmann::json::json_pointer(std::string(s, n)); 5147c5f01b2fSopenharmony_ci} 5148c5f01b2fSopenharmony_ci 5149c5f01b2fSopenharmony_ci} // namespace json_literals 5150c5f01b2fSopenharmony_ci} // namespace literals 5151c5f01b2fSopenharmony_ciNLOHMANN_JSON_NAMESPACE_END 5152c5f01b2fSopenharmony_ci 5153c5f01b2fSopenharmony_ci/////////////////////// 5154c5f01b2fSopenharmony_ci// nonmember support // 5155c5f01b2fSopenharmony_ci/////////////////////// 5156c5f01b2fSopenharmony_ci 5157c5f01b2fSopenharmony_cinamespace std // NOLINT(cert-dcl58-cpp) 5158c5f01b2fSopenharmony_ci{ 5159c5f01b2fSopenharmony_ci 5160c5f01b2fSopenharmony_ci/// @brief hash value for JSON objects 5161c5f01b2fSopenharmony_ci/// @sa https://json.nlohmann.me/api/basic_json/std_hash/ 5162c5f01b2fSopenharmony_ciNLOHMANN_BASIC_JSON_TPL_DECLARATION 5163c5f01b2fSopenharmony_cistruct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL> 5164c5f01b2fSopenharmony_ci{ 5165c5f01b2fSopenharmony_ci std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const 5166c5f01b2fSopenharmony_ci { 5167c5f01b2fSopenharmony_ci return nlohmann::detail::hash(j); 5168c5f01b2fSopenharmony_ci } 5169c5f01b2fSopenharmony_ci}; 5170c5f01b2fSopenharmony_ci 5171c5f01b2fSopenharmony_ci// specialization for std::less<value_t> 5172c5f01b2fSopenharmony_citemplate<> 5173c5f01b2fSopenharmony_cistruct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679 5174c5f01b2fSopenharmony_ci{ 5175c5f01b2fSopenharmony_ci /*! 5176c5f01b2fSopenharmony_ci @brief compare two value_t enum values 5177c5f01b2fSopenharmony_ci @since version 3.0.0 5178c5f01b2fSopenharmony_ci */ 5179c5f01b2fSopenharmony_ci bool operator()(::nlohmann::detail::value_t lhs, 5180c5f01b2fSopenharmony_ci ::nlohmann::detail::value_t rhs) const noexcept 5181c5f01b2fSopenharmony_ci { 5182c5f01b2fSopenharmony_ci#if JSON_HAS_THREE_WAY_COMPARISON 5183c5f01b2fSopenharmony_ci return std::is_lt(lhs <=> rhs); // *NOPAD* 5184c5f01b2fSopenharmony_ci#else 5185c5f01b2fSopenharmony_ci return ::nlohmann::detail::operator<(lhs, rhs); 5186c5f01b2fSopenharmony_ci#endif 5187c5f01b2fSopenharmony_ci } 5188c5f01b2fSopenharmony_ci}; 5189c5f01b2fSopenharmony_ci 5190c5f01b2fSopenharmony_ci// C++20 prohibit function specialization in the std namespace. 5191c5f01b2fSopenharmony_ci#ifndef JSON_HAS_CPP_20 5192c5f01b2fSopenharmony_ci 5193c5f01b2fSopenharmony_ci/// @brief exchanges the values of two JSON objects 5194c5f01b2fSopenharmony_ci/// @sa https://json.nlohmann.me/api/basic_json/std_swap/ 5195c5f01b2fSopenharmony_ciNLOHMANN_BASIC_JSON_TPL_DECLARATION 5196c5f01b2fSopenharmony_ciinline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name) 5197c5f01b2fSopenharmony_ci is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression) 5198c5f01b2fSopenharmony_ci is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value) 5199c5f01b2fSopenharmony_ci{ 5200c5f01b2fSopenharmony_ci j1.swap(j2); 5201c5f01b2fSopenharmony_ci} 5202c5f01b2fSopenharmony_ci 5203c5f01b2fSopenharmony_ci#endif 5204c5f01b2fSopenharmony_ci 5205c5f01b2fSopenharmony_ci} // namespace std 5206c5f01b2fSopenharmony_ci 5207c5f01b2fSopenharmony_ci#if JSON_USE_GLOBAL_UDLS 5208c5f01b2fSopenharmony_ci using nlohmann::literals::json_literals::operator "" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers) 5209c5f01b2fSopenharmony_ci using nlohmann::literals::json_literals::operator "" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers) 5210c5f01b2fSopenharmony_ci#endif 5211c5f01b2fSopenharmony_ci 5212c5f01b2fSopenharmony_ci#include <nlohmann/detail/macro_unscope.hpp> 5213c5f01b2fSopenharmony_ci 5214c5f01b2fSopenharmony_ci#endif // INCLUDE_NLOHMANN_JSON_HPP_ 5215