add support for from_json/to_json member function

This commit is contained in:
益彤 孙 2021-09-28 14:10:59 +08:00
parent 0b345b20c8
commit d1f0f595f3
3 changed files with 46 additions and 1 deletions

View File

@ -138,7 +138,7 @@ using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
// dispatch utility (taken from ranges-v3)
template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
template<> struct priority_tag<0> {};
template<> struct priority_tag<-1> {};
// taken from ranges-v3
template<typename T>

View File

@ -145,6 +145,26 @@ struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
T>::value;
};
template<typename Json, typename T>
struct has_to_json_member {
private:
template<typename U>
static auto check(int) -> decltype(std::declval<U>().to_json(std::declval<Json&>()), std::true_type());
template<typename U>
static std::false_type check(...);
public:
static constexpr bool value = std::is_same_v<decltype(check<T>(0)),std::true_type>;
};
template<typename Json, typename T>
struct has_from_json_member {
private:
template<typename U>
static auto check(int) -> decltype(std::declval<U>().from_json(std::declval<const Json&>()), std::true_type());
template<typename U>
static std::false_type check(...);
public:
static constexpr bool value = std::is_same_v<decltype(check<T>(0)),std::true_type>;
};
///////////////////
// is_ functions //
@ -274,6 +294,7 @@ struct is_constructible_object_type_impl <
typename ConstructibleObjectType::mapped_type >::value)) ||
(has_from_json<BasicJsonType,
typename ConstructibleObjectType::mapped_type>::value ||
has_from_json_member<BasicJsonType, typename ConstructibleObjectType::mapped_type>::value ||
has_non_default_from_json <
BasicJsonType,
typename ConstructibleObjectType::mapped_type >::value);
@ -379,6 +400,7 @@ detected_t<value_type_t, ConstructibleArrayType >>::value >>
typename BasicJsonType::array_t::value_type>::value ||
has_from_json<BasicJsonType,
typename ConstructibleArrayType::value_type>::value ||
has_from_json_member<BasicJsonType, typename ConstructibleArrayType::value_type>::value ||
has_non_default_from_json <
BasicJsonType, typename ConstructibleArrayType::value_type >::value);
};

View File

@ -1655,6 +1655,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
assert_invariant();
}
template<typename T, detail::enable_if_t<detail::has_to_json_member<basic_json, T>::value, int> = 0>
basic_json(const T& val) {
val.to_json(*this);
set_parents();
assert_invariant();
}
/*!
@brief create a container (array or object) from an initializer list
@ -3114,6 +3121,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return JSONSerializer<ValueType>::from_json(*this);
}
template<typename ValueType, detail::enable_if_t<detail::has_from_json_member<basic_json_t, ValueType>::value, int> = 0>
ValueType get_impl(detail::priority_tag<-1>)const{
ValueType v{};
v.from_json(*this);
return v;
}
/*!
@brief get special-case overload
@ -3296,6 +3310,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return v;
}
template<typename ValueType, detail::enable_if_t<
!detail::is_basic_json<ValueType>::value &&
detail::has_from_json_member<basic_json_t, ValueType>::value, int> = 0>
ValueType& get_to(ValueType& v) const
{
v.from_json(*this);
return v;
}
// specialization to allow to call get_to with a basic_json value
// see https://github.com/nlohmann/json/issues/2175
template<typename ValueType,