111
|
1 // DR 339
|
|
2 //
|
|
3 // Test of the use of casts with SFINAE
|
|
4
|
|
5 // Boilerplate helpers
|
|
6 typedef char yes_type;
|
|
7 struct no_type { char data[2]; };
|
|
8
|
|
9 template<typename T> T create_a();
|
|
10 template<typename T> struct type { };
|
|
11
|
|
12 template<bool, typename T = void> struct enable_if { typedef T type; };
|
|
13 template<typename T> struct enable_if<false, T> { };
|
|
14
|
|
15 #define JOIN( X, Y ) DO_JOIN( X, Y )
|
|
16 #define DO_JOIN( X, Y ) DO_JOIN2(X,Y)
|
|
17 #define DO_JOIN2( X, Y ) X##Y
|
|
18
|
|
19 #define CHECK_CAST(CastKind) \
|
|
20 template<typename T, typename U> \
|
|
21 typename enable_if<(sizeof((JOIN(CastKind,_cast)<U>(create_a<T>())), 0) > 0), \
|
|
22 yes_type>::type \
|
|
23 JOIN(check_,JOIN(CastKind,_cast))(int); \
|
|
24 \
|
|
25 template<typename T, typename U> \
|
|
26 no_type JOIN(check_,JOIN(CastKind,_cast))(...); \
|
|
27 \
|
|
28 template<typename T, typename U> \
|
|
29 struct JOIN(has_,JOIN(CastKind,_cast)) \
|
|
30 { \
|
|
31 static const bool value = \
|
|
32 (sizeof(JOIN(check_,JOIN(CastKind,_cast))<T, U>(0)) == sizeof(yes_type)); \
|
|
33 }
|
|
34
|
|
35 template<typename T, typename U>
|
|
36 typename enable_if<(sizeof(((U)create_a<T>()), 0) > 0), yes_type>::type
|
|
37 check_c_cast(int);
|
|
38
|
|
39 template<typename T, typename U> no_type check_c_cast(...);
|
|
40
|
|
41 template<typename T, typename U>
|
|
42 struct has_c_cast
|
|
43 {
|
|
44 static const bool value =
|
|
45 (sizeof(check_c_cast<T, U>(0)) == sizeof(yes_type));
|
|
46 };
|
|
47
|
|
48 #ifdef __GXX_EXPERIMENTAL_CXX0X__
|
|
49 # define STATIC_ASSERT(Expr) static_assert(Expr, #Expr)
|
|
50 #else
|
|
51 # define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1]
|
|
52 #endif
|
|
53
|
|
54 CHECK_CAST(static);
|
|
55 CHECK_CAST(dynamic);
|
|
56 CHECK_CAST(const);
|
|
57 CHECK_CAST(reinterpret);
|
|
58
|
|
59 struct X { virtual void f(); };
|
|
60 struct Y { operator bool(); };
|
|
61 struct Z : public X { };
|
|
62
|
|
63 STATIC_ASSERT((has_static_cast<int, float>::value));
|
|
64 STATIC_ASSERT((!has_static_cast<X, Y>::value));
|
|
65 STATIC_ASSERT((has_static_cast<Z, X>::value));
|
|
66
|
|
67 STATIC_ASSERT(!(has_dynamic_cast<int, float>::value));
|
|
68 STATIC_ASSERT(!(has_dynamic_cast<X, Y>::value));
|
|
69 STATIC_ASSERT(!(has_dynamic_cast<X, Z>::value));
|
|
70 STATIC_ASSERT(!(has_dynamic_cast<Y, Z>::value));
|
|
71 STATIC_ASSERT((has_dynamic_cast<X*, Z*>::value));
|
|
72 STATIC_ASSERT((has_dynamic_cast<X*, Y*>::value));
|
|
73 STATIC_ASSERT(!(has_dynamic_cast<Y*, Z*>::value));
|
|
74
|
|
75 STATIC_ASSERT(!(has_const_cast<int, float>::value));
|
|
76 STATIC_ASSERT((has_const_cast<const int*, int*>::value));
|
|
77 STATIC_ASSERT((has_const_cast<int*, const int*>::value));
|
|
78 STATIC_ASSERT(!(has_const_cast<const int*, float*>::value));
|
|
79
|
|
80 STATIC_ASSERT((has_reinterpret_cast<int*, float*>::value));
|
|
81 STATIC_ASSERT(!(has_reinterpret_cast<void*, char>::value));
|
|
82 STATIC_ASSERT(!(has_reinterpret_cast<const X, X>::value));
|
|
83
|
|
84 STATIC_ASSERT((has_c_cast<int, float>::value));
|
|
85 STATIC_ASSERT(!(has_c_cast<X, Y>::value));
|
|
86 STATIC_ASSERT(!(has_c_cast<void*, char>::value));
|