use detected instead of has_* traits
This commit is contained in:
parent
1ea8cd128c
commit
b59c3367c9
4 changed files with 157 additions and 178 deletions
|
@ -102,22 +102,3 @@
|
||||||
basic_json<ObjectType, ArrayType, StringType, BooleanType, \
|
basic_json<ObjectType, ArrayType, StringType, BooleanType, \
|
||||||
NumberIntegerType, NumberUnsignedType, NumberFloatType, \
|
NumberIntegerType, NumberUnsignedType, NumberFloatType, \
|
||||||
AllocatorType, JSONSerializer>
|
AllocatorType, JSONSerializer>
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief Helper to determine whether there's a key_type for T.
|
|
||||||
|
|
||||||
This helper is used to tell associative containers apart from other containers
|
|
||||||
such as sequence containers. For instance, `std::map` passes the test as it
|
|
||||||
contains a `mapped_type`, whereas `std::vector` fails the test.
|
|
||||||
|
|
||||||
@sa http://stackoverflow.com/a/7728728/266378
|
|
||||||
@since version 1.0.0, overworked in version 2.0.6
|
|
||||||
*/
|
|
||||||
#define NLOHMANN_JSON_HAS_HELPER(type) \
|
|
||||||
template<typename T> struct has_##type { \
|
|
||||||
template<typename U, typename = typename U::type> \
|
|
||||||
static int detect(U &&); \
|
|
||||||
static void detect(...); \
|
|
||||||
static constexpr bool value = \
|
|
||||||
std::is_integral<decltype(detect(std::declval<T>()))>::value; \
|
|
||||||
}
|
|
||||||
|
|
|
@ -20,4 +20,3 @@
|
||||||
#undef JSON_HAS_CPP_17
|
#undef JSON_HAS_CPP_17
|
||||||
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
#undef NLOHMANN_BASIC_JSON_TPL
|
#undef NLOHMANN_BASIC_JSON_TPL
|
||||||
#undef NLOHMANN_JSON_HAS_HELPER
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <nlohmann/json_fwd.hpp>
|
#include <nlohmann/json_fwd.hpp>
|
||||||
#include <nlohmann/detail/meta/cpp_future.hpp>
|
#include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
|
#include <nlohmann/detail/meta/detected.hpp>
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
|
|
||||||
namespace nlohmann
|
namespace nlohmann
|
||||||
|
@ -30,9 +31,31 @@ template<typename> struct is_basic_json : std::false_type {};
|
||||||
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
|
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
|
||||||
|
|
||||||
////////////////////////
|
//////////////////////////
|
||||||
// has_/is_ functions //
|
// aliases for detected //
|
||||||
////////////////////////
|
//////////////////////////
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using mapped_type_t = typename T::mapped_type;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using key_type_t = typename T::key_type;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using value_type_t = typename T::value_type;
|
||||||
|
|
||||||
|
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>()...));
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
using from_json_function = decltype(T::from_json(std::declval<Args>()...));
|
||||||
|
|
||||||
|
///////////////////
|
||||||
|
// is_ functions //
|
||||||
|
///////////////////
|
||||||
|
|
||||||
// source: https://stackoverflow.com/a/37193089/4116453
|
// source: https://stackoverflow.com/a/37193089/4116453
|
||||||
|
|
||||||
|
@ -42,11 +65,6 @@ struct is_complete_type : std::false_type {};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
|
struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
|
||||||
|
|
||||||
NLOHMANN_JSON_HAS_HELPER(mapped_type);
|
|
||||||
NLOHMANN_JSON_HAS_HELPER(key_type);
|
|
||||||
NLOHMANN_JSON_HAS_HELPER(value_type);
|
|
||||||
NLOHMANN_JSON_HAS_HELPER(iterator);
|
|
||||||
|
|
||||||
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 {};
|
||||||
|
|
||||||
|
@ -74,8 +92,8 @@ struct is_compatible_object_type
|
||||||
{
|
{
|
||||||
static auto constexpr value = is_compatible_object_type_impl <
|
static auto constexpr value = is_compatible_object_type_impl <
|
||||||
conjunction<negation<std::is_same<void, CompatibleObjectType>>,
|
conjunction<negation<std::is_same<void, CompatibleObjectType>>,
|
||||||
has_mapped_type<CompatibleObjectType>,
|
is_detected<mapped_type_t, CompatibleObjectType>,
|
||||||
has_key_type<CompatibleObjectType>>::value,
|
is_detected<key_type_t, CompatibleObjectType>>::value,
|
||||||
typename BasicJsonType::object_t, CompatibleObjectType >::value;
|
typename BasicJsonType::object_t, CompatibleObjectType >::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,7 +102,7 @@ struct is_compatible_string_type
|
||||||
{
|
{
|
||||||
static auto constexpr value = is_compatible_string_type_impl <
|
static auto constexpr value = is_compatible_string_type_impl <
|
||||||
conjunction<negation<std::is_same<void, CompatibleStringType>>,
|
conjunction<negation<std::is_same<void, CompatibleStringType>>,
|
||||||
has_value_type<CompatibleStringType>>::value,
|
is_detected<value_type_t, CompatibleStringType>>::value,
|
||||||
typename BasicJsonType::string_t, CompatibleStringType >::value;
|
typename BasicJsonType::string_t, CompatibleStringType >::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -107,8 +125,8 @@ struct is_compatible_array_type
|
||||||
negation<std::is_constructible<typename BasicJsonType::string_t,
|
negation<std::is_constructible<typename BasicJsonType::string_t,
|
||||||
CompatibleArrayType>>,
|
CompatibleArrayType>>,
|
||||||
negation<is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>>,
|
negation<is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>>,
|
||||||
has_value_type<CompatibleArrayType>,
|
is_detected<value_type_t, CompatibleArrayType>,
|
||||||
has_iterator<CompatibleArrayType>>::value;
|
is_detected<iterator_t, CompatibleArrayType>>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<bool, typename, typename>
|
template<bool, typename, typename>
|
||||||
|
@ -141,14 +159,11 @@ struct is_compatible_integer_type
|
||||||
template<typename BasicJsonType, typename T>
|
template<typename BasicJsonType, typename T>
|
||||||
struct has_from_json
|
struct has_from_json
|
||||||
{
|
{
|
||||||
// also check the return type of from_json
|
using serializer = typename BasicJsonType::template json_serializer<T, void>;
|
||||||
template<typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
|
|
||||||
std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
|
|
||||||
static int detect(U&&);
|
|
||||||
static void detect(...);
|
|
||||||
|
|
||||||
static constexpr bool value = std::is_integral<decltype(
|
static constexpr bool value =
|
||||||
detect(std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
|
is_detected_exact<void, from_json_function, serializer,
|
||||||
|
const BasicJsonType&, T&>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This trait checks if JSONSerializer<T>::from_json(json const&) exists
|
// This trait checks if JSONSerializer<T>::from_json(json const&) exists
|
||||||
|
@ -156,28 +171,22 @@ struct has_from_json
|
||||||
template<typename BasicJsonType, typename T>
|
template<typename BasicJsonType, typename T>
|
||||||
struct has_non_default_from_json
|
struct has_non_default_from_json
|
||||||
{
|
{
|
||||||
template <
|
using serializer = typename BasicJsonType::template json_serializer<T, void>;
|
||||||
typename U,
|
|
||||||
typename = enable_if_t<std::is_same<
|
|
||||||
T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
|
|
||||||
static int detect(U&&);
|
|
||||||
static void detect(...);
|
|
||||||
|
|
||||||
static constexpr bool value = std::is_integral<decltype(detect(
|
static constexpr bool value =
|
||||||
std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
|
is_detected_exact<T, from_json_function, serializer,
|
||||||
|
const BasicJsonType&>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
|
// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
|
||||||
template<typename BasicJsonType, typename T>
|
template<typename BasicJsonType, typename T>
|
||||||
struct has_to_json
|
struct has_to_json
|
||||||
{
|
{
|
||||||
template<typename U, typename = decltype(uncvref_t<U>::to_json(
|
using serializer = typename BasicJsonType::template json_serializer<T, void>;
|
||||||
std::declval<BasicJsonType&>(), std::declval<T>()))>
|
|
||||||
static int detect(U&&);
|
|
||||||
static void detect(...);
|
|
||||||
|
|
||||||
static constexpr bool value = std::is_integral<decltype(detect(
|
static constexpr bool value =
|
||||||
std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
|
is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
|
||||||
|
T>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename BasicJsonType, typename CompatibleCompleteType>
|
template <typename BasicJsonType, typename CompatibleCompleteType>
|
||||||
|
|
|
@ -218,25 +218,6 @@ using json = basic_json<>;
|
||||||
NumberIntegerType, NumberUnsignedType, NumberFloatType, \
|
NumberIntegerType, NumberUnsignedType, NumberFloatType, \
|
||||||
AllocatorType, JSONSerializer>
|
AllocatorType, JSONSerializer>
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief Helper to determine whether there's a key_type for T.
|
|
||||||
|
|
||||||
This helper is used to tell associative containers apart from other containers
|
|
||||||
such as sequence containers. For instance, `std::map` passes the test as it
|
|
||||||
contains a `mapped_type`, whereas `std::vector` fails the test.
|
|
||||||
|
|
||||||
@sa http://stackoverflow.com/a/7728728/266378
|
|
||||||
@since version 1.0.0, overworked in version 2.0.6
|
|
||||||
*/
|
|
||||||
#define NLOHMANN_JSON_HAS_HELPER(type) \
|
|
||||||
template<typename T> struct has_##type { \
|
|
||||||
template<typename U, typename = typename U::type> \
|
|
||||||
static int detect(U &&); \
|
|
||||||
static void detect(...); \
|
|
||||||
static constexpr bool value = \
|
|
||||||
std::is_integral<decltype(detect(std::declval<T>()))>::value; \
|
|
||||||
}
|
|
||||||
|
|
||||||
// #include <nlohmann/detail/meta/cpp_future.hpp>
|
// #include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
@ -334,6 +315,78 @@ constexpr T static_const<T>::value;
|
||||||
|
|
||||||
// #include <nlohmann/detail/meta/cpp_future.hpp>
|
// #include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
|
|
||||||
|
// #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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// http://en.cppreference.com/w/cpp/experimental/is_detected
|
||||||
|
namespace nlohmann
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
struct nonesuch
|
||||||
|
{
|
||||||
|
nonesuch() = delete;
|
||||||
|
~nonesuch() = delete;
|
||||||
|
nonesuch(nonesuch const&) = delete;
|
||||||
|
void operator=(nonesuch const&) = 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>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// #include <nlohmann/detail/macro_scope.hpp>
|
// #include <nlohmann/detail/macro_scope.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
@ -358,9 +411,31 @@ template<typename> struct is_basic_json : std::false_type {};
|
||||||
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
|
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
|
||||||
|
|
||||||
////////////////////////
|
//////////////////////////
|
||||||
// has_/is_ functions //
|
// aliases for detected //
|
||||||
////////////////////////
|
//////////////////////////
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using mapped_type_t = typename T::mapped_type;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using key_type_t = typename T::key_type;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using value_type_t = typename T::value_type;
|
||||||
|
|
||||||
|
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>()...));
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
using from_json_function = decltype(T::from_json(std::declval<Args>()...));
|
||||||
|
|
||||||
|
///////////////////
|
||||||
|
// is_ functions //
|
||||||
|
///////////////////
|
||||||
|
|
||||||
// source: https://stackoverflow.com/a/37193089/4116453
|
// source: https://stackoverflow.com/a/37193089/4116453
|
||||||
|
|
||||||
|
@ -370,11 +445,6 @@ struct is_complete_type : std::false_type {};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
|
struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
|
||||||
|
|
||||||
NLOHMANN_JSON_HAS_HELPER(mapped_type);
|
|
||||||
NLOHMANN_JSON_HAS_HELPER(key_type);
|
|
||||||
NLOHMANN_JSON_HAS_HELPER(value_type);
|
|
||||||
NLOHMANN_JSON_HAS_HELPER(iterator);
|
|
||||||
|
|
||||||
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 {};
|
||||||
|
|
||||||
|
@ -402,8 +472,8 @@ struct is_compatible_object_type
|
||||||
{
|
{
|
||||||
static auto constexpr value = is_compatible_object_type_impl <
|
static auto constexpr value = is_compatible_object_type_impl <
|
||||||
conjunction<negation<std::is_same<void, CompatibleObjectType>>,
|
conjunction<negation<std::is_same<void, CompatibleObjectType>>,
|
||||||
has_mapped_type<CompatibleObjectType>,
|
is_detected<mapped_type_t, CompatibleObjectType>,
|
||||||
has_key_type<CompatibleObjectType>>::value,
|
is_detected<key_type_t, CompatibleObjectType>>::value,
|
||||||
typename BasicJsonType::object_t, CompatibleObjectType >::value;
|
typename BasicJsonType::object_t, CompatibleObjectType >::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -412,7 +482,7 @@ struct is_compatible_string_type
|
||||||
{
|
{
|
||||||
static auto constexpr value = is_compatible_string_type_impl <
|
static auto constexpr value = is_compatible_string_type_impl <
|
||||||
conjunction<negation<std::is_same<void, CompatibleStringType>>,
|
conjunction<negation<std::is_same<void, CompatibleStringType>>,
|
||||||
has_value_type<CompatibleStringType>>::value,
|
is_detected<value_type_t, CompatibleStringType>>::value,
|
||||||
typename BasicJsonType::string_t, CompatibleStringType >::value;
|
typename BasicJsonType::string_t, CompatibleStringType >::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -435,8 +505,8 @@ struct is_compatible_array_type
|
||||||
negation<std::is_constructible<typename BasicJsonType::string_t,
|
negation<std::is_constructible<typename BasicJsonType::string_t,
|
||||||
CompatibleArrayType>>,
|
CompatibleArrayType>>,
|
||||||
negation<is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>>,
|
negation<is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>>,
|
||||||
has_value_type<CompatibleArrayType>,
|
is_detected<value_type_t, CompatibleArrayType>,
|
||||||
has_iterator<CompatibleArrayType>>::value;
|
is_detected<iterator_t, CompatibleArrayType>>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<bool, typename, typename>
|
template<bool, typename, typename>
|
||||||
|
@ -469,14 +539,11 @@ struct is_compatible_integer_type
|
||||||
template<typename BasicJsonType, typename T>
|
template<typename BasicJsonType, typename T>
|
||||||
struct has_from_json
|
struct has_from_json
|
||||||
{
|
{
|
||||||
// also check the return type of from_json
|
using serializer = typename BasicJsonType::template json_serializer<T, void>;
|
||||||
template<typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
|
|
||||||
std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
|
|
||||||
static int detect(U&&);
|
|
||||||
static void detect(...);
|
|
||||||
|
|
||||||
static constexpr bool value = std::is_integral<decltype(
|
static constexpr bool value =
|
||||||
detect(std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
|
is_detected_exact<void, from_json_function, serializer,
|
||||||
|
const BasicJsonType&, T&>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This trait checks if JSONSerializer<T>::from_json(json const&) exists
|
// This trait checks if JSONSerializer<T>::from_json(json const&) exists
|
||||||
|
@ -484,28 +551,22 @@ struct has_from_json
|
||||||
template<typename BasicJsonType, typename T>
|
template<typename BasicJsonType, typename T>
|
||||||
struct has_non_default_from_json
|
struct has_non_default_from_json
|
||||||
{
|
{
|
||||||
template <
|
using serializer = typename BasicJsonType::template json_serializer<T, void>;
|
||||||
typename U,
|
|
||||||
typename = enable_if_t<std::is_same<
|
|
||||||
T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
|
|
||||||
static int detect(U&&);
|
|
||||||
static void detect(...);
|
|
||||||
|
|
||||||
static constexpr bool value = std::is_integral<decltype(detect(
|
static constexpr bool value =
|
||||||
std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
|
is_detected_exact<T, from_json_function, serializer,
|
||||||
|
const BasicJsonType&>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
|
// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
|
||||||
template<typename BasicJsonType, typename T>
|
template<typename BasicJsonType, typename T>
|
||||||
struct has_to_json
|
struct has_to_json
|
||||||
{
|
{
|
||||||
template<typename U, typename = decltype(uncvref_t<U>::to_json(
|
using serializer = typename BasicJsonType::template json_serializer<T, void>;
|
||||||
std::declval<BasicJsonType&>(), std::declval<T>()))>
|
|
||||||
static int detect(U&&);
|
|
||||||
static void detect(...);
|
|
||||||
|
|
||||||
static constexpr bool value = std::is_integral<decltype(detect(
|
static constexpr bool value =
|
||||||
std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
|
is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
|
||||||
|
T>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename BasicJsonType, typename CompatibleCompleteType>
|
template <typename BasicJsonType, typename CompatibleCompleteType>
|
||||||
|
@ -3562,76 +3623,6 @@ scan_number_done:
|
||||||
|
|
||||||
// #include <nlohmann/detail/meta/detected.hpp>
|
// #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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// http://en.cppreference.com/w/cpp/experimental/is_detected
|
|
||||||
namespace nlohmann
|
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
struct nonesuch
|
|
||||||
{
|
|
||||||
nonesuch() = delete;
|
|
||||||
~nonesuch() = delete;
|
|
||||||
nonesuch(nonesuch const&) = delete;
|
|
||||||
void operator=(nonesuch const&) = 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>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// #include <nlohmann/detail/meta/type_traits.hpp>
|
// #include <nlohmann/detail/meta/type_traits.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
@ -18902,7 +18893,6 @@ inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std
|
||||||
#undef JSON_HAS_CPP_17
|
#undef JSON_HAS_CPP_17
|
||||||
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
#undef NLOHMANN_BASIC_JSON_TPL
|
#undef NLOHMANN_BASIC_JSON_TPL
|
||||||
#undef NLOHMANN_JSON_HAS_HELPER
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue