-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathP428.IsConvertible.cpp
More file actions
44 lines (36 loc) · 1.29 KB
/
P428.IsConvertible.cpp
File metadata and controls
44 lines (36 loc) · 1.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <type_traits>
// special cases
template<typename From, typename To, bool = std::is_void_v<To> || std::is_array_v<To> || std::is_function_v<To>>
struct IsConvertibleHelper
{
using type = std::bool_constant<std::is_void_v<To> && std::is_void_v<From>>; // If From and To are both void, the convesion will be valid.
};
// normal cases
template<typename From, typename To>
struct IsConvertibleHelper<From, To, false>
{
private:
static void aux(To);
template<typename F, typename = decltype(aux(std::declval<F>()))>
static std::true_type test(void*);
template<typename>
static std::false_type test(...);
public:
using type = decltype(test<From>(nullptr));
};
template<typename From, typename To>
struct IsConvertible : IsConvertibleHelper<From, To>::type {};
template<typename From, typename To>
using IsConvertible_t = IsConvertible<From, To>::type;
template<typename From, typename To>
constexpr bool IsConvertible_v = IsConvertible<From, To>::value;
// special cases
int main(int argc, char const *argv[])
{
static_assert(IsConvertible_v<int, double>);
static_assert(IsConvertible_v<void, void>);
static_assert(!IsConvertible_v<int, void>);
static_assert(!IsConvertible_v<int[10], int[10]>);
static_assert(!IsConvertible_v<int(), int()>);
return 0;
}