mirror of
https://github.com/nlohmann/json.git
synced 2026-10-26 07:48:55 +00:00
json_view: from_json() of the macros reads views directly
get<T>() and get_to() of a view call T's from_json() with the view itself when that from_json() accepts views but not an unrelated probe type, and fall back to materialize() otherwise. The from_json() functions of the NLOHMANN_DEFINE_TYPE_*, NLOHMANN_DEFINE_DERIVED_TYPE_* and NLOHMANN_JSON_SERIALIZE_ENUM(_STRICT) macros accept basic_json values and views; a derived type whose base reads only json reads the base part through materialize(). The library's own from_json() overloads are not called with views: from_json() of a view (and of the probe) only looks up functions by ADL. New public trait nlohmann::is_json_view<T>, and the member type basic_json_type of basic_json_view. With duplicate keys, the members of such a T are those the view's lookups find (the first ones). bench_decode.cpp measures decoding into structs (4-6x faster than materialize().get<T>() on twitter, citm_catalog, and synthetic records). Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
23 files changed
+1342
-130
No files matched your search
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <algorithm> // min, transform
|
||||
#include <array> // array
|
||||
#include <cstddef> // nullptr_t
|
||||
#include <forward_list> // forward_list
|
||||
#include <iterator> // inserter, front_inserter, end
|
||||
#include <map> // map
|
||||
@@ -27,6 +28,7 @@
|
||||
#include <nlohmann/detail/meta/identity_tag.hpp>
|
||||
#include <nlohmann/detail/meta/std_fs.hpp>
|
||||
#include <nlohmann/detail/meta/type_traits.hpp>
|
||||
#include <nlohmann/detail/output/error_handler.hpp>
|
||||
#include <nlohmann/detail/string_concat.hpp>
|
||||
#include <nlohmann/detail/value_t.hpp>
|
||||
|
||||
@@ -665,16 +667,114 @@ inline void from_json(const BasicJsonType& j, std_fs::path& p)
|
||||
}
|
||||
#endif
|
||||
|
||||
struct from_json_fn
|
||||
namespace from_json_adl
|
||||
{
|
||||
template<typename BasicJsonType, typename T>
|
||||
auto operator()(const BasicJsonType& j, T&& val) const
|
||||
// hides the library's from_json() overloads above (and the from_json object):
|
||||
// a call from this namespace finds only the from_json() functions of the
|
||||
// arguments' own namespaces and classes (ADL); the declaration is never viable
|
||||
// and never defined (not "= delete", which GCC before 6 reports as a use)
|
||||
struct hidden;
|
||||
void from_json(const hidden&);
|
||||
|
||||
// a type no from_json() written for JSON values accepts: a from_json() that
|
||||
// accepts it is not constrained to them (see has_view_from_json; it lives
|
||||
// here, so that ADL finds no other from_json() for it)
|
||||
struct probe
|
||||
{};
|
||||
|
||||
struct fn
|
||||
{
|
||||
template<typename SourceType, typename T>
|
||||
auto operator()(const SourceType& j, T&& val) const
|
||||
noexcept(noexcept(from_json(j, std::forward<T>(val))))
|
||||
-> decltype(from_json(j, std::forward<T>(val)))
|
||||
{
|
||||
return from_json(j, std::forward<T>(val));
|
||||
}
|
||||
};
|
||||
} // namespace from_json_adl
|
||||
|
||||
// the sources whose from_json() is only looked up by ADL: views (the library's
|
||||
// overloads are written for basic_json) and the probe
|
||||
template<typename T>
|
||||
struct is_adl_only_from_json_source : disjunction<is_json_view<T>, std::is_same<T, from_json_adl::probe>> {};
|
||||
|
||||
struct from_json_fn
|
||||
{
|
||||
template < typename BasicJsonType, typename T,
|
||||
enable_if_t < !is_adl_only_from_json_source<BasicJsonType>::value, int > = 0 >
|
||||
auto operator()(const BasicJsonType& j, T && val) const
|
||||
noexcept(noexcept(from_json(j, std::forward<T>(val))))
|
||||
-> decltype(from_json(j, std::forward<T>(val)))
|
||||
{
|
||||
return from_json(j, std::forward<T>(val));
|
||||
}
|
||||
|
||||
template < typename SourceType, typename T,
|
||||
enable_if_t < is_adl_only_from_json_source<SourceType>::value, int > = 0 >
|
||||
auto operator()(const SourceType& j, T && val) const
|
||||
noexcept(noexcept(from_json_adl::fn {}(j, std::forward<T>(val))))
|
||||
-> decltype(from_json_adl::fn {}(j, std::forward<T>(val)))
|
||||
{
|
||||
return from_json_adl::fn {}(j, std::forward<T>(val));
|
||||
}
|
||||
};
|
||||
|
||||
// Whether JSONSerializer::from_json(view, T&) reads T from a view (of
|
||||
// <nlohmann/json_view.hpp>) directly: it must accept the view but not the
|
||||
// probe. An unconstrained from_json() template (written for basic_json, but
|
||||
// accepting anything) is thus not called with a view, nor are the library's
|
||||
// own conversions; the view converts such types through materialize().
|
||||
template<typename Serializer, typename SourceType, typename T>
|
||||
using serializer_from_json_t = decltype(Serializer::from_json(std::declval<const SourceType&>(), std::declval<T&>()));
|
||||
|
||||
template<typename Serializer, typename View, typename T>
|
||||
struct has_view_from_json
|
||||
: conjunction < is_detected<serializer_from_json_t, Serializer, View, T>,
|
||||
negation<is_detected<serializer_from_json_t, Serializer, from_json_adl::probe, T>>> {};
|
||||
|
||||
// the base part of a type of the NLOHMANN_DEFINE_DERIVED_TYPE_* macros: from a
|
||||
// view through its get_to(), which reads the base from the view where the
|
||||
// base's from_json() accepts views, and from materialize() otherwise
|
||||
template<typename BasicJsonType, typename T, enable_if_t<is_basic_json<BasicJsonType>::value, int> = 0>
|
||||
void from_json_base(const BasicJsonType& j, T& base)
|
||||
{
|
||||
from_json_fn {}(j, base);
|
||||
}
|
||||
|
||||
template<typename View, typename T, enable_if_t<is_json_view<View>::value, int> = 0>
|
||||
void from_json_base(const View& v, T& base)
|
||||
{
|
||||
v.get_to(base);
|
||||
}
|
||||
|
||||
// the context of an exception thrown by a from_json() of the macros: the value
|
||||
// itself for basic_json (for JSON_DIAGNOSTICS), none for a view
|
||||
template<typename BasicJsonType, enable_if_t<is_basic_json<BasicJsonType>::value, int> = 0>
|
||||
const BasicJsonType * from_json_context(const BasicJsonType& j) noexcept
|
||||
{
|
||||
return &j;
|
||||
}
|
||||
|
||||
template<typename View, enable_if_t<is_json_view<View>::value, int> = 0>
|
||||
std::nullptr_t from_json_context(const View& /*unused*/) noexcept
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// a value as an exception message shows it (invalid UTF-8 replaced; the
|
||||
// strings of a view are always valid UTF-8)
|
||||
template<typename BasicJsonType, enable_if_t<is_basic_json<BasicJsonType>::value, int> = 0>
|
||||
typename BasicJsonType::string_t from_json_dump(const BasicJsonType& j)
|
||||
{
|
||||
return j.dump(-1, ' ', false, error_handler_t::replace);
|
||||
}
|
||||
|
||||
template<typename View, enable_if_t<is_json_view<View>::value, int> = 0>
|
||||
typename View::string_t from_json_dump(const View& v)
|
||||
{
|
||||
return v.dump();
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
@@ -291,15 +291,17 @@
|
||||
}); \
|
||||
j = ((it != std::end(m)) ? it : std::begin(m))->second; \
|
||||
} \
|
||||
template<typename BasicJsonType> \
|
||||
template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json_or_view<BasicJsonType>::value, int> = 0> \
|
||||
inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
|
||||
{ \
|
||||
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
||||
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
||||
/* (for a view, the table holds basic_json values, which compare with the view) */ \
|
||||
using nlohmann_json_value_t = nlohmann::detail::json_type_of_t<BasicJsonType>; \
|
||||
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
||||
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
||||
static const std::pair<ENUM_TYPE, nlohmann_json_value_t> m[] = __VA_ARGS__; \
|
||||
auto it = std::find_if(std::begin(m), std::end(m), \
|
||||
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
||||
[&j](const std::pair<ENUM_TYPE, nlohmann_json_value_t>& ej_pair) -> bool \
|
||||
{ \
|
||||
return ej_pair.second == j; \
|
||||
}); \
|
||||
@@ -330,20 +332,22 @@
|
||||
if (it != std::end(m)) j = it->second; \
|
||||
else ::nlohmann::detail::templated_json_throw<nlohmann::detail::out_of_range>(nlohmann::detail::out_of_range::create(nlohmann::detail::exception_id::value_out_of_range,"enum value out of range for " #ENUM_TYPE, nullptr)); \
|
||||
} \
|
||||
template<typename BasicJsonType> \
|
||||
template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json_or_view<BasicJsonType>::value, int> = 0> \
|
||||
inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
|
||||
{ \
|
||||
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
||||
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
||||
/* (for a view, the table holds basic_json values, which compare with the view) */ \
|
||||
using nlohmann_json_value_t = nlohmann::detail::json_type_of_t<BasicJsonType>; \
|
||||
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
||||
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
||||
static const std::pair<ENUM_TYPE, nlohmann_json_value_t> m[] = __VA_ARGS__; \
|
||||
auto it = std::find_if(std::begin(m), std::end(m), \
|
||||
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
||||
[&j](const std::pair<ENUM_TYPE, nlohmann_json_value_t>& ej_pair) -> bool \
|
||||
{ \
|
||||
return ej_pair.second == j; \
|
||||
}); \
|
||||
if (it != std::end(m)) e = it->first; \
|
||||
else ::nlohmann::detail::templated_json_throw<nlohmann::detail::out_of_range>(nlohmann::detail::out_of_range::create(nlohmann::detail::exception_id::value_out_of_range, nlohmann::detail::concat("enum value out of range for " #ENUM_TYPE ": ", j.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace)), &j)); \
|
||||
else ::nlohmann::detail::templated_json_throw<nlohmann::detail::out_of_range>(nlohmann::detail::out_of_range::create(nlohmann::detail::exception_id::value_out_of_range, nlohmann::detail::concat("enum value out of range for " #ENUM_TYPE ": ", nlohmann::detail::from_json_dump(j)), nlohmann::detail::from_json_context(j))); \
|
||||
}
|
||||
|
||||
// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
|
||||
@@ -603,6 +607,8 @@
|
||||
#define NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME(v1, v2) nlohmann_json_t.v2 = !nlohmann_json_j.is_null() ? nlohmann_json_j.value(v1, nlohmann_json_default_obj.v2) : nlohmann_json_default_obj.v2;
|
||||
|
||||
#define NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(...) template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> __VA_ARGS__
|
||||
// from_json() also reads from the views of <nlohmann/json_view.hpp>
|
||||
#define NLOHMANN_JSON_FROM_TYPE_TEMPLATE(...) template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json_or_view<BasicJsonType>::value, int> = 0> __VA_ARGS__
|
||||
|
||||
// Helpers used to dispatch the NLOHMANN_DEFINE_TYPE_*/NLOHMANN_DEFINE_DERIVED_TYPE_*
|
||||
// macros below between a zero-member and a one-or-more-member implementation
|
||||
@@ -655,18 +661,18 @@
|
||||
*/
|
||||
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_MEMBERS(Type, ...) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
||||
|
||||
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_EMPTY(Type) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type&) { nlohmann_json_j = BasicJsonType::object(); }) \
|
||||
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type is used as a declarator type, not in an expression */ \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType&, Type&) noexcept { })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType&, Type&) noexcept { })
|
||||
|
||||
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_TYPE_BODY(NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
||||
|
||||
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES(Type, ...) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
||||
|
||||
/*!
|
||||
@brief macro
|
||||
@@ -676,7 +682,7 @@
|
||||
*/
|
||||
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, ...) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) })
|
||||
|
||||
// identical to NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_EMPTY: with no members there is nothing to default
|
||||
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_EMPTY(Type) NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_EMPTY(Type)
|
||||
@@ -685,7 +691,7 @@
|
||||
|
||||
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, ...) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
||||
|
||||
/*!
|
||||
@brief macro
|
||||
@@ -712,18 +718,18 @@
|
||||
*/
|
||||
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_MEMBERS(Type, ...) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
||||
|
||||
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_EMPTY(Type) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type&) { nlohmann_json_j = BasicJsonType::object(); }) \
|
||||
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type is used as a declarator type, not in an expression */ \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType&, Type&) noexcept { })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType&, Type&) noexcept { })
|
||||
|
||||
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_TYPE_BODY(NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
||||
|
||||
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES(Type, ...) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
||||
|
||||
/*!
|
||||
@brief macro
|
||||
@@ -733,7 +739,7 @@
|
||||
*/
|
||||
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, ...) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) })
|
||||
|
||||
// identical to NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_EMPTY: with no members there is nothing to default
|
||||
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_EMPTY(Type) NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_EMPTY(Type)
|
||||
@@ -742,7 +748,7 @@
|
||||
|
||||
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, ...) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
||||
|
||||
/*!
|
||||
@brief macro
|
||||
@@ -769,18 +775,18 @@
|
||||
*/
|
||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_MEMBERS(Type, BaseType, ...) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
||||
|
||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_EMPTY(Type, BaseType) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); }) \
|
||||
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type/BaseType are used as declarator types, not in expressions */ \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); })
|
||||
|
||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DERIVED_TYPE_BODY(NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
||||
|
||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES(Type, BaseType, ...) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
||||
|
||||
/*!
|
||||
@brief macro
|
||||
@@ -790,7 +796,7 @@
|
||||
*/
|
||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, BaseType, ...) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) })
|
||||
|
||||
// identical to NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_EMPTY: with no members there is nothing to default
|
||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_EMPTY(Type, BaseType) NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_EMPTY(Type, BaseType)
|
||||
@@ -799,7 +805,7 @@
|
||||
|
||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, BaseType, ...) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
||||
|
||||
/*!
|
||||
@brief macro
|
||||
@@ -827,18 +833,18 @@
|
||||
*/
|
||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_MEMBERS(Type, BaseType, ...) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
||||
|
||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_EMPTY(Type, BaseType) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); }) \
|
||||
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type/BaseType are used as declarator types, not in expressions */ \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); })
|
||||
|
||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DERIVED_TYPE_BODY(NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
||||
|
||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES(Type, BaseType, ...) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
||||
|
||||
/*!
|
||||
@brief macro
|
||||
@@ -848,7 +854,7 @@
|
||||
*/
|
||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, BaseType, ...) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) })
|
||||
|
||||
// identical to NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_EMPTY: with no members there is nothing to default
|
||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_EMPTY(Type, BaseType) NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_EMPTY(Type, BaseType)
|
||||
@@ -857,7 +863,7 @@
|
||||
|
||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, BaseType, ...) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
||||
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
||||
|
||||
/*!
|
||||
@brief macro
|
||||
|
||||
@@ -340,6 +340,47 @@ template<class B> struct negation : std::integral_constant < bool, !B::value > {
|
||||
|
||||
#endif
|
||||
|
||||
///////////////////////
|
||||
// json_view helpers //
|
||||
///////////////////////
|
||||
|
||||
template<typename T>
|
||||
using basic_json_type_t = typename T::basic_json_type;
|
||||
|
||||
template<typename T>
|
||||
using materialize_function_t = decltype(std::declval<const T&>().materialize());
|
||||
|
||||
// a basic_json_view of <nlohmann/json_view.hpp> (detected by its member type
|
||||
// basic_json_type, a basic_json, and materialize() returning that type, so that
|
||||
// json.hpp needs no declaration of the view)
|
||||
template<typename T, typename = void>
|
||||
struct is_json_view : std::false_type {};
|
||||
|
||||
template<typename T>
|
||||
struct is_json_view<T, enable_if_t<is_basic_json<detected_t<basic_json_type_t, T>>::value>>
|
||||
: std::is_same<detected_t<materialize_function_t, T>, basic_json_type_t<T>> {};
|
||||
|
||||
// the types from_json() functions of the NLOHMANN_DEFINE_TYPE_* and
|
||||
// NLOHMANN_JSON_SERIALIZE_ENUM macros read from
|
||||
template<typename T>
|
||||
struct is_basic_json_or_view : disjunction<is_basic_json<T>, is_json_view<T>> {};
|
||||
|
||||
// the basic_json type of a basic_json value or of a view
|
||||
template<typename T, typename = void>
|
||||
struct json_type_of
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct json_type_of<T, enable_if_t<is_json_view<T>::value>>
|
||||
{
|
||||
using type = typename T::basic_json_type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using json_type_of_t = typename json_type_of<T>::type;
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -106,6 +106,8 @@ class basic_json_view
|
||||
using navigation = detail::view::navigation<is_editable>;
|
||||
|
||||
public:
|
||||
/// the basic_json type of the document (it also marks views for is_json_view)
|
||||
using basic_json_type = BasicJsonType;
|
||||
using value_t = detail::value_t;
|
||||
using string_t = typename BasicJsonType::string_t;
|
||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||
@@ -567,8 +569,10 @@ class basic_json_view
|
||||
|
||||
/// the value converted to T, as BasicJsonType::get<T>(): arithmetic types,
|
||||
/// strings (string_view_t without a copy), std::nullptr_t, std::vector,
|
||||
/// maps with string keys, and views are converted directly; other types
|
||||
/// through materialize().get<T>()
|
||||
/// maps with string keys, and views are converted directly; types whose
|
||||
/// from_json() accepts views (those of the NLOHMANN_DEFINE_TYPE_* and
|
||||
/// NLOHMANN_JSON_SERIALIZE_ENUM macros, say) read the view; other types
|
||||
/// go through materialize().get<T>()
|
||||
template<typename T>
|
||||
NLOHMANN_VIEW_ALWAYS_INLINE T get() const
|
||||
{
|
||||
@@ -576,11 +580,12 @@ class basic_json_view
|
||||
}
|
||||
|
||||
/// as BasicJsonType::get_to(): the types get<T>() converts directly are
|
||||
/// assigned, all others are passed to from_json with v as it is
|
||||
/// assigned, all others are passed to from_json with v as it is (with
|
||||
/// the view if from_json() accepts views, else with materialize())
|
||||
template<typename T>
|
||||
T& get_to(T& v) const
|
||||
{
|
||||
get_to_impl(v, detail::view::is_direct_value<T, BasicJsonType, basic_json_view> {});
|
||||
get_to_impl(v, get_to_kind<T> {});
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -923,6 +928,26 @@ class basic_json_view
|
||||
return detail::view::map_value<std::unordered_map<K, V, H, E, A>>(*this);
|
||||
}
|
||||
|
||||
/// whether the from_json() of T's serializer reads views (see
|
||||
/// detail::has_view_from_json)
|
||||
template<typename T>
|
||||
using reads_view = detail::has_view_from_json<typename BasicJsonType::template json_serializer<T, void>, basic_json_view, T>;
|
||||
|
||||
/// how get_to() converts: 2 directly, 1 with a from_json() that reads
|
||||
/// views, 0 through materialize()
|
||||
template<typename T>
|
||||
using get_to_kind = std::integral_constant < int, detail::view::is_direct_value<T, BasicJsonType, basic_json_view>::value
|
||||
? 2 : static_cast<int>(reads_view<T>::value) >;
|
||||
|
||||
/// types whose from_json() reads views, without materialize()
|
||||
template < typename T, typename std::enable_if < reads_view<T>::value && std::is_default_constructible<T>::value, int >::type = 0 >
|
||||
T get_impl(detail::view::value_tag<T> /*unused*/, detail::priority_tag<1> /*unused*/) const
|
||||
{
|
||||
auto v = T();
|
||||
BasicJsonType::template json_serializer<T, void>::from_json(*this, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// everything else through the BasicJsonType value (from_json included)
|
||||
template<typename T>
|
||||
T get_impl(detail::view::value_tag<T> /*unused*/, detail::priority_tag<0> /*unused*/) const
|
||||
@@ -933,14 +958,20 @@ class basic_json_view
|
||||
// --- get_to() dispatch ---
|
||||
|
||||
template<typename T>
|
||||
void get_to_impl(T& v, std::true_type /*direct*/) const
|
||||
void get_to_impl(T& v, std::integral_constant<int, 2> /*direct*/) const
|
||||
{
|
||||
v = get<T>();
|
||||
}
|
||||
|
||||
/// from_json may keep parts of v (members a JSON object lacks, say)
|
||||
template<typename T>
|
||||
void get_to_impl(T& v, std::false_type /*direct*/) const
|
||||
void get_to_impl(T& v, std::integral_constant<int, 1> /*from_json reads views*/) const
|
||||
{
|
||||
BasicJsonType::template json_serializer<T, void>::from_json(*this, v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void get_to_impl(T& v, std::integral_constant<int, 0> /*through materialize()*/) const
|
||||
{
|
||||
materialize().get_to(v);
|
||||
}
|
||||
@@ -1645,6 +1676,15 @@ class basic_json_document
|
||||
std::unique_ptr<document_data, document_data::deleter> m_data{}; // NOLINT(readability-redundant-member-init)
|
||||
};
|
||||
|
||||
/*!
|
||||
@brief whether T is a basic_json_view (of any BasicJsonType and view_mode)
|
||||
|
||||
For constraining templates that accept views, e.g. a from_json() written for
|
||||
both basic_json values and views.
|
||||
*/
|
||||
template<typename T>
|
||||
struct is_json_view : detail::is_json_view<T> {};
|
||||
|
||||
/// a parsed JSON text for json
|
||||
using json_document = basic_json_document<json>;
|
||||
/// a value of a json_document
|
||||
|
||||
Reference in new issue
Block a user