json/include/nlohmann/json.hpp

5176 lines
188 KiB
C++
Raw Normal View History

2018-01-10 01:30:02 +08:00
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++
2022-01-03 05:35:35 +08:00
| | |__ | | | | | | version 3.10.5
2018-01-10 01:30:02 +08:00
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
SPDX-License-Identifier: MIT
2022-01-03 05:35:35 +08:00
Copyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.
2018-01-10 01:30:02 +08:00
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/****************************************************************************\
* Note on documentation: The source files contain links to the online *
* documentation of the public API at https://json.nlohmann.me. This URL *
* contains the most recent documentation and should also be applicable to *
* previous versions; documentation for deprecated functions is not *
* removed, but marked deprecated. See "Generate documentation" section in *
* file docs/README.md. *
\****************************************************************************/
2019-03-15 21:55:13 +08:00
#ifndef INCLUDE_NLOHMANN_JSON_HPP_
#define INCLUDE_NLOHMANN_JSON_HPP_
2018-01-10 01:30:02 +08:00
#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
#if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
#if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 10 || NLOHMANN_JSON_VERSION_PATCH != 5
#warning "Already included a different version of the library!"
#endif
#endif
#endif
#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)
#define NLOHMANN_JSON_VERSION_MINOR 10 // NOLINT(modernize-macro-to-enum)
#define NLOHMANN_JSON_VERSION_PATCH 5 // NOLINT(modernize-macro-to-enum)
2018-01-10 01:30:02 +08:00
#include <algorithm> // all_of, find, for_each
#include <cstddef> // nullptr_t, ptrdiff_t, size_t
#include <functional> // hash, less
#include <initializer_list> // initializer_list
#ifndef JSON_NO_IO
#include <iosfwd> // istream, ostream
#endif // JSON_NO_IO
#include <iterator> // random_access_iterator_tag
2019-03-15 21:55:13 +08:00
#include <memory> // unique_ptr
2018-01-10 01:30:02 +08:00
#include <numeric> // accumulate
#include <string> // string, stoi, to_string
#include <utility> // declval, forward, move, pair, swap
2019-03-15 21:55:13 +08:00
#include <vector> // vector
2018-01-10 01:30:02 +08:00
2019-03-17 19:01:49 +08:00
#include <nlohmann/adl_serializer.hpp>
#include <nlohmann/byte_container_with_subtype.hpp>
#include <nlohmann/detail/conversions/from_json.hpp>
#include <nlohmann/detail/conversions/to_json.hpp>
2019-03-17 19:01:49 +08:00
#include <nlohmann/detail/exceptions.hpp>
2020-07-14 20:31:19 +08:00
#include <nlohmann/detail/hash.hpp>
2019-03-17 19:01:49 +08:00
#include <nlohmann/detail/input/binary_reader.hpp>
#include <nlohmann/detail/input/input_adapters.hpp>
#include <nlohmann/detail/input/lexer.hpp>
#include <nlohmann/detail/input/parser.hpp>
#include <nlohmann/detail/iterators/internal_iterator.hpp>
#include <nlohmann/detail/iterators/iter_impl.hpp>
#include <nlohmann/detail/iterators/iteration_proxy.hpp>
#include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
2019-03-17 19:01:49 +08:00
#include <nlohmann/detail/iterators/primitive_iterator.hpp>
#include <nlohmann/detail/json_pointer.hpp>
#include <nlohmann/detail/json_ref.hpp>
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/string_concat.hpp>
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
#include <nlohmann/detail/string_escape.hpp>
2019-03-17 19:01:49 +08:00
#include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/output/binary_writer.hpp>
2019-03-17 19:01:49 +08:00
#include <nlohmann/detail/output/output_adapters.hpp>
#include <nlohmann/detail/output/serializer.hpp>
2019-03-17 19:01:49 +08:00
#include <nlohmann/detail/value_t.hpp>
#include <nlohmann/json_fwd.hpp>
#include <nlohmann/ordered_map.hpp>
2018-01-10 01:30:02 +08:00
#if defined(JSON_HAS_CPP_17)
#include <any>
#include <string_view>
#endif
2018-01-10 01:30:02 +08:00
/*!
@brief namespace for Niels Lohmann
@see https://github.com/nlohmann
@since version 1.0.0
*/
namespace nlohmann
{
/*!
@brief a class to store JSON values
@internal
2018-01-10 01:30:02 +08:00
@invariant The member variables @a m_value and @a m_type have the following
relationship:
- If `m_type == value_t::object`, then `m_value.object != nullptr`.
- If `m_type == value_t::array`, then `m_value.array != nullptr`.
- If `m_type == value_t::string`, then `m_value.string != nullptr`.
The invariants are checked by member function assert_invariant().
2020-02-02 17:29:37 +08:00
@note ObjectType trick from https://stackoverflow.com/a/9860911
2018-01-10 01:30:02 +08:00
@endinternal
@since version 1.0.0
@nosubgrouping
*/
NLOHMANN_BASIC_JSON_TPL_DECLARATION
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
2018-01-10 01:30:02 +08:00
{
private:
template<detail::value_t> friend struct detail::external_constructor;
template<typename>
friend class ::nlohmann::json_pointer;
// can be restored when json_pointer backwards compatibility is removed
// friend ::nlohmann::json_pointer<StringType>;
2020-02-19 23:32:49 +08:00
template<typename BasicJsonType, typename InputType>
friend class ::nlohmann::detail::parser;
2018-01-10 01:30:02 +08:00
friend ::nlohmann::detail::serializer<basic_json>;
template<typename BasicJsonType>
friend class ::nlohmann::detail::iter_impl;
template<typename BasicJsonType, typename CharType>
friend class ::nlohmann::detail::binary_writer;
2020-02-20 03:59:31 +08:00
template<typename BasicJsonType, typename InputType, typename SAX>
2018-01-10 01:30:02 +08:00
friend class ::nlohmann::detail::binary_reader;
2018-03-06 04:06:00 +08:00
template<typename BasicJsonType>
friend class ::nlohmann::detail::json_sax_dom_parser;
template<typename BasicJsonType>
friend class ::nlohmann::detail::json_sax_dom_callback_parser;
2021-01-25 20:47:50 +08:00
friend class ::nlohmann::detail::exception;
2018-01-10 01:30:02 +08:00
/// workaround type for MSVC
using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
JSON_PRIVATE_UNLESS_TESTED:
2018-01-10 01:30:02 +08:00
// convenience aliases for types residing in namespace detail;
2020-02-19 23:32:49 +08:00
using lexer = ::nlohmann::detail::lexer_base<basic_json>;
template<typename InputAdapterType>
static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
2020-02-20 03:59:31 +08:00
InputAdapterType adapter,
2020-02-19 23:32:49 +08:00
detail::parser_callback_t<basic_json>cb = nullptr,
2020-06-18 04:03:14 +08:00
const bool allow_exceptions = true,
const bool ignore_comments = false
2020-02-19 23:32:49 +08:00
)
{
2020-06-18 04:03:14 +08:00
return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
std::move(cb), allow_exceptions, ignore_comments);
2020-02-19 23:32:49 +08:00
}
2018-01-10 01:30:02 +08:00
private:
2018-01-10 01:30:02 +08:00
using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
template<typename BasicJsonType>
using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
template<typename BasicJsonType>
using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
template<typename Iterator>
using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
template<typename CharType>
using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
2020-02-20 03:59:31 +08:00
template<typename InputType>
using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
2018-01-10 01:30:02 +08:00
template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
JSON_PRIVATE_UNLESS_TESTED:
2018-01-10 01:30:02 +08:00
using serializer = ::nlohmann::detail::serializer<basic_json>;
public:
using value_t = detail::value_t;
2018-08-17 03:53:47 +08:00
/// JSON Pointer, see @ref nlohmann::json_pointer
using json_pointer = ::nlohmann::json_pointer<StringType>;
2018-01-10 01:30:02 +08:00
template<typename T, typename SFINAE>
using json_serializer = JSONSerializer<T, SFINAE>;
/// how to treat decoding errors
using error_handler_t = detail::error_handler_t;
2020-07-12 22:51:43 +08:00
/// how to treat CBOR tags
using cbor_tag_handler_t = detail::cbor_tag_handler_t;
2018-01-10 01:30:02 +08:00
/// helper type for initializer lists of basic_json values
using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
2018-03-21 05:39:08 +08:00
using input_format_t = detail::input_format_t;
2018-08-17 03:53:47 +08:00
/// SAX interface type, see @ref nlohmann::json_sax
2018-08-16 16:52:33 +08:00
using json_sax_t = json_sax<basic_json>;
2018-03-21 05:39:08 +08:00
2018-01-10 01:30:02 +08:00
////////////////
// exceptions //
////////////////
/// @name exceptions
/// Classes to implement user-defined exceptions.
/// @{
using exception = detail::exception;
using parse_error = detail::parse_error;
using invalid_iterator = detail::invalid_iterator;
using type_error = detail::type_error;
using out_of_range = detail::out_of_range;
using other_error = detail::other_error;
/// @}
/////////////////////
// container types //
/////////////////////
/// @name container types
/// The canonic container types to use @ref basic_json like any other STL
/// container.
/// @{
/// the type of elements in a basic_json container
using value_type = basic_json;
/// the type of an element reference
using reference = value_type&;
/// the type of an element const reference
using const_reference = const value_type&;
/// a type to represent differences between iterators
using difference_type = std::ptrdiff_t;
/// a type to represent container sizes
using size_type = std::size_t;
/// the allocator type
using allocator_type = AllocatorType<basic_json>;
/// the type of an element pointer
using pointer = typename std::allocator_traits<allocator_type>::pointer;
/// the type of an element const pointer
using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
/// an iterator for a basic_json container
using iterator = iter_impl<basic_json>;
/// a const iterator for a basic_json container
using const_iterator = iter_impl<const basic_json>;
/// a reverse iterator for a basic_json container
using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
/// a const reverse iterator for a basic_json container
using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
/// @}
/// @brief returns the allocator associated with the container
/// @sa https://json.nlohmann.me/api/basic_json/get_allocator/
2018-01-10 01:30:02 +08:00
static allocator_type get_allocator()
{
return allocator_type();
}
/// @brief returns version information on the library
/// @sa https://json.nlohmann.me/api/basic_json/meta/
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2018-01-10 01:30:02 +08:00
static basic_json meta()
{
basic_json result;
2022-01-03 05:35:35 +08:00
result["copyright"] = "(C) 2013-2022 Niels Lohmann";
2018-01-10 01:30:02 +08:00
result["name"] = "JSON for Modern C++";
result["url"] = "https://github.com/nlohmann/json";
result["version"]["string"] =
detail::concat(std::to_string(NLOHMANN_JSON_VERSION_MAJOR), '.',
std::to_string(NLOHMANN_JSON_VERSION_MINOR), '.',
std::to_string(NLOHMANN_JSON_VERSION_PATCH));
result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
2018-01-10 01:30:02 +08:00
#ifdef _WIN32
result["platform"] = "win32";
#elif defined __linux__
result["platform"] = "linux";
#elif defined __APPLE__
result["platform"] = "apple";
#elif defined __unix__
result["platform"] = "unix";
#else
result["platform"] = "unknown";
#endif
#if defined(__ICC) || defined(__INTEL_COMPILER)
result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
#elif defined(__clang__)
result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
#elif defined(__GNUC__) || defined(__GNUG__)
result["compiler"] = {{"family", "gcc"}, {"version", detail::concat(
std::to_string(__GNUC__), '.',
std::to_string(__GNUC_MINOR__), '.',
std::to_string(__GNUC_PATCHLEVEL__))
}
};
2018-01-10 01:30:02 +08:00
#elif defined(__HP_cc) || defined(__HP_aCC)
result["compiler"] = "hp"
#elif defined(__IBMCPP__)
result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
#elif defined(_MSC_VER)
result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
#elif defined(__PGI)
result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
#elif defined(__SUNPRO_CC)
result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
#else
result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
#endif
#if defined(_MSVC_LANG)
result["compiler"]["c++"] = std::to_string(_MSVC_LANG);
#elif defined(__cplusplus)
2018-01-10 01:30:02 +08:00
result["compiler"]["c++"] = std::to_string(__cplusplus);
#else
result["compiler"]["c++"] = "unknown";
#endif
return result;
}
///////////////////////////
// JSON value data types //
///////////////////////////
/// @name JSON value data types
/// The data types to store a JSON value. These types are derived from
/// the template arguments passed to class @ref basic_json.
/// @{
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
/// @brief default object key comparator type
/// The actual object key comparator type (@ref object_comparator_t) may be
/// different.
/// @sa https://json.nlohmann.me/api/basic_json/default_object_comparator_t/
2018-01-10 01:30:02 +08:00
#if defined(JSON_HAS_CPP_14)
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
// use of transparent comparator avoids unnecessary repeated construction of temporaries
// in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
using default_object_comparator_t = std::less<>;
2018-01-10 01:30:02 +08:00
#else
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
using default_object_comparator_t = std::less<StringType>;
2018-01-10 01:30:02 +08:00
#endif
/// @brief a type for an object
/// @sa https://json.nlohmann.me/api/basic_json/object_t/
2018-01-10 01:30:02 +08:00
using object_t = ObjectType<StringType,
basic_json,
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
default_object_comparator_t,
2018-01-10 01:30:02 +08:00
AllocatorType<std::pair<const StringType,
basic_json>>>;
/// @brief a type for an array
/// @sa https://json.nlohmann.me/api/basic_json/array_t/
2018-01-10 01:30:02 +08:00
using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
/// @brief a type for a string
/// @sa https://json.nlohmann.me/api/basic_json/string_t/
2018-01-10 01:30:02 +08:00
using string_t = StringType;
/// @brief a type for a boolean
/// @sa https://json.nlohmann.me/api/basic_json/boolean_t/
2018-01-10 01:30:02 +08:00
using boolean_t = BooleanType;
/// @brief a type for a number (integer)
/// @sa https://json.nlohmann.me/api/basic_json/number_integer_t/
2018-01-10 01:30:02 +08:00
using number_integer_t = NumberIntegerType;
/// @brief a type for a number (unsigned)
/// @sa https://json.nlohmann.me/api/basic_json/number_unsigned_t/
2018-01-10 01:30:02 +08:00
using number_unsigned_t = NumberUnsignedType;
/// @brief a type for a number (floating-point)
/// @sa https://json.nlohmann.me/api/basic_json/number_float_t/
2018-01-10 01:30:02 +08:00
using number_float_t = NumberFloatType;
/// @brief a type for a packed binary type
/// @sa https://json.nlohmann.me/api/basic_json/binary_t/
using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
/// @brief object key comparator type
/// @sa https://json.nlohmann.me/api/basic_json/object_comparator_t/
using object_comparator_t = detail::actual_object_comparator_t<basic_json>;
2018-01-10 01:30:02 +08:00
/// @}
private:
/// helper for exception-safe object creation
template<typename T, typename... Args>
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_RETURNS_NON_NULL
2018-01-10 01:30:02 +08:00
static T* create(Args&& ... args)
{
AllocatorType<T> alloc;
using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
2020-12-16 05:15:36 +08:00
auto deleter = [&](T * obj)
2018-01-10 01:30:02 +08:00
{
2020-12-16 05:15:36 +08:00
AllocatorTraits::deallocate(alloc, obj, 1);
2018-01-10 01:30:02 +08:00
};
2020-12-16 05:15:36 +08:00
std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
JSON_ASSERT(obj != nullptr);
return obj.release();
2018-01-10 01:30:02 +08:00
}
////////////////////////
// JSON value storage //
////////////////////////
JSON_PRIVATE_UNLESS_TESTED:
2018-01-10 01:30:02 +08:00
/*!
@brief a JSON value
The actual storage for a JSON value of the @ref basic_json class. This
union combines the different storage types for the JSON value types
defined in @ref value_t.
JSON type | value_t type | used type
--------- | --------------- | ------------------------
object | object | pointer to @ref object_t
array | array | pointer to @ref array_t
string | string | pointer to @ref string_t
boolean | boolean | @ref boolean_t
number | number_integer | @ref number_integer_t
number | number_unsigned | @ref number_unsigned_t
number | number_float | @ref number_float_t
binary | binary | pointer to @ref binary_t
2018-01-10 01:30:02 +08:00
null | null | *no value is stored*
@note Variable-length types (objects, arrays, and strings) are stored as
pointers. The size of the union should not exceed 64 bits if the default
value types are used.
@since version 1.0.0
*/
union json_value
{
/// object (stored with pointer to save storage)
object_t* object;
/// array (stored with pointer to save storage)
array_t* array;
/// string (stored with pointer to save storage)
string_t* string;
/// binary (stored with pointer to save storage)
binary_t* binary;
2018-01-10 01:30:02 +08:00
/// boolean
boolean_t boolean;
/// number (integer)
number_integer_t number_integer;
/// number (unsigned integer)
number_unsigned_t number_unsigned;
/// number (floating-point)
number_float_t number_float;
/// default constructor (for null values)
json_value() = default;
/// constructor for booleans
json_value(boolean_t v) noexcept : boolean(v) {}
/// constructor for numbers (integer)
json_value(number_integer_t v) noexcept : number_integer(v) {}
/// constructor for numbers (unsigned)
json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
/// constructor for numbers (floating-point)
json_value(number_float_t v) noexcept : number_float(v) {}
/// constructor for empty values of a given type
json_value(value_t t)
{
switch (t)
{
case value_t::object:
{
object = create<object_t>();
break;
}
case value_t::array:
{
array = create<array_t>();
break;
}
case value_t::string:
{
string = create<string_t>("");
break;
}
case value_t::binary:
{
binary = create<binary_t>();
break;
}
2018-01-10 01:30:02 +08:00
case value_t::boolean:
{
boolean = static_cast<boolean_t>(false);
2018-01-10 01:30:02 +08:00
break;
}
case value_t::number_integer:
{
number_integer = static_cast<number_integer_t>(0);
2018-01-10 01:30:02 +08:00
break;
}
case value_t::number_unsigned:
{
number_unsigned = static_cast<number_unsigned_t>(0);
2018-01-10 01:30:02 +08:00
break;
}
case value_t::number_float:
{
number_float = static_cast<number_float_t>(0.0);
2018-01-10 01:30:02 +08:00
break;
}
case value_t::null:
{
object = nullptr; // silence warning, see #821
break;
}
case value_t::discarded:
2018-01-10 01:30:02 +08:00
default:
{
object = nullptr; // silence warning, see #821
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.5", nullptr)); // LCOV_EXCL_LINE
2018-01-10 01:30:02 +08:00
}
break;
}
}
}
/// constructor for strings
json_value(const string_t& value) : string(create<string_t>(value)) {}
2018-01-10 01:30:02 +08:00
/// constructor for rvalue strings
json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
2018-01-10 01:30:02 +08:00
/// constructor for objects
json_value(const object_t& value) : object(create<object_t>(value)) {}
2018-01-10 01:30:02 +08:00
/// constructor for rvalue objects
json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
2018-01-10 01:30:02 +08:00
/// constructor for arrays
json_value(const array_t& value) : array(create<array_t>(value)) {}
2018-01-10 01:30:02 +08:00
/// constructor for rvalue arrays
json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
2018-01-10 01:30:02 +08:00
/// constructor for binary arrays
json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
/// constructor for rvalue binary arrays
json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
/// constructor for binary arrays (internal type)
json_value(const binary_t& value) : binary(create<binary_t>(value)) {}
/// constructor for rvalue binary arrays (internal type)
json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
2021-07-16 03:49:09 +08:00
void destroy(value_t t)
2018-01-10 01:30:02 +08:00
{
if (t == value_t::array || t == value_t::object)
{
// flatten the current json_value to a heap-allocated stack
std::vector<basic_json> stack;
// move the top-level items to stack
if (t == value_t::array)
{
stack.reserve(array->size());
std::move(array->begin(), array->end(), std::back_inserter(stack));
}
else
{
stack.reserve(object->size());
for (auto&& it : *object)
{
stack.push_back(std::move(it.second));
}
}
while (!stack.empty())
{
// move the last item to local variable to be processed
basic_json current_item(std::move(stack.back()));
stack.pop_back();
// if current_item is array/object, move
// its children to the stack to be processed later
if (current_item.is_array())
{
std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
current_item.m_value.array->clear();
}
else if (current_item.is_object())
{
for (auto&& it : *current_item.m_value.object)
{
stack.push_back(std::move(it.second));
}
current_item.m_value.object->clear();
}
// it's now safe that current_item get destructed
// since it doesn't have any children
}
}
2018-01-10 01:30:02 +08:00
switch (t)
{
case value_t::object:
{
AllocatorType<object_t> alloc;
std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
break;
}
case value_t::array:
{
AllocatorType<array_t> alloc;
std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
break;
}
case value_t::string:
{
AllocatorType<string_t> alloc;
std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
break;
}
case value_t::binary:
{
AllocatorType<binary_t> alloc;
std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
break;
}
case value_t::null:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::discarded:
2018-01-10 01:30:02 +08:00
default:
{
break;
}
}
}
};
private:
2018-01-10 01:30:02 +08:00
/*!
@brief checks the class invariants
This function asserts the class invariants. It needs to be called at the
end of every constructor to make sure that created objects respect the
invariant. Furthermore, it has to be called each time the type of a JSON
value is changed, because the invariant expresses a relationship between
@a m_type and @a m_value.
2021-01-11 05:40:50 +08:00
Furthermore, the parent relation is checked for arrays and objects: If
@a check_parents true and the value is an array or object, then the
container's elements must have the current value as parent.
@param[in] check_parents whether the parent relation should be checked.
2021-01-15 04:56:19 +08:00
The value is true by default and should only be set to false
2021-01-11 05:40:50 +08:00
during destruction of objects when the invariant does not
need to hold.
2018-01-10 01:30:02 +08:00
*/
2021-01-11 05:40:50 +08:00
void assert_invariant(bool check_parents = true) const noexcept
2018-01-10 01:30:02 +08:00
{
JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
2021-01-11 05:40:50 +08:00
#if JSON_DIAGNOSTICS
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
JSON_TRY
2021-01-11 05:40:50 +08:00
{
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
// cppcheck-suppress assertWithSideEffect
JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
{
return j.m_parent == this;
}));
}
JSON_CATCH(...) {} // LCOV_EXCL_LINE
2021-01-11 05:40:50 +08:00
#endif
2021-04-13 07:47:02 +08:00
static_cast<void>(check_parents);
2018-01-10 01:30:02 +08:00
}
2021-01-15 04:55:49 +08:00
void set_parents()
2021-01-10 22:04:14 +08:00
{
#if JSON_DIAGNOSTICS
2021-01-15 04:55:49 +08:00
switch (m_type)
2021-01-10 22:04:14 +08:00
{
2021-01-15 04:55:49 +08:00
case value_t::array:
2021-01-10 22:04:14 +08:00
{
2021-01-15 04:55:49 +08:00
for (auto& element : *m_value.array)
2021-01-10 22:04:14 +08:00
{
2021-01-15 04:55:49 +08:00
element.m_parent = this;
2021-01-10 22:04:14 +08:00
}
2021-01-15 04:55:49 +08:00
break;
}
2021-01-10 22:04:14 +08:00
2021-01-15 04:55:49 +08:00
case value_t::object:
{
for (auto& element : *m_value.object)
2021-01-10 22:04:14 +08:00
{
2021-01-15 04:55:49 +08:00
element.second.m_parent = this;
2021-01-10 22:04:14 +08:00
}
2021-01-15 04:55:49 +08:00
break;
2021-01-10 22:04:14 +08:00
}
2021-01-15 04:55:49 +08:00
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
2021-01-15 04:55:49 +08:00
default:
break;
2021-01-10 22:04:14 +08:00
}
2021-01-15 04:55:49 +08:00
#endif
}
iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
{
#if JSON_DIAGNOSTICS
for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
{
(it + i)->m_parent = this;
}
#else
static_cast<void>(count_set_parents);
#endif
return it;
}
reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))
2021-01-15 04:55:49 +08:00
{
#if JSON_DIAGNOSTICS
if (old_capacity != static_cast<std::size_t>(-1))
{
// see https://github.com/nlohmann/json/issues/2838
JSON_ASSERT(type() == value_t::array);
if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
{
// capacity has changed: update all parents
set_parents();
return j;
}
}
// ordered_json uses a vector internally, so pointers could have
// been invalidated; see https://github.com/nlohmann/json/issues/2962
#ifdef JSON_HEDLEY_MSVC_VERSION
#pragma warning(push )
#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
#endif
if (detail::is_ordered_map<object_t>::value)
{
set_parents();
return j;
}
#ifdef JSON_HEDLEY_MSVC_VERSION
#pragma warning( pop )
#endif
2021-01-15 04:55:49 +08:00
j.m_parent = this;
2021-01-10 22:04:14 +08:00
#else
static_cast<void>(j);
2021-07-13 21:37:57 +08:00
static_cast<void>(old_capacity);
2021-01-10 22:04:14 +08:00
#endif
return j;
2018-01-10 01:30:02 +08:00
}
public:
//////////////////////////
// JSON parser callback //
//////////////////////////
/// @brief parser event types
/// @sa https://json.nlohmann.me/api/basic_json/parse_event_t/
2020-02-19 23:32:49 +08:00
using parse_event_t = detail::parse_event_t;
2018-01-10 01:30:02 +08:00
/// @brief per-element parser callback type
/// @sa https://json.nlohmann.me/api/basic_json/parser_callback_t/
2020-02-19 23:32:49 +08:00
using parser_callback_t = detail::parser_callback_t<basic_json>;
2018-01-10 01:30:02 +08:00
//////////////////
// constructors //
//////////////////
/// @name constructors and destructors
/// Constructors of class @ref basic_json, copy/move constructor, copy
/// assignment, static functions creating objects, and the destructor.
/// @{
/// @brief create an empty value with a given type
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
2018-01-10 01:30:02 +08:00
basic_json(const value_t v)
: m_type(v), m_value(v)
{
assert_invariant();
}
/// @brief create a null object
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
2018-01-10 01:30:02 +08:00
: basic_json(value_t::null)
{
assert_invariant();
}
/// @brief create a JSON value from compatible types
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
template < typename CompatibleType,
typename U = detail::uncvref_t<CompatibleType>,
detail::enable_if_t <
!detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
std::forward<CompatibleType>(val))))
2018-01-10 01:30:02 +08:00
{
JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
2021-01-15 04:55:49 +08:00
set_parents();
2018-01-10 01:30:02 +08:00
assert_invariant();
}
/// @brief create a JSON value from an existing one
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
template < typename BasicJsonType,
detail::enable_if_t <
detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
basic_json(const BasicJsonType& val)
{
using other_boolean_t = typename BasicJsonType::boolean_t;
using other_number_float_t = typename BasicJsonType::number_float_t;
using other_number_integer_t = typename BasicJsonType::number_integer_t;
using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
using other_string_t = typename BasicJsonType::string_t;
using other_object_t = typename BasicJsonType::object_t;
using other_array_t = typename BasicJsonType::array_t;
using other_binary_t = typename BasicJsonType::binary_t;
switch (val.type())
{
case value_t::boolean:
JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
break;
case value_t::number_float:
JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
break;
case value_t::number_integer:
JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
break;
case value_t::number_unsigned:
JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
break;
case value_t::string:
JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
break;
case value_t::object:
JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
break;
case value_t::array:
JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
break;
case value_t::binary:
JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
break;
case value_t::null:
*this = nullptr;
break;
case value_t::discarded:
m_type = value_t::discarded;
break;
2019-03-18 20:53:48 +08:00
default: // LCOV_EXCL_LINE
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
}
JSON_ASSERT(m_type == val.type());
2021-01-15 04:55:49 +08:00
set_parents();
assert_invariant();
}
/// @brief create a container (array or object) from an initializer list
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
2018-01-10 01:30:02 +08:00
basic_json(initializer_list_t init,
bool type_deduction = true,
value_t manual_type = value_t::array)
{
// check if each element is an array with two elements whose first
// element is a string
bool is_an_object = std::all_of(init.begin(), init.end(),
[](const detail::json_ref<basic_json>& element_ref)
{
return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
2018-01-10 01:30:02 +08:00
});
// adjust type if type deduction is not wanted
if (!type_deduction)
2018-01-10 01:30:02 +08:00
{
// if array is wanted, do not create an object though possible
if (manual_type == value_t::array)
{
is_an_object = false;
}
// if object is wanted but impossible, throw an exception
if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
2018-01-10 01:30:02 +08:00
}
}
if (is_an_object)
{
// the initializer list is a list of pairs -> create object
m_type = value_t::object;
m_value = value_t::object;
2021-01-09 01:00:23 +08:00
for (auto& element_ref : init)
2018-01-10 01:30:02 +08:00
{
auto element = element_ref.moved_or_copied();
m_value.object->emplace(
std::move(*((*element.m_value.array)[0].m_value.string)),
std::move((*element.m_value.array)[1]));
2021-01-09 01:00:23 +08:00
}
2018-01-10 01:30:02 +08:00
}
else
{
// the initializer list describes an array -> create array
m_type = value_t::array;
m_value.array = create<array_t>(init.begin(), init.end());
}
2021-01-15 04:55:49 +08:00
set_parents();
2018-01-10 01:30:02 +08:00
assert_invariant();
}
/// @brief explicitly create a binary array (without subtype)
/// @sa https://json.nlohmann.me/api/basic_json/binary/
JSON_HEDLEY_WARN_UNUSED_RESULT
static basic_json binary(const typename binary_t::container_type& init)
{
auto res = basic_json();
res.m_type = value_t::binary;
res.m_value = init;
return res;
}
/// @brief explicitly create a binary array (with subtype)
/// @sa https://json.nlohmann.me/api/basic_json/binary/
JSON_HEDLEY_WARN_UNUSED_RESULT
2021-08-06 20:36:38 +08:00
static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
{
auto res = basic_json();
res.m_type = value_t::binary;
res.m_value = binary_t(init, subtype);
return res;
}
/// @brief explicitly create a binary array
/// @sa https://json.nlohmann.me/api/basic_json/binary/
JSON_HEDLEY_WARN_UNUSED_RESULT
static basic_json binary(typename binary_t::container_type&& init)
{
auto res = basic_json();
res.m_type = value_t::binary;
res.m_value = std::move(init);
return res;
}
/// @brief explicitly create a binary array (with subtype)
/// @sa https://json.nlohmann.me/api/basic_json/binary/
JSON_HEDLEY_WARN_UNUSED_RESULT
2021-08-06 20:36:38 +08:00
static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
{
auto res = basic_json();
res.m_type = value_t::binary;
res.m_value = binary_t(std::move(init), subtype);
return res;
}
/// @brief explicitly create an array from an initializer list
/// @sa https://json.nlohmann.me/api/basic_json/array/
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2018-01-10 01:30:02 +08:00
static basic_json array(initializer_list_t init = {})
{
return basic_json(init, false, value_t::array);
}
/// @brief explicitly create an object from an initializer list
/// @sa https://json.nlohmann.me/api/basic_json/object/
JSON_HEDLEY_WARN_UNUSED_RESULT
static basic_json object(initializer_list_t init = {})
{
return basic_json(init, false, value_t::object);
}
2018-01-10 01:30:02 +08:00
/// @brief construct an array with count copies of given value
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
2018-01-10 01:30:02 +08:00
basic_json(size_type cnt, const basic_json& val)
: m_type(value_t::array)
{
m_value.array = create<array_t>(cnt, val);
2021-01-15 04:55:49 +08:00
set_parents();
2018-01-10 01:30:02 +08:00
assert_invariant();
}
/// @brief construct a JSON container given an iterator range
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
template < class InputIT, typename std::enable_if <
std::is_same<InputIT, typename basic_json_t::iterator>::value ||
std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
2018-01-10 01:30:02 +08:00
basic_json(InputIT first, InputIT last)
{
JSON_ASSERT(first.m_object != nullptr);
JSON_ASSERT(last.m_object != nullptr);
2018-01-10 01:30:02 +08:00
// make sure iterator fits the current value
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
2018-01-10 01:30:02 +08:00
}
// copy type from first iterator
m_type = first.m_object->m_type;
// check if iterator range is complete for primitive values
switch (m_type)
{
case value_t::boolean:
case value_t::number_float:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::string:
{
if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
|| !last.m_it.primitive_iterator.is_end()))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
2018-01-10 01:30:02 +08:00
}
break;
}
case value_t::null:
case value_t::object:
case value_t::array:
case value_t::binary:
case value_t::discarded:
2018-01-10 01:30:02 +08:00
default:
break;
}
switch (m_type)
{
case value_t::number_integer:
{
m_value.number_integer = first.m_object->m_value.number_integer;
break;
}
case value_t::number_unsigned:
{
m_value.number_unsigned = first.m_object->m_value.number_unsigned;
break;
}
case value_t::number_float:
{
m_value.number_float = first.m_object->m_value.number_float;
break;
}
case value_t::boolean:
{
m_value.boolean = first.m_object->m_value.boolean;
break;
}
case value_t::string:
{
m_value = *first.m_object->m_value.string;
break;
}
case value_t::object:
{
m_value.object = create<object_t>(first.m_it.object_iterator,
last.m_it.object_iterator);
break;
}
case value_t::array:
{
m_value.array = create<array_t>(first.m_it.array_iterator,
last.m_it.array_iterator);
break;
}
case value_t::binary:
{
2020-05-09 20:16:49 +08:00
m_value = *first.m_object->m_value.binary;
break;
}
case value_t::null:
case value_t::discarded:
2018-01-10 01:30:02 +08:00
default:
JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
2018-01-10 01:30:02 +08:00
}
2021-01-15 04:55:49 +08:00
set_parents();
2018-01-10 01:30:02 +08:00
assert_invariant();
}
///////////////////////////////////////
// other constructors and destructor //
///////////////////////////////////////
template<typename JsonRef,
detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
2018-01-10 01:30:02 +08:00
/// @brief copy constructor
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
2018-01-10 01:30:02 +08:00
basic_json(const basic_json& other)
: m_type(other.m_type)
{
// check of passed value is valid
other.assert_invariant();
switch (m_type)
{
case value_t::object:
{
m_value = *other.m_value.object;
break;
}
case value_t::array:
{
m_value = *other.m_value.array;
break;
}
case value_t::string:
{
m_value = *other.m_value.string;
break;
}
case value_t::boolean:
{
m_value = other.m_value.boolean;
break;
}
case value_t::number_integer:
{
m_value = other.m_value.number_integer;
break;
}
case value_t::number_unsigned:
{
m_value = other.m_value.number_unsigned;
break;
}
case value_t::number_float:
{
m_value = other.m_value.number_float;
break;
}
case value_t::binary:
{
m_value = *other.m_value.binary;
break;
}
case value_t::null:
case value_t::discarded:
2018-01-10 01:30:02 +08:00
default:
break;
}
2021-01-15 04:55:49 +08:00
set_parents();
2018-01-10 01:30:02 +08:00
assert_invariant();
}
/// @brief move constructor
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
2018-01-10 01:30:02 +08:00
basic_json(basic_json&& other) noexcept
: m_type(std::move(other.m_type)),
m_value(std::move(other.m_value))
{
// check that passed value is valid
2021-01-11 05:40:50 +08:00
other.assert_invariant(false);
2018-01-10 01:30:02 +08:00
// invalidate payload
other.m_type = value_t::null;
other.m_value = {};
2021-01-15 04:55:49 +08:00
set_parents();
2018-01-10 01:30:02 +08:00
assert_invariant();
}
/// @brief copy assignment
/// @sa https://json.nlohmann.me/api/basic_json/operator=/
basic_json& operator=(basic_json other) noexcept (
std::is_nothrow_move_constructible<value_t>::value&&
std::is_nothrow_move_assignable<value_t>::value&&
std::is_nothrow_move_constructible<json_value>::value&&
2018-01-10 01:30:02 +08:00
std::is_nothrow_move_assignable<json_value>::value
)
{
// check that passed value is valid
other.assert_invariant();
using std::swap;
swap(m_type, other.m_type);
swap(m_value, other.m_value);
2021-01-15 04:55:49 +08:00
set_parents();
2018-01-10 01:30:02 +08:00
assert_invariant();
return *this;
}
/// @brief destructor
/// @sa https://json.nlohmann.me/api/basic_json/~basic_json/
2018-01-17 03:41:04 +08:00
~basic_json() noexcept
2018-01-10 01:30:02 +08:00
{
2021-01-11 05:40:50 +08:00
assert_invariant(false);
2018-01-10 01:30:02 +08:00
m_value.destroy(m_type);
}
/// @}
public:
///////////////////////
// object inspection //
///////////////////////
/// @name object inspection
/// Functions to inspect the type of a JSON value.
/// @{
/// @brief serialization
/// @sa https://json.nlohmann.me/api/basic_json/dump/
string_t dump(const int indent = -1,
const char indent_char = ' ',
const bool ensure_ascii = false,
const error_handler_t error_handler = error_handler_t::strict) const
2018-01-10 01:30:02 +08:00
{
string_t result;
serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
2018-01-10 01:30:02 +08:00
if (indent >= 0)
{
s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
2018-01-10 01:30:02 +08:00
}
else
{
s.dump(*this, false, ensure_ascii, 0);
2018-01-10 01:30:02 +08:00
}
return result;
}
/// @brief return the type of the JSON value (explicit)
/// @sa https://json.nlohmann.me/api/basic_json/type/
2018-01-10 01:30:02 +08:00
constexpr value_t type() const noexcept
{
return m_type;
}
/// @brief return whether type is primitive
/// @sa https://json.nlohmann.me/api/basic_json/is_primitive/
2018-01-10 01:30:02 +08:00
constexpr bool is_primitive() const noexcept
{
return is_null() || is_string() || is_boolean() || is_number() || is_binary();
2018-01-10 01:30:02 +08:00
}
/// @brief return whether type is structured
/// @sa https://json.nlohmann.me/api/basic_json/is_structured/
2018-01-10 01:30:02 +08:00
constexpr bool is_structured() const noexcept
{
return is_array() || is_object();
2018-01-10 01:30:02 +08:00
}
/// @brief return whether value is null
/// @sa https://json.nlohmann.me/api/basic_json/is_null/
2018-01-10 01:30:02 +08:00
constexpr bool is_null() const noexcept
{
2019-03-18 20:53:48 +08:00
return m_type == value_t::null;
2018-01-10 01:30:02 +08:00
}
/// @brief return whether value is a boolean
/// @sa https://json.nlohmann.me/api/basic_json/is_boolean/
2018-01-10 01:30:02 +08:00
constexpr bool is_boolean() const noexcept
{
2019-03-18 20:53:48 +08:00
return m_type == value_t::boolean;
2018-01-10 01:30:02 +08:00
}
/// @brief return whether value is a number
/// @sa https://json.nlohmann.me/api/basic_json/is_number/
2018-01-10 01:30:02 +08:00
constexpr bool is_number() const noexcept
{
return is_number_integer() || is_number_float();
2018-01-10 01:30:02 +08:00
}
/// @brief return whether value is an integer number
/// @sa https://json.nlohmann.me/api/basic_json/is_number_integer/
2018-01-10 01:30:02 +08:00
constexpr bool is_number_integer() const noexcept
{
return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
2018-01-10 01:30:02 +08:00
}
/// @brief return whether value is an unsigned integer number
/// @sa https://json.nlohmann.me/api/basic_json/is_number_unsigned/
2018-01-10 01:30:02 +08:00
constexpr bool is_number_unsigned() const noexcept
{
2019-03-18 20:53:48 +08:00
return m_type == value_t::number_unsigned;
2018-01-10 01:30:02 +08:00
}
/// @brief return whether value is a floating-point number
/// @sa https://json.nlohmann.me/api/basic_json/is_number_float/
2018-01-10 01:30:02 +08:00
constexpr bool is_number_float() const noexcept
{
2019-03-18 20:53:48 +08:00
return m_type == value_t::number_float;
2018-01-10 01:30:02 +08:00
}
/// @brief return whether value is an object
/// @sa https://json.nlohmann.me/api/basic_json/is_object/
2018-01-10 01:30:02 +08:00
constexpr bool is_object() const noexcept
{
2019-03-18 20:53:48 +08:00
return m_type == value_t::object;
2018-01-10 01:30:02 +08:00
}
/// @brief return whether value is an array
/// @sa https://json.nlohmann.me/api/basic_json/is_array/
2018-01-10 01:30:02 +08:00
constexpr bool is_array() const noexcept
{
2019-03-18 20:53:48 +08:00
return m_type == value_t::array;
2018-01-10 01:30:02 +08:00
}
/// @brief return whether value is a string
/// @sa https://json.nlohmann.me/api/basic_json/is_string/
2018-01-10 01:30:02 +08:00
constexpr bool is_string() const noexcept
{
2019-03-18 20:53:48 +08:00
return m_type == value_t::string;
2018-01-10 01:30:02 +08:00
}
/// @brief return whether value is a binary array
/// @sa https://json.nlohmann.me/api/basic_json/is_binary/
constexpr bool is_binary() const noexcept
{
return m_type == value_t::binary;
}
/// @brief return whether value is discarded
/// @sa https://json.nlohmann.me/api/basic_json/is_discarded/
2018-01-10 01:30:02 +08:00
constexpr bool is_discarded() const noexcept
{
2019-03-18 20:53:48 +08:00
return m_type == value_t::discarded;
2018-01-10 01:30:02 +08:00
}
/// @brief return the type of the JSON value (implicit)
/// @sa https://json.nlohmann.me/api/basic_json/operator_value_t/
2018-01-10 01:30:02 +08:00
constexpr operator value_t() const noexcept
{
return m_type;
}
/// @}
private:
//////////////////
// value access //
//////////////////
/// get a boolean (explicit)
boolean_t get_impl(boolean_t* /*unused*/) const
{
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(is_boolean()))
2018-01-10 01:30:02 +08:00
{
return m_value.boolean;
}
JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
/// get a pointer to the value (object)
object_t* get_impl_ptr(object_t* /*unused*/) noexcept
{
return is_object() ? m_value.object : nullptr;
}
/// get a pointer to the value (object)
constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
{
return is_object() ? m_value.object : nullptr;
}
/// get a pointer to the value (array)
array_t* get_impl_ptr(array_t* /*unused*/) noexcept
{
return is_array() ? m_value.array : nullptr;
}
/// get a pointer to the value (array)
constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
{
return is_array() ? m_value.array : nullptr;
}
/// get a pointer to the value (string)
string_t* get_impl_ptr(string_t* /*unused*/) noexcept
{
return is_string() ? m_value.string : nullptr;
}
/// get a pointer to the value (string)
constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
{
return is_string() ? m_value.string : nullptr;
}
/// get a pointer to the value (boolean)
boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
{
return is_boolean() ? &m_value.boolean : nullptr;
}
/// get a pointer to the value (boolean)
constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
{
return is_boolean() ? &m_value.boolean : nullptr;
}
/// get a pointer to the value (integer number)
number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
{
return is_number_integer() ? &m_value.number_integer : nullptr;
}
/// get a pointer to the value (integer number)
constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
{
return is_number_integer() ? &m_value.number_integer : nullptr;
}
/// get a pointer to the value (unsigned number)
number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
{
return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
}
/// get a pointer to the value (unsigned number)
constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
{
return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
}
/// get a pointer to the value (floating-point number)
number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
{
return is_number_float() ? &m_value.number_float : nullptr;
}
/// get a pointer to the value (floating-point number)
constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
{
return is_number_float() ? &m_value.number_float : nullptr;
}
/// get a pointer to the value (binary)
binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
{
return is_binary() ? m_value.binary : nullptr;
}
/// get a pointer to the value (binary)
constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
{
return is_binary() ? m_value.binary : nullptr;
}
2018-01-10 01:30:02 +08:00
/*!
@brief helper function to implement get_ref()
This function helps to implement get_ref() without code duplication for
const and non-const overloads
@tparam ThisType will be deduced as `basic_json` or `const basic_json`
@throw type_error.303 if ReferenceType does not match underlying value
type of the current JSON
*/
template<typename ReferenceType, typename ThisType>
static ReferenceType get_ref_impl(ThisType& obj)
{
// delegate the call to get_ptr<>()
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
2018-01-10 01:30:02 +08:00
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(ptr != nullptr))
2018-01-10 01:30:02 +08:00
{
return *ptr;
}
JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
2018-01-10 01:30:02 +08:00
}
public:
/// @name value access
/// Direct access to the stored value of a JSON value.
/// @{
/// @brief get a pointer value (implicit)
/// @sa https://json.nlohmann.me/api/basic_json/get_ptr/
template<typename PointerType, typename std::enable_if<
std::is_pointer<PointerType>::value, int>::type = 0>
auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
2018-01-10 01:30:02 +08:00
{
// delegate the call to get_impl_ptr<>()
return get_impl_ptr(static_cast<PointerType>(nullptr));
2018-01-10 01:30:02 +08:00
}
/// @brief get a pointer value (implicit)
/// @sa https://json.nlohmann.me/api/basic_json/get_ptr/
template < typename PointerType, typename std::enable_if <
std::is_pointer<PointerType>::value&&
std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
{
// delegate the call to get_impl_ptr<>() const
return get_impl_ptr(static_cast<PointerType>(nullptr));
}
private:
2018-01-10 01:30:02 +08:00
/*!
@brief get a value (explicit)
Explicit type conversion between the JSON value and a compatible value
which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
2018-01-10 01:30:02 +08:00
The value is converted by calling the @ref json_serializer<ValueType>
`from_json()` method.
The function is equivalent to executing
@code {.cpp}
ValueType ret;
JSONSerializer<ValueType>::from_json(*this, ret);
return ret;
@endcode
This overloads is chosen if:
- @a ValueType is not @ref basic_json,
- @ref json_serializer<ValueType> has a `from_json()` method of the form
`void from_json(const basic_json&, ValueType&)`, and
- @ref json_serializer<ValueType> does not have a `from_json()` method of
the form `ValueType from_json(const basic_json&)`
@tparam ValueType the returned value type
@return copy of the JSON value, converted to @a ValueType
@throw what @ref json_serializer<ValueType> `from_json()` method throws
@liveexample{The example below shows several conversions from JSON values
to other types. There a few things to note: (1) Floating-point numbers can
be converted to integers\, (2) A JSON array can be converted to a standard
`std::vector<short>`\, (3) A JSON object can be converted to C++
associative containers such as `std::unordered_map<std::string\,
json>`.,get__ValueType_const}
@since version 2.1.0
*/
template < typename ValueType,
detail::enable_if_t <
detail::is_default_constructible<ValueType>::value&&
detail::has_from_json<basic_json_t, ValueType>::value,
int > = 0 >
ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
2018-01-10 01:30:02 +08:00
{
auto ret = ValueType();
2018-01-10 01:30:02 +08:00
JSONSerializer<ValueType>::from_json(*this, ret);
return ret;
}
/*!
@brief get a value (explicit); special case
Explicit type conversion between the JSON value and a compatible value
which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
2018-01-10 01:30:02 +08:00
The value is converted by calling the @ref json_serializer<ValueType>
`from_json()` method.
The function is equivalent to executing
@code {.cpp}
return JSONSerializer<ValueType>::from_json(*this);
2018-01-10 01:30:02 +08:00
@endcode
This overloads is chosen if:
- @a ValueType is not @ref basic_json and
- @ref json_serializer<ValueType> has a `from_json()` method of the form
`ValueType from_json(const basic_json&)`
@note If @ref json_serializer<ValueType> has both overloads of
`from_json()`, this one is chosen.
@tparam ValueType the returned value type
@return copy of the JSON value, converted to @a ValueType
@throw what @ref json_serializer<ValueType> `from_json()` method throws
@since version 2.1.0
*/
template < typename ValueType,
detail::enable_if_t <
detail::has_non_default_from_json<basic_json_t, ValueType>::value,
int > = 0 >
ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
2018-01-10 01:30:02 +08:00
{
return JSONSerializer<ValueType>::from_json(*this);
2018-01-10 01:30:02 +08:00
}
/*!
@brief get special-case overload
This overloads converts the current @ref basic_json in a different
@ref basic_json type
@tparam BasicJsonType == @ref basic_json
@return a copy of *this, converted into @a BasicJsonType
@complexity Depending on the implementation of the called `from_json()`
method.
@since version 3.2.0
*/
template < typename BasicJsonType,
detail::enable_if_t <
detail::is_basic_json<BasicJsonType>::value,
int > = 0 >
BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
{
return *this;
}
/*!
@brief get special-case overload
This overloads avoids a lot of template boilerplate, it can be seen as the
identity method
@tparam BasicJsonType == @ref basic_json
@return a copy of *this
@complexity Constant.
@since version 2.1.0
*/
template<typename BasicJsonType,
detail::enable_if_t<
std::is_same<BasicJsonType, basic_json_t>::value,
int> = 0>
basic_json get_impl(detail::priority_tag<3> /*unused*/) const
{
return *this;
}
/*!
@brief get a pointer value (explicit)
@copydoc get()
*/
template<typename PointerType,
detail::enable_if_t<
std::is_pointer<PointerType>::value,
int> = 0>
constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
-> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
2019-04-01 19:32:06 +08:00
{
// delegate the call to get_ptr
return get_ptr<PointerType>();
2019-04-01 19:32:06 +08:00
}
public:
2018-01-10 01:30:02 +08:00
/*!
@brief get a (pointer) value (explicit)
2018-01-10 01:30:02 +08:00
Performs explicit type conversion between the JSON value and a compatible value if required.
2018-01-10 01:30:02 +08:00
- If the requested type is a pointer to the internally stored JSON value that pointer is returned.
No copies are made.
2018-01-10 01:30:02 +08:00
- If the requested type is the current @ref basic_json, or a different @ref basic_json convertible
from the current @ref basic_json.
2018-01-10 01:30:02 +08:00
- Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()`
method.
2018-01-10 01:30:02 +08:00
@tparam ValueTypeCV the provided value type
@tparam ValueType the returned value type
2018-01-10 01:30:02 +08:00
@return copy of the JSON value, converted to @tparam ValueType if necessary
2018-01-10 01:30:02 +08:00
@throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required
2018-01-10 01:30:02 +08:00
@since version 2.1.0
2018-01-10 01:30:02 +08:00
*/
template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
#if defined(JSON_HAS_CPP_14)
constexpr
#endif
auto get() const noexcept(
noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
-> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
2018-01-10 01:30:02 +08:00
{
// we cannot static_assert on ValueTypeCV being non-const, because
// there is support for get<const basic_json_t>(), which is why we
// still need the uncvref
static_assert(!std::is_reference<ValueTypeCV>::value,
"get() cannot be used with reference types, you might want to use get_ref()");
return get_impl<ValueType>(detail::priority_tag<4> {});
2018-01-10 01:30:02 +08:00
}
/*!
@brief get a pointer value (explicit)
2018-01-10 01:30:02 +08:00
Explicit pointer access to the internally stored JSON value. No copies are
2018-01-10 01:30:02 +08:00
made.
@warning The pointer becomes invalid if the underlying JSON object
changes.
2018-01-10 01:30:02 +08:00
@tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
@ref number_unsigned_t, or @ref number_float_t.
2018-01-10 01:30:02 +08:00
@return pointer to the internally stored JSON value if the requested
pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
@complexity Constant.
@liveexample{The example below shows how pointers to internal values of a
JSON value can be requested. Note that no type conversions are made and a
`nullptr` is returned if the value and the requested pointer type does not
match.,get__PointerType}
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
@sa see @ref get_ptr() for explicit pointer-member access
2018-01-10 01:30:02 +08:00
@since version 1.0.0
*/
template<typename PointerType, typename std::enable_if<
std::is_pointer<PointerType>::value, int>::type = 0>
auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
2018-01-10 01:30:02 +08:00
{
// delegate the call to get_ptr
return get_ptr<PointerType>();
2018-01-10 01:30:02 +08:00
}
/// @brief get a value (explicit)
/// @sa https://json.nlohmann.me/api/basic_json/get_to/
template < typename ValueType,
detail::enable_if_t <
!detail::is_basic_json<ValueType>::value&&
detail::has_from_json<basic_json_t, ValueType>::value,
int > = 0 >
ValueType & get_to(ValueType& v) const noexcept(noexcept(
JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
2018-01-10 01:30:02 +08:00
{
JSONSerializer<ValueType>::from_json(*this, v);
return v;
}
// specialization to allow calling get_to with a basic_json value
// see https://github.com/nlohmann/json/issues/2175
template<typename ValueType,
detail::enable_if_t <
detail::is_basic_json<ValueType>::value,
int> = 0>
ValueType & get_to(ValueType& v) const
{
v = *this;
return v;
}
template <
typename T, std::size_t N,
typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
detail::enable_if_t <
detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
noexcept(noexcept(JSONSerializer<Array>::from_json(
std::declval<const basic_json_t&>(), v)))
{
JSONSerializer<Array>::from_json(*this, v);
return v;
2018-01-10 01:30:02 +08:00
}
/// @brief get a reference value (implicit)
/// @sa https://json.nlohmann.me/api/basic_json/get_ref/
2018-01-10 01:30:02 +08:00
template<typename ReferenceType, typename std::enable_if<
std::is_reference<ReferenceType>::value, int>::type = 0>
ReferenceType get_ref()
{
// delegate call to get_ref_impl
return get_ref_impl<ReferenceType>(*this);
}
/// @brief get a reference value (implicit)
/// @sa https://json.nlohmann.me/api/basic_json/get_ref/
template < typename ReferenceType, typename std::enable_if <
std::is_reference<ReferenceType>::value&&
std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
2018-01-10 01:30:02 +08:00
ReferenceType get_ref() const
{
// delegate call to get_ref_impl
return get_ref_impl<ReferenceType>(*this);
}
/*!
@brief get a value (implicit)
Implicit type conversion between the JSON value and a compatible value.
The call is realized by calling @ref get() const.
@tparam ValueType non-pointer type compatible to the JSON value, for
instance `int` for JSON integer numbers, `bool` for JSON booleans, or
`std::vector` types for JSON arrays. The character type of @ref string_t
as well as an initializer list of this type is excluded to avoid
ambiguities as these types implicitly convert to `std::string`.
@return copy of the JSON value, converted to type @a ValueType
@throw type_error.302 in case passed type @a ValueType is incompatible
to the JSON value type (e.g., the JSON value is of type boolean, but a
string is requested); see example below
@complexity Linear in the size of the JSON value.
@liveexample{The example below shows several conversions from JSON values
to other types. There a few things to note: (1) Floating-point numbers can
be converted to integers\, (2) A JSON array can be converted to a standard
`std::vector<short>`\, (3) A JSON object can be converted to C++
associative containers such as `std::unordered_map<std::string\,
json>`.,operator__ValueType}
@since version 1.0.0
*/
template < typename ValueType, typename std::enable_if <
detail::conjunction <
detail::negation<std::is_pointer<ValueType>>,
detail::negation<std::is_same<ValueType, std::nullptr_t>>,
detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
detail::negation<detail::is_basic_json<ValueType>>,
detail::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>,
#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
detail::negation<std::is_same<ValueType, std::string_view>>,
#endif
#if defined(JSON_HAS_CPP_17)
detail::negation<std::is_same<ValueType, std::any>>,
2018-01-10 01:30:02 +08:00
#endif
detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType>
>::value, int >::type = 0 >
JSON_EXPLICIT operator ValueType() const
2018-01-10 01:30:02 +08:00
{
// delegate the call to get<>() const
return get<ValueType>();
}
/// @brief get a binary value
/// @sa https://json.nlohmann.me/api/basic_json/get_binary/
binary_t& get_binary()
{
if (!is_binary())
{
JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
}
return *get_ptr<binary_t*>();
}
/// @brief get a binary value
/// @sa https://json.nlohmann.me/api/basic_json/get_binary/
const binary_t& get_binary() const
{
if (!is_binary())
{
JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
}
return *get_ptr<const binary_t*>();
}
2018-01-10 01:30:02 +08:00
/// @}
////////////////////
// element access //
////////////////////
/// @name element access
/// Access to the JSON value.
/// @{
/// @brief access specified array element with bounds checking
/// @sa https://json.nlohmann.me/api/basic_json/at/
2018-01-10 01:30:02 +08:00
reference at(size_type idx)
{
// at only works for arrays
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(is_array()))
2018-01-10 01:30:02 +08:00
{
JSON_TRY
{
2021-01-15 04:55:49 +08:00
return set_parent(m_value.array->at(idx));
2018-01-10 01:30:02 +08:00
}
JSON_CATCH (std::out_of_range&)
{
// create better exception explanation
JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
2018-01-10 01:30:02 +08:00
}
}
else
{
JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
}
/// @brief access specified array element with bounds checking
/// @sa https://json.nlohmann.me/api/basic_json/at/
2018-01-10 01:30:02 +08:00
const_reference at(size_type idx) const
{
// at only works for arrays
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(is_array()))
2018-01-10 01:30:02 +08:00
{
JSON_TRY
{
return m_value.array->at(idx);
}
JSON_CATCH (std::out_of_range&)
{
// create better exception explanation
JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
2018-01-10 01:30:02 +08:00
}
}
else
{
JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
}
/// @brief access specified object element with bounds checking
/// @sa https://json.nlohmann.me/api/basic_json/at/
2018-01-10 01:30:02 +08:00
reference at(const typename object_t::key_type& key)
{
// at only works for objects
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
if (JSON_HEDLEY_UNLIKELY(!is_object()))
2018-01-10 01:30:02 +08:00
{
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
auto it = m_value.object->find(key);
if (it == m_value.object->end())
{
JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
}
return set_parent(it->second);
}
/// @brief access specified object element with bounds checking
/// @sa https://json.nlohmann.me/api/basic_json/at/
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<basic_json_t, KeyType>::value, int> = 0>
reference at(KeyType && key)
{
// at only works for objects
if (JSON_HEDLEY_UNLIKELY(!is_object()))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
auto it = m_value.object->find(std::forward<KeyType>(key));
if (it == m_value.object->end())
{
JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
}
return set_parent(it->second);
2018-01-10 01:30:02 +08:00
}
/// @brief access specified object element with bounds checking
/// @sa https://json.nlohmann.me/api/basic_json/at/
2018-01-10 01:30:02 +08:00
const_reference at(const typename object_t::key_type& key) const
{
// at only works for objects
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
if (JSON_HEDLEY_UNLIKELY(!is_object()))
2018-01-10 01:30:02 +08:00
{
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
auto it = m_value.object->find(key);
if (it == m_value.object->end())
{
JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
}
return it->second;
}
/// @brief access specified object element with bounds checking
/// @sa https://json.nlohmann.me/api/basic_json/at/
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<basic_json_t, KeyType>::value, int> = 0>
const_reference at(KeyType && key) const
{
// at only works for objects
if (JSON_HEDLEY_UNLIKELY(!is_object()))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
auto it = m_value.object->find(std::forward<KeyType>(key));
if (it == m_value.object->end())
{
JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
}
return it->second;
2018-01-10 01:30:02 +08:00
}
/// @brief access specified array element
/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
2018-01-10 01:30:02 +08:00
reference operator[](size_type idx)
{
// implicitly convert null value to an empty array
if (is_null())
{
m_type = value_t::array;
m_value.array = create<array_t>();
assert_invariant();
}
// operator[] only works for arrays
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(is_array()))
2018-01-10 01:30:02 +08:00
{
// fill up array with null values if given idx is outside range
if (idx >= m_value.array->size())
{
2021-01-08 18:21:41 +08:00
#if JSON_DIAGNOSTICS
// remember array size & capacity before resizing
const auto old_size = m_value.array->size();
const auto old_capacity = m_value.array->capacity();
2021-01-08 18:21:41 +08:00
#endif
m_value.array->resize(idx + 1);
2021-01-15 23:58:05 +08:00
#if JSON_DIAGNOSTICS
if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
{
// capacity has changed: update all parents
set_parents();
}
else
{
// set parent for values added above
set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
}
2021-01-15 23:58:05 +08:00
#endif
assert_invariant();
2018-01-10 01:30:02 +08:00
}
return m_value.array->operator[](idx);
}
JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
/// @brief access specified array element
/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
2018-01-10 01:30:02 +08:00
const_reference operator[](size_type idx) const
{
// const operator[] only works for arrays
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(is_array()))
2018-01-10 01:30:02 +08:00
{
return m_value.array->operator[](idx);
}
JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
/// @brief access specified object element
/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
reference operator[](typename object_t::key_type key)
2018-01-10 01:30:02 +08:00
{
// implicitly convert null value to an empty object
if (is_null())
{
m_type = value_t::object;
m_value.object = create<object_t>();
assert_invariant();
}
// operator[] only works for objects
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(is_object()))
2018-01-10 01:30:02 +08:00
{
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
auto result = m_value.object->emplace(std::move(key), nullptr);
return set_parent(result.first->second);
2018-01-10 01:30:02 +08:00
}
JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
/// @brief access specified object element
/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
2018-01-10 01:30:02 +08:00
const_reference operator[](const typename object_t::key_type& key) const
{
// const operator[] only works for objects
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(is_object()))
2018-01-10 01:30:02 +08:00
{
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
auto it = m_value.object->find(key);
JSON_ASSERT(it != m_value.object->end());
return it->second;
2018-01-10 01:30:02 +08:00
}
JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
// these two functions resolve a (const) char * ambiguity affecting Clang and MSVC
// (they seemingly cannot be constrained to resolve the ambiguity)
2018-01-10 01:30:02 +08:00
template<typename T>
reference operator[](T* key)
{
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
return operator[](typename object_t::key_type(key));
}
template<typename T>
const_reference operator[](T* key) const
{
return operator[](typename object_t::key_type(key));
}
/// @brief access specified object element
/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<basic_json_t, KeyType>::value, int > = 0 >
reference operator[](KeyType && key)
{
// implicitly convert null value to an empty object
2018-01-10 01:30:02 +08:00
if (is_null())
{
m_type = value_t::object;
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
m_value.object = create<object_t>();
2018-01-10 01:30:02 +08:00
assert_invariant();
}
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
// operator[] only works for objects
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(is_object()))
2018-01-10 01:30:02 +08:00
{
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
auto result = m_value.object->emplace(std::forward<KeyType>(key), nullptr);
return set_parent(result.first->second);
2018-01-10 01:30:02 +08:00
}
JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
/// @brief access specified object element
/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<basic_json_t, KeyType>::value, int > = 0 >
const_reference operator[](KeyType && key) const
2018-01-10 01:30:02 +08:00
{
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
// const operator[] only works for objects
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(is_object()))
2018-01-10 01:30:02 +08:00
{
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
auto it = m_value.object->find(std::forward<KeyType>(key));
JSON_ASSERT(it != m_value.object->end());
return it->second;
2018-01-10 01:30:02 +08:00
}
JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
/// @brief access specified object element with default value
/// @sa https://json.nlohmann.me/api/basic_json/value/
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
// this is the value(const typename object_t::key_type&) overload
template < class KeyType, class ValueType, detail::enable_if_t <
std::is_same<KeyType, typename object_t::key_type>::value
&& detail::is_getable<basic_json_t, ValueType>::value
&& !std::is_same<value_t, ValueType>::value, int > = 0 >
typename std::decay<ValueType>::type value(const KeyType& key, ValueType && default_value) const
{
// value only works for objects
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(is_object()))
2018-01-10 01:30:02 +08:00
{
// if key is found, return value and given default value otherwise
const auto it = find(key);
if (it != end())
{
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
return it->template get<typename std::decay<ValueType>::type>();
2018-01-10 01:30:02 +08:00
}
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
return std::forward<ValueType>(default_value);
2018-01-10 01:30:02 +08:00
}
JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
/// @brief access specified object element with default value
/// @sa https://json.nlohmann.me/api/basic_json/value/
/// overload for a default value of type const char*
2018-01-10 01:30:02 +08:00
string_t value(const typename object_t::key_type& key, const char* default_value) const
{
2020-07-08 20:02:28 +08:00
return value(key, string_t(default_value));
2018-01-10 01:30:02 +08:00
}
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
// these two functions, in conjunction with value(const KeyType &, ValueType &&),
// resolve an ambiguity that would otherwise occur between the json_pointer and
// typename object_t::key_type & overloads
template < class ValueType, detail::enable_if_t <
detail::is_getable<basic_json_t, ValueType>::value
&& !std::is_same<value_t, ValueType>::value, int > = 0 >
typename std::decay<ValueType>::type value(const char* key, ValueType && default_value) const
{
return value(typename object_t::key_type(key), std::forward<ValueType>(default_value));
}
string_t value(const char* key, const char* default_value) const
{
return value(typename object_t::key_type(key), string_t(default_value));
}
/// @brief access specified object element with default value
/// @sa https://json.nlohmann.me/api/basic_json/value/
/// using std::is_convertible in a std::enable_if will fail when using explicit conversions
template < class KeyType, class ValueType, detail::enable_if_t <
detail::is_getable<basic_json_t, ValueType>::value
&& !std::is_same<value_t, ValueType>::value
&& detail::is_usable_as_key_type<basic_json_t, KeyType>::value, int > = 0 >
typename std::decay<ValueType>::type value(KeyType && key, ValueType && default_value) const
{
// value only works for objects
if (JSON_HEDLEY_LIKELY(is_object()))
{
// if key is found, return value and given default value otherwise
const auto it = find(std::forward<KeyType>(key));
if (it != end())
{
return it->template get<typename std::decay<ValueType>::type>();
}
return std::forward<ValueType>(default_value);
}
JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
}
/// @brief access specified object element with default value
/// @sa https://json.nlohmann.me/api/basic_json/value/
/// overload for a default value of type const char*
template < class KeyType, detail::enable_if_t <
!detail::is_json_pointer<KeyType>::value, int > = 0 >
string_t value(KeyType && key, const char* default_value) const
{
return value(std::forward<KeyType>(key), string_t(default_value));
}
/// @brief access specified object element via JSON Pointer with default value
/// @sa https://json.nlohmann.me/api/basic_json/value/
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
template < class ValueType, detail::enable_if_t <
detail::is_getable<basic_json_t, ValueType>::value, int> = 0 >
2020-07-08 20:02:28 +08:00
ValueType value(const json_pointer& ptr, const ValueType& default_value) const
2018-01-10 01:30:02 +08:00
{
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
// value only works for objects
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(is_object()))
2018-01-10 01:30:02 +08:00
{
// if pointer resolves a value, return it or use default value
JSON_TRY
{
return ptr.get_checked(this).template get<ValueType>();
2018-01-10 01:30:02 +08:00
}
JSON_INTERNAL_CATCH (out_of_range&)
2018-01-10 01:30:02 +08:00
{
2020-07-08 20:02:28 +08:00
return default_value;
2018-01-10 01:30:02 +08:00
}
}
JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
}
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
template < class ValueType, class BasicJsonType, detail::enable_if_t <
detail::is_getable<basic_json_t, ValueType>::value, int> = 0 >
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
{
return value(ptr.convert(), default_value);
2018-01-10 01:30:02 +08:00
}
/// @brief access specified object element via JSON Pointer with default value
/// @sa https://json.nlohmann.me/api/basic_json/value/
/// overload for a default value of type const char*
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_NON_NULL(3)
2018-01-10 01:30:02 +08:00
string_t value(const json_pointer& ptr, const char* default_value) const
{
2020-07-08 20:02:28 +08:00
return value(ptr, string_t(default_value));
2018-01-10 01:30:02 +08:00
}
template<typename BasicJsonType>
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
JSON_HEDLEY_NON_NULL(3)
string_t value(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr, const char* default_value) const
{
return value(ptr.convert(), default_value);
}
/// @brief access the first element
/// @sa https://json.nlohmann.me/api/basic_json/front/
2018-01-10 01:30:02 +08:00
reference front()
{
return *begin();
}
/// @brief access the first element
/// @sa https://json.nlohmann.me/api/basic_json/front/
2018-01-10 01:30:02 +08:00
const_reference front() const
{
return *cbegin();
}
/// @brief access the last element
/// @sa https://json.nlohmann.me/api/basic_json/back/
2018-01-10 01:30:02 +08:00
reference back()
{
auto tmp = end();
--tmp;
return *tmp;
}
/// @brief access the last element
/// @sa https://json.nlohmann.me/api/basic_json/back/
2018-01-10 01:30:02 +08:00
const_reference back() const
{
auto tmp = cend();
--tmp;
return *tmp;
}
/// @brief remove element given an iterator
/// @sa https://json.nlohmann.me/api/basic_json/erase/
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
template < class IteratorType, detail::enable_if_t <
std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
2018-01-10 01:30:02 +08:00
IteratorType erase(IteratorType pos)
{
// make sure iterator fits the current value
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
2018-01-10 01:30:02 +08:00
}
IteratorType result = end();
switch (m_type)
{
case value_t::boolean:
case value_t::number_float:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::string:
case value_t::binary:
2018-01-10 01:30:02 +08:00
{
if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
2018-01-10 01:30:02 +08:00
}
if (is_string())
{
AllocatorType<string_t> alloc;
std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
m_value.string = nullptr;
}
else if (is_binary())
{
AllocatorType<binary_t> alloc;
std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
m_value.binary = nullptr;
}
2018-01-10 01:30:02 +08:00
m_type = value_t::null;
assert_invariant();
break;
}
case value_t::object:
{
result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
break;
}
case value_t::array:
{
result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
break;
}
case value_t::null:
case value_t::discarded:
2018-01-10 01:30:02 +08:00
default:
JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
return result;
}
/// @brief remove elements given an iterator range
/// @sa https://json.nlohmann.me/api/basic_json/erase/
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
template < class IteratorType, detail::enable_if_t <
std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
2018-01-10 01:30:02 +08:00
IteratorType erase(IteratorType first, IteratorType last)
{
// make sure iterator fits the current value
if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
2018-01-10 01:30:02 +08:00
}
IteratorType result = end();
switch (m_type)
{
case value_t::boolean:
case value_t::number_float:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::string:
case value_t::binary:
2018-01-10 01:30:02 +08:00
{
if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
|| !last.m_it.primitive_iterator.is_end()))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
2018-01-10 01:30:02 +08:00
}
if (is_string())
{
AllocatorType<string_t> alloc;
std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
m_value.string = nullptr;
}
else if (is_binary())
{
AllocatorType<binary_t> alloc;
std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
m_value.binary = nullptr;
}
2018-01-10 01:30:02 +08:00
m_type = value_t::null;
assert_invariant();
break;
}
case value_t::object:
{
result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
last.m_it.object_iterator);
break;
}
case value_t::array:
{
result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
last.m_it.array_iterator);
break;
}
case value_t::null:
case value_t::discarded:
2018-01-10 01:30:02 +08:00
default:
JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
return result;
}
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
private:
template < typename KeyType, detail::enable_if_t <
detail::has_erase_with_key_type<basic_json_t, KeyType>::value, int > = 0 >
size_type erase_internal(KeyType && key)
{
// this erase only works for objects
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
if (JSON_HEDLEY_UNLIKELY(!is_object()))
{
JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
}
return m_value.object->erase(std::forward<KeyType>(key));
}
template < typename KeyType, detail::enable_if_t <
!detail::has_erase_with_key_type<basic_json_t, KeyType>::value, int > = 0 >
size_type erase_internal(KeyType && key)
{
// this erase only works for objects
if (JSON_HEDLEY_UNLIKELY(!is_object()))
{
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
}
2018-01-10 01:30:02 +08:00
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
const auto it = m_value.object->find(std::forward<KeyType>(key));
if (it != m_value.object->end())
{
m_value.object->erase(it);
return 1;
}
return 0;
}
public:
/// @brief remove element from a JSON object given a key
/// @sa https://json.nlohmann.me/api/basic_json/erase/
size_type erase(const typename object_t::key_type& key)
{
// the indirection via erase_internal() is added to avoid making this
// function a template and thus de-rank it during overload resolution
return erase_internal(key);
}
/// @brief remove element from a JSON object given a key
/// @sa https://json.nlohmann.me/api/basic_json/erase/
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<basic_json_t, KeyType>::value, int> = 0>
size_type erase(KeyType && key)
{
return erase_internal(std::forward<KeyType>(key));
}
2018-01-10 01:30:02 +08:00
/// @brief remove element from a JSON array given an index
/// @sa https://json.nlohmann.me/api/basic_json/erase/
2018-01-10 01:30:02 +08:00
void erase(const size_type idx)
{
// this erase only works for arrays
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(is_array()))
2018-01-10 01:30:02 +08:00
{
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_UNLIKELY(idx >= size()))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
2018-01-10 01:30:02 +08:00
}
m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
}
else
{
JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
}
/// @}
////////////
// lookup //
////////////
/// @name lookup
/// @{
/// @brief find an element in a JSON object
/// @sa https://json.nlohmann.me/api/basic_json/find/
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
iterator find(const typename object_t::key_type& key)
{
auto result = end();
if (is_object())
{
result.m_it.object_iterator = m_value.object->find(key);
}
return result;
}
/// @brief find an element in a JSON object
/// @sa https://json.nlohmann.me/api/basic_json/find/
const_iterator find(const typename object_t::key_type& key) const
{
auto result = cend();
if (is_object())
{
result.m_it.object_iterator = m_value.object->find(key);
}
return result;
}
/// @brief find an element in a JSON object
/// @sa https://json.nlohmann.me/api/basic_json/find/
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<basic_json_t, KeyType>::value, int> = 0>
iterator find(KeyType && key)
2018-01-10 01:30:02 +08:00
{
auto result = end();
if (is_object())
{
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key));
2018-01-10 01:30:02 +08:00
}
return result;
}
/// @brief find an element in a JSON object
/// @sa https://json.nlohmann.me/api/basic_json/find/
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<basic_json_t, KeyType>::value, int> = 0>
const_iterator find(KeyType && key) const
2018-01-10 01:30:02 +08:00
{
auto result = cend();
if (is_object())
{
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key));
2018-01-10 01:30:02 +08:00
}
return result;
}
/// @brief returns the number of occurrences of a key in a JSON object
/// @sa https://json.nlohmann.me/api/basic_json/count/
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
size_type count(const typename object_t::key_type& key) const
{
// return 0 for all nonobject types
return is_object() ? m_value.object->count(key) : 0;
}
/// @brief returns the number of occurrences of a key in a JSON object
/// @sa https://json.nlohmann.me/api/basic_json/count/
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<basic_json_t, KeyType>::value, int> = 0>
size_type count(KeyType && key) const
2018-01-10 01:30:02 +08:00
{
// return 0 for all nonobject types
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
return is_object() ? m_value.object->count(std::forward<KeyType>(key)) : 0;
2018-01-10 01:30:02 +08:00
}
/// @brief check the existence of an element in a JSON object
/// @sa https://json.nlohmann.me/api/basic_json/contains/
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
bool contains(const typename object_t::key_type& key) const
{
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
return is_object() && m_value.object->find(key) != m_value.object->end();
}
/// @brief check the existence of an element in a JSON object
/// @sa https://json.nlohmann.me/api/basic_json/contains/
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<basic_json_t, KeyType>::value, int> = 0>
bool contains(KeyType && key) const
{
return is_object() && m_value.object->find(std::forward<KeyType>(key)) != m_value.object->end();
}
/// @brief check the existence of an element in a JSON object given a JSON pointer
/// @sa https://json.nlohmann.me/api/basic_json/contains/
bool contains(const json_pointer& ptr) const
{
return ptr.contains(this);
}
template<typename BasicJsonType>
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
bool contains(const typename ::nlohmann::json_pointer<BasicJsonType> ptr) const
{
return ptr.contains(this);
}
2018-01-10 01:30:02 +08:00
/// @}
///////////////
// iterators //
///////////////
/// @name iterators
/// @{
/// @brief returns an iterator to the first element
/// @sa https://json.nlohmann.me/api/basic_json/begin/
2018-01-10 01:30:02 +08:00
iterator begin() noexcept
{
iterator result(this);
result.set_begin();
return result;
}
/// @brief returns an iterator to the first element
/// @sa https://json.nlohmann.me/api/basic_json/begin/
2018-01-10 01:30:02 +08:00
const_iterator begin() const noexcept
{
return cbegin();
}
/// @brief returns a const iterator to the first element
/// @sa https://json.nlohmann.me/api/basic_json/cbegin/
2018-01-10 01:30:02 +08:00
const_iterator cbegin() const noexcept
{
const_iterator result(this);
result.set_begin();
return result;
}
/// @brief returns an iterator to one past the last element
/// @sa https://json.nlohmann.me/api/basic_json/end/
2018-01-10 01:30:02 +08:00
iterator end() noexcept
{
iterator result(this);
result.set_end();
return result;
}
/// @brief returns an iterator to one past the last element
/// @sa https://json.nlohmann.me/api/basic_json/end/
2018-01-10 01:30:02 +08:00
const_iterator end() const noexcept
{
return cend();
}
/// @brief returns an iterator to one past the last element
/// @sa https://json.nlohmann.me/api/basic_json/cend/
2018-01-10 01:30:02 +08:00
const_iterator cend() const noexcept
{
const_iterator result(this);
result.set_end();
return result;
}
/// @brief returns an iterator to the reverse-beginning
/// @sa https://json.nlohmann.me/api/basic_json/rbegin/
2018-01-10 01:30:02 +08:00
reverse_iterator rbegin() noexcept
{
return reverse_iterator(end());
}
/// @brief returns an iterator to the reverse-beginning
/// @sa https://json.nlohmann.me/api/basic_json/rbegin/
2018-01-10 01:30:02 +08:00
const_reverse_iterator rbegin() const noexcept
{
return crbegin();
}
/// @brief returns an iterator to the reverse-end
/// @sa https://json.nlohmann.me/api/basic_json/rend/
2018-01-10 01:30:02 +08:00
reverse_iterator rend() noexcept
{
return reverse_iterator(begin());
}
/// @brief returns an iterator to the reverse-end
/// @sa https://json.nlohmann.me/api/basic_json/rend/
2018-01-10 01:30:02 +08:00
const_reverse_iterator rend() const noexcept
{
return crend();
}
/// @brief returns a const reverse iterator to the last element
/// @sa https://json.nlohmann.me/api/basic_json/crbegin/
2018-01-10 01:30:02 +08:00
const_reverse_iterator crbegin() const noexcept
{
return const_reverse_iterator(cend());
}
/// @brief returns a const reverse iterator to one before the first
/// @sa https://json.nlohmann.me/api/basic_json/crend/
2018-01-10 01:30:02 +08:00
const_reverse_iterator crend() const noexcept
{
return const_reverse_iterator(cbegin());
}
public:
/// @brief wrapper to access iterator member functions in range-based for
/// @sa https://json.nlohmann.me/api/basic_json/items/
/// @deprecated This function is deprecated since 3.1.0 and will be removed in
/// version 4.0.0 of the library. Please use @ref items() instead;
/// that is, replace `json::iterator_wrapper(j)` with `j.items()`.
2020-06-06 20:30:17 +08:00
JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
2018-01-17 03:41:04 +08:00
static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
2018-01-10 01:30:02 +08:00
{
return ref.items();
2018-01-10 01:30:02 +08:00
}
/// @brief wrapper to access iterator member functions in range-based for
/// @sa https://json.nlohmann.me/api/basic_json/items/
/// @deprecated This function is deprecated since 3.1.0 and will be removed in
/// version 4.0.0 of the library. Please use @ref items() instead;
/// that is, replace `json::iterator_wrapper(j)` with `j.items()`.
2020-06-06 20:30:17 +08:00
JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
2018-01-17 03:41:04 +08:00
static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
2018-01-10 01:30:02 +08:00
{
return ref.items();
2018-01-10 01:30:02 +08:00
}
/// @brief helper to access iterator member functions in range-based for
/// @sa https://json.nlohmann.me/api/basic_json/items/
2018-01-17 03:41:04 +08:00
iteration_proxy<iterator> items() noexcept
2018-01-10 01:30:02 +08:00
{
return iteration_proxy<iterator>(*this);
}
/// @brief helper to access iterator member functions in range-based for
/// @sa https://json.nlohmann.me/api/basic_json/items/
2018-01-17 03:41:04 +08:00
iteration_proxy<const_iterator> items() const noexcept
2018-01-10 01:30:02 +08:00
{
return iteration_proxy<const_iterator>(*this);
}
/// @}
//////////////
// capacity //
//////////////
/// @name capacity
/// @{
/// @brief checks whether the container is empty.
/// @sa https://json.nlohmann.me/api/basic_json/empty/
2018-01-10 01:30:02 +08:00
bool empty() const noexcept
{
switch (m_type)
{
case value_t::null:
{
// null values are empty
return true;
}
case value_t::array:
{
// delegate call to array_t::empty()
return m_value.array->empty();
}
case value_t::object:
{
// delegate call to object_t::empty()
return m_value.object->empty();
}
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
2018-01-10 01:30:02 +08:00
default:
{
// all other types are nonempty
return false;
}
}
}
/// @brief returns the number of elements
/// @sa https://json.nlohmann.me/api/basic_json/size/
2018-01-10 01:30:02 +08:00
size_type size() const noexcept
{
switch (m_type)
{
case value_t::null:
{
// null values are empty
return 0;
}
case value_t::array:
{
// delegate call to array_t::size()
return m_value.array->size();
}
case value_t::object:
{
// delegate call to object_t::size()
return m_value.object->size();
}
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
2018-01-10 01:30:02 +08:00
default:
{
// all other types have size 1
return 1;
}
}
}
/// @brief returns the maximum possible number of elements
/// @sa https://json.nlohmann.me/api/basic_json/max_size/
2018-01-10 01:30:02 +08:00
size_type max_size() const noexcept
{
switch (m_type)
{
case value_t::array:
{
// delegate call to array_t::max_size()
return m_value.array->max_size();
}
case value_t::object:
{
// delegate call to object_t::max_size()
return m_value.object->max_size();
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
2018-01-10 01:30:02 +08:00
default:
{
// all other types have max_size() == size()
return size();
}
}
}
/// @}
///////////////
// modifiers //
///////////////
/// @name modifiers
/// @{
/// @brief clears the contents
/// @sa https://json.nlohmann.me/api/basic_json/clear/
2018-01-10 01:30:02 +08:00
void clear() noexcept
{
switch (m_type)
{
case value_t::number_integer:
{
m_value.number_integer = 0;
break;
}
case value_t::number_unsigned:
{
m_value.number_unsigned = 0;
break;
}
case value_t::number_float:
{
m_value.number_float = 0.0;
break;
}
case value_t::boolean:
{
m_value.boolean = false;
break;
}
case value_t::string:
{
m_value.string->clear();
break;
}
case value_t::binary:
{
m_value.binary->clear();
break;
}
2018-01-10 01:30:02 +08:00
case value_t::array:
{
m_value.array->clear();
break;
}
case value_t::object:
{
m_value.object->clear();
break;
}
case value_t::null:
case value_t::discarded:
2018-01-10 01:30:02 +08:00
default:
break;
}
}
/// @brief add an object to an array
/// @sa https://json.nlohmann.me/api/basic_json/push_back/
2018-01-10 01:30:02 +08:00
void push_back(basic_json&& val)
{
// push_back only works for null objects or arrays
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
// transform null object into an array
if (is_null())
{
m_type = value_t::array;
m_value = value_t::array;
assert_invariant();
}
// add element to array (move semantics)
const auto old_capacity = m_value.array->capacity();
2018-01-10 01:30:02 +08:00
m_value.array->push_back(std::move(val));
set_parent(m_value.array->back(), old_capacity);
// if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
2018-01-10 01:30:02 +08:00
}
/// @brief add an object to an array
/// @sa https://json.nlohmann.me/api/basic_json/operator+=/
2018-01-10 01:30:02 +08:00
reference operator+=(basic_json&& val)
{
push_back(std::move(val));
return *this;
}
/// @brief add an object to an array
/// @sa https://json.nlohmann.me/api/basic_json/push_back/
2018-01-10 01:30:02 +08:00
void push_back(const basic_json& val)
{
// push_back only works for null objects or arrays
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
// transform null object into an array
if (is_null())
{
m_type = value_t::array;
m_value = value_t::array;
assert_invariant();
}
// add element to array
const auto old_capacity = m_value.array->capacity();
2018-01-10 01:30:02 +08:00
m_value.array->push_back(val);
set_parent(m_value.array->back(), old_capacity);
2018-01-10 01:30:02 +08:00
}
/// @brief add an object to an array
/// @sa https://json.nlohmann.me/api/basic_json/operator+=/
2018-01-10 01:30:02 +08:00
reference operator+=(const basic_json& val)
{
push_back(val);
return *this;
}
/// @brief add an object to an object
/// @sa https://json.nlohmann.me/api/basic_json/push_back/
2018-01-10 01:30:02 +08:00
void push_back(const typename object_t::value_type& val)
{
// push_back only works for null objects or objects
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
// transform null object into an object
if (is_null())
{
m_type = value_t::object;
m_value = value_t::object;
assert_invariant();
}
2021-01-02 00:23:10 +08:00
// add element to object
auto res = m_value.object->insert(val);
2021-01-15 04:55:49 +08:00
set_parent(res.first->second);
2018-01-10 01:30:02 +08:00
}
/// @brief add an object to an object
/// @sa https://json.nlohmann.me/api/basic_json/operator+=/
2018-01-10 01:30:02 +08:00
reference operator+=(const typename object_t::value_type& val)
{
push_back(val);
return *this;
}
/// @brief add an object to an object
/// @sa https://json.nlohmann.me/api/basic_json/push_back/
2018-01-10 01:30:02 +08:00
void push_back(initializer_list_t init)
{
if (is_object() && init.size() == 2 && (*init.begin())->is_string())
2018-01-10 01:30:02 +08:00
{
basic_json&& key = init.begin()->moved_or_copied();
push_back(typename object_t::value_type(
std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
}
else
{
push_back(basic_json(init));
}
}
/// @brief add an object to an object
/// @sa https://json.nlohmann.me/api/basic_json/operator+=/
2018-01-10 01:30:02 +08:00
reference operator+=(initializer_list_t init)
{
push_back(init);
return *this;
}
/// @brief add an object to an array
/// @sa https://json.nlohmann.me/api/basic_json/emplace_back/
2018-01-10 01:30:02 +08:00
template<class... Args>
reference emplace_back(Args&& ... args)
2018-01-10 01:30:02 +08:00
{
// emplace_back only works for null objects or arrays
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
// transform null object into an array
if (is_null())
{
m_type = value_t::array;
m_value = value_t::array;
assert_invariant();
}
// add element to array (perfect forwarding)
const auto old_capacity = m_value.array->capacity();
2018-01-10 01:30:02 +08:00
m_value.array->emplace_back(std::forward<Args>(args)...);
return set_parent(m_value.array->back(), old_capacity);
2018-01-10 01:30:02 +08:00
}
/// @brief add an object to an object if key does not exist
/// @sa https://json.nlohmann.me/api/basic_json/emplace/
2018-01-10 01:30:02 +08:00
template<class... Args>
std::pair<iterator, bool> emplace(Args&& ... args)
{
// emplace only works for null objects or arrays
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
// transform null object into an object
if (is_null())
{
m_type = value_t::object;
m_value = value_t::object;
assert_invariant();
}
// add element to array (perfect forwarding)
auto res = m_value.object->emplace(std::forward<Args>(args)...);
2021-01-15 04:55:49 +08:00
set_parent(res.first->second);
2018-01-10 01:30:02 +08:00
// create result iterator and set iterator to the result of emplace
auto it = begin();
it.m_it.object_iterator = res.first;
// return pair of iterator and boolean
return {it, res.second};
}
2018-09-26 00:15:29 +08:00
/// Helper for insertion of an iterator
/// @note: This uses std::distance to support GCC 4.8,
/// see https://github.com/nlohmann/json/pull/1257
template<typename... Args>
2021-07-12 21:24:06 +08:00
iterator insert_iterator(const_iterator pos, Args&& ... args)
{
iterator result(this);
JSON_ASSERT(m_value.array != nullptr);
auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
result.m_it.array_iterator = m_value.array->begin() + insert_pos;
2018-09-26 00:15:29 +08:00
// This could have been written as:
// result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
2018-09-26 00:15:29 +08:00
// but the return value of insert is missing in GCC 4.8, so it is written this way instead.
2021-07-12 21:24:06 +08:00
set_parents();
return result;
}
/// @brief inserts element into array
/// @sa https://json.nlohmann.me/api/basic_json/insert/
2018-01-10 01:30:02 +08:00
iterator insert(const_iterator pos, const basic_json& val)
{
// insert only works for arrays
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(is_array()))
2018-01-10 01:30:02 +08:00
{
// check if iterator pos fits to this JSON value
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
2018-01-10 01:30:02 +08:00
}
// insert to array and return iterator
2021-07-12 21:24:06 +08:00
return insert_iterator(pos, val);
2018-01-10 01:30:02 +08:00
}
JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
/// @brief inserts element into array
/// @sa https://json.nlohmann.me/api/basic_json/insert/
2018-01-10 01:30:02 +08:00
iterator insert(const_iterator pos, basic_json&& val)
{
return insert(pos, val);
}
/// @brief inserts copies of element into array
/// @sa https://json.nlohmann.me/api/basic_json/insert/
2018-01-10 01:30:02 +08:00
iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
{
// insert only works for arrays
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(is_array()))
2018-01-10 01:30:02 +08:00
{
// check if iterator pos fits to this JSON value
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
2018-01-10 01:30:02 +08:00
}
// insert to array and return iterator
2021-07-12 21:24:06 +08:00
return insert_iterator(pos, cnt, val);
2018-01-10 01:30:02 +08:00
}
JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
/// @brief inserts range of elements into array
/// @sa https://json.nlohmann.me/api/basic_json/insert/
2018-01-10 01:30:02 +08:00
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
{
// insert only works for arrays
if (JSON_HEDLEY_UNLIKELY(!is_array()))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
// check if iterator pos fits to this JSON value
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
2018-01-10 01:30:02 +08:00
}
// check if range iterators belong to the same JSON object
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
2018-01-10 01:30:02 +08:00
}
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
2018-01-10 01:30:02 +08:00
}
// insert to array and return iterator
2021-07-12 21:24:06 +08:00
return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
2018-01-10 01:30:02 +08:00
}
/// @brief inserts elements from initializer list into array
/// @sa https://json.nlohmann.me/api/basic_json/insert/
2018-01-10 01:30:02 +08:00
iterator insert(const_iterator pos, initializer_list_t ilist)
{
// insert only works for arrays
if (JSON_HEDLEY_UNLIKELY(!is_array()))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
// check if iterator pos fits to this JSON value
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
2018-01-10 01:30:02 +08:00
}
// insert to array and return iterator
2021-07-12 21:24:06 +08:00
return insert_iterator(pos, ilist.begin(), ilist.end());
2018-01-10 01:30:02 +08:00
}
/// @brief inserts range of elements into object
/// @sa https://json.nlohmann.me/api/basic_json/insert/
2018-01-10 01:30:02 +08:00
void insert(const_iterator first, const_iterator last)
{
// insert only works for objects
if (JSON_HEDLEY_UNLIKELY(!is_object()))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
// check if range iterators belong to the same JSON object
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
2018-01-10 01:30:02 +08:00
}
// passed iterators must belong to objects
if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
2018-01-10 01:30:02 +08:00
}
m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
}
/// @brief updates a JSON object from another object, overwriting existing keys
/// @sa https://json.nlohmann.me/api/basic_json/update/
void update(const_reference j, bool merge_objects = false)
2018-01-10 01:30:02 +08:00
{
update(j.begin(), j.end(), merge_objects);
2018-01-10 01:30:02 +08:00
}
/// @brief updates a JSON object from another object, overwriting existing keys
/// @sa https://json.nlohmann.me/api/basic_json/update/
void update(const_iterator first, const_iterator last, bool merge_objects = false)
2018-01-10 01:30:02 +08:00
{
// implicitly convert null value to an empty object
if (is_null())
{
m_type = value_t::object;
m_value.object = create<object_t>();
assert_invariant();
}
if (JSON_HEDLEY_UNLIKELY(!is_object()))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
// check if range iterators belong to the same JSON object
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
2018-01-10 01:30:02 +08:00
}
// passed iterators must belong to objects
if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
2018-01-10 01:30:02 +08:00
}
for (auto it = first; it != last; ++it)
{
if (merge_objects && it.value().is_object())
{
auto it2 = m_value.object->find(it.key());
if (it2 != m_value.object->end())
{
it2->second.update(it.value(), true);
continue;
}
}
2018-01-10 01:30:02 +08:00
m_value.object->operator[](it.key()) = it.value();
#if JSON_DIAGNOSTICS
m_value.object->operator[](it.key()).m_parent = this;
#endif
2018-01-10 01:30:02 +08:00
}
}
/// @brief exchanges the values
/// @sa https://json.nlohmann.me/api/basic_json/swap/
2018-01-10 01:30:02 +08:00
void swap(reference other) noexcept (
std::is_nothrow_move_constructible<value_t>::value&&
std::is_nothrow_move_assignable<value_t>::value&&
std::is_nothrow_move_constructible<json_value>::value&&
2018-01-10 01:30:02 +08:00
std::is_nothrow_move_assignable<json_value>::value
)
{
std::swap(m_type, other.m_type);
std::swap(m_value, other.m_value);
2021-01-11 05:40:50 +08:00
2021-01-15 04:55:49 +08:00
set_parents();
2021-01-15 23:54:00 +08:00
other.set_parents();
2018-01-10 01:30:02 +08:00
assert_invariant();
}
/// @brief exchanges the values
/// @sa https://json.nlohmann.me/api/basic_json/swap/
friend void swap(reference left, reference right) noexcept (
std::is_nothrow_move_constructible<value_t>::value&&
std::is_nothrow_move_assignable<value_t>::value&&
std::is_nothrow_move_constructible<json_value>::value&&
std::is_nothrow_move_assignable<json_value>::value
)
{
left.swap(right);
}
/// @brief exchanges the values
/// @sa https://json.nlohmann.me/api/basic_json/swap/
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
void swap(array_t& other) // NOLINT(bugprone-exception-escape)
2018-01-10 01:30:02 +08:00
{
// swap only works for arrays
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(is_array()))
2018-01-10 01:30:02 +08:00
{
std::swap(*(m_value.array), other);
}
else
{
JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
}
/// @brief exchanges the values
/// @sa https://json.nlohmann.me/api/basic_json/swap/
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
void swap(object_t& other) // NOLINT(bugprone-exception-escape)
2018-01-10 01:30:02 +08:00
{
// swap only works for objects
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(is_object()))
2018-01-10 01:30:02 +08:00
{
std::swap(*(m_value.object), other);
}
else
{
JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
}
/// @brief exchanges the values
/// @sa https://json.nlohmann.me/api/basic_json/swap/
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
void swap(string_t& other) // NOLINT(bugprone-exception-escape)
2018-01-10 01:30:02 +08:00
{
// swap only works for strings
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(is_string()))
2018-01-10 01:30:02 +08:00
{
std::swap(*(m_value.string), other);
}
else
{
JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
2018-01-10 01:30:02 +08:00
}
}
/// @brief exchanges the values
/// @sa https://json.nlohmann.me/api/basic_json/swap/
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
{
// swap only works for strings
if (JSON_HEDLEY_LIKELY(is_binary()))
{
std::swap(*(m_value.binary), other);
}
else
{
JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
}
}
/// @brief exchanges the values
/// @sa https://json.nlohmann.me/api/basic_json/swap/
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
{
// swap only works for strings
if (JSON_HEDLEY_LIKELY(is_binary()))
{
std::swap(*(m_value.binary), other);
}
else
{
JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
}
}
2018-01-10 01:30:02 +08:00
/// @}
//////////////////////////////////////////
// lexicographical comparison operators //
//////////////////////////////////////////
/// @name lexicographical comparison operators
/// @{
// note parentheses around operands are necessary; see
// https://github.com/nlohmann/json/issues/1530
#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
const auto lhs_type = lhs.type(); \
const auto rhs_type = rhs.type(); \
\
if (lhs_type == rhs_type) /* NOLINT(readability/braces) */ \
{ \
switch (lhs_type) \
{ \
case value_t::array: \
return (*lhs.m_value.array) op (*rhs.m_value.array); \
\
case value_t::object: \
return (*lhs.m_value.object) op (*rhs.m_value.object); \
\
case value_t::null: \
return (null_result); \
\
case value_t::string: \
return (*lhs.m_value.string) op (*rhs.m_value.string); \
\
case value_t::boolean: \
return (lhs.m_value.boolean) op (rhs.m_value.boolean); \
\
case value_t::number_integer: \
return (lhs.m_value.number_integer) op (rhs.m_value.number_integer); \
\
case value_t::number_unsigned: \
return (lhs.m_value.number_unsigned) op (rhs.m_value.number_unsigned); \
\
case value_t::number_float: \
return (lhs.m_value.number_float) op (rhs.m_value.number_float); \
\
case value_t::binary: \
return (*lhs.m_value.binary) op (*rhs.m_value.binary); \
\
case value_t::discarded: \
default: \
return (unordered_result); \
} \
} \
else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \
{ \
return static_cast<number_float_t>(lhs.m_value.number_integer) op rhs.m_value.number_float; \
} \
else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \
{ \
return lhs.m_value.number_float op static_cast<number_float_t>(rhs.m_value.number_integer); \
} \
else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \
{ \
return static_cast<number_float_t>(lhs.m_value.number_unsigned) op rhs.m_value.number_float; \
} \
else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \
{ \
return lhs.m_value.number_float op static_cast<number_float_t>(rhs.m_value.number_unsigned); \
} \
else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
{ \
return static_cast<number_integer_t>(lhs.m_value.number_unsigned) op rhs.m_value.number_integer; \
} \
else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
{ \
return lhs.m_value.number_integer op static_cast<number_integer_t>(rhs.m_value.number_unsigned); \
} \
else if(compares_unordered(lhs, rhs))\
{\
return (unordered_result);\
}\
\
return (default_result);
JSON_PRIVATE_UNLESS_TESTED:
// returns true if:
// - any operand is NaN and the other operand is of number type
// - any operand is discarded
// in legacy mode, discarded values are considered ordered if
// an operation is computed as an odd number of inverses of others
static bool compares_unordered(const_reference lhs, const_reference rhs, bool inverse = false) noexcept
{
if ((lhs.is_number_float() && std::isnan(lhs.m_value.number_float) && rhs.is_number())
|| (rhs.is_number_float() && std::isnan(rhs.m_value.number_float) && lhs.is_number()))
{
return true;
}
#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
return (lhs.is_discarded() || rhs.is_discarded()) && !inverse;
#else
static_cast<void>(inverse);
return lhs.is_discarded() || rhs.is_discarded();
#endif
}
private:
bool compares_unordered(const_reference rhs, bool inverse = false) const noexcept
{
return compares_unordered(*this, rhs, inverse);
}
public:
#if JSON_HAS_THREE_WAY_COMPARISON
/// @brief comparison: equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
bool operator==(const_reference rhs) const noexcept
2018-01-10 01:30:02 +08:00
{
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
const_reference lhs = *this;
JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
}
2018-01-10 01:30:02 +08:00
/// @brief comparison: equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
template<typename ScalarType>
requires std::is_scalar_v<ScalarType>
bool operator==(ScalarType rhs) const noexcept
{
return *this == basic_json(rhs);
}
2018-01-10 01:30:02 +08:00
/// @brief comparison: not equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
bool operator!=(const_reference rhs) const noexcept
{
if (compares_unordered(rhs, true))
{
return false;
}
return !operator==(rhs);
}
2018-01-10 01:30:02 +08:00
/// @brief comparison: 3-way
/// @sa https://json.nlohmann.me/api/basic_json/operator_spaceship/
std::partial_ordering operator<=>(const_reference rhs) const noexcept // *NOPAD*
{
const_reference lhs = *this;
// default_result is used if we cannot compare values. In that case,
// we compare types.
JSON_IMPLEMENT_OPERATOR(<=>, // *NOPAD*
std::partial_ordering::equivalent,
std::partial_ordering::unordered,
lhs_type <=> rhs_type) // *NOPAD*
}
2018-01-10 01:30:02 +08:00
/// @brief comparison: 3-way
/// @sa https://json.nlohmann.me/api/basic_json/operator_spaceship/
template<typename ScalarType>
requires std::is_scalar_v<ScalarType>
std::partial_ordering operator<=>(ScalarType rhs) const noexcept // *NOPAD*
{
return *this <=> basic_json(rhs); // *NOPAD*
}
2018-01-10 01:30:02 +08:00
#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
// all operators that are computed as an odd number of inverses of others
// need to be overloaded to emulate the legacy comparison behavior
/// @brief comparison: less than or equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_le/
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON)
bool operator<=(const_reference rhs) const noexcept
{
if (compares_unordered(rhs, true))
2018-01-10 01:30:02 +08:00
{
return false;
2018-01-10 01:30:02 +08:00
}
return !(rhs < *this);
}
/// @brief comparison: less than or equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_le/
template<typename ScalarType>
requires std::is_scalar_v<ScalarType>
bool operator<=(ScalarType rhs) const noexcept
{
return *this <= basic_json(rhs);
}
/// @brief comparison: greater than or equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON)
bool operator>=(const_reference rhs) const noexcept
{
if (compares_unordered(rhs, true))
2018-01-10 01:30:02 +08:00
{
return false;
2018-01-10 01:30:02 +08:00
}
return !(*this < rhs);
}
2018-01-10 01:30:02 +08:00
/// @brief comparison: greater than or equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
template<typename ScalarType>
requires std::is_scalar_v<ScalarType>
bool operator>=(ScalarType rhs) const noexcept
{
return *this >= basic_json(rhs);
}
#endif
#else
/// @brief comparison: equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
{
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
2018-01-10 01:30:02 +08:00
}
/// @brief comparison: equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
2018-01-10 01:30:02 +08:00
template<typename ScalarType, typename std::enable_if<
std::is_scalar<ScalarType>::value, int>::type = 0>
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
return lhs == basic_json(rhs);
2018-01-10 01:30:02 +08:00
}
/// @brief comparison: equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
2018-01-10 01:30:02 +08:00
template<typename ScalarType, typename std::enable_if<
std::is_scalar<ScalarType>::value, int>::type = 0>
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
return basic_json(lhs) == rhs;
2018-01-10 01:30:02 +08:00
}
/// @brief comparison: not equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
2018-01-10 01:30:02 +08:00
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
{
if (compares_unordered(lhs, rhs, true))
{
return false;
}
return !(lhs == rhs);
2018-01-10 01:30:02 +08:00
}
/// @brief comparison: not equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
2018-01-10 01:30:02 +08:00
template<typename ScalarType, typename std::enable_if<
std::is_scalar<ScalarType>::value, int>::type = 0>
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
return lhs != basic_json(rhs);
2018-01-10 01:30:02 +08:00
}
/// @brief comparison: not equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
2018-01-10 01:30:02 +08:00
template<typename ScalarType, typename std::enable_if<
std::is_scalar<ScalarType>::value, int>::type = 0>
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
return basic_json(lhs) != rhs;
2018-01-10 01:30:02 +08:00
}
/// @brief comparison: less than
/// @sa https://json.nlohmann.me/api/basic_json/operator_lt/
2018-01-10 01:30:02 +08:00
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
{
// default_result is used if we cannot compare values. In that case,
2018-01-10 01:30:02 +08:00
// we compare types. Note we have to call the operator explicitly,
// because MSVC has problems otherwise.
JSON_IMPLEMENT_OPERATOR( <, false, false, operator<(lhs_type, rhs_type))
2018-01-10 01:30:02 +08:00
}
/// @brief comparison: less than
/// @sa https://json.nlohmann.me/api/basic_json/operator_lt/
2018-01-10 01:30:02 +08:00
template<typename ScalarType, typename std::enable_if<
std::is_scalar<ScalarType>::value, int>::type = 0>
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
return lhs < basic_json(rhs);
2018-01-10 01:30:02 +08:00
}
/// @brief comparison: less than
/// @sa https://json.nlohmann.me/api/basic_json/operator_lt/
2018-01-10 01:30:02 +08:00
template<typename ScalarType, typename std::enable_if<
std::is_scalar<ScalarType>::value, int>::type = 0>
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
return basic_json(lhs) < rhs;
2018-01-10 01:30:02 +08:00
}
/// @brief comparison: less than or equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_le/
2018-01-10 01:30:02 +08:00
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
{
if (compares_unordered(lhs, rhs, true))
{
return false;
}
return !(rhs < lhs);
2018-01-10 01:30:02 +08:00
}
/// @brief comparison: less than or equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_le/
2018-01-10 01:30:02 +08:00
template<typename ScalarType, typename std::enable_if<
std::is_scalar<ScalarType>::value, int>::type = 0>
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
return lhs <= basic_json(rhs);
2018-01-10 01:30:02 +08:00
}
/// @brief comparison: less than or equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_le/
2018-01-10 01:30:02 +08:00
template<typename ScalarType, typename std::enable_if<
std::is_scalar<ScalarType>::value, int>::type = 0>
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
return basic_json(lhs) <= rhs;
2018-01-10 01:30:02 +08:00
}
/// @brief comparison: greater than
/// @sa https://json.nlohmann.me/api/basic_json/operator_gt/
2018-01-10 01:30:02 +08:00
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
{
// double inverse
if (compares_unordered(lhs, rhs))
{
return false;
}
return !(lhs <= rhs);
2018-01-10 01:30:02 +08:00
}
/// @brief comparison: greater than
/// @sa https://json.nlohmann.me/api/basic_json/operator_gt/
2018-01-10 01:30:02 +08:00
template<typename ScalarType, typename std::enable_if<
std::is_scalar<ScalarType>::value, int>::type = 0>
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
return lhs > basic_json(rhs);
2018-01-10 01:30:02 +08:00
}
/// @brief comparison: greater than
/// @sa https://json.nlohmann.me/api/basic_json/operator_gt/
2018-01-10 01:30:02 +08:00
template<typename ScalarType, typename std::enable_if<
std::is_scalar<ScalarType>::value, int>::type = 0>
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
return basic_json(lhs) > rhs;
2018-01-10 01:30:02 +08:00
}
/// @brief comparison: greater than or equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
2018-01-10 01:30:02 +08:00
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
{
if (compares_unordered(lhs, rhs, true))
{
return false;
}
return !(lhs < rhs);
2018-01-10 01:30:02 +08:00
}
/// @brief comparison: greater than or equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
2018-01-10 01:30:02 +08:00
template<typename ScalarType, typename std::enable_if<
std::is_scalar<ScalarType>::value, int>::type = 0>
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
return lhs >= basic_json(rhs);
2018-01-10 01:30:02 +08:00
}
/// @brief comparison: greater than or equal
/// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
2018-01-10 01:30:02 +08:00
template<typename ScalarType, typename std::enable_if<
std::is_scalar<ScalarType>::value, int>::type = 0>
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
return basic_json(lhs) >= rhs;
2018-01-10 01:30:02 +08:00
}
#endif
#undef JSON_IMPLEMENT_OPERATOR
2018-01-10 01:30:02 +08:00
/// @}
///////////////////
// serialization //
///////////////////
/// @name serialization
/// @{
#ifndef JSON_NO_IO
/// @brief serialize to stream
/// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/
2018-01-10 01:30:02 +08:00
friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
{
// read width member and use it as indentation parameter if nonzero
2019-03-18 20:53:48 +08:00
const bool pretty_print = o.width() > 0;
const auto indentation = pretty_print ? o.width() : 0;
2018-01-10 01:30:02 +08:00
// reset width to 0 for subsequent calls to this stream
o.width(0);
// do the actual serialization
serializer s(detail::output_adapter<char>(o), o.fill());
s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
return o;
}
/// @brief serialize to stream
/// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/
/// @deprecated This function is deprecated since 3.0.0 and will be removed in
/// version 4.0.0 of the library. Please use
/// operator<<(std::ostream&, const basic_json&) instead; that is,
/// replace calls like `j >> o;` with `o << j;`.
2020-06-06 20:30:17 +08:00
JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
2018-01-10 01:30:02 +08:00
friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
{
return o << j;
}
#endif // JSON_NO_IO
2018-01-10 01:30:02 +08:00
/// @}
/////////////////////
// deserialization //
/////////////////////
/// @name deserialization
/// @{
/// @brief deserialize from a compatible input
/// @sa https://json.nlohmann.me/api/basic_json/parse/
2020-02-19 23:32:49 +08:00
template<typename InputType>
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-02-19 23:32:49 +08:00
static basic_json parse(InputType&& i,
2018-01-10 01:30:02 +08:00
const parser_callback_t cb = nullptr,
2020-06-18 04:03:14 +08:00
const bool allow_exceptions = true,
const bool ignore_comments = false)
2018-01-10 01:30:02 +08:00
{
basic_json result;
2020-06-18 04:03:14 +08:00
parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
2018-01-10 01:30:02 +08:00
return result;
}
/// @brief deserialize from a pair of character iterators
/// @sa https://json.nlohmann.me/api/basic_json/parse/
2020-05-28 00:40:04 +08:00
template<typename IteratorType>
2020-02-19 23:32:49 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-05-28 14:29:53 +08:00
static basic_json parse(IteratorType first,
IteratorType last,
2020-05-28 00:40:04 +08:00
const parser_callback_t cb = nullptr,
2020-06-18 04:03:14 +08:00
const bool allow_exceptions = true,
const bool ignore_comments = false)
2020-05-28 00:40:04 +08:00
{
basic_json result;
2020-06-18 04:03:14 +08:00
parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
2020-05-28 00:40:04 +08:00
return result;
}
2020-02-19 23:32:49 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-05-29 00:26:29 +08:00
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
2020-02-19 23:32:49 +08:00
static basic_json parse(detail::span_input_adapter&& i,
const parser_callback_t cb = nullptr,
2020-06-18 04:03:14 +08:00
const bool allow_exceptions = true,
const bool ignore_comments = false)
2020-02-19 23:32:49 +08:00
{
basic_json result;
2020-06-18 04:03:14 +08:00
parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
2020-02-19 23:32:49 +08:00
return result;
}
/// @brief check if the input is valid JSON
/// @sa https://json.nlohmann.me/api/basic_json/accept/
2020-02-19 23:32:49 +08:00
template<typename InputType>
2020-06-18 04:03:14 +08:00
static bool accept(InputType&& i,
const bool ignore_comments = false)
2018-01-10 01:30:02 +08:00
{
2020-06-18 04:03:14 +08:00
return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
2018-01-10 01:30:02 +08:00
}
/// @brief check if the input is valid JSON
/// @sa https://json.nlohmann.me/api/basic_json/accept/
2020-05-28 00:40:04 +08:00
template<typename IteratorType>
2020-06-18 04:03:14 +08:00
static bool accept(IteratorType first, IteratorType last,
const bool ignore_comments = false)
2018-01-10 01:30:02 +08:00
{
2020-06-18 04:03:14 +08:00
return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
2018-01-10 01:30:02 +08:00
}
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-05-29 00:26:29 +08:00
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
2020-06-18 04:03:14 +08:00
static bool accept(detail::span_input_adapter&& i,
const bool ignore_comments = false)
2020-02-19 23:32:49 +08:00
{
2020-06-18 04:03:14 +08:00
return parser(i.get(), nullptr, false, ignore_comments).accept(true);
2020-02-19 23:32:49 +08:00
}
2020-05-28 00:40:04 +08:00
/// @brief generate SAX events
/// @sa https://json.nlohmann.me/api/basic_json/sax_parse/
2020-05-28 00:40:04 +08:00
template <typename InputType, typename SAX>
2020-02-19 23:32:49 +08:00
JSON_HEDLEY_NON_NULL(2)
static bool sax_parse(InputType&& i, SAX* sax,
input_format_t format = input_format_t::json,
2020-06-18 04:03:14 +08:00
const bool strict = true,
const bool ignore_comments = false)
2020-02-19 23:32:49 +08:00
{
2020-02-20 03:59:31 +08:00
auto ia = detail::input_adapter(std::forward<InputType>(i));
2020-02-19 23:32:49 +08:00
return format == input_format_t::json
2020-06-18 04:03:14 +08:00
? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
Support UBJSON-derived Binary JData (BJData) format (#3336) * support UBJSON-derived Binary JData (BJData) format * fix Codacy warning * partially fix VS compilation errors * fix additional VS errors * fix more VS compilation errors * fix additional warnings and errors for clang and msvc * add more tests to cover the new bjdata types * add tests for optimized ndarray, improve coverage, fix clang/gcc warnings * gcc warn useless conversion but msvc gives an error * fix ci_test errors * complete test coverage, fix ci_test errors * add half precision error test * fix No newline at end of file error by clang * simplify endian condition, format unit-bjdata * remove broken test due to alloc limit * full coverage, I hope * move bjdata new markers from default to the same level as ubjson markers * fix ci errors, add tests for new bjdata switch structure * make is_bjdata const after using initializer list * remove the unwanted assert * move is_bjdata to an optional param to write_ubjson * pass use_bjdata via output adapter * revert order to avoid msvc 2015 unreferenced formal param error * update BJData Spect V1 Draft-2 URL after spec release * amalgamate code * code polishing following @gregmarr's feedback * make use_bjdata a non-default parameter * fix ci error, remove unwanted param comment * encode and decode bjdata ndarray in jdata annotations, enable roundtrip tests * partially fix ci errors, add tests to improve coverage * polish patch to remove ci errors * fix a ndarray dim vector condition * fix clang tidy error * add sax test cases for ndarray * add additional sax event tests * adjust sax event numbering * fix sax tests * ndarray can only be used with array containers, discard if used in object * complete test coverage * disable [{SHTFNZ in optimized type due to security risks in #2793 and hampered readability * fix ci error * move OutputIsLittleEndian from tparam to param to replace use_bjdata * fix ci clang gcc error * fix ci static analysis error * update json_test_data to 3.1.0, enable file-based bjdata unit tests * fix stack overflow error on msvc 2019 and 2022 * use https link, update sax_parse_error after rebase * make input_format const and use initializer * return bool for write_bjdata_ndarray * test write_bjdata_ndarray return value as boolean * fix ci error
2022-04-30 03:17:30 +08:00
: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
2020-02-19 23:32:49 +08:00
}
/// @brief generate SAX events
/// @sa https://json.nlohmann.me/api/basic_json/sax_parse/
2020-05-28 00:40:04 +08:00
template<class IteratorType, class SAX>
JSON_HEDLEY_NON_NULL(3)
static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
2018-03-21 05:39:08 +08:00
input_format_t format = input_format_t::json,
2020-06-18 04:03:14 +08:00
const bool strict = true,
const bool ignore_comments = false)
2018-01-10 01:30:02 +08:00
{
2020-05-28 00:40:04 +08:00
auto ia = detail::input_adapter(std::move(first), std::move(last));
2019-03-17 07:27:44 +08:00
return format == input_format_t::json
2020-06-18 04:03:14 +08:00
? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
Support UBJSON-derived Binary JData (BJData) format (#3336) * support UBJSON-derived Binary JData (BJData) format * fix Codacy warning * partially fix VS compilation errors * fix additional VS errors * fix more VS compilation errors * fix additional warnings and errors for clang and msvc * add more tests to cover the new bjdata types * add tests for optimized ndarray, improve coverage, fix clang/gcc warnings * gcc warn useless conversion but msvc gives an error * fix ci_test errors * complete test coverage, fix ci_test errors * add half precision error test * fix No newline at end of file error by clang * simplify endian condition, format unit-bjdata * remove broken test due to alloc limit * full coverage, I hope * move bjdata new markers from default to the same level as ubjson markers * fix ci errors, add tests for new bjdata switch structure * make is_bjdata const after using initializer list * remove the unwanted assert * move is_bjdata to an optional param to write_ubjson * pass use_bjdata via output adapter * revert order to avoid msvc 2015 unreferenced formal param error * update BJData Spect V1 Draft-2 URL after spec release * amalgamate code * code polishing following @gregmarr's feedback * make use_bjdata a non-default parameter * fix ci error, remove unwanted param comment * encode and decode bjdata ndarray in jdata annotations, enable roundtrip tests * partially fix ci errors, add tests to improve coverage * polish patch to remove ci errors * fix a ndarray dim vector condition * fix clang tidy error * add sax test cases for ndarray * add additional sax event tests * adjust sax event numbering * fix sax tests * ndarray can only be used with array containers, discard if used in object * complete test coverage * disable [{SHTFNZ in optimized type due to security risks in #2793 and hampered readability * fix ci error * move OutputIsLittleEndian from tparam to param to replace use_bjdata * fix ci clang gcc error * fix ci static analysis error * update json_test_data to 3.1.0, enable file-based bjdata unit tests * fix stack overflow error on msvc 2019 and 2022 * use https link, update sax_parse_error after rebase * make input_format const and use initializer * return bool for write_bjdata_ndarray * test write_bjdata_ndarray return value as boolean * fix ci error
2022-04-30 03:17:30 +08:00
: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
2018-02-25 01:04:07 +08:00
}
/// @brief generate SAX events
/// @sa https://json.nlohmann.me/api/basic_json/sax_parse/
/// @deprecated This function is deprecated since 3.8.0 and will be removed in
/// version 4.0.0 of the library. Please use
/// sax_parse(ptr, ptr + len) instead.
template <typename SAX>
2020-05-29 00:26:29 +08:00
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
2020-06-06 20:30:17 +08:00
JSON_HEDLEY_NON_NULL(2)
2020-02-19 23:32:49 +08:00
static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
2018-03-21 05:39:08 +08:00
input_format_t format = input_format_t::json,
2020-06-18 04:03:14 +08:00
const bool strict = true,
const bool ignore_comments = false)
2018-02-25 01:04:07 +08:00
{
2020-02-20 03:59:31 +08:00
auto ia = i.get();
2019-03-17 07:27:44 +08:00
return format == input_format_t::json
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
2020-06-18 04:03:14 +08:00
? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
Support UBJSON-derived Binary JData (BJData) format (#3336) * support UBJSON-derived Binary JData (BJData) format * fix Codacy warning * partially fix VS compilation errors * fix additional VS errors * fix more VS compilation errors * fix additional warnings and errors for clang and msvc * add more tests to cover the new bjdata types * add tests for optimized ndarray, improve coverage, fix clang/gcc warnings * gcc warn useless conversion but msvc gives an error * fix ci_test errors * complete test coverage, fix ci_test errors * add half precision error test * fix No newline at end of file error by clang * simplify endian condition, format unit-bjdata * remove broken test due to alloc limit * full coverage, I hope * move bjdata new markers from default to the same level as ubjson markers * fix ci errors, add tests for new bjdata switch structure * make is_bjdata const after using initializer list * remove the unwanted assert * move is_bjdata to an optional param to write_ubjson * pass use_bjdata via output adapter * revert order to avoid msvc 2015 unreferenced formal param error * update BJData Spect V1 Draft-2 URL after spec release * amalgamate code * code polishing following @gregmarr's feedback * make use_bjdata a non-default parameter * fix ci error, remove unwanted param comment * encode and decode bjdata ndarray in jdata annotations, enable roundtrip tests * partially fix ci errors, add tests to improve coverage * polish patch to remove ci errors * fix a ndarray dim vector condition * fix clang tidy error * add sax test cases for ndarray * add additional sax event tests * adjust sax event numbering * fix sax tests * ndarray can only be used with array containers, discard if used in object * complete test coverage * disable [{SHTFNZ in optimized type due to security risks in #2793 and hampered readability * fix ci error * move OutputIsLittleEndian from tparam to param to replace use_bjdata * fix ci clang gcc error * fix ci static analysis error * update json_test_data to 3.1.0, enable file-based bjdata unit tests * fix stack overflow error on msvc 2019 and 2022 * use https link, update sax_parse_error after rebase * make input_format const and use initializer * return bool for write_bjdata_ndarray * test write_bjdata_ndarray return value as boolean * fix ci error
2022-04-30 03:17:30 +08:00
: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
2018-02-25 01:04:07 +08:00
}
#ifndef JSON_NO_IO
/// @brief deserialize from stream
/// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/
/// @deprecated This stream operator is deprecated since 3.0.0 and will be removed in
/// version 4.0.0 of the library. Please use
/// operator>>(std::istream&, basic_json&) instead; that is,
/// replace calls like `j << i;` with `i >> j;`.
2020-06-06 20:30:17 +08:00
JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
2018-01-10 01:30:02 +08:00
friend std::istream& operator<<(basic_json& j, std::istream& i)
{
return operator>>(i, j);
}
/// @brief deserialize from stream
/// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/
2018-01-10 01:30:02 +08:00
friend std::istream& operator>>(std::istream& i, basic_json& j)
{
parser(detail::input_adapter(i)).parse(false, j);
return i;
}
#endif // JSON_NO_IO
2018-01-10 01:30:02 +08:00
/// @}
///////////////////////////
// convenience functions //
///////////////////////////
/// @brief return the type as string
/// @sa https://json.nlohmann.me/api/basic_json/type_name/
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_RETURNS_NON_NULL
2018-01-10 01:30:02 +08:00
const char* type_name() const noexcept
{
switch (m_type)
2018-01-10 01:30:02 +08:00
{
case value_t::null:
return "null";
case value_t::object:
return "object";
case value_t::array:
return "array";
case value_t::string:
return "string";
case value_t::boolean:
return "boolean";
case value_t::binary:
return "binary";
case value_t::discarded:
return "discarded";
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
default:
return "number";
2018-01-10 01:30:02 +08:00
}
}
JSON_PRIVATE_UNLESS_TESTED:
2018-01-10 01:30:02 +08:00
//////////////////////
// member variables //
//////////////////////
/// the type of the current element
value_t m_type = value_t::null;
/// the value of the current element
json_value m_value = {};
2021-01-02 20:58:05 +08:00
#if JSON_DIAGNOSTICS
2021-01-02 00:23:10 +08:00
/// a pointer to a parent value (for debugging purposes)
basic_json* m_parent = nullptr;
#endif
2018-01-10 01:30:02 +08:00
//////////////////////////////////////////
// binary serialization/deserialization //
//////////////////////////////////////////
/// @name binary serialization/deserialization support
/// @{
public:
/// @brief create a CBOR serialization of a given JSON value
/// @sa https://json.nlohmann.me/api/basic_json/to_cbor/
2021-08-08 19:24:17 +08:00
static std::vector<std::uint8_t> to_cbor(const basic_json& j)
2018-01-10 01:30:02 +08:00
{
2021-08-08 19:24:17 +08:00
std::vector<std::uint8_t> result;
2018-01-10 01:30:02 +08:00
to_cbor(j, result);
return result;
}
/// @brief create a CBOR serialization of a given JSON value
/// @sa https://json.nlohmann.me/api/basic_json/to_cbor/
2021-08-08 19:24:17 +08:00
static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o)
2018-01-10 01:30:02 +08:00
{
2021-08-08 19:24:17 +08:00
binary_writer<std::uint8_t>(o).write_cbor(j);
2018-01-10 01:30:02 +08:00
}
/// @brief create a CBOR serialization of a given JSON value
/// @sa https://json.nlohmann.me/api/basic_json/to_cbor/
2018-01-10 01:30:02 +08:00
static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
{
binary_writer<char>(o).write_cbor(j);
}
/// @brief create a MessagePack serialization of a given JSON value
/// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/
2021-08-08 19:24:17 +08:00
static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
2018-01-10 01:30:02 +08:00
{
2021-08-08 19:24:17 +08:00
std::vector<std::uint8_t> result;
2018-01-10 01:30:02 +08:00
to_msgpack(j, result);
return result;
}
/// @brief create a MessagePack serialization of a given JSON value
/// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/
2021-08-08 19:24:17 +08:00
static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o)
2018-01-10 01:30:02 +08:00
{
2021-08-08 19:24:17 +08:00
binary_writer<std::uint8_t>(o).write_msgpack(j);
2018-01-10 01:30:02 +08:00
}
/// @brief create a MessagePack serialization of a given JSON value
/// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/
2018-01-10 01:30:02 +08:00
static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
{
binary_writer<char>(o).write_msgpack(j);
}
/// @brief create a UBJSON serialization of a given JSON value
/// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/
2021-08-08 19:24:17 +08:00
static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
const bool use_size = false,
const bool use_type = false)
{
2021-08-08 19:24:17 +08:00
std::vector<std::uint8_t> result;
to_ubjson(j, result, use_size, use_type);
return result;
}
/// @brief create a UBJSON serialization of a given JSON value
/// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/
2021-08-08 19:24:17 +08:00
static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,
const bool use_size = false, const bool use_type = false)
{
2021-08-08 19:24:17 +08:00
binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
}
/// @brief create a UBJSON serialization of a given JSON value
/// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/
static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
const bool use_size = false, const bool use_type = false)
{
binary_writer<char>(o).write_ubjson(j, use_size, use_type);
}
Support UBJSON-derived Binary JData (BJData) format (#3336) * support UBJSON-derived Binary JData (BJData) format * fix Codacy warning * partially fix VS compilation errors * fix additional VS errors * fix more VS compilation errors * fix additional warnings and errors for clang and msvc * add more tests to cover the new bjdata types * add tests for optimized ndarray, improve coverage, fix clang/gcc warnings * gcc warn useless conversion but msvc gives an error * fix ci_test errors * complete test coverage, fix ci_test errors * add half precision error test * fix No newline at end of file error by clang * simplify endian condition, format unit-bjdata * remove broken test due to alloc limit * full coverage, I hope * move bjdata new markers from default to the same level as ubjson markers * fix ci errors, add tests for new bjdata switch structure * make is_bjdata const after using initializer list * remove the unwanted assert * move is_bjdata to an optional param to write_ubjson * pass use_bjdata via output adapter * revert order to avoid msvc 2015 unreferenced formal param error * update BJData Spect V1 Draft-2 URL after spec release * amalgamate code * code polishing following @gregmarr's feedback * make use_bjdata a non-default parameter * fix ci error, remove unwanted param comment * encode and decode bjdata ndarray in jdata annotations, enable roundtrip tests * partially fix ci errors, add tests to improve coverage * polish patch to remove ci errors * fix a ndarray dim vector condition * fix clang tidy error * add sax test cases for ndarray * add additional sax event tests * adjust sax event numbering * fix sax tests * ndarray can only be used with array containers, discard if used in object * complete test coverage * disable [{SHTFNZ in optimized type due to security risks in #2793 and hampered readability * fix ci error * move OutputIsLittleEndian from tparam to param to replace use_bjdata * fix ci clang gcc error * fix ci static analysis error * update json_test_data to 3.1.0, enable file-based bjdata unit tests * fix stack overflow error on msvc 2019 and 2022 * use https link, update sax_parse_error after rebase * make input_format const and use initializer * return bool for write_bjdata_ndarray * test write_bjdata_ndarray return value as boolean * fix ci error
2022-04-30 03:17:30 +08:00
/// @brief create a BJData serialization of a given JSON value
/// @sa https://json.nlohmann.me/api/basic_json/to_bjdata/
static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
const bool use_size = false,
const bool use_type = false)
{
std::vector<std::uint8_t> result;
to_bjdata(j, result, use_size, use_type);
return result;
}
/// @brief create a BJData serialization of a given JSON value
/// @sa https://json.nlohmann.me/api/basic_json/to_bjdata/
static void to_bjdata(const basic_json& j, detail::output_adapter<std::uint8_t> o,
const bool use_size = false, const bool use_type = false)
{
binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true);
}
/// @brief create a BJData serialization of a given JSON value
/// @sa https://json.nlohmann.me/api/basic_json/to_bjdata/
static void to_bjdata(const basic_json& j, detail::output_adapter<char> o,
const bool use_size = false, const bool use_type = false)
{
binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true);
}
/// @brief create a BSON serialization of a given JSON value
/// @sa https://json.nlohmann.me/api/basic_json/to_bson/
2021-08-08 19:24:17 +08:00
static std::vector<std::uint8_t> to_bson(const basic_json& j)
{
2021-08-08 19:24:17 +08:00
std::vector<std::uint8_t> result;
to_bson(j, result);
return result;
}
/// @brief create a BSON serialization of a given JSON value
/// @sa https://json.nlohmann.me/api/basic_json/to_bson/
2021-08-08 19:24:17 +08:00
static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o)
{
2021-08-08 19:24:17 +08:00
binary_writer<std::uint8_t>(o).write_bson(j);
}
/// @brief create a BSON serialization of a given JSON value
/// @sa https://json.nlohmann.me/api/basic_json/to_bson/
static void to_bson(const basic_json& j, detail::output_adapter<char> o)
{
binary_writer<char>(o).write_bson(j);
}
/// @brief create a JSON value from an input in CBOR format
/// @sa https://json.nlohmann.me/api/basic_json/from_cbor/
2020-02-19 23:32:49 +08:00
template<typename InputType>
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-02-19 23:32:49 +08:00
static basic_json from_cbor(InputType&& i,
const bool strict = true,
2020-07-12 22:51:43 +08:00
const bool allow_exceptions = true,
const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
2018-01-10 01:30:02 +08:00
{
basic_json result;
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2020-02-20 03:59:31 +08:00
auto ia = detail::input_adapter(std::forward<InputType>(i));
Support UBJSON-derived Binary JData (BJData) format (#3336) * support UBJSON-derived Binary JData (BJData) format * fix Codacy warning * partially fix VS compilation errors * fix additional VS errors * fix more VS compilation errors * fix additional warnings and errors for clang and msvc * add more tests to cover the new bjdata types * add tests for optimized ndarray, improve coverage, fix clang/gcc warnings * gcc warn useless conversion but msvc gives an error * fix ci_test errors * complete test coverage, fix ci_test errors * add half precision error test * fix No newline at end of file error by clang * simplify endian condition, format unit-bjdata * remove broken test due to alloc limit * full coverage, I hope * move bjdata new markers from default to the same level as ubjson markers * fix ci errors, add tests for new bjdata switch structure * make is_bjdata const after using initializer list * remove the unwanted assert * move is_bjdata to an optional param to write_ubjson * pass use_bjdata via output adapter * revert order to avoid msvc 2015 unreferenced formal param error * update BJData Spect V1 Draft-2 URL after spec release * amalgamate code * code polishing following @gregmarr's feedback * make use_bjdata a non-default parameter * fix ci error, remove unwanted param comment * encode and decode bjdata ndarray in jdata annotations, enable roundtrip tests * partially fix ci errors, add tests to improve coverage * polish patch to remove ci errors * fix a ndarray dim vector condition * fix clang tidy error * add sax test cases for ndarray * add additional sax event tests * adjust sax event numbering * fix sax tests * ndarray can only be used with array containers, discard if used in object * complete test coverage * disable [{SHTFNZ in optimized type due to security risks in #2793 and hampered readability * fix ci error * move OutputIsLittleEndian from tparam to param to replace use_bjdata * fix ci clang gcc error * fix ci static analysis error * update json_test_data to 3.1.0, enable file-based bjdata unit tests * fix stack overflow error on msvc 2019 and 2022 * use https link, update sax_parse_error after rebase * make input_format const and use initializer * return bool for write_bjdata_ndarray * test write_bjdata_ndarray return value as boolean * fix ci error
2022-04-30 03:17:30 +08:00
const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
return res ? result : basic_json(value_t::discarded);
2018-01-10 01:30:02 +08:00
}
/// @brief create a JSON value from an input in CBOR format
/// @sa https://json.nlohmann.me/api/basic_json/from_cbor/
2020-05-28 00:40:04 +08:00
template<typename IteratorType>
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-05-28 00:40:04 +08:00
static basic_json from_cbor(IteratorType first, IteratorType last,
const bool strict = true,
2020-07-12 22:51:43 +08:00
const bool allow_exceptions = true,
const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
2018-01-10 01:30:02 +08:00
{
basic_json result;
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2020-05-28 00:40:04 +08:00
auto ia = detail::input_adapter(std::move(first), std::move(last));
Support UBJSON-derived Binary JData (BJData) format (#3336) * support UBJSON-derived Binary JData (BJData) format * fix Codacy warning * partially fix VS compilation errors * fix additional VS errors * fix more VS compilation errors * fix additional warnings and errors for clang and msvc * add more tests to cover the new bjdata types * add tests for optimized ndarray, improve coverage, fix clang/gcc warnings * gcc warn useless conversion but msvc gives an error * fix ci_test errors * complete test coverage, fix ci_test errors * add half precision error test * fix No newline at end of file error by clang * simplify endian condition, format unit-bjdata * remove broken test due to alloc limit * full coverage, I hope * move bjdata new markers from default to the same level as ubjson markers * fix ci errors, add tests for new bjdata switch structure * make is_bjdata const after using initializer list * remove the unwanted assert * move is_bjdata to an optional param to write_ubjson * pass use_bjdata via output adapter * revert order to avoid msvc 2015 unreferenced formal param error * update BJData Spect V1 Draft-2 URL after spec release * amalgamate code * code polishing following @gregmarr's feedback * make use_bjdata a non-default parameter * fix ci error, remove unwanted param comment * encode and decode bjdata ndarray in jdata annotations, enable roundtrip tests * partially fix ci errors, add tests to improve coverage * polish patch to remove ci errors * fix a ndarray dim vector condition * fix clang tidy error * add sax test cases for ndarray * add additional sax event tests * adjust sax event numbering * fix sax tests * ndarray can only be used with array containers, discard if used in object * complete test coverage * disable [{SHTFNZ in optimized type due to security risks in #2793 and hampered readability * fix ci error * move OutputIsLittleEndian from tparam to param to replace use_bjdata * fix ci clang gcc error * fix ci static analysis error * update json_test_data to 3.1.0, enable file-based bjdata unit tests * fix stack overflow error on msvc 2019 and 2022 * use https link, update sax_parse_error after rebase * make input_format const and use initializer * return bool for write_bjdata_ndarray * test write_bjdata_ndarray return value as boolean * fix ci error
2022-04-30 03:17:30 +08:00
const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
2020-02-19 23:32:49 +08:00
return res ? result : basic_json(value_t::discarded);
}
template<typename T>
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-05-29 00:26:29 +08:00
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
static basic_json from_cbor(const T* ptr, std::size_t len,
const bool strict = true,
2020-07-12 22:51:43 +08:00
const bool allow_exceptions = true,
const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
{
2020-07-21 04:38:00 +08:00
return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
}
2020-02-19 23:32:49 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-05-29 00:26:29 +08:00
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
2020-02-19 23:32:49 +08:00
static basic_json from_cbor(detail::span_input_adapter&& i,
const bool strict = true,
2020-07-12 22:51:43 +08:00
const bool allow_exceptions = true,
const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
2020-02-19 23:32:49 +08:00
{
basic_json result;
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2020-05-28 00:40:04 +08:00
auto ia = i.get();
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
Support UBJSON-derived Binary JData (BJData) format (#3336) * support UBJSON-derived Binary JData (BJData) format * fix Codacy warning * partially fix VS compilation errors * fix additional VS errors * fix more VS compilation errors * fix additional warnings and errors for clang and msvc * add more tests to cover the new bjdata types * add tests for optimized ndarray, improve coverage, fix clang/gcc warnings * gcc warn useless conversion but msvc gives an error * fix ci_test errors * complete test coverage, fix ci_test errors * add half precision error test * fix No newline at end of file error by clang * simplify endian condition, format unit-bjdata * remove broken test due to alloc limit * full coverage, I hope * move bjdata new markers from default to the same level as ubjson markers * fix ci errors, add tests for new bjdata switch structure * make is_bjdata const after using initializer list * remove the unwanted assert * move is_bjdata to an optional param to write_ubjson * pass use_bjdata via output adapter * revert order to avoid msvc 2015 unreferenced formal param error * update BJData Spect V1 Draft-2 URL after spec release * amalgamate code * code polishing following @gregmarr's feedback * make use_bjdata a non-default parameter * fix ci error, remove unwanted param comment * encode and decode bjdata ndarray in jdata annotations, enable roundtrip tests * partially fix ci errors, add tests to improve coverage * polish patch to remove ci errors * fix a ndarray dim vector condition * fix clang tidy error * add sax test cases for ndarray * add additional sax event tests * adjust sax event numbering * fix sax tests * ndarray can only be used with array containers, discard if used in object * complete test coverage * disable [{SHTFNZ in optimized type due to security risks in #2793 and hampered readability * fix ci error * move OutputIsLittleEndian from tparam to param to replace use_bjdata * fix ci clang gcc error * fix ci static analysis error * update json_test_data to 3.1.0, enable file-based bjdata unit tests * fix stack overflow error on msvc 2019 and 2022 * use https link, update sax_parse_error after rebase * make input_format const and use initializer * return bool for write_bjdata_ndarray * test write_bjdata_ndarray return value as boolean * fix ci error
2022-04-30 03:17:30 +08:00
const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
return res ? result : basic_json(value_t::discarded);
2018-01-10 01:30:02 +08:00
}
/// @brief create a JSON value from an input in MessagePack format
/// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/
2020-02-19 23:32:49 +08:00
template<typename InputType>
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-02-19 23:32:49 +08:00
static basic_json from_msgpack(InputType&& i,
const bool strict = true,
const bool allow_exceptions = true)
2018-01-10 01:30:02 +08:00
{
basic_json result;
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2020-02-20 03:59:31 +08:00
auto ia = detail::input_adapter(std::forward<InputType>(i));
Support UBJSON-derived Binary JData (BJData) format (#3336) * support UBJSON-derived Binary JData (BJData) format * fix Codacy warning * partially fix VS compilation errors * fix additional VS errors * fix more VS compilation errors * fix additional warnings and errors for clang and msvc * add more tests to cover the new bjdata types * add tests for optimized ndarray, improve coverage, fix clang/gcc warnings * gcc warn useless conversion but msvc gives an error * fix ci_test errors * complete test coverage, fix ci_test errors * add half precision error test * fix No newline at end of file error by clang * simplify endian condition, format unit-bjdata * remove broken test due to alloc limit * full coverage, I hope * move bjdata new markers from default to the same level as ubjson markers * fix ci errors, add tests for new bjdata switch structure * make is_bjdata const after using initializer list * remove the unwanted assert * move is_bjdata to an optional param to write_ubjson * pass use_bjdata via output adapter * revert order to avoid msvc 2015 unreferenced formal param error * update BJData Spect V1 Draft-2 URL after spec release * amalgamate code * code polishing following @gregmarr's feedback * make use_bjdata a non-default parameter * fix ci error, remove unwanted param comment * encode and decode bjdata ndarray in jdata annotations, enable roundtrip tests * partially fix ci errors, add tests to improve coverage * polish patch to remove ci errors * fix a ndarray dim vector condition * fix clang tidy error * add sax test cases for ndarray * add additional sax event tests * adjust sax event numbering * fix sax tests * ndarray can only be used with array containers, discard if used in object * complete test coverage * disable [{SHTFNZ in optimized type due to security risks in #2793 and hampered readability * fix ci error * move OutputIsLittleEndian from tparam to param to replace use_bjdata * fix ci clang gcc error * fix ci static analysis error * update json_test_data to 3.1.0, enable file-based bjdata unit tests * fix stack overflow error on msvc 2019 and 2022 * use https link, update sax_parse_error after rebase * make input_format const and use initializer * return bool for write_bjdata_ndarray * test write_bjdata_ndarray return value as boolean * fix ci error
2022-04-30 03:17:30 +08:00
const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
return res ? result : basic_json(value_t::discarded);
2018-01-10 01:30:02 +08:00
}
/// @brief create a JSON value from an input in MessagePack format
/// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/
2020-05-28 00:40:04 +08:00
template<typename IteratorType>
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-05-28 00:40:04 +08:00
static basic_json from_msgpack(IteratorType first, IteratorType last,
const bool strict = true,
const bool allow_exceptions = true)
2018-01-10 01:30:02 +08:00
{
basic_json result;
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2020-05-28 00:40:04 +08:00
auto ia = detail::input_adapter(std::move(first), std::move(last));
Support UBJSON-derived Binary JData (BJData) format (#3336) * support UBJSON-derived Binary JData (BJData) format * fix Codacy warning * partially fix VS compilation errors * fix additional VS errors * fix more VS compilation errors * fix additional warnings and errors for clang and msvc * add more tests to cover the new bjdata types * add tests for optimized ndarray, improve coverage, fix clang/gcc warnings * gcc warn useless conversion but msvc gives an error * fix ci_test errors * complete test coverage, fix ci_test errors * add half precision error test * fix No newline at end of file error by clang * simplify endian condition, format unit-bjdata * remove broken test due to alloc limit * full coverage, I hope * move bjdata new markers from default to the same level as ubjson markers * fix ci errors, add tests for new bjdata switch structure * make is_bjdata const after using initializer list * remove the unwanted assert * move is_bjdata to an optional param to write_ubjson * pass use_bjdata via output adapter * revert order to avoid msvc 2015 unreferenced formal param error * update BJData Spect V1 Draft-2 URL after spec release * amalgamate code * code polishing following @gregmarr's feedback * make use_bjdata a non-default parameter * fix ci error, remove unwanted param comment * encode and decode bjdata ndarray in jdata annotations, enable roundtrip tests * partially fix ci errors, add tests to improve coverage * polish patch to remove ci errors * fix a ndarray dim vector condition * fix clang tidy error * add sax test cases for ndarray * add additional sax event tests * adjust sax event numbering * fix sax tests * ndarray can only be used with array containers, discard if used in object * complete test coverage * disable [{SHTFNZ in optimized type due to security risks in #2793 and hampered readability * fix ci error * move OutputIsLittleEndian from tparam to param to replace use_bjdata * fix ci clang gcc error * fix ci static analysis error * update json_test_data to 3.1.0, enable file-based bjdata unit tests * fix stack overflow error on msvc 2019 and 2022 * use https link, update sax_parse_error after rebase * make input_format const and use initializer * return bool for write_bjdata_ndarray * test write_bjdata_ndarray return value as boolean * fix ci error
2022-04-30 03:17:30 +08:00
const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
return res ? result : basic_json(value_t::discarded);
2018-01-10 01:30:02 +08:00
}
template<typename T>
2020-02-19 23:32:49 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-05-29 00:26:29 +08:00
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
static basic_json from_msgpack(const T* ptr, std::size_t len,
const bool strict = true,
const bool allow_exceptions = true)
{
return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
}
2020-02-19 23:32:49 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-05-29 00:26:29 +08:00
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
2020-02-19 23:32:49 +08:00
static basic_json from_msgpack(detail::span_input_adapter&& i,
const bool strict = true,
const bool allow_exceptions = true)
{
basic_json result;
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2020-05-28 00:40:04 +08:00
auto ia = i.get();
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
Support UBJSON-derived Binary JData (BJData) format (#3336) * support UBJSON-derived Binary JData (BJData) format * fix Codacy warning * partially fix VS compilation errors * fix additional VS errors * fix more VS compilation errors * fix additional warnings and errors for clang and msvc * add more tests to cover the new bjdata types * add tests for optimized ndarray, improve coverage, fix clang/gcc warnings * gcc warn useless conversion but msvc gives an error * fix ci_test errors * complete test coverage, fix ci_test errors * add half precision error test * fix No newline at end of file error by clang * simplify endian condition, format unit-bjdata * remove broken test due to alloc limit * full coverage, I hope * move bjdata new markers from default to the same level as ubjson markers * fix ci errors, add tests for new bjdata switch structure * make is_bjdata const after using initializer list * remove the unwanted assert * move is_bjdata to an optional param to write_ubjson * pass use_bjdata via output adapter * revert order to avoid msvc 2015 unreferenced formal param error * update BJData Spect V1 Draft-2 URL after spec release * amalgamate code * code polishing following @gregmarr's feedback * make use_bjdata a non-default parameter * fix ci error, remove unwanted param comment * encode and decode bjdata ndarray in jdata annotations, enable roundtrip tests * partially fix ci errors, add tests to improve coverage * polish patch to remove ci errors * fix a ndarray dim vector condition * fix clang tidy error * add sax test cases for ndarray * add additional sax event tests * adjust sax event numbering * fix sax tests * ndarray can only be used with array containers, discard if used in object * complete test coverage * disable [{SHTFNZ in optimized type due to security risks in #2793 and hampered readability * fix ci error * move OutputIsLittleEndian from tparam to param to replace use_bjdata * fix ci clang gcc error * fix ci static analysis error * update json_test_data to 3.1.0, enable file-based bjdata unit tests * fix stack overflow error on msvc 2019 and 2022 * use https link, update sax_parse_error after rebase * make input_format const and use initializer * return bool for write_bjdata_ndarray * test write_bjdata_ndarray return value as boolean * fix ci error
2022-04-30 03:17:30 +08:00
const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
2020-02-19 23:32:49 +08:00
return res ? result : basic_json(value_t::discarded);
}
/// @brief create a JSON value from an input in UBJSON format
/// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/
2020-02-19 23:32:49 +08:00
template<typename InputType>
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-02-19 23:32:49 +08:00
static basic_json from_ubjson(InputType&& i,
const bool strict = true,
const bool allow_exceptions = true)
{
basic_json result;
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2020-02-20 03:59:31 +08:00
auto ia = detail::input_adapter(std::forward<InputType>(i));
Support UBJSON-derived Binary JData (BJData) format (#3336) * support UBJSON-derived Binary JData (BJData) format * fix Codacy warning * partially fix VS compilation errors * fix additional VS errors * fix more VS compilation errors * fix additional warnings and errors for clang and msvc * add more tests to cover the new bjdata types * add tests for optimized ndarray, improve coverage, fix clang/gcc warnings * gcc warn useless conversion but msvc gives an error * fix ci_test errors * complete test coverage, fix ci_test errors * add half precision error test * fix No newline at end of file error by clang * simplify endian condition, format unit-bjdata * remove broken test due to alloc limit * full coverage, I hope * move bjdata new markers from default to the same level as ubjson markers * fix ci errors, add tests for new bjdata switch structure * make is_bjdata const after using initializer list * remove the unwanted assert * move is_bjdata to an optional param to write_ubjson * pass use_bjdata via output adapter * revert order to avoid msvc 2015 unreferenced formal param error * update BJData Spect V1 Draft-2 URL after spec release * amalgamate code * code polishing following @gregmarr's feedback * make use_bjdata a non-default parameter * fix ci error, remove unwanted param comment * encode and decode bjdata ndarray in jdata annotations, enable roundtrip tests * partially fix ci errors, add tests to improve coverage * polish patch to remove ci errors * fix a ndarray dim vector condition * fix clang tidy error * add sax test cases for ndarray * add additional sax event tests * adjust sax event numbering * fix sax tests * ndarray can only be used with array containers, discard if used in object * complete test coverage * disable [{SHTFNZ in optimized type due to security risks in #2793 and hampered readability * fix ci error * move OutputIsLittleEndian from tparam to param to replace use_bjdata * fix ci clang gcc error * fix ci static analysis error * update json_test_data to 3.1.0, enable file-based bjdata unit tests * fix stack overflow error on msvc 2019 and 2022 * use https link, update sax_parse_error after rebase * make input_format const and use initializer * return bool for write_bjdata_ndarray * test write_bjdata_ndarray return value as boolean * fix ci error
2022-04-30 03:17:30 +08:00
const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
return res ? result : basic_json(value_t::discarded);
}
/// @brief create a JSON value from an input in UBJSON format
/// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/
2020-05-28 00:40:04 +08:00
template<typename IteratorType>
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-05-28 00:40:04 +08:00
static basic_json from_ubjson(IteratorType first, IteratorType last,
const bool strict = true,
const bool allow_exceptions = true)
{
basic_json result;
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2020-05-28 00:40:04 +08:00
auto ia = detail::input_adapter(std::move(first), std::move(last));
Support UBJSON-derived Binary JData (BJData) format (#3336) * support UBJSON-derived Binary JData (BJData) format * fix Codacy warning * partially fix VS compilation errors * fix additional VS errors * fix more VS compilation errors * fix additional warnings and errors for clang and msvc * add more tests to cover the new bjdata types * add tests for optimized ndarray, improve coverage, fix clang/gcc warnings * gcc warn useless conversion but msvc gives an error * fix ci_test errors * complete test coverage, fix ci_test errors * add half precision error test * fix No newline at end of file error by clang * simplify endian condition, format unit-bjdata * remove broken test due to alloc limit * full coverage, I hope * move bjdata new markers from default to the same level as ubjson markers * fix ci errors, add tests for new bjdata switch structure * make is_bjdata const after using initializer list * remove the unwanted assert * move is_bjdata to an optional param to write_ubjson * pass use_bjdata via output adapter * revert order to avoid msvc 2015 unreferenced formal param error * update BJData Spect V1 Draft-2 URL after spec release * amalgamate code * code polishing following @gregmarr's feedback * make use_bjdata a non-default parameter * fix ci error, remove unwanted param comment * encode and decode bjdata ndarray in jdata annotations, enable roundtrip tests * partially fix ci errors, add tests to improve coverage * polish patch to remove ci errors * fix a ndarray dim vector condition * fix clang tidy error * add sax test cases for ndarray * add additional sax event tests * adjust sax event numbering * fix sax tests * ndarray can only be used with array containers, discard if used in object * complete test coverage * disable [{SHTFNZ in optimized type due to security risks in #2793 and hampered readability * fix ci error * move OutputIsLittleEndian from tparam to param to replace use_bjdata * fix ci clang gcc error * fix ci static analysis error * update json_test_data to 3.1.0, enable file-based bjdata unit tests * fix stack overflow error on msvc 2019 and 2022 * use https link, update sax_parse_error after rebase * make input_format const and use initializer * return bool for write_bjdata_ndarray * test write_bjdata_ndarray return value as boolean * fix ci error
2022-04-30 03:17:30 +08:00
const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
2020-02-19 23:32:49 +08:00
return res ? result : basic_json(value_t::discarded);
}
template<typename T>
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-05-29 00:26:29 +08:00
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
static basic_json from_ubjson(const T* ptr, std::size_t len,
const bool strict = true,
const bool allow_exceptions = true)
{
return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
}
2020-02-19 23:32:49 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-05-29 00:26:29 +08:00
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
2020-02-19 23:32:49 +08:00
static basic_json from_ubjson(detail::span_input_adapter&& i,
const bool strict = true,
const bool allow_exceptions = true)
{
basic_json result;
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2020-05-28 00:40:04 +08:00
auto ia = i.get();
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
Support UBJSON-derived Binary JData (BJData) format (#3336) * support UBJSON-derived Binary JData (BJData) format * fix Codacy warning * partially fix VS compilation errors * fix additional VS errors * fix more VS compilation errors * fix additional warnings and errors for clang and msvc * add more tests to cover the new bjdata types * add tests for optimized ndarray, improve coverage, fix clang/gcc warnings * gcc warn useless conversion but msvc gives an error * fix ci_test errors * complete test coverage, fix ci_test errors * add half precision error test * fix No newline at end of file error by clang * simplify endian condition, format unit-bjdata * remove broken test due to alloc limit * full coverage, I hope * move bjdata new markers from default to the same level as ubjson markers * fix ci errors, add tests for new bjdata switch structure * make is_bjdata const after using initializer list * remove the unwanted assert * move is_bjdata to an optional param to write_ubjson * pass use_bjdata via output adapter * revert order to avoid msvc 2015 unreferenced formal param error * update BJData Spect V1 Draft-2 URL after spec release * amalgamate code * code polishing following @gregmarr's feedback * make use_bjdata a non-default parameter * fix ci error, remove unwanted param comment * encode and decode bjdata ndarray in jdata annotations, enable roundtrip tests * partially fix ci errors, add tests to improve coverage * polish patch to remove ci errors * fix a ndarray dim vector condition * fix clang tidy error * add sax test cases for ndarray * add additional sax event tests * adjust sax event numbering * fix sax tests * ndarray can only be used with array containers, discard if used in object * complete test coverage * disable [{SHTFNZ in optimized type due to security risks in #2793 and hampered readability * fix ci error * move OutputIsLittleEndian from tparam to param to replace use_bjdata * fix ci clang gcc error * fix ci static analysis error * update json_test_data to 3.1.0, enable file-based bjdata unit tests * fix stack overflow error on msvc 2019 and 2022 * use https link, update sax_parse_error after rebase * make input_format const and use initializer * return bool for write_bjdata_ndarray * test write_bjdata_ndarray return value as boolean * fix ci error
2022-04-30 03:17:30 +08:00
const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
return res ? result : basic_json(value_t::discarded);
}
Support UBJSON-derived Binary JData (BJData) format (#3336) * support UBJSON-derived Binary JData (BJData) format * fix Codacy warning * partially fix VS compilation errors * fix additional VS errors * fix more VS compilation errors * fix additional warnings and errors for clang and msvc * add more tests to cover the new bjdata types * add tests for optimized ndarray, improve coverage, fix clang/gcc warnings * gcc warn useless conversion but msvc gives an error * fix ci_test errors * complete test coverage, fix ci_test errors * add half precision error test * fix No newline at end of file error by clang * simplify endian condition, format unit-bjdata * remove broken test due to alloc limit * full coverage, I hope * move bjdata new markers from default to the same level as ubjson markers * fix ci errors, add tests for new bjdata switch structure * make is_bjdata const after using initializer list * remove the unwanted assert * move is_bjdata to an optional param to write_ubjson * pass use_bjdata via output adapter * revert order to avoid msvc 2015 unreferenced formal param error * update BJData Spect V1 Draft-2 URL after spec release * amalgamate code * code polishing following @gregmarr's feedback * make use_bjdata a non-default parameter * fix ci error, remove unwanted param comment * encode and decode bjdata ndarray in jdata annotations, enable roundtrip tests * partially fix ci errors, add tests to improve coverage * polish patch to remove ci errors * fix a ndarray dim vector condition * fix clang tidy error * add sax test cases for ndarray * add additional sax event tests * adjust sax event numbering * fix sax tests * ndarray can only be used with array containers, discard if used in object * complete test coverage * disable [{SHTFNZ in optimized type due to security risks in #2793 and hampered readability * fix ci error * move OutputIsLittleEndian from tparam to param to replace use_bjdata * fix ci clang gcc error * fix ci static analysis error * update json_test_data to 3.1.0, enable file-based bjdata unit tests * fix stack overflow error on msvc 2019 and 2022 * use https link, update sax_parse_error after rebase * make input_format const and use initializer * return bool for write_bjdata_ndarray * test write_bjdata_ndarray return value as boolean * fix ci error
2022-04-30 03:17:30 +08:00
/// @brief create a JSON value from an input in BJData format
/// @sa https://json.nlohmann.me/api/basic_json/from_bjdata/
template<typename InputType>
JSON_HEDLEY_WARN_UNUSED_RESULT
static basic_json from_bjdata(InputType&& i,
const bool strict = true,
const bool allow_exceptions = true)
{
basic_json result;
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
auto ia = detail::input_adapter(std::forward<InputType>(i));
const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
return res ? result : basic_json(value_t::discarded);
}
/// @brief create a JSON value from an input in BJData format
/// @sa https://json.nlohmann.me/api/basic_json/from_bjdata/
template<typename IteratorType>
JSON_HEDLEY_WARN_UNUSED_RESULT
static basic_json from_bjdata(IteratorType first, IteratorType last,
const bool strict = true,
const bool allow_exceptions = true)
{
basic_json result;
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
auto ia = detail::input_adapter(std::move(first), std::move(last));
const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
return res ? result : basic_json(value_t::discarded);
}
/// @brief create a JSON value from an input in BSON format
/// @sa https://json.nlohmann.me/api/basic_json/from_bson/
2020-02-19 23:32:49 +08:00
template<typename InputType>
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-02-19 23:32:49 +08:00
static basic_json from_bson(InputType&& i,
const bool strict = true,
const bool allow_exceptions = true)
{
basic_json result;
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2020-02-20 03:59:31 +08:00
auto ia = detail::input_adapter(std::forward<InputType>(i));
Support UBJSON-derived Binary JData (BJData) format (#3336) * support UBJSON-derived Binary JData (BJData) format * fix Codacy warning * partially fix VS compilation errors * fix additional VS errors * fix more VS compilation errors * fix additional warnings and errors for clang and msvc * add more tests to cover the new bjdata types * add tests for optimized ndarray, improve coverage, fix clang/gcc warnings * gcc warn useless conversion but msvc gives an error * fix ci_test errors * complete test coverage, fix ci_test errors * add half precision error test * fix No newline at end of file error by clang * simplify endian condition, format unit-bjdata * remove broken test due to alloc limit * full coverage, I hope * move bjdata new markers from default to the same level as ubjson markers * fix ci errors, add tests for new bjdata switch structure * make is_bjdata const after using initializer list * remove the unwanted assert * move is_bjdata to an optional param to write_ubjson * pass use_bjdata via output adapter * revert order to avoid msvc 2015 unreferenced formal param error * update BJData Spect V1 Draft-2 URL after spec release * amalgamate code * code polishing following @gregmarr's feedback * make use_bjdata a non-default parameter * fix ci error, remove unwanted param comment * encode and decode bjdata ndarray in jdata annotations, enable roundtrip tests * partially fix ci errors, add tests to improve coverage * polish patch to remove ci errors * fix a ndarray dim vector condition * fix clang tidy error * add sax test cases for ndarray * add additional sax event tests * adjust sax event numbering * fix sax tests * ndarray can only be used with array containers, discard if used in object * complete test coverage * disable [{SHTFNZ in optimized type due to security risks in #2793 and hampered readability * fix ci error * move OutputIsLittleEndian from tparam to param to replace use_bjdata * fix ci clang gcc error * fix ci static analysis error * update json_test_data to 3.1.0, enable file-based bjdata unit tests * fix stack overflow error on msvc 2019 and 2022 * use https link, update sax_parse_error after rebase * make input_format const and use initializer * return bool for write_bjdata_ndarray * test write_bjdata_ndarray return value as boolean * fix ci error
2022-04-30 03:17:30 +08:00
const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
return res ? result : basic_json(value_t::discarded);
}
/// @brief create a JSON value from an input in BSON format
/// @sa https://json.nlohmann.me/api/basic_json/from_bson/
2020-05-28 00:40:04 +08:00
template<typename IteratorType>
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-05-28 00:40:04 +08:00
static basic_json from_bson(IteratorType first, IteratorType last,
const bool strict = true,
const bool allow_exceptions = true)
{
basic_json result;
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2020-05-28 00:40:04 +08:00
auto ia = detail::input_adapter(std::move(first), std::move(last));
Support UBJSON-derived Binary JData (BJData) format (#3336) * support UBJSON-derived Binary JData (BJData) format * fix Codacy warning * partially fix VS compilation errors * fix additional VS errors * fix more VS compilation errors * fix additional warnings and errors for clang and msvc * add more tests to cover the new bjdata types * add tests for optimized ndarray, improve coverage, fix clang/gcc warnings * gcc warn useless conversion but msvc gives an error * fix ci_test errors * complete test coverage, fix ci_test errors * add half precision error test * fix No newline at end of file error by clang * simplify endian condition, format unit-bjdata * remove broken test due to alloc limit * full coverage, I hope * move bjdata new markers from default to the same level as ubjson markers * fix ci errors, add tests for new bjdata switch structure * make is_bjdata const after using initializer list * remove the unwanted assert * move is_bjdata to an optional param to write_ubjson * pass use_bjdata via output adapter * revert order to avoid msvc 2015 unreferenced formal param error * update BJData Spect V1 Draft-2 URL after spec release * amalgamate code * code polishing following @gregmarr's feedback * make use_bjdata a non-default parameter * fix ci error, remove unwanted param comment * encode and decode bjdata ndarray in jdata annotations, enable roundtrip tests * partially fix ci errors, add tests to improve coverage * polish patch to remove ci errors * fix a ndarray dim vector condition * fix clang tidy error * add sax test cases for ndarray * add additional sax event tests * adjust sax event numbering * fix sax tests * ndarray can only be used with array containers, discard if used in object * complete test coverage * disable [{SHTFNZ in optimized type due to security risks in #2793 and hampered readability * fix ci error * move OutputIsLittleEndian from tparam to param to replace use_bjdata * fix ci clang gcc error * fix ci static analysis error * update json_test_data to 3.1.0, enable file-based bjdata unit tests * fix stack overflow error on msvc 2019 and 2022 * use https link, update sax_parse_error after rebase * make input_format const and use initializer * return bool for write_bjdata_ndarray * test write_bjdata_ndarray return value as boolean * fix ci error
2022-04-30 03:17:30 +08:00
const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
return res ? result : basic_json(value_t::discarded);
}
template<typename T>
2020-02-19 23:32:49 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-05-29 00:26:29 +08:00
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
static basic_json from_bson(const T* ptr, std::size_t len,
const bool strict = true,
const bool allow_exceptions = true)
{
return from_bson(ptr, ptr + len, strict, allow_exceptions);
}
2020-02-19 23:32:49 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2020-05-29 00:26:29 +08:00
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
2020-02-19 23:32:49 +08:00
static basic_json from_bson(detail::span_input_adapter&& i,
const bool strict = true,
const bool allow_exceptions = true)
{
basic_json result;
detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
2020-05-28 00:40:04 +08:00
auto ia = i.get();
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
Support UBJSON-derived Binary JData (BJData) format (#3336) * support UBJSON-derived Binary JData (BJData) format * fix Codacy warning * partially fix VS compilation errors * fix additional VS errors * fix more VS compilation errors * fix additional warnings and errors for clang and msvc * add more tests to cover the new bjdata types * add tests for optimized ndarray, improve coverage, fix clang/gcc warnings * gcc warn useless conversion but msvc gives an error * fix ci_test errors * complete test coverage, fix ci_test errors * add half precision error test * fix No newline at end of file error by clang * simplify endian condition, format unit-bjdata * remove broken test due to alloc limit * full coverage, I hope * move bjdata new markers from default to the same level as ubjson markers * fix ci errors, add tests for new bjdata switch structure * make is_bjdata const after using initializer list * remove the unwanted assert * move is_bjdata to an optional param to write_ubjson * pass use_bjdata via output adapter * revert order to avoid msvc 2015 unreferenced formal param error * update BJData Spect V1 Draft-2 URL after spec release * amalgamate code * code polishing following @gregmarr's feedback * make use_bjdata a non-default parameter * fix ci error, remove unwanted param comment * encode and decode bjdata ndarray in jdata annotations, enable roundtrip tests * partially fix ci errors, add tests to improve coverage * polish patch to remove ci errors * fix a ndarray dim vector condition * fix clang tidy error * add sax test cases for ndarray * add additional sax event tests * adjust sax event numbering * fix sax tests * ndarray can only be used with array containers, discard if used in object * complete test coverage * disable [{SHTFNZ in optimized type due to security risks in #2793 and hampered readability * fix ci error * move OutputIsLittleEndian from tparam to param to replace use_bjdata * fix ci clang gcc error * fix ci static analysis error * update json_test_data to 3.1.0, enable file-based bjdata unit tests * fix stack overflow error on msvc 2019 and 2022 * use https link, update sax_parse_error after rebase * make input_format const and use initializer * return bool for write_bjdata_ndarray * test write_bjdata_ndarray return value as boolean * fix ci error
2022-04-30 03:17:30 +08:00
const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
2020-02-19 23:32:49 +08:00
return res ? result : basic_json(value_t::discarded);
}
2018-01-10 01:30:02 +08:00
/// @}
//////////////////////////
// JSON Pointer support //
//////////////////////////
/// @name JSON Pointer functions
/// @{
/// @brief access specified element via JSON Pointer
/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
2018-01-10 01:30:02 +08:00
reference operator[](const json_pointer& ptr)
{
return ptr.get_unchecked(this);
}
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
{
return ptr.get_unchecked(this);
}
/// @brief access specified element via JSON Pointer
/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
2018-01-10 01:30:02 +08:00
const_reference operator[](const json_pointer& ptr) const
{
return ptr.get_unchecked(this);
}
Implement support for string_view (attempt no. 3) (#3423) * Add key_compare member to ordered_map * Replace == with key_compare in ordered_map * Expose the actual comparison function used by object_t nlohmann::ordered_map uses a different comparison function than the one provided via template parameter. * Introduce a type trait to detect if object_t has a key_compare member. * Rename object_comparator_t to default_object_comparator_t. * Add object_comparator_t to be conditionally defined as object_t::key_compare, if available, or default_object_comparator_t otherwise. * Update the documentation accordingly. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Add type traits to check if a type is usable as object key Add type trait to check: * if a type is a specialization of a template. * if a type is a json_pointer. * if a type is a basic_json::{const_,}iterator. * if two types are comparable using a given comparison functor. * if a type is comparable to basic_json::object_t::key_type. * if a type has a member type is_transparent. * if a type is usable as object key. * if a type has an erase() function accepting a given KeyType. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> * Rework basic_json element access to accept more key types Rework basic_json element access member functions and operators to accept any type that meets the requirements defined by type trait detail::is_usable_as_key_type. Member functions and operators: * at() * operator[] * value() * erase() * find() * count() * contains() Update documentation to reflect these changes. Add unit tests to excercise the new functions using std::string_view. Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com> Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
2022-04-30 03:40:02 +08:00
template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
{
return ptr.get_unchecked(this);
}
/// @brief access specified element via JSON Pointer
/// @sa https://json.nlohmann.me/api/basic_json/at/
2018-01-10 01:30:02 +08:00
reference at(const json_pointer& ptr)
{
return ptr.get_checked(this);
}
template<typename BasicJsonType>
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
{
return ptr.get_checked(this);
}
/// @brief access specified element via JSON Pointer
/// @sa https://json.nlohmann.me/api/basic_json/at/
2018-01-10 01:30:02 +08:00
const_reference at(const json_pointer& ptr) const
{
return ptr.get_checked(this);
}
template<typename BasicJsonType>
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
{
return ptr.get_checked(this);
}
/// @brief return flattened JSON value
/// @sa https://json.nlohmann.me/api/basic_json/flatten/
2018-01-10 01:30:02 +08:00
basic_json flatten() const
{
basic_json result(value_t::object);
json_pointer::flatten("", *this, result);
return result;
}
/// @brief unflatten a previously flattened JSON value
/// @sa https://json.nlohmann.me/api/basic_json/unflatten/
2018-01-10 01:30:02 +08:00
basic_json unflatten() const
{
return json_pointer::unflatten(*this);
}
/// @}
//////////////////////////
// JSON Patch functions //
//////////////////////////
/// @name JSON Patch functions
/// @{
/// @brief applies a JSON patch
/// @sa https://json.nlohmann.me/api/basic_json/patch/
2018-01-10 01:30:02 +08:00
basic_json patch(const basic_json& json_patch) const
{
// make a working copy to apply the patch to
basic_json result = *this;
// the valid JSON Patch operations
enum class patch_operations {add, remove, replace, move, copy, test, invalid};
const auto get_op = [](const std::string & op)
{
if (op == "add")
{
return patch_operations::add;
}
if (op == "remove")
{
return patch_operations::remove;
}
if (op == "replace")
{
return patch_operations::replace;
}
if (op == "move")
{
return patch_operations::move;
}
if (op == "copy")
{
return patch_operations::copy;
}
if (op == "test")
{
return patch_operations::test;
}
return patch_operations::invalid;
};
// wrapper for "add" operation; add value at ptr
const auto operation_add = [&result](json_pointer & ptr, basic_json val)
{
// adding to the root of the target document means replacing it
if (ptr.empty())
2018-01-10 01:30:02 +08:00
{
result = val;
2019-03-18 20:53:48 +08:00
return;
2018-01-10 01:30:02 +08:00
}
2019-03-18 20:53:48 +08:00
// make sure the top element of the pointer exists
json_pointer top_pointer = ptr.top();
if (top_pointer != ptr)
{
result.at(top_pointer);
2018-01-10 01:30:02 +08:00
}
2019-03-18 20:53:48 +08:00
// get reference to parent of JSON pointer ptr
2019-03-19 22:40:23 +08:00
const auto last_path = ptr.back();
ptr.pop_back();
2019-03-18 20:53:48 +08:00
basic_json& parent = result[ptr];
switch (parent.m_type)
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
case value_t::null:
case value_t::object:
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
// use operator[] to add value
parent[last_path] = val;
break;
2018-01-10 01:30:02 +08:00
}
2019-03-18 20:53:48 +08:00
case value_t::array:
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
if (last_path == "-")
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
// special case: append to back
parent.push_back(val);
2018-01-10 01:30:02 +08:00
}
2019-03-18 20:53:48 +08:00
else
2018-01-10 01:30:02 +08:00
{
const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
// avoid undefined behavior
JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
2018-01-10 01:30:02 +08:00
}
2019-03-18 20:53:48 +08:00
// default case: insert add offset
parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
2018-01-10 01:30:02 +08:00
}
2019-03-18 20:53:48 +08:00
break;
2018-01-10 01:30:02 +08:00
}
2019-03-18 20:53:48 +08:00
// if there exists a parent it cannot be primitive
case value_t::string: // LCOV_EXCL_LINE
case value_t::boolean: // LCOV_EXCL_LINE
case value_t::number_integer: // LCOV_EXCL_LINE
case value_t::number_unsigned: // LCOV_EXCL_LINE
case value_t::number_float: // LCOV_EXCL_LINE
case value_t::binary: // LCOV_EXCL_LINE
case value_t::discarded: // LCOV_EXCL_LINE
2019-03-18 20:53:48 +08:00
default: // LCOV_EXCL_LINE
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
2018-01-10 01:30:02 +08:00
}
};
// wrapper for "remove" operation; remove value at ptr
2021-01-02 23:13:04 +08:00
const auto operation_remove = [this, &result](json_pointer & ptr)
2018-01-10 01:30:02 +08:00
{
// get reference to parent of JSON pointer ptr
2019-03-19 22:40:23 +08:00
const auto last_path = ptr.back();
ptr.pop_back();
2018-01-10 01:30:02 +08:00
basic_json& parent = result.at(ptr);
// remove child
if (parent.is_object())
{
// perform range check
auto it = parent.find(last_path);
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_LIKELY(it != parent.end()))
2018-01-10 01:30:02 +08:00
{
parent.erase(it);
}
else
{
JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
2018-01-10 01:30:02 +08:00
}
}
else if (parent.is_array())
{
// note erase performs range check
parent.erase(json_pointer::template array_index<basic_json_t>(last_path));
2018-01-10 01:30:02 +08:00
}
};
// type check: top level value must be an array
if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
2018-01-10 01:30:02 +08:00
}
// iterate and apply the operations
for (const auto& val : json_patch)
{
// wrapper to get a value for an operation
const auto get_value = [&val](const std::string & op,
const std::string & member,
bool string_type) -> basic_json &
2018-01-10 01:30:02 +08:00
{
// find value
auto it = val.m_value.object->find(member);
// context-sensitive error message
const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\'');
2018-01-10 01:30:02 +08:00
// check if desired value is present
2019-07-02 04:37:30 +08:00
if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
2018-01-10 01:30:02 +08:00
{
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
// NOLINTNEXTLINE(performance-inefficient-string-concatenation)
JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
2018-01-10 01:30:02 +08:00
}
// check if result is of type string
if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
2018-01-10 01:30:02 +08:00
{
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
// NOLINTNEXTLINE(performance-inefficient-string-concatenation)
JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
2018-01-10 01:30:02 +08:00
}
// no error: return value
return it->second;
};
// type check: every element of the array must be an object
if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
2018-01-10 01:30:02 +08:00
}
// collect mandatory members
const auto op = get_value("op", "op", true).template get<std::string>();
const auto path = get_value(op, "path", true).template get<std::string>();
2018-01-10 01:30:02 +08:00
json_pointer ptr(path);
switch (get_op(op))
{
case patch_operations::add:
{
operation_add(ptr, get_value("add", "value", false));
break;
}
case patch_operations::remove:
{
operation_remove(ptr);
break;
}
case patch_operations::replace:
{
// the "path" location must exist - use at()
result.at(ptr) = get_value("replace", "value", false);
break;
}
case patch_operations::move:
{
const auto from_path = get_value("move", "from", true).template get<std::string>();
2018-01-10 01:30:02 +08:00
json_pointer from_ptr(from_path);
// the "from" location must exist - use at()
basic_json v = result.at(from_ptr);
// The move operation is functionally identical to a
// "remove" operation on the "from" location, followed
// immediately by an "add" operation at the target
// location with the value that was just removed.
operation_remove(from_ptr);
operation_add(ptr, v);
break;
}
case patch_operations::copy:
{
const auto from_path = get_value("copy", "from", true).template get<std::string>();
2018-01-10 01:30:02 +08:00
const json_pointer from_ptr(from_path);
// the "from" location must exist - use at()
basic_json v = result.at(from_ptr);
// The copy is functionally identical to an "add"
// operation at the target location using the value
// specified in the "from" member.
operation_add(ptr, v);
break;
}
case patch_operations::test:
{
bool success = false;
JSON_TRY
{
// check if "value" matches the one at "path"
// the "path" location must exist - use at()
success = (result.at(ptr) == get_value("test", "value", false));
}
JSON_INTERNAL_CATCH (out_of_range&)
2018-01-10 01:30:02 +08:00
{
// ignore out of range errors: success remains false
}
// throw an exception if test fails
if (JSON_HEDLEY_UNLIKELY(!success))
2018-01-10 01:30:02 +08:00
{
JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
2018-01-10 01:30:02 +08:00
}
break;
}
case patch_operations::invalid:
2019-03-17 19:01:49 +08:00
default:
2018-01-10 01:30:02 +08:00
{
// op must be "add", "remove", "replace", "move", "copy", or
// "test"
JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
2018-01-10 01:30:02 +08:00
}
}
}
return result;
}
/// @brief creates a diff as a JSON patch
/// @sa https://json.nlohmann.me/api/basic_json/diff/
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_WARN_UNUSED_RESULT
2018-01-10 01:30:02 +08:00
static basic_json diff(const basic_json& source, const basic_json& target,
const std::string& path = "")
{
// the patch
basic_json result(value_t::array);
// if the values are the same, return empty patch
if (source == target)
{
return result;
}
if (source.type() != target.type())
{
// different types: replace value
result.push_back(
{
{"op", "replace"}, {"path", path}, {"value", target}
});
2019-03-18 20:53:48 +08:00
return result;
2018-01-10 01:30:02 +08:00
}
2019-03-18 20:53:48 +08:00
switch (source.type())
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
case value_t::array:
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
// first pass: traverse common elements
std::size_t i = 0;
while (i < source.size() && i < target.size())
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
// recursive call to compare array values at index i
auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
2019-03-18 20:53:48 +08:00
result.insert(result.end(), temp_diff.begin(), temp_diff.end());
++i;
}
2018-01-10 01:30:02 +08:00
// We now reached the end of at least one array
2019-03-18 20:53:48 +08:00
// in a second pass, traverse the remaining elements
2018-01-10 01:30:02 +08:00
2019-03-18 20:53:48 +08:00
// remove my remaining elements
const auto end_index = static_cast<difference_type>(result.size());
while (i < source.size())
{
// add operations in reverse order to avoid invalid
// indices
result.insert(result.begin() + end_index, object(
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
{"op", "remove"},
{"path", detail::concat(path, '/', std::to_string(i))}
2019-03-18 20:53:48 +08:00
}));
++i;
}
2018-01-10 01:30:02 +08:00
2019-03-18 20:53:48 +08:00
// add other remaining elements
while (i < target.size())
{
result.push_back(
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
{"op", "add"},
{"path", detail::concat(path, "/-")},
2019-03-18 20:53:48 +08:00
{"value", target[i]}
});
++i;
2018-01-10 01:30:02 +08:00
}
2019-03-18 20:53:48 +08:00
break;
}
case value_t::object:
{
// first pass: traverse this object's elements
for (auto it = source.cbegin(); it != source.cend(); ++it)
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
// escape the key name to be used in a JSON patch
const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
2018-01-10 01:30:02 +08:00
2019-03-18 20:53:48 +08:00
if (target.find(it.key()) != target.end())
{
// recursive call to compare object values at key it
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
auto temp_diff = diff(it.value(), target[it.key()], path_key);
2019-03-18 20:53:48 +08:00
result.insert(result.end(), temp_diff.begin(), temp_diff.end());
2018-01-10 01:30:02 +08:00
}
2019-03-18 20:53:48 +08:00
else
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
// found a key that is not in o -> remove it
result.push_back(object(
2018-01-10 01:30:02 +08:00
{
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
{"op", "remove"}, {"path", path_key}
2019-03-18 20:53:48 +08:00
}));
2018-01-10 01:30:02 +08:00
}
}
2019-03-18 20:53:48 +08:00
// second pass: traverse other object's elements
for (auto it = target.cbegin(); it != target.cend(); ++it)
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
if (source.find(it.key()) == source.end())
2018-01-10 01:30:02 +08:00
{
2019-03-18 20:53:48 +08:00
// found a key that is not in this -> add it
const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
2019-03-18 20:53:48 +08:00
result.push_back(
{
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
{"op", "add"}, {"path", path_key},
2019-03-18 20:53:48 +08:00
{"value", it.value()}
});
}
2018-01-10 01:30:02 +08:00
}
2019-03-18 20:53:48 +08:00
break;
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
2019-03-18 20:53:48 +08:00
default:
{
// both primitive type: replace value
result.push_back(
{
{"op", "replace"}, {"path", path}, {"value", target}
});
break;
2018-01-10 01:30:02 +08:00
}
}
return result;
}
/// @}
////////////////////////////////
// JSON Merge Patch functions //
////////////////////////////////
/// @name JSON Merge Patch functions
/// @{
/// @brief applies a JSON Merge Patch
/// @sa https://json.nlohmann.me/api/basic_json/merge_patch/
void merge_patch(const basic_json& apply_patch)
{
if (apply_patch.is_object())
{
if (!is_object())
{
*this = object();
}
for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
{
if (it.value().is_null())
{
erase(it.key());
}
else
{
operator[](it.key()).merge_patch(it.value());
}
}
}
else
{
*this = apply_patch;
}
}
/// @}
2018-01-10 01:30:02 +08:00
};
/// @brief user-defined to_string function for JSON values
/// @sa https://json.nlohmann.me/api/basic_json/to_string/
NLOHMANN_BASIC_JSON_TPL_DECLARATION
std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
{
return j.dump();
}
2018-01-10 01:30:02 +08:00
} // namespace nlohmann
///////////////////////
// nonmember support //
///////////////////////
namespace std // NOLINT(cert-dcl58-cpp)
2018-01-10 01:30:02 +08:00
{
/// @brief hash value for JSON objects
/// @sa https://json.nlohmann.me/api/basic_json/std_hash/
NLOHMANN_BASIC_JSON_TPL_DECLARATION
struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL>
2018-01-10 01:30:02 +08:00
{
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
2018-01-10 01:30:02 +08:00
{
2020-07-14 20:31:19 +08:00
return nlohmann::detail::hash(j);
2018-01-10 01:30:02 +08:00
}
};
// specialization for std::less<value_t>
2018-01-10 01:30:02 +08:00
template<>
struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
2018-01-10 01:30:02 +08:00
{
/*!
@brief compare two value_t enum values
@since version 3.0.0
*/
bool operator()(::nlohmann::detail::value_t lhs,
::nlohmann::detail::value_t rhs) const noexcept
2018-01-10 01:30:02 +08:00
{
#if JSON_HAS_THREE_WAY_COMPARISON
return std::is_lt(lhs <=> rhs); // *NOPAD*
#else
return ::nlohmann::detail::operator<(lhs, rhs);
#endif
2018-01-10 01:30:02 +08:00
}
};
// C++20 prohibit function specialization in the std namespace.
#ifndef JSON_HAS_CPP_20
/// @brief exchanges the values of two JSON objects
/// @sa https://json.nlohmann.me/api/basic_json/std_swap/
NLOHMANN_BASIC_JSON_TPL_DECLARATION
inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression)
is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
{
j1.swap(j2);
}
#endif
2018-01-10 01:30:02 +08:00
} // namespace std
/// @brief user-defined string literal for JSON values
/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json/
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_NON_NULL(1)
2018-01-10 01:30:02 +08:00
inline nlohmann::json operator "" _json(const char* s, std::size_t n)
{
return nlohmann::json::parse(s, s + n);
}
/// @brief user-defined string literal for JSON pointer
/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json_pointer/
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_NON_NULL(1)
2018-01-10 01:30:02 +08:00
inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
{
return nlohmann::json::json_pointer(std::string(s, n));
}
#include <nlohmann/detail/macro_unscope.hpp>
2018-01-10 01:30:02 +08:00
2019-03-15 21:55:13 +08:00
#endif // INCLUDE_NLOHMANN_JSON_HPP_