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