111
|
1 // DR 339
|
|
2 //
|
|
3 // Test of the use of various unary operators with SFINAE
|
|
4 // { dg-options "-fmessage-length=0 -pedantic-errors -Wno-long-long -ftrack-macro-expansion=0 " }
|
|
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 DEFINE_PREFIX_UNARY_TRAIT(Name,Op) \
|
|
20 template<typename T> \
|
|
21 typename enable_if<(sizeof(Op create_a<T>(), 1) > 0), \
|
|
22 yes_type>::type \
|
|
23 JOIN(check_,Name)(int); \
|
|
24 \
|
|
25 template<typename T> \
|
|
26 no_type JOIN(check_,Name)(...); \
|
|
27 \
|
|
28 template<typename T> \
|
|
29 struct Name \
|
|
30 { \
|
|
31 static const bool value = \
|
|
32 (sizeof(JOIN(check_,Name)<T&>(0)) == sizeof(yes_type)); \
|
|
33 }
|
|
34
|
|
35 #define DEFINE_POSTFIX_UNARY_TRAIT(Name,Op) \
|
|
36 template<typename T> \
|
|
37 typename enable_if<(sizeof(create_a<T>() Op, 1) > 0), \
|
|
38 yes_type>::type \
|
|
39 JOIN(check_,Name)(int); \
|
|
40 \
|
|
41 template<typename T> \
|
|
42 no_type JOIN(check_,Name)(...); \
|
|
43 \
|
|
44 template<typename T> \
|
|
45 struct Name \
|
|
46 { \
|
|
47 static const bool value = \
|
|
48 (sizeof(JOIN(check_,Name)<T&>(0)) == sizeof(yes_type)); \
|
|
49 }
|
|
50
|
|
51 #ifdef __GXX_EXPERIMENTAL_CXX0X__
|
|
52 # define STATIC_ASSERT(Expr) static_assert(Expr, #Expr)
|
|
53 #else
|
|
54 # define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1]
|
|
55 #endif
|
|
56
|
|
57 struct W {
|
|
58 W operator+();
|
|
59 W operator-();
|
|
60 int operator*();
|
|
61 W operator~();
|
|
62 bool operator!();
|
|
63 W& operator++();
|
|
64 W& operator--();
|
|
65 W& operator++(int);
|
|
66 W& operator--(int);
|
|
67 };
|
|
68
|
|
69 struct X { };
|
|
70 X operator+(X);
|
|
71 X operator-(X);
|
|
72 int operator*(X);
|
|
73 X operator~(X);
|
|
74 bool operator!(X);
|
|
75 X& operator++(X&);
|
|
76 X& operator--(X&);
|
|
77 X& operator++(X&, int);
|
|
78 X& operator--(X&, int);
|
|
79
|
|
80 struct Y { };
|
|
81
|
|
82 struct Z {
|
|
83 private:
|
|
84 Z operator+();
|
|
85 Z operator-();
|
|
86 int operator*();
|
|
87 Z operator~();
|
|
88 bool operator!();
|
|
89 Z& operator++();
|
|
90 Z& operator--();
|
|
91 Z& operator++(int);
|
|
92 Z& operator--(int);
|
|
93 };
|
|
94
|
|
95 // has_unary_plus
|
|
96 DEFINE_PREFIX_UNARY_TRAIT(has_unary_plus, +);
|
|
97 STATIC_ASSERT((has_unary_plus<int>::value));
|
|
98 STATIC_ASSERT((!has_unary_plus<int X::*>::value));
|
|
99 STATIC_ASSERT((has_unary_plus<W>::value));
|
|
100 STATIC_ASSERT((has_unary_plus<X>::value));
|
|
101 STATIC_ASSERT((!has_unary_plus<Y>::value));
|
|
102
|
|
103 // is_negatable
|
|
104 DEFINE_PREFIX_UNARY_TRAIT(is_negatable, -);
|
|
105 STATIC_ASSERT((is_negatable<int>::value));
|
|
106 STATIC_ASSERT((!is_negatable<int X::*>::value));
|
|
107 STATIC_ASSERT((is_negatable<W>::value));
|
|
108 STATIC_ASSERT((is_negatable<X>::value));
|
|
109 STATIC_ASSERT((!is_negatable<Y>::value));
|
|
110
|
|
111 // is_dereferenceable
|
|
112 DEFINE_PREFIX_UNARY_TRAIT(is_dereferenceable, *);
|
|
113 STATIC_ASSERT((!is_dereferenceable<int>::value));
|
|
114 STATIC_ASSERT((is_dereferenceable<int*>::value));
|
|
115 STATIC_ASSERT((is_dereferenceable<W>::value));
|
|
116 STATIC_ASSERT((is_dereferenceable<X>::value));
|
|
117 STATIC_ASSERT((!is_dereferenceable<Y>::value));
|
|
118
|
|
119 // has_bitwise_not
|
|
120 DEFINE_PREFIX_UNARY_TRAIT(has_bitwise_not, ~);
|
|
121 STATIC_ASSERT((has_bitwise_not<int>::value));
|
|
122 STATIC_ASSERT((!has_bitwise_not<int*>::value));
|
|
123 STATIC_ASSERT((has_bitwise_not<W>::value));
|
|
124 STATIC_ASSERT((has_bitwise_not<X>::value));
|
|
125 STATIC_ASSERT((!has_bitwise_not<Y>::value));
|
|
126
|
|
127 // has_truth_not
|
|
128 DEFINE_PREFIX_UNARY_TRAIT(has_truth_not, !);
|
|
129 STATIC_ASSERT((has_truth_not<int>::value));
|
|
130 STATIC_ASSERT((has_truth_not<int*>::value));
|
|
131 STATIC_ASSERT((has_truth_not<W>::value));
|
|
132 STATIC_ASSERT((has_truth_not<X>::value));
|
|
133 STATIC_ASSERT((!has_truth_not<Y>::value));
|
|
134
|
|
135 // has_preincrement
|
|
136 DEFINE_PREFIX_UNARY_TRAIT(has_preincrement, ++);
|
|
137 STATIC_ASSERT((has_preincrement<int>::value));
|
|
138 STATIC_ASSERT((has_preincrement<int*>::value));
|
|
139 STATIC_ASSERT((!has_preincrement<int X::*>::value));
|
|
140 STATIC_ASSERT((has_preincrement<W>::value));
|
|
141 STATIC_ASSERT((has_preincrement<X>::value));
|
|
142 STATIC_ASSERT((!has_preincrement<Y>::value));
|
|
143
|
|
144 // has_predecrement
|
|
145 DEFINE_PREFIX_UNARY_TRAIT(has_predecrement, --);
|
|
146 STATIC_ASSERT((has_predecrement<int>::value));
|
|
147 STATIC_ASSERT((has_predecrement<int*>::value));
|
|
148 STATIC_ASSERT((!has_predecrement<int X::*>::value));
|
|
149 STATIC_ASSERT((has_predecrement<W>::value));
|
|
150 STATIC_ASSERT((has_predecrement<X>::value));
|
|
151 STATIC_ASSERT((!has_predecrement<Y>::value));
|
|
152
|
|
153 // has_postincrement
|
|
154 DEFINE_POSTFIX_UNARY_TRAIT(has_postincrement, ++);
|
|
155 STATIC_ASSERT((has_postincrement<int>::value));
|
|
156 STATIC_ASSERT((has_postincrement<int*>::value));
|
|
157 STATIC_ASSERT((!has_postincrement<int X::*>::value));
|
|
158 STATIC_ASSERT((has_postincrement<W>::value));
|
|
159 STATIC_ASSERT((has_postincrement<X>::value));
|
|
160 STATIC_ASSERT((!has_postincrement<Y>::value));
|
|
161
|
|
162 // has_postdecrement
|
|
163 DEFINE_POSTFIX_UNARY_TRAIT(has_postdecrement, --);
|
|
164 STATIC_ASSERT((has_postdecrement<int>::value));
|
|
165 STATIC_ASSERT((has_postdecrement<int*>::value));
|
|
166 STATIC_ASSERT((!has_postdecrement<int X::*>::value));
|
|
167 STATIC_ASSERT((has_postdecrement<W>::value));
|
|
168 STATIC_ASSERT((has_postdecrement<X>::value));
|
|
169 STATIC_ASSERT((!has_postdecrement<Y>::value));
|
|
170
|
|
171 // Check for private members
|
|
172 STATIC_ASSERT((!has_unary_plus<Z>::value));
|
|
173 STATIC_ASSERT((!is_negatable<Z>::value));
|
|
174 STATIC_ASSERT((!is_dereferenceable<Z>::value));
|
|
175 STATIC_ASSERT((!has_bitwise_not<Z>::value));
|
|
176 STATIC_ASSERT((!has_truth_not<Z>::value));
|
|
177 STATIC_ASSERT((!has_preincrement<Z>::value));
|
|
178 STATIC_ASSERT((!has_predecrement<Z>::value));
|
|
179 STATIC_ASSERT((!has_postincrement<Z>::value));
|
|
180 STATIC_ASSERT((!has_postdecrement<Z>::value));
|