[gcn] install.texi: Update for new ISA targets and their requirements
[gcc.git] / gcc / testsuite / g++.dg / cpp23 / explicit-obj-ops-requires-non-mem.C
blob865b1f57d4a607c947507ad902c9b5496a99cfc4
1 // P0847R7
2 // { dg-do compile { target c++23 } }
4 // well-formed and ill-formed uses of non-member capable operators in a requires expression
6 #include "explicit-obj-ops-non-mem.h"
8 // we only need the structs from the header
9 #undef TEST_OPS
10 #undef VALIDATE_RETURN_TYPES
12 // It's very hard to test for incorrect successes without requires, and by extension a non dependent variable
13 // so for the time being, there are no non dependent tests invalid calls.
15 template<typename T, typename U>
16 concept same_as = __is_same(T, U);
18 #define TEST_INVALID(OPERAND, CORRECT_TYPE) \
19   static_assert(!requires{ (OPERAND) += 0; }, "Unexpected success calling operator += with " #OPERAND);         \
20   static_assert(!requires{ (OPERAND) -= 0; }, "Unexpected success calling operator -= with " #OPERAND);         \
21   static_assert(!requires{ (OPERAND) *= 0; }, "Unexpected success calling operator *= with " #OPERAND);         \
22   static_assert(!requires{ (OPERAND) /= 0; }, "Unexpected success calling operator /= with " #OPERAND);         \
23   static_assert(!requires{ (OPERAND) %= 0; }, "Unexpected success calling operator %= with " #OPERAND);         \
24   static_assert(!requires{ (OPERAND) &= 0; }, "Unexpected success calling operator &= with " #OPERAND);         \
25   static_assert(!requires{ (OPERAND) |= 0; }, "Unexpected success calling operator |= with " #OPERAND);         \
26   static_assert(!requires{ (OPERAND) ^= 0; }, "Unexpected success calling operator ^= with " #OPERAND);         \
27   static_assert(!requires{ (OPERAND) <<= 0; }, "Unexpected success calling operator <<= with " #OPERAND);       \
28   static_assert(!requires{ (OPERAND) >>= 0; }, "Unexpected success calling operator >>= with " #OPERAND);       \
29                                                                                                                 \
30   static_assert(!requires{ ++(OPERAND); }, "Unexpected success calling operator pre++ with " #OPERAND);         \
31   static_assert(!requires{ --(OPERAND); }, "Unexpected success calling operator pre-- with " #OPERAND);         \
32   static_assert(!requires{ (OPERAND)++; }, "Unexpected success calling operator post++ with " #OPERAND);        \
33   static_assert(!requires{ (OPERAND)--; }, "Unexpected success calling operator post-- with " #OPERAND);        \
34                                                                                                                 \
35   static_assert(!requires{ +(OPERAND); }, "Unexpected success calling operator unary+ with " #OPERAND);         \
36   static_assert(!requires{ -(OPERAND); }, "Unexpected success calling operator unary- with " #OPERAND);         \
37   static_assert(!requires{ (OPERAND) + 0; }, "Unexpected success calling operator binary+ with " #OPERAND);     \
38   static_assert(!requires{ (OPERAND) - 0; }, "Unexpected success calling operator binary- with " #OPERAND);     \
39   static_assert(!requires{ (OPERAND) * 0; }, "Unexpected success calling operator binary* with " #OPERAND);     \
40   static_assert(!requires{ (OPERAND) / 0; }, "Unexpected success calling operator / with " #OPERAND);           \
41   static_assert(!requires{ (OPERAND) % 0; }, "Unexpected success calling operator % with " #OPERAND);           \
42   static_assert(!requires{ (OPERAND) & 0; }, "Unexpected success calling operator binary& with " #OPERAND);     \
43   static_assert(!requires{ (OPERAND) | 0; }, "Unexpected success calling operator | with " #OPERAND);           \
44   static_assert(!requires{ (OPERAND) ^ 0; }, "Unexpected success calling operator ^ with " #OPERAND);           \
45   static_assert(!requires{ (OPERAND) << 0; }, "Unexpected success calling operator << with " #OPERAND);         \
46   static_assert(!requires{ (OPERAND) >> 0; }, "Unexpected success calling operator >> with " #OPERAND);         \
47                                                                                                                 \
48   static_assert(!requires{ !(OPERAND); }, "Unexpected success calling operator ! with " #OPERAND);              \
49   static_assert(!requires{ (OPERAND) && 0; }, "Unexpected success calling operator && with " #OPERAND);         \
50   static_assert(!requires{ (OPERAND) || 0; }, "Unexpected success calling operator || with " #OPERAND);         \
51                                                                                                                 \
52   static_assert(!requires{ (OPERAND) == 0; }, "Unexpected success calling operator == with " #OPERAND);         \
53   static_assert(!requires{ (OPERAND) != 0; }, "Unexpected success calling operator != with " #OPERAND);         \
54   static_assert(!requires{ (OPERAND) < 0; }, "Unexpected success calling operator < with " #OPERAND);           \
55   static_assert(!requires{ (OPERAND) > 0; }, "Unexpected success calling operator > with " #OPERAND);           \
56   static_assert(!requires{ (OPERAND) <= 0; }, "Unexpected success calling operator <= with " #OPERAND);         \
57   static_assert(!requires{ (OPERAND) >= 0; }, "Unexpected success calling operator >= with " #OPERAND);         \
58   static_assert(!requires{ (OPERAND) <=> 0; }, "Unexpected success calling operator <=> with " #OPERAND);       \
59                                                                                                                 \
60   static_assert(!requires{ *(OPERAND); }, "Unexpected success calling operator unary* with " #OPERAND);         \
61   static_assert(!requires{ (OPERAND) ->* 0; }, "Unexpected success calling operator ->* with " #OPERAND);       \
62   /* We need to check the return type to confirm the built-in operator was not selected.  */                    \
63   static_assert(!requires{ {&(OPERAND)} -> same_as<CORRECT_TYPE>; },                                            \
64                 "Unexpected success calling operator unary& with " #OPERAND);                                   \
65   static_assert(!requires{ {(OPERAND), 0} -> same_as<CORRECT_TYPE>; },                                          \
66                 "Unexpected success calling operator , with " #OPERAND);
68 #define TEST_VALID(OPERAND, CORRECT_TYPE) \
69   static_assert(requires{ (OPERAND) += 0; }, "Unexpected failure calling operator += with " #OPERAND);          \
70   static_assert(requires{ (OPERAND) -= 0; }, "Unexpected failure calling operator -= with " #OPERAND);          \
71   static_assert(requires{ (OPERAND) *= 0; }, "Unexpected failure calling operator *= with " #OPERAND);          \
72   static_assert(requires{ (OPERAND) /= 0; }, "Unexpected failure calling operator /= with " #OPERAND);          \
73   static_assert(requires{ (OPERAND) %= 0; }, "Unexpected failure calling operator %= with " #OPERAND);          \
74   static_assert(requires{ (OPERAND) &= 0; }, "Unexpected failure calling operator &= with " #OPERAND);          \
75   static_assert(requires{ (OPERAND) |= 0; }, "Unexpected failure calling operator |= with " #OPERAND);          \
76   static_assert(requires{ (OPERAND) ^= 0; }, "Unexpected failure calling operator ^= with " #OPERAND);          \
77   static_assert(requires{ (OPERAND) <<= 0; }, "Unexpected failure calling operator <<= with " #OPERAND);        \
78   static_assert(requires{ (OPERAND) >>= 0; }, "Unexpected failure calling operator >>= with " #OPERAND);        \
79                                                                                                                 \
80   static_assert(requires{ ++(OPERAND); }, "Unexpected failure calling operator pre++ with " #OPERAND);          \
81   static_assert(requires{ --(OPERAND); }, "Unexpected failure calling operator pre-- with " #OPERAND);          \
82   static_assert(requires{ (OPERAND)++; }, "Unexpected failure calling operator post++ with " #OPERAND);         \
83   static_assert(requires{ (OPERAND)--; }, "Unexpected failure calling operator post-- with " #OPERAND);         \
84                                                                                                                 \
85   static_assert(requires{ +(OPERAND); }, "Unexpected failure calling operator unary+ with " #OPERAND);          \
86   static_assert(requires{ -(OPERAND); }, "Unexpected failure calling operator unary- with " #OPERAND);          \
87   static_assert(requires{ (OPERAND) + 0; }, "Unexpected failure calling operator binary+ with " #OPERAND);      \
88   static_assert(requires{ (OPERAND) - 0; }, "Unexpected failure calling operator binary- with " #OPERAND);      \
89   static_assert(requires{ (OPERAND) * 0; }, "Unexpected failure calling operator binary* with " #OPERAND);      \
90   static_assert(requires{ (OPERAND) / 0; }, "Unexpected failure calling operator / with " #OPERAND);            \
91   static_assert(requires{ (OPERAND) % 0; }, "Unexpected failure calling operator % with " #OPERAND);            \
92   static_assert(requires{ (OPERAND) & 0; }, "Unexpected failure calling operator binary& with " #OPERAND);      \
93   static_assert(requires{ (OPERAND) | 0; }, "Unexpected failure calling operator | with " #OPERAND);            \
94   static_assert(requires{ (OPERAND) ^ 0; }, "Unexpected failure calling operator ^ with " #OPERAND);            \
95   static_assert(requires{ (OPERAND) << 0; }, "Unexpected failure calling operator << with " #OPERAND);          \
96   static_assert(requires{ (OPERAND) >> 0; }, "Unexpected failure calling operator >> with " #OPERAND);          \
97                                                                                                                 \
98   static_assert(requires{ !(OPERAND); }, "Unexpected failure calling operator ! with " #OPERAND);               \
99   static_assert(requires{ (OPERAND) && 0; }, "Unexpected failure calling operator && with " #OPERAND);          \
100   static_assert(requires{ (OPERAND) || 0; }, "Unexpected failure calling operator || with " #OPERAND);          \
101                                                                                                                 \
102   static_assert(requires{ (OPERAND) == 0; }, "Unexpected failure calling operator == with " #OPERAND);          \
103   static_assert(requires{ (OPERAND) != 0; }, "Unexpected failure calling operator != with " #OPERAND);          \
104   static_assert(requires{ (OPERAND) < 0; }, "Unexpected failure calling operator < with " #OPERAND);            \
105   static_assert(requires{ (OPERAND) > 0; }, "Unexpected failure calling operator > with " #OPERAND);            \
106   static_assert(requires{ (OPERAND) <= 0; }, "Unexpected failure calling operator <= with " #OPERAND);          \
107   static_assert(requires{ (OPERAND) >= 0; }, "Unexpected failure calling operator >= with " #OPERAND);          \
108   static_assert(requires{ (OPERAND) <=> 0; }, "Unexpected failure calling operator <=> with " #OPERAND);        \
109                                                                                                                 \
110   static_assert(requires{ *(OPERAND); }, "Unexpected failure calling operator unary* with " #OPERAND);          \
111   static_assert(requires{ (OPERAND) ->* 0; }, "Unexpected failure calling operator ->* with " #OPERAND);        \
112   /* We need to check the return type to confirm we selected our overload, not the built-in operator.  */       \
113   static_assert(requires{ {&(OPERAND)} -> same_as<CORRECT_TYPE>; },                                             \
114                 "Unexpected failure calling operator unary& with " #OPERAND);                                   \
115   static_assert(requires{ {(OPERAND), 0} -> same_as<CORRECT_TYPE>; },                                           \
116                 "Unexpected failure calling operator , with " #OPERAND);
118 // Return types need to be tested for the deduced case
120 #define TEST_VALID_WITH_RETURN_TYPES(OPERAND, CORRECT_TYPE) \
121   static_assert(requires{ {(OPERAND) += 0} -> same_as<CORRECT_TYPE>; });        \
122   static_assert(requires{ {(OPERAND) -= 0} -> same_as<CORRECT_TYPE>; });        \
123   static_assert(requires{ {(OPERAND) *= 0} -> same_as<CORRECT_TYPE>; });        \
124   static_assert(requires{ {(OPERAND) /= 0} -> same_as<CORRECT_TYPE>; });        \
125   static_assert(requires{ {(OPERAND) %= 0} -> same_as<CORRECT_TYPE>; });        \
126   static_assert(requires{ {(OPERAND) &= 0} -> same_as<CORRECT_TYPE>; });        \
127   static_assert(requires{ {(OPERAND) |= 0} -> same_as<CORRECT_TYPE>; });        \
128   static_assert(requires{ {(OPERAND) ^= 0} -> same_as<CORRECT_TYPE>; });        \
129   static_assert(requires{ {(OPERAND) <<= 0} -> same_as<CORRECT_TYPE>; });       \
130   static_assert(requires{ {(OPERAND) >>= 0} -> same_as<CORRECT_TYPE>; });       \
131                                                                                 \
132   static_assert(requires{ {++(OPERAND)} -> same_as<CORRECT_TYPE>; });           \
133   static_assert(requires{ {--(OPERAND)} -> same_as<CORRECT_TYPE>; });           \
134   static_assert(requires{ {(OPERAND)++} -> same_as<CORRECT_TYPE>; });           \
135   static_assert(requires{ {(OPERAND)--} -> same_as<CORRECT_TYPE>; });           \
136                                                                                 \
137   static_assert(requires{ {+(OPERAND)} -> same_as<CORRECT_TYPE>; });            \
138   static_assert(requires{ {-(OPERAND)} -> same_as<CORRECT_TYPE>; });            \
139   static_assert(requires{ {(OPERAND) + 0} -> same_as<CORRECT_TYPE>; });         \
140   static_assert(requires{ {(OPERAND) - 0} -> same_as<CORRECT_TYPE>; });         \
141   static_assert(requires{ {(OPERAND) * 0} -> same_as<CORRECT_TYPE>; });         \
142   static_assert(requires{ {(OPERAND) / 0} -> same_as<CORRECT_TYPE>; });         \
143   static_assert(requires{ {(OPERAND) % 0} -> same_as<CORRECT_TYPE>; });         \
144   static_assert(requires{ {(OPERAND) & 0} -> same_as<CORRECT_TYPE>; });         \
145   static_assert(requires{ {(OPERAND) | 0} -> same_as<CORRECT_TYPE>; });         \
146   static_assert(requires{ {(OPERAND) ^ 0} -> same_as<CORRECT_TYPE>; });         \
147   static_assert(requires{ {(OPERAND) << 0} -> same_as<CORRECT_TYPE>; });        \
148   static_assert(requires{ {(OPERAND) >> 0} -> same_as<CORRECT_TYPE>; });        \
149                                                                                 \
150   static_assert(requires{ {!(OPERAND)} -> same_as<CORRECT_TYPE>; });            \
151   static_assert(requires{ {(OPERAND) && 0} -> same_as<CORRECT_TYPE>; });        \
152   static_assert(requires{ {(OPERAND) || 0} -> same_as<CORRECT_TYPE>; });        \
153                                                                                 \
154   static_assert(requires{ {(OPERAND) == 0} -> same_as<CORRECT_TYPE>; });        \
155   static_assert(requires{ {(OPERAND) != 0} -> same_as<CORRECT_TYPE>; });        \
156   static_assert(requires{ {(OPERAND) < 0} -> same_as<CORRECT_TYPE>; });         \
157   static_assert(requires{ {(OPERAND) > 0} -> same_as<CORRECT_TYPE>; });         \
158   static_assert(requires{ {(OPERAND) <= 0} -> same_as<CORRECT_TYPE>; });        \
159   static_assert(requires{ {(OPERAND) >= 0} -> same_as<CORRECT_TYPE>; });        \
160   static_assert(requires{ {(OPERAND) <=> 0} -> same_as<CORRECT_TYPE>; });       \
161                                                                                 \
162   static_assert(requires{ {*(OPERAND)} -> same_as<CORRECT_TYPE>; });            \
163   static_assert(requires{ {(OPERAND) ->* 0} -> same_as<CORRECT_TYPE>; });       \
164   static_assert(requires{ {&(OPERAND)} -> same_as<CORRECT_TYPE>; });            \
165   static_assert(requires{ {(OPERAND), 0} -> same_as<CORRECT_TYPE>; });
167 template<typename DepValue = Value>
168 void test_value()
170   DepValue value{};
171   TEST_VALID(value, DepValue)
172   TEST_VALID(static_cast<DepValue&&>(value), DepValue)
173   TEST_VALID(static_cast<DepValue const&>(value), DepValue)
174   TEST_VALID(static_cast<DepValue const&&>(value), DepValue)
177 template<typename DepLRef = LRef>
178 void test_l_ref()
180   DepLRef l_ref{};
181   TEST_VALID(l_ref, DepLRef&)
182   TEST_INVALID(static_cast<DepLRef&&>(l_ref), DepLRef&)
183   TEST_INVALID(static_cast<DepLRef const&>(l_ref), DepLRef&)
184   TEST_INVALID(static_cast<DepLRef const&&>(l_ref), DepLRef&)
187 template<typename DepRRef = RRef>
188 void test_r_ref()
190   DepRRef r_ref{};
191   TEST_INVALID(r_ref, DepRRef&&)
192   TEST_VALID(static_cast<DepRRef&&>(r_ref), DepRRef&&)
193   TEST_INVALID(static_cast<DepRRef const&>(r_ref), DepRRef&&)
194   TEST_INVALID(static_cast<DepRRef const&&>(r_ref), DepRRef&&)
197 template<typename DepConstLRef = ConstLRef>
198 void test_const_l_ref()
200   DepConstLRef const_l_ref{};
201   TEST_VALID(const_l_ref, DepConstLRef const&)
202   TEST_VALID(static_cast<DepConstLRef&&>(const_l_ref), DepConstLRef const&)
203   TEST_VALID(static_cast<DepConstLRef const&>(const_l_ref), DepConstLRef const&)
204   TEST_VALID(static_cast<DepConstLRef const&&>(const_l_ref), DepConstLRef const&)
207 template<typename DepConstRRef = ConstRRef>
208 void test_const_r_ref()
210   DepConstRRef const_r_ref{};
211   TEST_INVALID(const_r_ref, DepConstRRef const&&)
212   TEST_VALID(static_cast<DepConstRRef&&>(const_r_ref), DepConstRRef const&&)
213   TEST_INVALID(static_cast<DepConstRRef const&>(const_r_ref), DepConstRRef const&&)
214   TEST_VALID(static_cast<DepConstRRef const&&>(const_r_ref), DepConstRRef const&&)
217 template<typename DepDeduced = Deduced>
218 void test_deduced()
220   DepDeduced deduced{};
222   TEST_VALID_WITH_RETURN_TYPES(deduced, DepDeduced&)
223   TEST_VALID_WITH_RETURN_TYPES(static_cast<DepDeduced&&>(deduced), DepDeduced&&)
224   TEST_VALID_WITH_RETURN_TYPES(static_cast<DepDeduced const&>(deduced), DepDeduced const&)
225   TEST_VALID_WITH_RETURN_TYPES(static_cast<DepDeduced const&&>(deduced), DepDeduced const&&)
228 void test()
230   test_value();
231   test_l_ref();
232   test_r_ref();
233   test_const_l_ref();
234   test_const_r_ref();
235   test_deduced();