remove constraints on JSONSerializer instances, constrain correctly new methods
This commit is contained in:
parent
23bd2bce35
commit
88819449c2
2 changed files with 70 additions and 30 deletions
97
src/json.hpp
97
src/json.hpp
|
@ -150,6 +150,9 @@ struct has_mapped_type
|
||||||
std::is_integral<decltype(detect(std::declval<T>()))>::value;
|
std::is_integral<decltype(detect(std::declval<T>()))>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <template <typename...> class T>
|
||||||
|
struct wrapper{};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct has_key_type
|
struct has_key_type
|
||||||
{
|
{
|
||||||
|
@ -176,6 +179,19 @@ struct has_value_type
|
||||||
std::is_integral<decltype(detect(std::declval<T>()))>::value;
|
std::is_integral<decltype(detect(std::declval<T>()))>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct has_iterator
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
template <typename U, typename = typename U::iterator>
|
||||||
|
static int detect(U&&);
|
||||||
|
|
||||||
|
static void detect(...);
|
||||||
|
public:
|
||||||
|
static constexpr bool value =
|
||||||
|
std::is_integral<decltype(detect(std::declval<T>()))>::value;
|
||||||
|
};
|
||||||
|
|
||||||
template <bool B, class RealType, class CompatibleObjectType>
|
template <bool B, class RealType, class CompatibleObjectType>
|
||||||
struct is_compatible_object_type_impl : std::false_type{};
|
struct is_compatible_object_type_impl : std::false_type{};
|
||||||
|
|
||||||
|
@ -187,7 +203,7 @@ struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType>
|
||||||
std::is_constructible<typename RealType::mapped_type, typename CompatibleObjectType::mapped_type>::value;
|
std::is_constructible<typename RealType::mapped_type, typename CompatibleObjectType::mapped_type>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class RealType, class CompatibleObjectType, typename = enable_if_t<has_mapped_type<CompatibleObjectType>::value and has_key_type<CompatibleObjectType>::value>>
|
template<class RealType, class CompatibleObjectType>
|
||||||
struct is_compatible_object_type
|
struct is_compatible_object_type
|
||||||
{
|
{
|
||||||
static auto constexpr value = is_compatible_object_type_impl<has_mapped_type<CompatibleObjectType>::value and has_key_type<CompatibleObjectType>::value, RealType, CompatibleObjectType>::value;
|
static auto constexpr value = is_compatible_object_type_impl<has_mapped_type<CompatibleObjectType>::value and has_key_type<CompatibleObjectType>::value, RealType, CompatibleObjectType>::value;
|
||||||
|
@ -213,26 +229,43 @@ struct is_compatible_array_type_impl<true, BasicJson, CompatibleArrayType>
|
||||||
template <class BasicJson, class CompatibleArrayType>
|
template <class BasicJson, class CompatibleArrayType>
|
||||||
struct is_compatible_array_type
|
struct is_compatible_array_type
|
||||||
{
|
{
|
||||||
static auto constexpr value = is_compatible_array_type_impl<has_value_type<CompatibleArrayType>::value, BasicJson, CompatibleArrayType>::value;
|
static auto constexpr value = is_compatible_array_type_impl<not is_compatible_object_type<typename BasicJson::object_t, CompatibleArrayType>::value and has_value_type<CompatibleArrayType>::value and has_iterator<CompatibleArrayType>::value, BasicJson, CompatibleArrayType>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <bool, typename, typename>
|
||||||
|
struct is_compatible_integer_type_impl : std::false_type{};
|
||||||
|
|
||||||
|
template <typename RealIntegerType, typename CompatibleNumberIntegerType>
|
||||||
|
struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType>
|
||||||
|
{
|
||||||
|
static constexpr auto value = std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
|
||||||
|
std::numeric_limits<CompatibleNumberIntegerType>::is_integer and
|
||||||
|
std::numeric_limits<CompatibleNumberIntegerType>::is_signed;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename RealIntegerType, typename CompatibleNumberIntegerType>
|
template <typename RealIntegerType, typename CompatibleNumberIntegerType>
|
||||||
struct is_compatible_integer_type
|
struct is_compatible_integer_type
|
||||||
{
|
{
|
||||||
static constexpr auto value =
|
static constexpr auto value = is_compatible_integer_type_impl<std::is_arithmetic<CompatibleNumberIntegerType>::value, RealIntegerType, CompatibleNumberIntegerType>::value;
|
||||||
std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
|
|
||||||
std::numeric_limits<CompatibleNumberIntegerType>::is_integer and
|
|
||||||
std::numeric_limits<CompatibleNumberIntegerType>::is_signed;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename RealInteger, typename CompatibleNumberUnsignedType>
|
template <bool, typename, typename>
|
||||||
struct is_compatible_unsigned_integer_type
|
struct is_compatible_unsigned_integer_type_impl : std::false_type{};
|
||||||
|
|
||||||
|
template <typename RealUnsignedType, typename CompatibleNumberUnsignedType>
|
||||||
|
struct is_compatible_unsigned_integer_type_impl<true, RealUnsignedType, CompatibleNumberUnsignedType>
|
||||||
{
|
{
|
||||||
static constexpr auto value = std::is_constructible<RealInteger, CompatibleNumberUnsignedType>::value and
|
static constexpr auto value = std::is_constructible<RealUnsignedType, CompatibleNumberUnsignedType>::value and
|
||||||
std::numeric_limits<CompatibleNumberUnsignedType>::is_integer and
|
std::numeric_limits<CompatibleNumberUnsignedType>::is_integer and
|
||||||
not std::numeric_limits<CompatibleNumberUnsignedType>::is_signed;
|
not std::numeric_limits<CompatibleNumberUnsignedType>::is_signed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename RealUnsignedType, typename CompatibleNumberUnsignedType>
|
||||||
|
struct is_compatible_unsigned_integer_type
|
||||||
|
{
|
||||||
|
static constexpr auto value = is_compatible_unsigned_integer_type_impl<std::is_arithmetic<CompatibleNumberUnsignedType>::value, RealUnsignedType, CompatibleNumberUnsignedType>::value;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename RealFloat, typename CompatibleFloat>
|
template <typename RealFloat, typename CompatibleFloat>
|
||||||
struct is_compatible_float_type
|
struct is_compatible_float_type
|
||||||
{
|
{
|
||||||
|
@ -341,13 +374,13 @@ template <typename = void, typename = void>
|
||||||
struct adl_serializer
|
struct adl_serializer
|
||||||
{
|
{
|
||||||
template <typename Json, typename T>
|
template <typename Json, typename T>
|
||||||
static auto from_json(Json&& j, T& val) -> decltype(::nlohmann::from_json(std::forward<Json>(j), val), void())
|
static void from_json(Json&& j, T& val)
|
||||||
{
|
{
|
||||||
::nlohmann::from_json(std::forward<Json>(j), val);
|
::nlohmann::from_json(std::forward<Json>(j), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Json, typename T>
|
template <typename Json, typename T>
|
||||||
static auto to_json(Json& j, T&& val) -> decltype(::nlohmann::to_json(j, std::forward<T>(val)), void())
|
static void to_json(Json& j, T&& val)
|
||||||
{
|
{
|
||||||
::nlohmann::to_json(j, std::forward<T>(val));
|
::nlohmann::to_json(j, std::forward<T>(val));
|
||||||
}
|
}
|
||||||
|
@ -451,11 +484,6 @@ class basic_json
|
||||||
BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType,
|
BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType,
|
||||||
AllocatorType>;
|
AllocatorType>;
|
||||||
|
|
||||||
template <template <typename...> class T>
|
|
||||||
struct wrapper{};
|
|
||||||
|
|
||||||
using supported_tpl_types = std::tuple<wrapper<ObjectType>, wrapper<ArrayType>, wrapper<AllocatorType>, wrapper<JSONSerializer>>;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// forward declarations
|
// forward declarations
|
||||||
template<typename U> class iter_impl;
|
template<typename U> class iter_impl;
|
||||||
|
@ -1507,8 +1535,15 @@ class basic_json
|
||||||
}
|
}
|
||||||
|
|
||||||
// constructor chosen when JSONSerializer::to_json exists for type T
|
// constructor chosen when JSONSerializer::to_json exists for type T
|
||||||
template <typename T, typename = typename std::enable_if<detail::has_to_json<
|
template <typename T, enable_if_t<detail::has_to_json<
|
||||||
JSONSerializer, basic_json, uncvref_t<T>>::value>::type>
|
JSONSerializer, basic_json, uncvref_t<T>>::value and not (detail::is_compatible_object_type<object_t, uncvref_t<T>>::value or
|
||||||
|
detail::is_compatible_array_type<basic_json_t, uncvref_t<T>>::value or
|
||||||
|
detail::is_compatible_float_type<number_float_t, uncvref_t<T>>::value or
|
||||||
|
detail::is_compatible_integer_type<number_integer_t, uncvref_t<T>>::value or
|
||||||
|
detail::is_compatible_unsigned_integer_type<number_unsigned_t, uncvref_t<T>>::value or
|
||||||
|
std::is_constructible<string_t, uncvref_t<T>>::value or
|
||||||
|
std::is_base_of<std::istream, uncvref_t<T>>::value or
|
||||||
|
std::is_same<boolean_t, uncvref_t<T>>::value), int> = 0>
|
||||||
explicit basic_json(T &&val)
|
explicit basic_json(T &&val)
|
||||||
{
|
{
|
||||||
JSONSerializer<uncvref_t<T>>::to_json(*this, std::forward<T>(val));
|
JSONSerializer<uncvref_t<T>>::to_json(*this, std::forward<T>(val));
|
||||||
|
@ -3167,21 +3202,27 @@ class basic_json
|
||||||
@since version 1.0.0
|
@since version 1.0.0
|
||||||
*/
|
*/
|
||||||
template <typename ValueType,
|
template <typename ValueType,
|
||||||
typename std::enable_if<
|
enable_if_t<
|
||||||
not std::is_pointer<ValueType>::value and
|
not std::is_pointer<ValueType>::value,
|
||||||
not detail::has_from_json<JSONSerializer, basic_json,
|
int> = 0>
|
||||||
uncvref_t<ValueType>>::value,
|
|
||||||
int>::type = 0>
|
|
||||||
auto get() const
|
auto get() const
|
||||||
-> decltype(this->get_impl(static_cast<ValueType *>(nullptr))) {
|
-> decltype(this->get_impl(static_cast<ValueType *>(nullptr))) {
|
||||||
return get_impl(static_cast<ValueType *>(nullptr));
|
return get_impl(static_cast<ValueType *>(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ValueType,
|
template <typename T,
|
||||||
typename = enable_if_t<detail::has_from_json<
|
enable_if_t<detail::has_from_json<
|
||||||
JSONSerializer, basic_json, uncvref_t<ValueType>>::value>>
|
JSONSerializer, basic_json, uncvref_t<T>>::value
|
||||||
auto get() const -> uncvref_t<ValueType> {
|
and not (detail::is_compatible_object_type<object_t, uncvref_t<T>>::value or
|
||||||
using type = uncvref_t<ValueType>;
|
detail::is_compatible_array_type<basic_json_t, uncvref_t<T>>::value or
|
||||||
|
detail::is_compatible_float_type<number_float_t, uncvref_t<T>>::value or
|
||||||
|
detail::is_compatible_integer_type<number_integer_t, uncvref_t<T>>::value or
|
||||||
|
detail::is_compatible_unsigned_integer_type<number_unsigned_t, uncvref_t<T>>::value or
|
||||||
|
std::is_constructible<string_t, uncvref_t<T>>::value or
|
||||||
|
std::is_same<boolean_t, uncvref_t<T>>::value), int> = 0>
|
||||||
|
auto get() const -> uncvref_t<T>
|
||||||
|
{
|
||||||
|
using type = uncvref_t<T>;
|
||||||
static_assert(std::is_default_constructible<type>::value &&
|
static_assert(std::is_default_constructible<type>::value &&
|
||||||
std::is_copy_constructible<type>::value,
|
std::is_copy_constructible<type>::value,
|
||||||
"user-defined types must be DefaultConstructible and "
|
"user-defined types must be DefaultConstructible and "
|
||||||
|
|
|
@ -397,7 +397,7 @@ struct my_serializer
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*using my_json = nlohmann::basic_json<std::map, std::vector, std::string, bool,
|
using my_json = nlohmann::basic_json<std::map, std::vector, std::string, bool,
|
||||||
std::int64_t, std::uint64_t, double,
|
std::int64_t, std::uint64_t, double,
|
||||||
std::allocator, my_serializer>;
|
std::allocator, my_serializer>;
|
||||||
|
|
||||||
|
@ -430,4 +430,3 @@ TEST_CASE("custom serializer")
|
||||||
CHECK(pod2 == pod);
|
CHECK(pod2 == pod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
Loading…
Reference in a new issue