bump to nlohmann/json 3.10.4
diff --git a/third_party/include/nlohmann/json.hpp b/third_party/include/nlohmann/json.hpp
index 34a8d32..87475ab 100644
--- a/third_party/include/nlohmann/json.hpp
+++ b/third_party/include/nlohmann/json.hpp
@@ -1,7 +1,7 @@
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++
-| | |__ | | | | | | version 3.9.1
+| | |__ | | | | | | version 3.10.4
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@@ -31,14 +31,16 @@
#define INCLUDE_NLOHMANN_JSON_HPP_
#define NLOHMANN_JSON_VERSION_MAJOR 3
-#define NLOHMANN_JSON_VERSION_MINOR 9
-#define NLOHMANN_JSON_VERSION_PATCH 1
+#define NLOHMANN_JSON_VERSION_MINOR 10
+#define NLOHMANN_JSON_VERSION_PATCH 4
#include <algorithm> // all_of, find, for_each
#include <cstddef> // nullptr_t, ptrdiff_t, size_t
#include <functional> // hash, less
#include <initializer_list> // initializer_list
-#include <iosfwd> // istream, ostream
+#ifndef JSON_NO_IO
+ #include <iosfwd> // istream, ostream
+#endif // JSON_NO_IO
#include <iterator> // random_access_iterator_tag
#include <memory> // unique_ptr
#include <numeric> // accumulate
@@ -165,7 +167,7 @@
// #include <nlohmann/detail/macro_scope.hpp>
-#include <utility> // pair
+#include <utility> // declval, pair
// #include <nlohmann/thirdparty/hedley/hedley.hpp>
@@ -2212,6 +2214,83 @@
#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
+// #include <nlohmann/detail/meta/detected.hpp>
+
+
+#include <type_traits>
+
+// #include <nlohmann/detail/meta/void_t.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+template<typename ...Ts> struct make_void
+{
+ using type = void;
+};
+template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
+} // namespace detail
+} // namespace nlohmann
+
+
+// https://en.cppreference.com/w/cpp/experimental/is_detected
+namespace nlohmann
+{
+namespace detail
+{
+struct nonesuch
+{
+ nonesuch() = delete;
+ ~nonesuch() = delete;
+ nonesuch(nonesuch const&) = delete;
+ nonesuch(nonesuch const&&) = delete;
+ void operator=(nonesuch const&) = delete;
+ void operator=(nonesuch&&) = delete;
+};
+
+template<class Default,
+ class AlwaysVoid,
+ template<class...> class Op,
+ class... Args>
+struct detector
+{
+ using value_t = std::false_type;
+ using type = Default;
+};
+
+template<class Default, template<class...> class Op, class... Args>
+struct detector<Default, void_t<Op<Args...>>, Op, Args...>
+{
+ using value_t = std::true_type;
+ using type = Op<Args...>;
+};
+
+template<template<class...> class Op, class... Args>
+using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
+
+template<template<class...> class Op, class... Args>
+struct is_detected_lazy : is_detected<Op, Args...> { };
+
+template<template<class...> class Op, class... Args>
+using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
+
+template<class Default, template<class...> class Op, class... Args>
+using detected_or = detector<Default, void, Op, Args...>;
+
+template<class Default, template<class...> class Op, class... Args>
+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
+} // namespace nlohmann
+
// This file contains all internal macro definitions
// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
@@ -2248,8 +2327,9 @@
// disable documentation warnings on clang
#if defined(__clang__)
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wdocumentation"
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdocumentation"
+ #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
#endif
// allow to disable exceptions
@@ -2501,6 +2581,45 @@
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
+
+// inspired from https://stackoverflow.com/a/26745591
+// allows to call any std function as if (e.g. with begin):
+// using std::begin; begin(x);
+//
+// it allows using the detected idiom to retrieve the return type
+// of such an expression
+#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
+ namespace detail { \
+ using std::std_name; \
+ \
+ 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
#define JSON_USE_IMPLICIT_CONVERSIONS 1
#endif
@@ -2511,6 +2630,10 @@
#define JSON_EXPLICIT explicit
#endif
+#ifndef JSON_DIAGNOSTICS
+ #define JSON_DIAGNOSTICS 0
+#endif
+
namespace nlohmann
{
@@ -2695,6 +2818,14 @@
break;
}
+ case value_t::null: // LCOV_EXCL_LINE
+ 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
default: // LCOV_EXCL_LINE
break; // LCOV_EXCL_LINE
}
@@ -3192,6 +3323,9 @@
#include <utility> // declval
#include <tuple> // tuple
+// #include <nlohmann/detail/macro_scope.hpp>
+
+
// #include <nlohmann/detail/iterators/iterator_traits.hpp>
@@ -3199,19 +3333,6 @@
// #include <nlohmann/detail/meta/void_t.hpp>
-
-namespace nlohmann
-{
-namespace detail
-{
-template<typename ...Ts> struct make_void
-{
- using type = void;
-};
-template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
-} // namespace detail
-} // namespace nlohmann
-
// #include <nlohmann/detail/meta/cpp_future.hpp>
@@ -3260,71 +3381,32 @@
} // namespace detail
} // namespace nlohmann
+// #include <nlohmann/detail/meta/call_std/begin.hpp>
+
+
// #include <nlohmann/detail/macro_scope.hpp>
+
+namespace nlohmann
+{
+NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin);
+} // namespace nlohmann
+
+// #include <nlohmann/detail/meta/call_std/end.hpp>
+
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+
+namespace nlohmann
+{
+NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end);
+} // namespace nlohmann
+
// #include <nlohmann/detail/meta/cpp_future.hpp>
// #include <nlohmann/detail/meta/detected.hpp>
-
-#include <type_traits>
-
-// #include <nlohmann/detail/meta/void_t.hpp>
-
-
-// https://en.cppreference.com/w/cpp/experimental/is_detected
-namespace nlohmann
-{
-namespace detail
-{
-struct nonesuch
-{
- nonesuch() = delete;
- ~nonesuch() = delete;
- nonesuch(nonesuch const&) = delete;
- nonesuch(nonesuch const&&) = delete;
- void operator=(nonesuch const&) = delete;
- void operator=(nonesuch&&) = delete;
-};
-
-template<class Default,
- class AlwaysVoid,
- template<class...> class Op,
- class... Args>
-struct detector
-{
- using value_t = std::false_type;
- using type = Default;
-};
-
-template<class Default, template<class...> class Op, class... Args>
-struct detector<Default, void_t<Op<Args...>>, Op, Args...>
-{
- using value_t = std::true_type;
- using type = Op<Args...>;
-};
-
-template<template<class...> class Op, class... Args>
-using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
-
-template<template<class...> class Op, class... Args>
-using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
-
-template<class Default, template<class...> class Op, class... Args>
-using detected_or = detector<Default, void, Op, Args...>;
-
-template<class Default, template<class...> class Op, class... Args>
-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
-} // namespace nlohmann
-
// #include <nlohmann/json_fwd.hpp>
#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
@@ -3474,9 +3556,6 @@
template<typename T>
using iterator_category_t = typename T::iterator_category;
-template<typename T>
-using iterator_t = typename T::iterator;
-
template<typename T, typename... Args>
using to_json_function = decltype(T::to_json(std::declval<Args>()...));
@@ -3552,6 +3631,9 @@
struct conjunction<B1, Bn...>
: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
+// https://en.cppreference.com/w/cpp/types/negation
+template<class B> struct negation : std::integral_constant < bool, !B::value > { };
+
// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
@@ -3609,6 +3691,31 @@
is_detected<reference_t, traits>::value;
};
+template<typename T>
+struct is_range
+{
+ private:
+ using t_ref = typename std::add_lvalue_reference<T>::type;
+
+ using iterator = detected_t<result_of_begin, t_ref>;
+ using sentinel = detected_t<result_of_end, t_ref>;
+
+ // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
+ // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
+ // but reimplementing these would be too much work, as a lot of other concepts are used underneath
+ static constexpr auto is_iterator_begin =
+ is_iterator_traits<iterator_traits<iterator>>::value;
+
+ public:
+ static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
+};
+
+template<typename R>
+using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
+
+template<typename T>
+using range_value_t = value_type_t<iterator_traits<iterator_t<T>>>;
+
// The following implementation of is_complete_type is taken from
// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
// and is written by Xiang Fan who agreed to using it in this library.
@@ -3676,60 +3783,37 @@
: is_constructible_object_type_impl<BasicJsonType,
ConstructibleObjectType> {};
-template<typename BasicJsonType, typename CompatibleStringType,
- typename = void>
-struct is_compatible_string_type_impl : std::false_type {};
-
template<typename BasicJsonType, typename CompatibleStringType>
-struct is_compatible_string_type_impl <
- BasicJsonType, CompatibleStringType,
- enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
- value_type_t, CompatibleStringType>::value >>
+struct is_compatible_string_type
{
static constexpr auto value =
is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
};
template<typename BasicJsonType, typename ConstructibleStringType>
-struct is_compatible_string_type
- : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
-
-template<typename BasicJsonType, typename ConstructibleStringType,
- typename = void>
-struct is_constructible_string_type_impl : std::false_type {};
-
-template<typename BasicJsonType, typename ConstructibleStringType>
-struct is_constructible_string_type_impl <
- BasicJsonType, ConstructibleStringType,
- enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
- value_type_t, ConstructibleStringType>::value >>
+struct is_constructible_string_type
{
static constexpr auto value =
is_constructible<ConstructibleStringType,
typename BasicJsonType::string_t>::value;
};
-template<typename BasicJsonType, typename ConstructibleStringType>
-struct is_constructible_string_type
- : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
-
template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
struct is_compatible_array_type_impl : std::false_type {};
template<typename BasicJsonType, typename CompatibleArrayType>
struct is_compatible_array_type_impl <
BasicJsonType, CompatibleArrayType,
- enable_if_t < is_detected<value_type_t, CompatibleArrayType>::value&&
+ enable_if_t <
is_detected<iterator_t, CompatibleArrayType>::value&&
-// This is needed because json_reverse_iterator has a ::iterator type...
-// Therefore it is detected as a CompatibleArrayType.
-// The real fix would be to have an Iterable concept.
- !is_iterator_traits <
- iterator_traits<CompatibleArrayType >>::value >>
+ is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
+// special case for types like std::filesystem::path whose iterator's value_type are themselves
+// c.f. https://github.com/nlohmann/json/pull/3073
+ !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
{
static constexpr bool value =
is_constructible<BasicJsonType,
- typename CompatibleArrayType::value_type>::value;
+ range_value_t<CompatibleArrayType>>::value;
};
template<typename BasicJsonType, typename CompatibleArrayType>
@@ -3751,28 +3835,29 @@
BasicJsonType, ConstructibleArrayType,
enable_if_t < !std::is_same<ConstructibleArrayType,
typename BasicJsonType::value_type>::value&&
+ !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
is_default_constructible<ConstructibleArrayType>::value&&
(std::is_move_assignable<ConstructibleArrayType>::value ||
std::is_copy_assignable<ConstructibleArrayType>::value)&&
-is_detected<value_type_t, ConstructibleArrayType>::value&&
is_detected<iterator_t, ConstructibleArrayType>::value&&
-is_complete_type <
-detected_t<value_type_t, ConstructibleArrayType >>::value >>
+is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
+is_detected<range_value_t, ConstructibleArrayType>::value&&
+// special case for types like std::filesystem::path whose iterator's value_type are themselves
+// c.f. https://github.com/nlohmann/json/pull/3073
+!std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
+ is_complete_type <
+ detected_t<range_value_t, ConstructibleArrayType >>::value >>
{
- static constexpr bool value =
- // This is needed because json_reverse_iterator has a ::iterator type,
- // furthermore, std::back_insert_iterator (and other iterators) have a
- // base class `iterator`... Therefore it is detected as a
- // ConstructibleArrayType. The real fix would be to have an Iterable
- // concept.
- !is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value &&
+ using value_type = range_value_t<ConstructibleArrayType>;
- (std::is_same<typename ConstructibleArrayType::value_type,
- typename BasicJsonType::array_t::value_type>::value ||
- has_from_json<BasicJsonType,
- typename ConstructibleArrayType::value_type>::value ||
- has_non_default_from_json <
- BasicJsonType, typename ConstructibleArrayType::value_type >::value);
+ static constexpr bool value =
+ std::is_same<value_type,
+ typename BasicJsonType::array_t::value_type>::value ||
+ has_from_json<BasicJsonType,
+ value_type>::value ||
+ has_non_default_from_json <
+ BasicJsonType,
+ value_type >::value;
};
template<typename BasicJsonType, typename ConstructibleArrayType>
@@ -3827,12 +3912,48 @@
template<typename T1, typename... Args>
struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
+
+// 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)
+};
+
+// 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 >
+T conditional_static_cast(U value)
+{
+ return static_cast<T>(value);
+}
+
+template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
+T conditional_static_cast(U value)
+{
+ return value;
+}
+
} // namespace detail
} // namespace nlohmann
// #include <nlohmann/detail/value_t.hpp>
+#ifdef JSON_HAS_CPP_17
+ #include <filesystem>
+#endif
+
namespace nlohmann
{
namespace detail
@@ -3872,6 +3993,13 @@
break;
}
+ case value_t::null:
+ case value_t::object:
+ case value_t::array:
+ case value_t::string:
+ case value_t::boolean:
+ case value_t::binary:
+ case value_t::discarded:
default:
JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
}
@@ -3976,7 +4104,7 @@
}
template<typename BasicJsonType, typename T, std::size_t N>
-auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
+auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
-> decltype(j.template get<T>(), void())
{
for (std::size_t i = 0; i < N; ++i)
@@ -4157,6 +4285,12 @@
break;
}
+ case value_t::null:
+ case value_t::object:
+ case value_t::array:
+ case value_t::string:
+ case value_t::binary:
+ case value_t::discarded:
default:
JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
}
@@ -4245,6 +4379,18 @@
}
}
+#ifdef JSON_HAS_CPP_17
+template<typename BasicJsonType>
+void from_json(const BasicJsonType& j, std::filesystem::path& p)
+{
+ if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
+ {
+ JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
+ }
+ p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
+}
+#endif
+
struct from_json_fn
{
template<typename BasicJsonType, typename T>
@@ -4278,6 +4424,8 @@
#include <valarray> // valarray
#include <vector> // vector
+// #include <nlohmann/detail/macro_scope.hpp>
+
// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
@@ -4380,6 +4528,14 @@
return anchor.key();
// use an empty key for all primitive types
+ 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:
default:
return empty_str;
}
@@ -4470,6 +4626,10 @@
// #include <nlohmann/detail/value_t.hpp>
+#ifdef JSON_HAS_CPP_17
+ #include <filesystem>
+#endif
+
namespace nlohmann
{
namespace detail
@@ -4478,6 +4638,13 @@
// constructors //
//////////////////
+/*
+ * Note all external_constructor<>::construct functions need to call
+ * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
+ * allocated value (e.g., a string). See bug issue
+ * https://github.com/nlohmann/json/issues/2865 for more information.
+ */
+
template<value_t> struct external_constructor;
template<>
@@ -4486,6 +4653,7 @@
template<typename BasicJsonType>
static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
{
+ j.m_value.destroy(j.m_type);
j.m_type = value_t::boolean;
j.m_value = b;
j.assert_invariant();
@@ -4498,6 +4666,7 @@
template<typename BasicJsonType>
static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
{
+ j.m_value.destroy(j.m_type);
j.m_type = value_t::string;
j.m_value = s;
j.assert_invariant();
@@ -4506,6 +4675,7 @@
template<typename BasicJsonType>
static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
{
+ j.m_value.destroy(j.m_type);
j.m_type = value_t::string;
j.m_value = std::move(s);
j.assert_invariant();
@@ -4516,6 +4686,7 @@
int > = 0 >
static void construct(BasicJsonType& j, const CompatibleStringType& str)
{
+ j.m_value.destroy(j.m_type);
j.m_type = value_t::string;
j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
j.assert_invariant();
@@ -4528,6 +4699,7 @@
template<typename BasicJsonType>
static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
{
+ j.m_value.destroy(j.m_type);
j.m_type = value_t::binary;
j.m_value = typename BasicJsonType::binary_t(b);
j.assert_invariant();
@@ -4536,8 +4708,9 @@
template<typename BasicJsonType>
static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
{
+ j.m_value.destroy(j.m_type);
j.m_type = value_t::binary;
- j.m_value = typename BasicJsonType::binary_t(std::move(b));;
+ j.m_value = typename BasicJsonType::binary_t(std::move(b));
j.assert_invariant();
}
};
@@ -4548,6 +4721,7 @@
template<typename BasicJsonType>
static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
{
+ j.m_value.destroy(j.m_type);
j.m_type = value_t::number_float;
j.m_value = val;
j.assert_invariant();
@@ -4560,6 +4734,7 @@
template<typename BasicJsonType>
static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
{
+ j.m_value.destroy(j.m_type);
j.m_type = value_t::number_unsigned;
j.m_value = val;
j.assert_invariant();
@@ -4572,6 +4747,7 @@
template<typename BasicJsonType>
static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
{
+ j.m_value.destroy(j.m_type);
j.m_type = value_t::number_integer;
j.m_value = val;
j.assert_invariant();
@@ -4584,6 +4760,7 @@
template<typename BasicJsonType>
static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
{
+ j.m_value.destroy(j.m_type);
j.m_type = value_t::array;
j.m_value = arr;
j.set_parents();
@@ -4593,6 +4770,7 @@
template<typename BasicJsonType>
static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
{
+ j.m_value.destroy(j.m_type);
j.m_type = value_t::array;
j.m_value = std::move(arr);
j.set_parents();
@@ -4606,6 +4784,8 @@
{
using std::begin;
using std::end;
+
+ j.m_value.destroy(j.m_type);
j.m_type = value_t::array;
j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
j.set_parents();
@@ -4615,6 +4795,7 @@
template<typename BasicJsonType>
static void construct(BasicJsonType& j, const std::vector<bool>& arr)
{
+ j.m_value.destroy(j.m_type);
j.m_type = value_t::array;
j.m_value = value_t::array;
j.m_value.array->reserve(arr.size());
@@ -4630,6 +4811,7 @@
enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
static void construct(BasicJsonType& j, const std::valarray<T>& arr)
{
+ j.m_value.destroy(j.m_type);
j.m_type = value_t::array;
j.m_value = value_t::array;
j.m_value.array->resize(arr.size());
@@ -4648,6 +4830,7 @@
template<typename BasicJsonType>
static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
{
+ j.m_value.destroy(j.m_type);
j.m_type = value_t::object;
j.m_value = obj;
j.set_parents();
@@ -4657,6 +4840,7 @@
template<typename BasicJsonType>
static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
{
+ j.m_value.destroy(j.m_type);
j.m_type = value_t::object;
j.m_value = std::move(obj);
j.set_parents();
@@ -4670,6 +4854,7 @@
using std::begin;
using std::end;
+ j.m_value.destroy(j.m_type);
j.m_type = value_t::object;
j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
j.set_parents();
@@ -4817,6 +5002,14 @@
to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
}
+#ifdef JSON_HAS_CPP_17
+template<typename BasicJsonType>
+void to_json(BasicJsonType& j, const std::filesystem::path& p)
+{
+ j = p.string();
+}
+#endif
+
struct to_json_fn
{
template<typename BasicJsonType, typename T>
@@ -4909,7 +5102,7 @@
// #include <nlohmann/byte_container_with_subtype.hpp>
-#include <cstdint> // uint8_t
+#include <cstdint> // uint8_t, uint64_t
#include <tuple> // tie
#include <utility> // move
@@ -4927,7 +5120,7 @@
@tparam BinaryType container to store bytes (`std::vector<std::uint8_t>` by
default)
-@since version 3.8.0
+@since version 3.8.0; changed type of subtypes to std::uint64_t in 3.10.0.
*/
template<typename BinaryType>
class byte_container_with_subtype : public BinaryType
@@ -4935,6 +5128,8 @@
public:
/// the type of the underlying container
using container_type = BinaryType;
+ /// the type of the subtype
+ using subtype_type = std::uint64_t;
byte_container_with_subtype() noexcept(noexcept(container_type()))
: container_type()
@@ -4948,13 +5143,13 @@
: container_type(std::move(b))
{}
- byte_container_with_subtype(const container_type& b, std::uint8_t subtype_) noexcept(noexcept(container_type(b)))
+ byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
: container_type(b)
, m_subtype(subtype_)
, m_has_subtype(true)
{}
- byte_container_with_subtype(container_type&& b, std::uint8_t subtype_) noexcept(noexcept(container_type(std::move(b))))
+ byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
: container_type(std::move(b))
, m_subtype(subtype_)
, m_has_subtype(true)
@@ -4989,7 +5184,7 @@
@since version 3.8.0
*/
- void set_subtype(std::uint8_t subtype_) noexcept
+ void set_subtype(subtype_type subtype_) noexcept
{
m_subtype = subtype_;
m_has_subtype = true;
@@ -4999,7 +5194,7 @@
@brief return the binary subtype
Returns the numerical subtype of the value if it has a subtype. If it does
- not have a subtype, this function will return size_t(-1) as a sentinel
+ not have a subtype, this function will return subtype_type(-1) as a sentinel
value.
@return the numerical subtype of the binary value
@@ -5014,11 +5209,12 @@
@sa see @ref has_subtype() -- returns whether or not the binary value has a
subtype
- @since version 3.8.0
+ @since version 3.8.0; fixed return value to properly return
+ subtype_type(-1) as documented in version 3.10.0
*/
- constexpr std::uint8_t subtype() const noexcept
+ constexpr subtype_type subtype() const noexcept
{
- return m_subtype;
+ return m_has_subtype ? m_subtype : subtype_type(-1);
}
/*!
@@ -5068,7 +5264,7 @@
}
private:
- std::uint8_t m_subtype = 0;
+ subtype_type m_subtype = 0;
bool m_has_subtype = false;
};
@@ -5089,6 +5285,8 @@
// #include <nlohmann/detail/macro_scope.hpp>
+// #include <nlohmann/detail/value_t.hpp>
+
namespace nlohmann
{
@@ -5187,7 +5385,7 @@
auto seed = combine(type, j.get_binary().size());
const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
seed = combine(seed, h);
- seed = combine(seed, j.get_binary().subtype());
+ seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
for (const auto byte : j.get_binary())
{
seed = combine(seed, std::hash<std::uint8_t> {}(byte));
@@ -5227,9 +5425,7 @@
#include <array> // array
#include <cstddef> // size_t
-#include <cstdio> //FILE *
#include <cstring> // strlen
-#include <istream> // istream
#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
#include <memory> // shared_ptr, make_shared, addressof
#include <numeric> // accumulate
@@ -5237,6 +5433,11 @@
#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
#include <utility> // pair, declval
+#ifndef JSON_NO_IO
+ #include <cstdio> // FILE *
+ #include <istream> // istream
+#endif // JSON_NO_IO
+
// #include <nlohmann/detail/iterators/iterator_traits.hpp>
// #include <nlohmann/detail/macro_scope.hpp>
@@ -5253,6 +5454,7 @@
// input adapters //
////////////////////
+#ifndef JSON_NO_IO
/*!
Input adapter for stdio file access. This adapter read only 1 byte and do not use any
buffer. This adapter is a very low level adapter.
@@ -5344,6 +5546,7 @@
std::istream* is = nullptr;
std::streambuf* sb = nullptr;
};
+#endif // JSON_NO_IO
// General-purpose iterator-based adapter. It might not be as fast as
// theoretically possible for some containers, but it is extremely versatile.
@@ -5630,6 +5833,7 @@
return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
}
+#ifndef JSON_NO_IO
// Special cases with fast paths
inline file_input_adapter input_adapter(std::FILE* file)
{
@@ -5645,6 +5849,7 @@
{
return input_stream_adapter(stream);
}
+#endif // JSON_NO_IO
using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
@@ -8200,6 +8405,8 @@
} // namespace detail
} // namespace nlohmann
+// #include <nlohmann/detail/meta/type_traits.hpp>
+
// #include <nlohmann/detail/value_t.hpp>
@@ -8211,8 +8418,9 @@
/// how to treat CBOR tags
enum class cbor_tag_handler_t
{
- error, ///< throw a parse_error exception in case of a tag
- ignore ///< ignore tags
+ error, ///< throw a parse_error exception in case of a tag
+ ignore, ///< ignore tags
+ store ///< store tags as binary type
};
/*!
@@ -8300,6 +8508,7 @@
result = parse_ubjson_internal();
break;
+ case input_format_t::json: // LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
}
@@ -8813,7 +9022,7 @@
case 0x9B: // array (eight-byte uint64_t for n follow)
{
std::uint64_t len{};
- return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
+ return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);
}
case 0x9F: // array (indefinite length)
@@ -8867,7 +9076,7 @@
case 0xBB: // map (eight-byte uint64_t for n follow)
{
std::uint64_t len{};
- return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
+ return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);
}
case 0xBF: // map (indefinite length)
@@ -8903,30 +9112,31 @@
case cbor_tag_handler_t::ignore:
{
+ // ignore binary subtype
switch (current)
{
case 0xD8:
{
- std::uint8_t len{};
- get_number(input_format_t::cbor, len);
+ std::uint8_t subtype_to_ignore{};
+ get_number(input_format_t::cbor, subtype_to_ignore);
break;
}
case 0xD9:
{
- std::uint16_t len{};
- get_number(input_format_t::cbor, len);
+ std::uint16_t subtype_to_ignore{};
+ get_number(input_format_t::cbor, subtype_to_ignore);
break;
}
case 0xDA:
{
- std::uint32_t len{};
- get_number(input_format_t::cbor, len);
+ std::uint32_t subtype_to_ignore{};
+ get_number(input_format_t::cbor, subtype_to_ignore);
break;
}
case 0xDB:
{
- std::uint64_t len{};
- get_number(input_format_t::cbor, len);
+ std::uint64_t subtype_to_ignore{};
+ get_number(input_format_t::cbor, subtype_to_ignore);
break;
}
default:
@@ -8935,6 +9145,47 @@
return parse_cbor_internal(true, tag_handler);
}
+ case cbor_tag_handler_t::store:
+ {
+ binary_t b;
+ // use binary subtype and store in binary container
+ switch (current)
+ {
+ case 0xD8:
+ {
+ std::uint8_t subtype{};
+ get_number(input_format_t::cbor, subtype);
+ b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
+ break;
+ }
+ case 0xD9:
+ {
+ std::uint16_t subtype{};
+ get_number(input_format_t::cbor, subtype);
+ b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
+ break;
+ }
+ case 0xDA:
+ {
+ std::uint32_t subtype{};
+ get_number(input_format_t::cbor, subtype);
+ b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
+ break;
+ }
+ case 0xDB:
+ {
+ std::uint64_t subtype{};
+ get_number(input_format_t::cbor, subtype);
+ b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
+ break;
+ }
+ default:
+ return parse_cbor_internal(true, tag_handler);
+ }
+ get();
+ return get_cbor_binary(b) && sax->binary(b);
+ }
+
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
return false; // LCOV_EXCL_LINE
@@ -9264,38 +9515,41 @@
return false;
}
- string_t key;
- if (len != std::size_t(-1))
+ if (len != 0)
{
- for (std::size_t i = 0; i < len; ++i)
+ string_t key;
+ if (len != std::size_t(-1))
{
- get();
- if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
+ for (std::size_t i = 0; i < len; ++i)
{
- return false;
- }
+ get();
+ if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
+ {
+ return false;
+ }
- if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
- {
- return false;
+ if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
+ {
+ return false;
+ }
+ key.clear();
}
- key.clear();
}
- }
- else
- {
- while (get() != 0xFF)
+ else
{
- if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
+ while (get() != 0xFF)
{
- return false;
- }
+ if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
+ {
+ return false;
+ }
- if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
- {
- return false;
+ if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
+ {
+ return false;
+ }
+ key.clear();
}
- key.clear();
}
}
@@ -10414,6 +10668,20 @@
return sax->number_unsigned(number_lexer.get_number_unsigned());
case token_type::value_float:
return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
+ case token_type::uninitialized:
+ case token_type::literal_true:
+ case token_type::literal_false:
+ case token_type::literal_null:
+ case token_type::value_string:
+ case token_type::begin_array:
+ case token_type::begin_object:
+ case token_type::end_array:
+ case token_type::end_object:
+ case token_type::name_separator:
+ case token_type::value_separator:
+ case token_type::parse_error:
+ case token_type::end_of_input:
+ case token_type::literal_or_value:
default:
return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
}
@@ -10616,6 +10884,7 @@
error_msg += "BSON";
break;
+ case input_format_t::json: // LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
}
@@ -10679,7 +10948,7 @@
// parser //
////////////
-enum class parse_event_t : uint8_t
+enum class parse_event_t : std::uint8_t
{
/// the parser read `{` and started to process a JSON object
object_start,
@@ -10990,6 +11259,13 @@
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
}
+ case token_type::uninitialized:
+ case token_type::end_array:
+ case token_type::end_object:
+ case token_type::name_separator:
+ case token_type::value_separator:
+ case token_type::end_of_input:
+ case token_type::literal_or_value:
default: // the last token was unexpected
{
return sax->parse_error(m_lexer.get_position(),
@@ -11413,6 +11689,14 @@
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:
default:
{
m_it.primitive_iterator = primitive_iterator_t();
@@ -11509,6 +11793,13 @@
break;
}
+ 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:
default:
{
m_it.primitive_iterator.set_begin();
@@ -11539,6 +11830,14 @@
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:
default:
{
m_it.primitive_iterator.set_end();
@@ -11573,6 +11872,13 @@
case value_t::null:
JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
+ 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:
default:
{
if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
@@ -11607,6 +11913,14 @@
return &*m_it.array_iterator;
}
+ 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:
default:
{
if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
@@ -11652,6 +11966,14 @@
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:
default:
{
++m_it.primitive_iterator;
@@ -11695,6 +12017,14 @@
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:
default:
{
--m_it.primitive_iterator;
@@ -11728,6 +12058,14 @@
case value_t::array:
return (m_it.array_iterator == other.m_it.array_iterator);
+ 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:
default:
return (m_it.primitive_iterator == other.m_it.primitive_iterator);
}
@@ -11765,6 +12103,14 @@
case value_t::array:
return (m_it.array_iterator < other.m_it.array_iterator);
+ 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:
default:
return (m_it.primitive_iterator < other.m_it.primitive_iterator);
}
@@ -11816,6 +12162,14 @@
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:
default:
{
m_it.primitive_iterator += i;
@@ -11884,6 +12238,14 @@
case value_t::array:
return m_it.array_iterator - other.m_it.array_iterator;
+ 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:
default:
return m_it.primitive_iterator - other.m_it.primitive_iterator;
}
@@ -11908,6 +12270,13 @@
case value_t::null:
JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
+ 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:
default:
{
if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
@@ -12527,6 +12896,13 @@
an error situation, because primitive values may only occur as
single value; that is, with an empty list of reference tokens.
*/
+ 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::type_error::create(313, "invalid value to unflatten", j));
}
@@ -12599,6 +12975,14 @@
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, "unresolved reference token '" + reference_token + "'", *ptr));
}
@@ -12641,6 +13025,14 @@
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, "unresolved reference token '" + reference_token + "'", *ptr));
}
@@ -12688,6 +13080,14 @@
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, "unresolved reference token '" + reference_token + "'", *ptr));
}
@@ -12730,6 +13130,14 @@
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, "unresolved reference token '" + reference_token + "'", *ptr));
}
@@ -12800,6 +13208,14 @@
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:
{
// we do not expect primitive values if there is still a
@@ -12933,6 +13349,14 @@
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:
{
// add primitive value with its reference string
@@ -13119,12 +13543,16 @@
#include <algorithm> // copy
#include <cstddef> // size_t
-#include <ios> // streamsize
#include <iterator> // back_inserter
#include <memory> // shared_ptr, make_shared
-#include <ostream> // basic_ostream
#include <string> // basic_string
#include <vector> // vector
+
+#ifndef JSON_NO_IO
+ #include <ios> // streamsize
+ #include <ostream> // basic_ostream
+#endif // JSON_NO_IO
+
// #include <nlohmann/detail/macro_scope.hpp>
@@ -13151,11 +13579,11 @@
using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
/// output adapter for byte vectors
-template<typename CharType>
+template<typename CharType, typename AllocatorType = std::allocator<CharType>>
class output_vector_adapter : public output_adapter_protocol<CharType>
{
public:
- explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
+ explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
: v(vec)
{}
@@ -13171,9 +13599,10 @@
}
private:
- std::vector<CharType>& v;
+ std::vector<CharType, AllocatorType>& v;
};
+#ifndef JSON_NO_IO
/// output adapter for output streams
template<typename CharType>
class output_stream_adapter : public output_adapter_protocol<CharType>
@@ -13197,6 +13626,7 @@
private:
std::basic_ostream<CharType>& stream;
};
+#endif // JSON_NO_IO
/// output adapter for basic_string
template<typename CharType, typename StringType = std::basic_string<CharType>>
@@ -13226,11 +13656,14 @@
class output_adapter
{
public:
- output_adapter(std::vector<CharType>& vec)
- : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
+ template<typename AllocatorType = std::allocator<CharType>>
+ output_adapter(std::vector<CharType, AllocatorType>& vec)
+ : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
+#ifndef JSON_NO_IO
output_adapter(std::basic_ostream<CharType>& s)
: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
+#endif // JSON_NO_IO
output_adapter(StringType& s)
: oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
@@ -13290,9 +13723,18 @@
break;
}
+ case value_t::null:
+ case value_t::array:
+ 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:
default:
{
- JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));;
+ JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));
}
}
}
@@ -13516,8 +13958,26 @@
{
if (j.m_value.binary->has_subtype())
{
- write_number(static_cast<std::uint8_t>(0xd8));
- write_number(j.m_value.binary->subtype());
+ if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
+ {
+ write_number(static_cast<std::uint8_t>(0xd8));
+ write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
+ }
+ else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
+ {
+ write_number(static_cast<std::uint8_t>(0xd9));
+ write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
+ }
+ else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
+ {
+ write_number(static_cast<std::uint8_t>(0xda));
+ write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
+ }
+ else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
+ {
+ write_number(static_cast<std::uint8_t>(0xdb));
+ write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
+ }
}
// step 1: write control byte and the binary array size
@@ -13597,6 +14057,7 @@
break;
}
+ case value_t::discarded:
default:
break;
}
@@ -13918,6 +14379,7 @@
break;
}
+ case value_t::discarded:
default:
break;
}
@@ -14122,6 +14584,7 @@
break;
}
+ case value_t::discarded:
default:
break;
}
@@ -14142,6 +14605,7 @@
if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
{
JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
+ static_cast<void>(j);
}
return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
@@ -14330,7 +14794,7 @@
write_bson_entry_header(name, 0x05);
write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
- write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
+ write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : std::uint8_t(0x00));
oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
}
@@ -14373,6 +14837,7 @@
return header_size + 0ul;
// LCOV_EXCL_START
+ case value_t::discarded:
default:
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
return 0ul;
@@ -14419,6 +14884,7 @@
return write_bson_null(name);
// LCOV_EXCL_START
+ case value_t::discarded:
default:
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
return;
@@ -14709,6 +15175,7 @@
case value_t::object:
return '{';
+ case value_t::discarded:
default: // discarded values
return 'N';
}
@@ -14758,6 +15225,10 @@
void write_compact_float(const number_float_t n, detail::input_format_t format)
{
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
@@ -14774,6 +15245,9 @@
: get_msgpack_float_prefix(n));
write_number(n);
}
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
}
public:
@@ -15914,6 +16388,10 @@
*first++ = '-';
}
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
if (value == 0) // +-0
{
*first++ = '0';
@@ -15922,6 +16400,9 @@
*first++ = '0';
return first;
}
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
@@ -16332,7 +16813,7 @@
for (std::size_t i = 0; i < s.size(); ++i)
{
- const auto byte = static_cast<uint8_t>(s[i]);
+ const auto byte = static_cast<std::uint8_t>(s[i]);
switch (decode(state, codepoint, byte))
{
@@ -16442,7 +16923,7 @@
{
case error_handler_t::strict:
{
- std::string sn(3, '\0');
+ std::string sn(9, '\0');
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
(std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn, BasicJsonType()));
@@ -16537,7 +17018,7 @@
{
case error_handler_t::strict:
{
- std::string sn(3, '\0');
+ std::string sn(9, '\0');
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
(std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn, BasicJsonType()));
@@ -16617,6 +17098,7 @@
@tparam NumberType either @a number_integer_t or @a number_unsigned_t
*/
template < typename NumberType, detail::enable_if_t <
+ std::is_integral<NumberType>::value ||
std::is_same<NumberType, number_unsigned_t>::value ||
std::is_same<NumberType, number_integer_t>::value ||
std::is_same<NumberType, binary_char_t>::value,
@@ -16649,7 +17131,7 @@
// use a pointer to fill the buffer
auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
- const bool is_negative = std::is_same<NumberType, number_integer_t>::value && !(x >= 0); // see issue #755
+ const bool is_negative = std::is_signed<NumberType>::value && !(x >= 0); // see issue #755
number_unsigned_t abs_value;
unsigned int n_chars{};
@@ -16753,8 +17235,8 @@
// erase thousands separator
if (thousands_sep != '\0')
{
- auto* const end = std::remove(number_buffer.begin(),
- number_buffer.begin() + len, thousands_sep);
+ // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
+ const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
std::fill(end, number_buffer.end(), '\0');
JSON_ASSERT((end - number_buffer.begin()) <= len);
len = (end - number_buffer.begin());
@@ -16763,7 +17245,8 @@
// convert decimal point to '.'
if (decimal_point != '\0' && decimal_point != '.')
{
- auto* const dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
+ // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
+ const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
if (dec_pos != number_buffer.end())
{
*dec_pos = '.';
@@ -17920,8 +18403,8 @@
#### Notes on subtypes
- CBOR
- - Binary values are represented as byte strings. No subtypes are
- supported and will be ignored when CBOR is written.
+ - Binary values are represented as byte strings. Subtypes are serialized
+ as tagged values.
- MessagePack
- If a subtype is given and the binary array contains exactly 1, 2, 4, 8,
or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8)
@@ -18077,12 +18560,13 @@
break;
}
+ case value_t::discarded:
default:
{
object = nullptr; // silence warning, see #821
if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
{
- JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.1", basic_json())); // LCOV_EXCL_LINE
+ JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.4", basic_json())); // LCOV_EXCL_LINE
}
break;
}
@@ -18149,53 +18633,55 @@
binary = create<binary_t>(std::move(value));
}
- void destroy(value_t t) noexcept
+ void destroy(value_t t)
{
- // flatten the current json_value to a heap-allocated stack
- std::vector<basic_json> stack;
+ 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 if (t == value_t::object)
- {
- stack.reserve(object->size());
- for (auto&& it : *object)
+ // move the top-level items to stack
+ if (t == value_t::array)
{
- stack.push_back(std::move(it.second));
+ stack.reserve(array->size());
+ std::move(array->begin(), array->end(), std::back_inserter(stack));
}
- }
-
- 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())
+ else
{
- 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.reserve(object->size());
+ for (auto&& it : *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
+ 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
+ }
}
switch (t)
@@ -18232,6 +18718,12 @@
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:
default:
{
break;
@@ -18303,6 +18795,14 @@
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:
default:
break;
}
@@ -18322,12 +18822,40 @@
return it;
}
- reference set_parent(reference j)
+ reference set_parent(reference j, std::size_t old_capacity = std::size_t(-1))
{
#if JSON_DIAGNOSTICS
+ if (old_capacity != 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
+
j.m_parent = this;
#else
static_cast<void>(j);
+ static_cast<void>(old_capacity);
#endif
return j;
}
@@ -18500,7 +19028,7 @@
@ref number_float_t, and all convertible number types such as `int`,
`size_t`, `int64_t`, `float` or `double` can be used.
- **boolean**: @ref boolean_t / `bool` can be used.
- - **binary**: @ref binary_t / `std::vector<uint8_t>` may be used,
+ - **binary**: @ref binary_t / `std::vector<std::uint8_t>` may be used,
unfortunately because string literals cannot be distinguished from binary
character arrays by the C++ type system, all types compatible with `const
char*` will be directed to the string constructor instead. This is both
@@ -18820,7 +19348,7 @@
@since version 3.8.0
*/
JSON_HEDLEY_WARN_UNUSED_RESULT
- static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
+ 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;
@@ -18838,9 +19366,9 @@
return res;
}
- /// @copydoc binary(const typename binary_t::container_type&, std::uint8_t)
+ /// @copydoc binary(const typename binary_t::container_type&, typename binary_t::subtype_type)
JSON_HEDLEY_WARN_UNUSED_RESULT
- static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
+ 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;
@@ -19054,6 +19582,11 @@
break;
}
+ case value_t::null:
+ case value_t::object:
+ case value_t::array:
+ case value_t::binary:
+ case value_t::discarded:
default:
break;
}
@@ -19110,6 +19643,8 @@
break;
}
+ case value_t::null:
+ case value_t::discarded:
default:
JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
}
@@ -19209,6 +19744,8 @@
break;
}
+ case value_t::null:
+ case value_t::discarded:
default:
break;
}
@@ -20033,7 +20570,7 @@
ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
{
- ValueType ret{};
+ auto ret = ValueType();
JSONSerializer<ValueType>::from_json(*this, ret);
return ret;
}
@@ -20362,17 +20899,19 @@
@since version 1.0.0
*/
template < typename ValueType, typename std::enable_if <
- !std::is_pointer<ValueType>::value&&
- !std::is_same<ValueType, detail::json_ref<basic_json>>::value&&
- !std::is_same<ValueType, typename string_t::value_type>::value&&
- !detail::is_basic_json<ValueType>::value
- && !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
+ detail::conjunction <
+ detail::negation<std::is_pointer<ValueType>>,
+ 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))
- && !std::is_same<ValueType, typename std::string_view>::value
+ detail::negation<std::is_same<ValueType, std::string_view>>,
#endif
- && detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
- , int >::type = 0 >
- JSON_EXPLICIT operator ValueType() const
+ detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType>
+ >::value, int >::type = 0 >
+ JSON_EXPLICIT operator ValueType() const
{
// delegate the call to get<>() const
return get<ValueType>();
@@ -20657,15 +21196,25 @@
if (idx >= m_value.array->size())
{
#if JSON_DIAGNOSTICS
- // remember array size before resizing
- const auto previous_size = m_value.array->size();
+ // remember array size & capacity before resizing
+ const auto old_size = m_value.array->size();
+ const auto old_capacity = m_value.array->capacity();
#endif
m_value.array->resize(idx + 1);
#if JSON_DIAGNOSTICS
- // set parent for values added above
- set_parents(begin() + static_cast<typename iterator::difference_type>(previous_size), static_cast<typename iterator::difference_type>(idx + 1 - previous_size));
+ 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));
+ }
#endif
+ assert_invariant();
}
return m_value.array->operator[](idx);
@@ -21231,6 +21780,8 @@
break;
}
+ case value_t::null:
+ case value_t::discarded:
default:
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
}
@@ -21347,6 +21898,8 @@
break;
}
+ case value_t::null:
+ case value_t::discarded:
default:
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
}
@@ -22102,6 +22655,13 @@
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:
default:
{
// all other types are nonempty
@@ -22175,6 +22735,13 @@
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:
default:
{
// all other types have size 1
@@ -22240,6 +22807,14 @@
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:
default:
{
// all other types have max_size() == size()
@@ -22347,6 +22922,8 @@
break;
}
+ case value_t::null:
+ case value_t::discarded:
default:
break;
}
@@ -22389,8 +22966,9 @@
}
// add element to array (move semantics)
+ const auto old_capacity = m_value.array->capacity();
m_value.array->push_back(std::move(val));
- set_parent(m_value.array->back());
+ 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
}
@@ -22425,8 +23003,9 @@
}
// add element to array
+ const auto old_capacity = m_value.array->capacity();
m_value.array->push_back(val);
- set_parent(m_value.array->back());
+ set_parent(m_value.array->back(), old_capacity);
}
/*!
@@ -22580,12 +23159,9 @@
}
// add element to array (perfect forwarding)
-#ifdef JSON_HAS_CPP_17
- return set_parent(m_value.array->emplace_back(std::forward<Args>(args)...));
-#else
+ const auto old_capacity = m_value.array->capacity();
m_value.array->emplace_back(std::forward<Args>(args)...);
- return set_parent(m_value.array->back());
-#endif
+ return set_parent(m_value.array->back(), old_capacity);
}
/*!
@@ -22661,6 +23237,7 @@
// result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
// but the return value of insert is missing in GCC 4.8, so it is written this way instead.
+ set_parents();
return result;
}
@@ -22698,7 +23275,7 @@
}
// insert to array and return iterator
- return set_parents(insert_iterator(pos, val), static_cast<typename iterator::difference_type>(1));
+ return insert_iterator(pos, val);
}
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
@@ -22749,7 +23326,7 @@
}
// insert to array and return iterator
- return set_parents(insert_iterator(pos, cnt, val), static_cast<typename iterator::difference_type>(cnt));
+ return insert_iterator(pos, cnt, val);
}
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
@@ -22811,7 +23388,7 @@
}
// insert to array and return iterator
- return set_parents(insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator), std::distance(first, last));
+ return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
}
/*!
@@ -22853,7 +23430,7 @@
}
// insert to array and return iterator
- return set_parents(insert_iterator(pos, ilist.begin(), ilist.end()), static_cast<typename iterator::difference_type>(ilist.size()));
+ return insert_iterator(pos, ilist.begin(), ilist.end());
}
/*!
@@ -22943,6 +23520,9 @@
for (auto it = j.cbegin(); it != j.cend(); ++it)
{
m_value.object->operator[](it.key()) = it.value();
+#if JSON_DIAGNOSTICS
+ m_value.object->operator[](it.key()).m_parent = this;
+#endif
}
}
@@ -23003,6 +23583,9 @@
for (auto it = first; it != last; ++it)
{
m_value.object->operator[](it.key()) = it.value();
+#if JSON_DIAGNOSTICS
+ m_value.object->operator[](it.key()).m_parent = this;
+#endif
}
}
@@ -23279,6 +23862,10 @@
*/
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
{
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
const auto lhs_type = lhs.type();
const auto rhs_type = rhs.type();
@@ -23313,6 +23900,7 @@
case value_t::binary:
return *lhs.m_value.binary == *rhs.m_value.binary;
+ case value_t::discarded:
default:
return false;
}
@@ -23343,6 +23931,9 @@
}
return false;
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
}
/*!
@@ -23476,6 +24067,7 @@
case value_t::binary:
return (*lhs.m_value.binary) < (*rhs.m_value.binary);
+ case value_t::discarded:
default:
return false;
}
@@ -23679,7 +24271,7 @@
/// @name serialization
/// @{
-
+#ifndef JSON_NO_IO
/*!
@brief serialize to stream
@@ -23739,7 +24331,7 @@
{
return o << j;
}
-
+#endif // JSON_NO_IO
/// @}
@@ -23997,7 +24589,7 @@
// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
}
-
+#ifndef JSON_NO_IO
/*!
@brief deserialize from stream
@deprecated This stream operator is deprecated and will be removed in
@@ -24042,7 +24634,7 @@
parser(detail::input_adapter(i)).parse(false, j);
return i;
}
-
+#endif // JSON_NO_IO
/// @}
///////////////////////////
@@ -24100,6 +24692,9 @@
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";
}
@@ -24185,6 +24780,10 @@
binary | *size*: 65536..4294967295 | byte string (4 bytes follow) | 0x5A
binary | *size*: 4294967296..18446744073709551615 | byte string (8 bytes follow) | 0x5B
+ Binary values with subtype are mapped to tagged values (0xD8..0xDB)
+ depending on the subtype, followed by a byte string, see "binary" cells
+ in the table above.
+
@note The mapping is **complete** in the sense that any JSON value type
can be converted to a CBOR value.
@@ -24225,16 +24824,16 @@
@since version 2.0.9; compact representation of floating-point numbers
since version 3.8.0
*/
- static std::vector<uint8_t> to_cbor(const basic_json& j)
+ static std::vector<std::uint8_t> to_cbor(const basic_json& j)
{
- std::vector<uint8_t> result;
+ std::vector<std::uint8_t> result;
to_cbor(j, result);
return result;
}
- static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
+ static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o)
{
- binary_writer<uint8_t>(o).write_cbor(j);
+ binary_writer<std::uint8_t>(o).write_cbor(j);
}
static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
@@ -24320,16 +24919,16 @@
@since version 2.0.9
*/
- static std::vector<uint8_t> to_msgpack(const basic_json& j)
+ static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
{
- std::vector<uint8_t> result;
+ std::vector<std::uint8_t> result;
to_msgpack(j, result);
return result;
}
- static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
+ static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o)
{
- binary_writer<uint8_t>(o).write_msgpack(j);
+ binary_writer<std::uint8_t>(o).write_msgpack(j);
}
static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
@@ -24423,19 +25022,19 @@
@since version 3.1.0
*/
- static std::vector<uint8_t> to_ubjson(const basic_json& j,
- const bool use_size = false,
- const bool use_type = false)
+ static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
+ const bool use_size = false,
+ const bool use_type = false)
{
- std::vector<uint8_t> result;
+ std::vector<std::uint8_t> result;
to_ubjson(j, result, use_size, use_type);
return result;
}
- static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
+ 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)
{
- binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
+ binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
}
static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
@@ -24501,9 +25100,9 @@
@sa see @ref to_cbor(const basic_json&) for the related CBOR format
@sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
*/
- static std::vector<uint8_t> to_bson(const basic_json& j)
+ static std::vector<std::uint8_t> to_bson(const basic_json& j)
{
- std::vector<uint8_t> result;
+ std::vector<std::uint8_t> result;
to_bson(j, result);
return result;
}
@@ -24516,13 +25115,13 @@
@pre The input `j` shall be an object: `j.is_object() == true`
@sa see @ref to_bson(const basic_json&)
*/
- static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
+ static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o)
{
- binary_writer<uint8_t>(o).write_bson(j);
+ binary_writer<std::uint8_t>(o).write_bson(j);
}
/*!
- @copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)
+ @copydoc to_bson(const basic_json&, detail::output_adapter<std::uint8_t>)
*/
static void to_bson(const basic_json& j, detail::output_adapter<char> o)
{
@@ -25433,6 +26032,13 @@
}
// 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
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
}
@@ -25592,6 +26198,7 @@
break;
}
+ case patch_operations::invalid:
default:
{
// op must be "add", "remove", "replace", "move", "copy", or
@@ -25748,6 +26355,14 @@
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:
default:
{
// both primitive type: replace value
@@ -25960,9 +26575,9 @@
// #include <nlohmann/detail/macro_unscope.hpp>
-// restore GCC/clang diagnostic settings
+// restore clang diagnostic settings
#if defined(__clang__)
- #pragma GCC diagnostic pop
+ #pragma clang diagnostic pop
#endif
// clean up
@@ -25979,6 +26594,7 @@
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
#undef NLOHMANN_BASIC_JSON_TPL
#undef JSON_EXPLICIT
+#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
@@ -26134,4 +26750,4 @@
-#endif // INCLUDE_NLOHMANN_JSON_HPP_
\ No newline at end of file
+#endif // INCLUDE_NLOHMANN_JSON_HPP_