mirror of
https://github.com/nlohmann/json.git
synced 2026-09-30 11:40:30 +00:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5fad30499 | ||
|
|
a9cc4243b7 | ||
|
|
03319da529 | ||
|
|
ae9ef9dde1 | ||
|
|
f9d4b51455 | ||
|
|
31883d06a8 | ||
|
|
4c208728e7 |
@@ -51,7 +51,6 @@ cc_library(
|
||||
"include/nlohmann/detail/meta/detected.hpp",
|
||||
"include/nlohmann/detail/meta/identity_tag.hpp",
|
||||
"include/nlohmann/detail/meta/is_sax.hpp",
|
||||
"include/nlohmann/detail/meta/logic.hpp",
|
||||
"include/nlohmann/detail/meta/std_fs.hpp",
|
||||
"include/nlohmann/detail/meta/type_traits.hpp",
|
||||
"include/nlohmann/detail/meta/void_t.hpp",
|
||||
|
||||
@@ -13,7 +13,7 @@ JSON object holding version information
|
||||
|
||||
| key | description |
|
||||
|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `compiler` | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `hp`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version). |
|
||||
| `compiler` | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version). On HP aCC compilers, `compiler` is instead the plain string `hp`. |
|
||||
| `copyright` | The copyright line for the library as string. |
|
||||
| `name` | The name of the library as string. |
|
||||
| `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`. |
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <nlohmann/detail/meta/identity_tag.hpp>
|
||||
#include <nlohmann/detail/meta/std_fs.hpp>
|
||||
#include <nlohmann/detail/meta/type_traits.hpp>
|
||||
#include <nlohmann/detail/meta/logic.hpp>
|
||||
#include <nlohmann/detail/string_concat.hpp>
|
||||
#include <nlohmann/detail/value_t.hpp>
|
||||
|
||||
@@ -429,9 +428,7 @@ inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
|
||||
}
|
||||
|
||||
// overload for arithmetic types, not chosen for basic_json template arguments
|
||||
// (BooleanType, etc.); note: Is it really necessary to provide explicit
|
||||
// overloads for boolean_t etc. in case of a custom BooleanType which is not
|
||||
// an arithmetic type?
|
||||
// (BooleanType, etc.)
|
||||
template < typename BasicJsonType, typename ArithmeticType,
|
||||
enable_if_t <
|
||||
std::is_arithmetic<ArithmeticType>::value&&
|
||||
@@ -527,7 +524,7 @@ inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priori
|
||||
template<typename BasicJsonType, typename... Args>
|
||||
std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
|
||||
{
|
||||
static_assert(cxpr_and<cxpr_or<cxpr_not<std::is_reference<Args>>, is_compatible_reference_type<BasicJsonType, Args>>...>::value,
|
||||
static_assert(conjunction<disjunction<negation<std::is_reference<Args>>, is_compatible_reference_type<BasicJsonType, Args>>...>::value,
|
||||
"Can not return a tuple containing references to types not contained in a Json, try Json::get_to()");
|
||||
return from_json_tuple_impl_base<1, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
|
||||
}
|
||||
@@ -592,7 +589,7 @@ inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Has
|
||||
|
||||
#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
||||
|
||||
// Workaround for MSVC 19.51 (and possibly later): in large in large cpp files, the compiler may fail to resolve with generic has_from_json (issue #4996)
|
||||
// Workaround for MSVC 19.51 (and possibly later): in large cpp files, the compiler may fail to resolve with generic has_from_json (issue #4996)
|
||||
template<typename BasicJsonType>
|
||||
struct has_from_json<BasicJsonType, std_fs::path, void> : std::true_type {};
|
||||
|
||||
|
||||
@@ -60,9 +60,11 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
|
||||
"iter_impl only accepts (const) basic_json");
|
||||
// superficial check for the LegacyBidirectionalIterator named requirement
|
||||
static_assert(std::is_base_of<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>::value
|
||||
&& std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,
|
||||
"basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement.");
|
||||
// note: only array_t::iterator is checked here; object_t::iterator may be
|
||||
// a forward-only iterator as long as reverse iteration and operator--
|
||||
// are never used on it
|
||||
static_assert(std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,
|
||||
"basic_json iterator assumes array type iterators satisfy the LegacyBidirectionalIterator named requirement.");
|
||||
|
||||
public:
|
||||
/// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
|
||||
|
||||
@@ -583,63 +583,6 @@ class json_pointer
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
@throw parse_error.106 if an array index begins with '0'
|
||||
@throw parse_error.109 if an array index was not a number
|
||||
@throw out_of_range.402 if the array index '-' is used
|
||||
@throw out_of_range.404 if the JSON pointer can not be resolved
|
||||
*/
|
||||
template<typename BasicJsonType>
|
||||
const BasicJsonType& get_checked(const BasicJsonType* ptr) const
|
||||
{
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
switch (ptr->type())
|
||||
{
|
||||
case detail::value_t::object:
|
||||
{
|
||||
// note: at performs range check
|
||||
ptr = &ptr->at(reference_token);
|
||||
break;
|
||||
}
|
||||
|
||||
case detail::value_t::array:
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
|
||||
{
|
||||
// "-" always fails the range check
|
||||
JSON_THROW(detail::out_of_range::create(402, detail::concat(
|
||||
"array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
|
||||
") is out of range"), ptr));
|
||||
}
|
||||
|
||||
const auto idx = array_index<BasicJsonType>(reference_token);
|
||||
// Bounds check before access to avoid exception with JSON_NOEXCEPTION
|
||||
if (JSON_HEDLEY_UNLIKELY(idx >= ptr->m_data.m_value.array->size()))
|
||||
{
|
||||
JSON_THROW(detail::out_of_range::create(401, detail::concat(
|
||||
"array index ", std::to_string(idx), " is out of range"), ptr));
|
||||
}
|
||||
ptr = &ptr->operator[](idx);
|
||||
break;
|
||||
}
|
||||
|
||||
case detail::value_t::null:
|
||||
case detail::value_t::string:
|
||||
case detail::value_t::boolean:
|
||||
case detail::value_t::number_integer:
|
||||
case detail::value_t::number_unsigned:
|
||||
case detail::value_t::number_float:
|
||||
case detail::value_t::binary:
|
||||
case detail::value_t::discarded:
|
||||
default:
|
||||
JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
|
||||
}
|
||||
}
|
||||
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief return a pointer to the pointed to value, or `nullptr` if the
|
||||
pointer cannot be resolved because a key is missing, an array
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <utility> // declval, pair
|
||||
#include <nlohmann/detail/meta/detected.hpp>
|
||||
#include <nlohmann/thirdparty/hedley/hedley.hpp>
|
||||
|
||||
// This file contains all internal macro definitions (except those affecting ABI)
|
||||
@@ -140,10 +139,12 @@
|
||||
// libstdc++ < 11 has incomplete C++20 ranges (issue #4440)
|
||||
#elif defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE < 11
|
||||
#define JSON_HAS_RANGES 0
|
||||
// libc++ < 16 has incomplete C++20 ranges (issue #4440)
|
||||
// clang < 16 with libstdc++ does not implement the ranges customization
|
||||
// points libstdc++ declares, so its C++20 ranges support is incomplete (issue #5161)
|
||||
#elif defined(__clang__) && !defined(__apple_build_version__) \
|
||||
&& __clang_major__ < 16 && defined(__GLIBCXX__)
|
||||
#define JSON_HAS_RANGES 0
|
||||
// libc++ < 16 has incomplete C++20 ranges (issue #4440)
|
||||
#elif defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 160000
|
||||
#define JSON_HAS_RANGES 0
|
||||
// nvcc CUDA 12.0/12.1 chokes on the enable_borrowed_range variable-template
|
||||
@@ -305,7 +306,7 @@ void templated_json_throw(ExceptionType exception)
|
||||
@brief macro to briefly define a mapping between an enum and JSON with exception
|
||||
on invalid input
|
||||
@def NLOHMANN_JSON_SERIALIZE_ENUM_STRICT
|
||||
@since version 3.12.0
|
||||
@since version 3.13.0
|
||||
*/
|
||||
#define NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(ENUM_TYPE, ...) \
|
||||
template<typename BasicJsonType> \
|
||||
@@ -876,30 +877,6 @@ void templated_json_throw(ExceptionType exception)
|
||||
\
|
||||
template<typename... T> \
|
||||
using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
|
||||
} \
|
||||
\
|
||||
namespace detail2 { \
|
||||
struct std_name##_tag \
|
||||
{ \
|
||||
}; \
|
||||
\
|
||||
template<typename... T> \
|
||||
std_name##_tag std_name(T&&...); \
|
||||
\
|
||||
template<typename... T> \
|
||||
using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
|
||||
\
|
||||
template<typename... T> \
|
||||
struct would_call_std_##std_name \
|
||||
{ \
|
||||
static constexpr auto const value = ::nlohmann::detail:: \
|
||||
is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
|
||||
}; \
|
||||
} /* namespace detail2 */ \
|
||||
\
|
||||
template<typename... T> \
|
||||
struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
|
||||
{ \
|
||||
}
|
||||
|
||||
#ifndef JSON_USE_IMPLICIT_CONVERSIONS
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
|
||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||
|
||||
NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin);
|
||||
NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin)
|
||||
|
||||
NLOHMANN_JSON_NAMESPACE_END
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
|
||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||
|
||||
NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end);
|
||||
NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end)
|
||||
|
||||
NLOHMANN_JSON_NAMESPACE_END
|
||||
|
||||
@@ -62,9 +62,5 @@ using detected_or_t = typename detected_or<Default, Op, Args...>::type;
|
||||
template<class Expected, template<class...> class Op, class... Args>
|
||||
using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
|
||||
|
||||
template<class To, template<class...> class Op, class... Args>
|
||||
using is_detected_convertible =
|
||||
std::is_convertible<detected_t<Op, Args...>, To>;
|
||||
|
||||
} // namespace detail
|
||||
NLOHMANN_JSON_NAMESPACE_END
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint> // size_t
|
||||
#include <cstddef> // size_t
|
||||
#include <utility> // declval
|
||||
#include <string> // string
|
||||
|
||||
@@ -70,37 +70,6 @@ using parse_error_function_t = decltype(std::declval<T&>().parse_error(
|
||||
std::declval<std::size_t>(), std::declval<const std::string&>(),
|
||||
std::declval<const Exception&>()));
|
||||
|
||||
template<typename SAX, typename BasicJsonType>
|
||||
struct is_sax
|
||||
{
|
||||
private:
|
||||
static_assert(is_basic_json<BasicJsonType>::value,
|
||||
"BasicJsonType must be of type basic_json<...>");
|
||||
|
||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
||||
using number_float_t = typename BasicJsonType::number_float_t;
|
||||
using string_t = typename BasicJsonType::string_t;
|
||||
using binary_t = typename BasicJsonType::binary_t;
|
||||
using exception_t = typename BasicJsonType::exception;
|
||||
|
||||
public:
|
||||
static constexpr bool value =
|
||||
is_detected_exact<bool, null_function_t, SAX>::value &&
|
||||
is_detected_exact<bool, boolean_function_t, SAX>::value &&
|
||||
is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
|
||||
is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
|
||||
is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
|
||||
is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
|
||||
is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
|
||||
is_detected_exact<bool, start_object_function_t, SAX>::value &&
|
||||
is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
|
||||
is_detected_exact<bool, end_object_function_t, SAX>::value &&
|
||||
is_detected_exact<bool, start_array_function_t, SAX>::value &&
|
||||
is_detected_exact<bool, end_array_function_t, SAX>::value &&
|
||||
is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
|
||||
};
|
||||
|
||||
template<typename SAX, typename BasicJsonType>
|
||||
struct is_sax_static_asserts
|
||||
{
|
||||
@@ -120,8 +89,6 @@ struct is_sax_static_asserts
|
||||
"Missing/invalid function: bool null()");
|
||||
static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
|
||||
"Missing/invalid function: bool boolean(bool)");
|
||||
static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
|
||||
"Missing/invalid function: bool boolean(bool)");
|
||||
static_assert(
|
||||
is_detected_exact<bool, number_integer_function_t, SAX,
|
||||
number_integer_t>::value,
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <nlohmann/detail/macro_scope.hpp>
|
||||
|
||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||
namespace detail
|
||||
{
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
|
||||
template<bool... Booleans>
|
||||
struct cxpr_or_impl : std::integral_constant < bool, (Booleans || ...) > {};
|
||||
|
||||
template<bool... Booleans>
|
||||
struct cxpr_and_impl : std::integral_constant < bool, (Booleans &&...) > {};
|
||||
|
||||
#else
|
||||
|
||||
template<bool... Booleans>
|
||||
struct cxpr_or_impl : std::false_type {};
|
||||
|
||||
template<bool... Booleans>
|
||||
struct cxpr_or_impl<true, Booleans...> : std::true_type {};
|
||||
|
||||
template<bool... Booleans>
|
||||
struct cxpr_or_impl<false, Booleans...> : cxpr_or_impl<Booleans...> {};
|
||||
|
||||
template<bool... Booleans>
|
||||
struct cxpr_and_impl : std::true_type {};
|
||||
|
||||
template<bool... Booleans>
|
||||
struct cxpr_and_impl<true, Booleans...> : cxpr_and_impl<Booleans...> {};
|
||||
|
||||
template<bool... Booleans>
|
||||
struct cxpr_and_impl<false, Booleans...> : std::false_type {};
|
||||
|
||||
#endif
|
||||
|
||||
template<class Boolean>
|
||||
struct cxpr_not : std::integral_constant < bool, !Boolean::value > {};
|
||||
|
||||
template<class... Booleans>
|
||||
struct cxpr_or : cxpr_or_impl<Booleans::value...> {};
|
||||
|
||||
template<bool... Booleans>
|
||||
struct cxpr_or_c : cxpr_or_impl<Booleans...> {};
|
||||
|
||||
template<class... Booleans>
|
||||
struct cxpr_and : cxpr_and_impl<Booleans::value...> {};
|
||||
|
||||
template<bool... Booleans>
|
||||
struct cxpr_and_c : cxpr_and_impl<Booleans...> {};
|
||||
|
||||
} // namespace detail
|
||||
NLOHMANN_JSON_NAMESPACE_END
|
||||
@@ -283,6 +283,13 @@ template<class B, class... Bn>
|
||||
struct conjunction<B, Bn...>
|
||||
: std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type {};
|
||||
|
||||
// https://en.cppreference.com/w/cpp/types/disjunction
|
||||
template<class...> struct disjunction : std::false_type { };
|
||||
template<class B> struct disjunction<B> : B { };
|
||||
template<class B, class... Bn>
|
||||
struct disjunction<B, Bn...>
|
||||
: std::conditional<static_cast<bool>(B::value), B, disjunction<Bn...>>::type {};
|
||||
|
||||
// https://en.cppreference.com/w/cpp/types/negation
|
||||
template<class B> struct negation : std::integral_constant < bool, !B::value > { };
|
||||
|
||||
@@ -604,7 +611,6 @@ struct is_compatible_integer_type_impl <
|
||||
std::is_integral<CompatibleNumberIntegerType>::value&&
|
||||
!std::is_same<bool, CompatibleNumberIntegerType>::value >>
|
||||
{
|
||||
// is there an assert somewhere on overflows?
|
||||
using RealLimits = std::numeric_limits<RealIntegerType>;
|
||||
using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
|
||||
|
||||
@@ -798,20 +804,7 @@ struct has_capacity : std::integral_constant<bool, is_detected<detect_capacity,
|
||||
// a naive helper to check if a type is an ordered_map (exploits the fact that
|
||||
// ordered_map inherits capacity() from std::vector)
|
||||
template <typename T>
|
||||
struct is_ordered_map
|
||||
{
|
||||
using one = char;
|
||||
|
||||
struct two
|
||||
{
|
||||
char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||
};
|
||||
|
||||
template <typename C> static one test( decltype(&C::capacity) ) ;
|
||||
template <typename C> static two test(...);
|
||||
|
||||
enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg,cppcoreguidelines-use-enum-class)
|
||||
};
|
||||
struct is_ordered_map : has_capacity<T> {};
|
||||
|
||||
// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
|
||||
template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
|
||||
@@ -835,10 +828,8 @@ using all_signed = conjunction<std::is_signed<Types>...>;
|
||||
template<typename... Types>
|
||||
using all_unsigned = conjunction<std::is_unsigned<Types>...>;
|
||||
|
||||
// there's a disjunction trait in another PR; replace when merged
|
||||
template<typename... Types>
|
||||
using same_sign = std::integral_constant < bool,
|
||||
all_signed<Types...>::value || all_unsigned<Types...>::value >;
|
||||
using same_sign = disjunction<all_signed<Types...>, all_unsigned<Types...>>;
|
||||
|
||||
template<typename OfType, typename T>
|
||||
using never_out_of_range = std::integral_constant < bool,
|
||||
|
||||
@@ -39,6 +39,7 @@ inline std::size_t concat_length(const char /*c*/, const Args& ... rest)
|
||||
template<typename... Args>
|
||||
inline std::size_t concat_length(const char* cstr, const Args& ... rest)
|
||||
{
|
||||
// cppcheck-suppress ignoredReturnValue
|
||||
return ::strlen(cstr) + concat_length(rest...);
|
||||
}
|
||||
|
||||
|
||||
+197
-91
@@ -110,12 +110,11 @@ struct is_std_optional<std::optional<T>> : std::true_type {};
|
||||
@brief a class to store JSON values
|
||||
|
||||
@internal
|
||||
@invariant The member variables @a m_data.m_value and @a m_data.m_type have
|
||||
the following relationship:
|
||||
- If `m_data.m_type == value_t::object`, then `m_data.m_value.object != nullptr`.
|
||||
- If `m_data.m_type == value_t::array`, then `m_data.m_value.array != nullptr`.
|
||||
- If `m_data.m_type == value_t::string`, then `m_data.m_value.string != nullptr`.
|
||||
- If `m_data.m_type == value_t::binary`, then `m_data.m_value.binary != nullptr`.
|
||||
@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().
|
||||
|
||||
@note ObjectType trick from https://stackoverflow.com/a/9860911
|
||||
@@ -175,12 +174,18 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
}
|
||||
|
||||
private:
|
||||
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>;
|
||||
|
||||
template<typename InputType>
|
||||
using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
|
||||
template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
|
||||
@@ -321,8 +326,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
std::to_string(__GNUC_PATCHLEVEL__))
|
||||
}
|
||||
};
|
||||
#elif defined(__HP_aCC)
|
||||
result["compiler"] = {{"family", "hp"}, {"version", __HP_aCC}};
|
||||
#elif defined(__HP_cc) || defined(__HP_aCC)
|
||||
result["compiler"] = "hp"
|
||||
#elif defined(__IBMCPP__)
|
||||
result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
|
||||
#elif defined(_MSC_VER)
|
||||
@@ -464,9 +469,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
binary | binary | pointer to @ref binary_t
|
||||
null | null | *no value is stored*
|
||||
|
||||
@note Variable-length types (objects, arrays, strings, and binary
|
||||
values) are stored as pointers. The size of the union should not exceed
|
||||
64 bits if the default value types are used.
|
||||
@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
|
||||
*/
|
||||
@@ -718,7 +723,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
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_data.m_type and @a m_data.m_value.
|
||||
@a m_type and @a m_value.
|
||||
|
||||
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
|
||||
@@ -739,6 +744,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
#if JSON_DIAGNOSTICS
|
||||
JSON_TRY
|
||||
{
|
||||
// cppcheck-suppress assertWithSideEffect
|
||||
JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
|
||||
{
|
||||
return j.m_parent == this;
|
||||
@@ -1578,7 +1584,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief create a null object
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
||||
basic_json(std::nullptr_t = nullptr) noexcept
|
||||
basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
|
||||
: basic_json(value_t::null)
|
||||
{
|
||||
assert_invariant();
|
||||
}
|
||||
@@ -1942,15 +1949,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// @brief move constructor
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
||||
basic_json(basic_json&& other) noexcept
|
||||
: json_base_class_t(std::move(static_cast<json_base_class_t&>(other))),
|
||||
m_data(std::move(other.m_data))
|
||||
: json_base_class_t(std::forward<json_base_class_t>(other)),
|
||||
m_data(std::move(other.m_data)) // cppcheck-suppress[accessForwarded] TODO check
|
||||
#if JSON_DIAGNOSTIC_POSITIONS
|
||||
, start_position(other.start_position)
|
||||
, end_position(other.end_position)
|
||||
, start_position(other.start_position) // cppcheck-suppress[accessForwarded] TODO check
|
||||
, end_position(other.end_position) // cppcheck-suppress[accessForwarded] TODO check
|
||||
#endif
|
||||
{
|
||||
// check that the passed value is valid
|
||||
other.assert_invariant(false);
|
||||
other.assert_invariant(false); // cppcheck-suppress[accessForwarded]
|
||||
|
||||
// invalidate payload
|
||||
other.m_data.m_type = value_t::null;
|
||||
@@ -2517,7 +2524,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
@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, @ref number_float_t, or @ref binary_t.
|
||||
@ref number_unsigned_t, or @ref number_float_t.
|
||||
|
||||
@return pointer to the internally stored JSON value if the requested
|
||||
pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
|
||||
@@ -3043,7 +3050,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
|
||||
}
|
||||
|
||||
/// @brief access specified object element with default value
|
||||
/// @brief access specified object element via JSON Pointer with default value
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/value/
|
||||
template < class ValueType, class KeyType, class ReturnType = typename value_return_type<ValueType>::type,
|
||||
detail::enable_if_t <
|
||||
@@ -3201,8 +3208,21 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
|
||||
}
|
||||
|
||||
m_data.m_value.destroy(m_data.m_type);
|
||||
m_data.m_value = {};
|
||||
if (is_string())
|
||||
{
|
||||
AllocatorType<string_t> alloc;
|
||||
std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
|
||||
std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
|
||||
m_data.m_value.string = nullptr;
|
||||
}
|
||||
else if (is_binary())
|
||||
{
|
||||
AllocatorType<binary_t> alloc;
|
||||
std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
|
||||
std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
|
||||
m_data.m_value.binary = nullptr;
|
||||
}
|
||||
|
||||
m_data.m_type = value_t::null;
|
||||
assert_invariant();
|
||||
break;
|
||||
@@ -3254,14 +3274,27 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
case value_t::string:
|
||||
case value_t::binary:
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
|
||||
|| !last.m_it.primitive_iterator.is_end()))
|
||||
if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
|
||||
|| !last.m_it.primitive_iterator.is_end()))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
|
||||
}
|
||||
|
||||
m_data.m_value.destroy(m_data.m_type);
|
||||
m_data.m_value = {};
|
||||
if (is_string())
|
||||
{
|
||||
AllocatorType<string_t> alloc;
|
||||
std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
|
||||
std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
|
||||
m_data.m_value.string = nullptr;
|
||||
}
|
||||
else if (is_binary())
|
||||
{
|
||||
AllocatorType<binary_t> alloc;
|
||||
std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
|
||||
std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
|
||||
m_data.m_value.binary = nullptr;
|
||||
}
|
||||
|
||||
m_data.m_type = value_t::null;
|
||||
assert_invariant();
|
||||
break;
|
||||
@@ -4043,22 +4076,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/insert/
|
||||
iterator insert(const_iterator pos, basic_json&& val) // NOLINT(performance-unnecessary-value-param)
|
||||
{
|
||||
// insert only works for arrays
|
||||
if (JSON_HEDLEY_LIKELY(is_array()))
|
||||
{
|
||||
// check if iterator pos fits to this JSON value
|
||||
if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
|
||||
}
|
||||
|
||||
// moving into a local first keeps this safe even if val aliases
|
||||
// an element of this array
|
||||
basic_json tmp(std::move(val));
|
||||
return insert_iterator(pos, std::move(tmp));
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
|
||||
return insert(std::move(pos), val);
|
||||
}
|
||||
|
||||
/// @brief inserts copies of element into array
|
||||
@@ -4399,7 +4417,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/swap/
|
||||
void swap(binary_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
|
||||
{
|
||||
// swap only works for binary values
|
||||
// swap only works for strings
|
||||
if (JSON_HEDLEY_LIKELY(is_binary()))
|
||||
{
|
||||
using std::swap;
|
||||
@@ -4415,7 +4433,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/swap/
|
||||
void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
|
||||
{
|
||||
// swap only works for binary values
|
||||
// swap only works for strings
|
||||
if (JSON_HEDLEY_LIKELY(is_binary()))
|
||||
{
|
||||
using std::swap;
|
||||
@@ -4895,8 +4913,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool ignore_trailing_commas = false)
|
||||
{
|
||||
basic_json result;
|
||||
auto p = parser(detail::input_adapter(std::forward<InputType>(i)), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas);
|
||||
p.parse(true, result);
|
||||
parser(detail::input_adapter(std::forward<InputType>(i)), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas).parse(true, result); // cppcheck-suppress[accessMoved,accessForwarded]
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -4913,8 +4930,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool ignore_trailing_commas = false)
|
||||
{
|
||||
basic_json result;
|
||||
auto p = parser(detail::input_adapter(std::move(first), std::move(last)), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas);
|
||||
p.parse(true, result);
|
||||
parser(detail::input_adapter(std::move(first), std::move(last)), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas).parse(true, result); // cppcheck-suppress[accessMoved]
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -4927,8 +4943,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool ignore_trailing_commas = false)
|
||||
{
|
||||
basic_json result;
|
||||
auto p = parser(i.get(), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas);
|
||||
p.parse(true, result);
|
||||
parser(i.get(), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas).parse(true, result); // cppcheck-suppress[accessMoved]
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -5136,31 +5151,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
/*!
|
||||
@brief shared implementation of the binary from_cbor/from_msgpack/
|
||||
from_ubjson/from_bjdata/from_bon8/from_bson overloads
|
||||
|
||||
Building the @ref binary_reader as a named local, rather than as a
|
||||
temporary that @ref detail::json_sax_dom_parser::parse is called on in
|
||||
the same expression, avoids a false-positive cppcheck accessMoved
|
||||
warning in each of the 16 callers.
|
||||
*/
|
||||
template<typename InputAdapterType>
|
||||
static basic_json from_binary_impl(InputAdapterType ia, const input_format_t format,
|
||||
const bool strict, const bool allow_exceptions,
|
||||
const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
|
||||
{
|
||||
basic_json result;
|
||||
detail::json_sax_dom_parser<basic_json, InputAdapterType> sdp(result, allow_exceptions);
|
||||
binary_reader<InputAdapterType> reader(std::move(ia), format);
|
||||
if (!reader.sax_parse(format, &sdp, strict, tag_handler))
|
||||
{
|
||||
result = value_t::discarded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// binary serialization/deserialization //
|
||||
//////////////////////////////////////////
|
||||
@@ -5333,7 +5323,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool allow_exceptions = true,
|
||||
const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
|
||||
{
|
||||
return from_binary_impl(detail::input_adapter(std::forward<InputType>(i)), input_format_t::cbor, strict, allow_exceptions, tag_handler);
|
||||
basic_json result;
|
||||
auto ia = detail::input_adapter(std::forward<InputType>(i));
|
||||
detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
|
||||
if (!binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler)) // cppcheck-suppress[accessMoved]
|
||||
{
|
||||
result = value_t::discarded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief create a JSON value from an input in CBOR format (iterator pair, or iterator+sentinel pair for C++20 ranges support)
|
||||
@@ -5346,7 +5343,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool allow_exceptions = true,
|
||||
const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
|
||||
{
|
||||
return from_binary_impl(detail::input_adapter(std::move(first), std::move(last)), input_format_t::cbor, strict, allow_exceptions, tag_handler);
|
||||
basic_json result;
|
||||
auto ia = detail::input_adapter(std::move(first), std::move(last));
|
||||
detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
|
||||
if (!binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler)) // cppcheck-suppress[accessMoved]
|
||||
{
|
||||
result = value_t::discarded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -5367,7 +5371,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool allow_exceptions = true,
|
||||
const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
|
||||
{
|
||||
return from_binary_impl(i.get(), input_format_t::cbor, strict, allow_exceptions, tag_handler);
|
||||
basic_json result;
|
||||
auto ia = i.get();
|
||||
detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
|
||||
// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
|
||||
if (!binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler)) // cppcheck-suppress[accessMoved]
|
||||
{
|
||||
result = value_t::discarded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief create a JSON value from an input in MessagePack format
|
||||
@@ -5378,7 +5390,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool strict = true,
|
||||
const bool allow_exceptions = true)
|
||||
{
|
||||
return from_binary_impl(detail::input_adapter(std::forward<InputType>(i)), input_format_t::msgpack, strict, allow_exceptions);
|
||||
basic_json result;
|
||||
auto ia = detail::input_adapter(std::forward<InputType>(i));
|
||||
detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
|
||||
if (!binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict)) // cppcheck-suppress[accessMoved]
|
||||
{
|
||||
result = value_t::discarded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief create a JSON value from an input in MessagePack format (iterator pair, or iterator+sentinel pair for C++20 ranges support)
|
||||
@@ -5390,7 +5409,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool strict = true,
|
||||
const bool allow_exceptions = true)
|
||||
{
|
||||
return from_binary_impl(detail::input_adapter(std::move(first), std::move(last)), input_format_t::msgpack, strict, allow_exceptions);
|
||||
basic_json result;
|
||||
auto ia = detail::input_adapter(std::move(first), std::move(last));
|
||||
detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
|
||||
if (!binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict)) // cppcheck-suppress[accessMoved]
|
||||
{
|
||||
result = value_t::discarded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -5409,7 +5435,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool strict = true,
|
||||
const bool allow_exceptions = true)
|
||||
{
|
||||
return from_binary_impl(i.get(), input_format_t::msgpack, strict, allow_exceptions);
|
||||
basic_json result;
|
||||
auto ia = i.get();
|
||||
detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
|
||||
// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
|
||||
if (!binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict)) // cppcheck-suppress[accessMoved]
|
||||
{
|
||||
result = value_t::discarded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief create a JSON value from an input in UBJSON format
|
||||
@@ -5420,7 +5454,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool strict = true,
|
||||
const bool allow_exceptions = true)
|
||||
{
|
||||
return from_binary_impl(detail::input_adapter(std::forward<InputType>(i)), input_format_t::ubjson, strict, allow_exceptions);
|
||||
basic_json result;
|
||||
auto ia = detail::input_adapter(std::forward<InputType>(i));
|
||||
detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
|
||||
if (!binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict)) // cppcheck-suppress[accessMoved]
|
||||
{
|
||||
result = value_t::discarded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief create a JSON value from an input in UBJSON format (iterator pair, or iterator+sentinel pair for C++20 ranges support)
|
||||
@@ -5432,7 +5473,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool strict = true,
|
||||
const bool allow_exceptions = true)
|
||||
{
|
||||
return from_binary_impl(detail::input_adapter(std::move(first), std::move(last)), input_format_t::ubjson, strict, allow_exceptions);
|
||||
basic_json result;
|
||||
auto ia = detail::input_adapter(std::move(first), std::move(last));
|
||||
detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
|
||||
if (!binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict)) // cppcheck-suppress[accessMoved]
|
||||
{
|
||||
result = value_t::discarded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -5451,7 +5499,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool strict = true,
|
||||
const bool allow_exceptions = true)
|
||||
{
|
||||
return from_binary_impl(i.get(), input_format_t::ubjson, strict, allow_exceptions);
|
||||
basic_json result;
|
||||
auto ia = i.get();
|
||||
detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
|
||||
// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
|
||||
if (!binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict)) // cppcheck-suppress[accessMoved]
|
||||
{
|
||||
result = value_t::discarded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief create a JSON value from an input in BJData format
|
||||
@@ -5462,7 +5518,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool strict = true,
|
||||
const bool allow_exceptions = true)
|
||||
{
|
||||
return from_binary_impl(detail::input_adapter(std::forward<InputType>(i)), input_format_t::bjdata, strict, allow_exceptions);
|
||||
basic_json result;
|
||||
auto ia = detail::input_adapter(std::forward<InputType>(i));
|
||||
detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
|
||||
if (!binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict)) // cppcheck-suppress[accessMoved]
|
||||
{
|
||||
result = value_t::discarded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief create a JSON value from an input in BJData format (iterator pair, or iterator+sentinel pair for C++20 ranges support)
|
||||
@@ -5474,7 +5537,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool strict = true,
|
||||
const bool allow_exceptions = true)
|
||||
{
|
||||
return from_binary_impl(detail::input_adapter(std::move(first), std::move(last)), input_format_t::bjdata, strict, allow_exceptions);
|
||||
basic_json result;
|
||||
auto ia = detail::input_adapter(std::move(first), std::move(last));
|
||||
detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
|
||||
if (!binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict)) // cppcheck-suppress[accessMoved]
|
||||
{
|
||||
result = value_t::discarded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief create a JSON value from an input in BON8 format
|
||||
@@ -5485,7 +5555,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool strict = true,
|
||||
const bool allow_exceptions = true)
|
||||
{
|
||||
return from_binary_impl(detail::input_adapter(std::forward<InputType>(i)), input_format_t::bon8, strict, allow_exceptions);
|
||||
basic_json result;
|
||||
auto ia = detail::input_adapter(std::forward<InputType>(i));
|
||||
detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
|
||||
if (!binary_reader<decltype(ia)>(std::move(ia), input_format_t::bon8).sax_parse(input_format_t::bon8, &sdp, strict)) // cppcheck-suppress[accessMoved]
|
||||
{
|
||||
result = value_t::discarded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief create a JSON value from an input in BON8 format (iterator pair, or iterator+sentinel pair for C++20 ranges support)
|
||||
@@ -5497,7 +5574,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool strict = true,
|
||||
const bool allow_exceptions = true)
|
||||
{
|
||||
return from_binary_impl(detail::input_adapter(std::move(first), std::move(last)), input_format_t::bon8, strict, allow_exceptions);
|
||||
basic_json result;
|
||||
auto ia = detail::input_adapter(std::move(first), std::move(last));
|
||||
detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
|
||||
if (!binary_reader<decltype(ia)>(std::move(ia), input_format_t::bon8).sax_parse(input_format_t::bon8, &sdp, strict)) // cppcheck-suppress[accessMoved]
|
||||
{
|
||||
result = value_t::discarded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief create a JSON value from an input in BSON format
|
||||
@@ -5508,7 +5592,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool strict = true,
|
||||
const bool allow_exceptions = true)
|
||||
{
|
||||
return from_binary_impl(detail::input_adapter(std::forward<InputType>(i)), input_format_t::bson, strict, allow_exceptions);
|
||||
basic_json result;
|
||||
auto ia = detail::input_adapter(std::forward<InputType>(i));
|
||||
detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
|
||||
if (!binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict)) // cppcheck-suppress[accessMoved]
|
||||
{
|
||||
result = value_t::discarded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief create a JSON value from an input in BSON format (iterator pair, or iterator+sentinel pair for C++20 ranges support)
|
||||
@@ -5520,7 +5611,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool strict = true,
|
||||
const bool allow_exceptions = true)
|
||||
{
|
||||
return from_binary_impl(detail::input_adapter(std::move(first), std::move(last)), input_format_t::bson, strict, allow_exceptions);
|
||||
basic_json result;
|
||||
auto ia = detail::input_adapter(std::move(first), std::move(last));
|
||||
detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
|
||||
if (!binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict)) // cppcheck-suppress[accessMoved]
|
||||
{
|
||||
result = value_t::discarded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -5539,7 +5637,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool strict = true,
|
||||
const bool allow_exceptions = true)
|
||||
{
|
||||
return from_binary_impl(i.get(), input_format_t::bson, strict, allow_exceptions);
|
||||
basic_json result;
|
||||
auto ia = i.get();
|
||||
detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
|
||||
// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
|
||||
if (!binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict)) // cppcheck-suppress[accessMoved]
|
||||
{
|
||||
result = value_t::discarded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/// @}
|
||||
|
||||
|
||||
+314
-391
File diff suppressed because it is too large
Load Diff
@@ -618,49 +618,6 @@ TEST_CASE("modifiers")
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("rvalue at position moves rather than copies")
|
||||
{
|
||||
// regression test: insert(pos, basic_json&&) used to forward to
|
||||
// insert(pos, const basic_json&) because the named rvalue
|
||||
// reference parameter is itself an lvalue, so it always
|
||||
// deep-copied its argument instead of moving it
|
||||
json j_big = std::string(1000, 'x');
|
||||
const auto* const original_buffer = j_big.get_ref<const std::string&>().data();
|
||||
|
||||
auto it = j_array.insert(j_array.begin(), std::move(j_big));
|
||||
CHECK(j_array.size() == 5);
|
||||
CHECK(*it == json(std::string(1000, 'x')));
|
||||
CHECK((*it).get_ref<const std::string&>().data() == original_buffer);
|
||||
|
||||
// the moved-from value is null, the same as after push_back(&&)
|
||||
CHECK(j_big.is_null()); // NOLINT(bugprone-use-after-move,hicpp-invalid-access-moved)
|
||||
}
|
||||
|
||||
SECTION("self-aliasing insertion")
|
||||
{
|
||||
SECTION("without reallocation")
|
||||
{
|
||||
json j_self = {1, 2, 3, 4};
|
||||
j_self.get_ref<json::array_t&>().reserve(j_self.size() + 1);
|
||||
|
||||
auto it = j_self.insert(j_self.begin(), std::move(j_self[1]));
|
||||
CHECK(j_self.size() == 5);
|
||||
CHECK(*it == json(2));
|
||||
CHECK(j_self == json({2, 1, nullptr, 3, 4}));
|
||||
}
|
||||
|
||||
SECTION("with reallocation")
|
||||
{
|
||||
json j_self = {1, 2, 3, 4};
|
||||
j_self.get_ref<json::array_t&>().shrink_to_fit();
|
||||
|
||||
auto it = j_self.insert(j_self.begin(), std::move(j_self[1]));
|
||||
CHECK(j_self.size() == 5);
|
||||
CHECK(*it == json(2));
|
||||
CHECK(j_self == json({2, 1, nullptr, 3, 4}));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("copies at position")
|
||||
{
|
||||
SECTION("insert before begin()")
|
||||
|
||||
@@ -10,10 +10,14 @@
|
||||
|
||||
#if JSON_TEST_USING_MULTIPLE_HEADERS
|
||||
#include <nlohmann/detail/meta/type_traits.hpp>
|
||||
#include <nlohmann/ordered_map.hpp>
|
||||
#else
|
||||
#include <nlohmann/json.hpp>
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
TEST_CASE("type traits")
|
||||
{
|
||||
SECTION("is_c_string")
|
||||
@@ -83,4 +87,12 @@ TEST_CASE("type traits")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("is_ordered_map")
|
||||
{
|
||||
using nlohmann::detail::is_ordered_map;
|
||||
|
||||
CHECK(is_ordered_map<nlohmann::ordered_map<std::string, int>>::value);
|
||||
CHECK_FALSE(is_ordered_map<std::map<std::string, int>>::value);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user