1 | //===----------------------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // UNSUPPORTED: c++03, c++11, c++14, c++17 |
10 | |
11 | // <compare> |
12 | |
13 | // template<class T> constexpr strong_ordering strong_order(const T& a, const T& b); |
14 | |
15 | #include <compare> |
16 | |
17 | #include <cassert> |
18 | #include <cmath> |
19 | #include <iterator> // std::size |
20 | #include <limits> |
21 | #include <type_traits> |
22 | #include <utility> |
23 | |
24 | #include "test_macros.h" |
25 | |
26 | #if defined(__i386__) |
27 | #define TEST_BUGGY_SIGNALING_NAN |
28 | #endif |
29 | |
30 | template<class T, class U> |
31 | constexpr auto has_strong_order(T&& t, U&& u) |
32 | -> decltype(std::strong_order(static_cast<T&&>(t), static_cast<U&&>(u)), true) |
33 | { |
34 | return true; |
35 | } |
36 | |
37 | constexpr bool has_strong_order(...) { |
38 | return false; |
39 | } |
40 | |
41 | namespace N11 { |
42 | struct A {}; |
43 | struct B {}; |
44 | std::strong_ordering strong_order(const A&, const A&) { return std::strong_ordering::less; } |
45 | std::strong_ordering strong_order(const A&, const B&); |
46 | } |
47 | |
48 | void test_1_1() |
49 | { |
50 | // If the decayed types of E and F differ, strong_order(E, F) is ill-formed. |
51 | |
52 | static_assert( has_strong_order(1, 2)); |
53 | static_assert(!has_strong_order(1, (short)2)); |
54 | static_assert(!has_strong_order(1, 2.0)); |
55 | static_assert(!has_strong_order(1.0f, 2.0)); |
56 | |
57 | static_assert( has_strong_order((int*)nullptr, (int*)nullptr)); |
58 | static_assert(!has_strong_order((int*)nullptr, (const int*)nullptr)); |
59 | static_assert(!has_strong_order((const int*)nullptr, (int*)nullptr)); |
60 | static_assert( has_strong_order((const int*)nullptr, (const int*)nullptr)); |
61 | |
62 | N11::A a; |
63 | N11::B b; |
64 | static_assert( has_strong_order(a, a)); |
65 | static_assert(!has_strong_order(a, b)); |
66 | } |
67 | |
68 | namespace N12 { |
69 | struct A {}; |
70 | std::strong_ordering strong_order(A&, A&&) { return std::strong_ordering::less; } |
71 | std::strong_ordering strong_order(A&&, A&&) { return std::strong_ordering::equal; } |
72 | std::strong_ordering strong_order(const A&, const A&); |
73 | |
74 | struct B { |
75 | friend std::weak_ordering strong_order(B&, B&); |
76 | }; |
77 | |
78 | struct StrongOrder { |
79 | explicit operator std::strong_ordering() const { return std::strong_ordering::less; } |
80 | }; |
81 | struct C { |
82 | bool touched = false; |
83 | friend StrongOrder strong_order(C& lhs, C&) { lhs.touched = true; return StrongOrder(); } |
84 | }; |
85 | } |
86 | |
87 | void test_1_2() |
88 | { |
89 | // Otherwise, strong_ordering(strong_order(E, F)) |
90 | // if it is a well-formed expression with overload resolution performed |
91 | // in a context that does not include a declaration of std::strong_order. |
92 | |
93 | // Test that strong_order does not const-qualify the forwarded arguments. |
94 | N12::A a; |
95 | assert(std::strong_order(a, std::move(a)) == std::strong_ordering::less); |
96 | assert(std::strong_order(std::move(a), std::move(a)) == std::strong_ordering::equal); |
97 | |
98 | // The type of strong_order(e,f) must be explicitly convertible to strong_ordering. |
99 | N12::B b; |
100 | static_assert(!has_strong_order(b, b)); |
101 | |
102 | N12::C c1, c2; |
103 | ASSERT_SAME_TYPE(decltype(std::strong_order(c1, c2)), std::strong_ordering); |
104 | assert(std::strong_order(c1, c2) == std::strong_ordering::less); |
105 | assert(c1.touched); |
106 | assert(!c2.touched); |
107 | } |
108 | |
109 | template<class F> |
110 | constexpr bool test_1_3() |
111 | { |
112 | // Otherwise, if the decayed type T of E is a floating-point type, |
113 | // yields a value of type strong_ordering that is consistent with |
114 | // the ordering observed by T's comparison operators, |
115 | // and if numeric_limits<T>::is_iec559 is true, is additionally consistent with |
116 | // the totalOrder operation as specified in ISO/IEC/IEEE 60559. |
117 | |
118 | static_assert(std::numeric_limits<F>::is_iec559); |
119 | |
120 | ASSERT_SAME_TYPE(decltype(std::strong_order(F(0), F(0))), std::strong_ordering); |
121 | |
122 | F v[] = { |
123 | -std::numeric_limits<F>::infinity(), |
124 | std::numeric_limits<F>::lowest(), // largest (finite) negative number |
125 | F(-1.0), F(-0.1), |
126 | -std::numeric_limits<F>::min(), // smallest (normal) negative number |
127 | F(-0.0), // negative zero |
128 | F(0.0), |
129 | std::numeric_limits<F>::min(), // smallest (normal) positive number |
130 | F(0.1), F(1.0), F(2.0), F(3.14), |
131 | std::numeric_limits<F>::max(), // largest (finite) positive number |
132 | std::numeric_limits<F>::infinity(), |
133 | }; |
134 | |
135 | static_assert(std::size(v) == 14); |
136 | |
137 | // Sanity-check that array 'v' is indeed in the right order. |
138 | for (int i=0; i < 14; ++i) { |
139 | for (int j=0; j < 14; ++j) { |
140 | auto naturalOrder = (v[i] <=> v[j]); |
141 | if (v[i] == 0 && v[j] == 0) { |
142 | assert(naturalOrder == std::partial_ordering::equivalent); |
143 | } else { |
144 | assert(naturalOrder == std::partial_ordering::unordered || naturalOrder == (i <=> j)); |
145 | } |
146 | } |
147 | } |
148 | |
149 | assert(std::strong_order(v[0], v[0]) == std::strong_ordering::equal); |
150 | assert(std::strong_order(v[0], v[1]) == std::strong_ordering::less); |
151 | assert(std::strong_order(v[0], v[2]) == std::strong_ordering::less); |
152 | assert(std::strong_order(v[0], v[3]) == std::strong_ordering::less); |
153 | assert(std::strong_order(v[0], v[4]) == std::strong_ordering::less); |
154 | assert(std::strong_order(v[0], v[5]) == std::strong_ordering::less); |
155 | assert(std::strong_order(v[0], v[6]) == std::strong_ordering::less); |
156 | assert(std::strong_order(v[0], v[7]) == std::strong_ordering::less); |
157 | assert(std::strong_order(v[0], v[8]) == std::strong_ordering::less); |
158 | assert(std::strong_order(v[0], v[9]) == std::strong_ordering::less); |
159 | assert(std::strong_order(v[0], v[10]) == std::strong_ordering::less); |
160 | assert(std::strong_order(v[0], v[11]) == std::strong_ordering::less); |
161 | assert(std::strong_order(v[0], v[12]) == std::strong_ordering::less); |
162 | assert(std::strong_order(v[0], v[13]) == std::strong_ordering::less); |
163 | assert(std::strong_order(v[1], v[0]) == std::strong_ordering::greater); |
164 | assert(std::strong_order(v[1], v[1]) == std::strong_ordering::equal); |
165 | assert(std::strong_order(v[1], v[2]) == std::strong_ordering::less); |
166 | assert(std::strong_order(v[1], v[3]) == std::strong_ordering::less); |
167 | assert(std::strong_order(v[1], v[4]) == std::strong_ordering::less); |
168 | assert(std::strong_order(v[1], v[5]) == std::strong_ordering::less); |
169 | assert(std::strong_order(v[1], v[6]) == std::strong_ordering::less); |
170 | assert(std::strong_order(v[1], v[7]) == std::strong_ordering::less); |
171 | assert(std::strong_order(v[1], v[8]) == std::strong_ordering::less); |
172 | assert(std::strong_order(v[1], v[9]) == std::strong_ordering::less); |
173 | assert(std::strong_order(v[1], v[10]) == std::strong_ordering::less); |
174 | assert(std::strong_order(v[1], v[11]) == std::strong_ordering::less); |
175 | assert(std::strong_order(v[1], v[12]) == std::strong_ordering::less); |
176 | assert(std::strong_order(v[1], v[13]) == std::strong_ordering::less); |
177 | assert(std::strong_order(v[2], v[0]) == std::strong_ordering::greater); |
178 | assert(std::strong_order(v[2], v[1]) == std::strong_ordering::greater); |
179 | assert(std::strong_order(v[2], v[2]) == std::strong_ordering::equal); |
180 | assert(std::strong_order(v[2], v[3]) == std::strong_ordering::less); |
181 | assert(std::strong_order(v[2], v[4]) == std::strong_ordering::less); |
182 | assert(std::strong_order(v[2], v[5]) == std::strong_ordering::less); |
183 | assert(std::strong_order(v[2], v[6]) == std::strong_ordering::less); |
184 | assert(std::strong_order(v[2], v[7]) == std::strong_ordering::less); |
185 | assert(std::strong_order(v[2], v[8]) == std::strong_ordering::less); |
186 | assert(std::strong_order(v[2], v[9]) == std::strong_ordering::less); |
187 | assert(std::strong_order(v[2], v[10]) == std::strong_ordering::less); |
188 | assert(std::strong_order(v[2], v[11]) == std::strong_ordering::less); |
189 | assert(std::strong_order(v[2], v[12]) == std::strong_ordering::less); |
190 | assert(std::strong_order(v[2], v[13]) == std::strong_ordering::less); |
191 | assert(std::strong_order(v[3], v[0]) == std::strong_ordering::greater); |
192 | assert(std::strong_order(v[3], v[1]) == std::strong_ordering::greater); |
193 | assert(std::strong_order(v[3], v[2]) == std::strong_ordering::greater); |
194 | assert(std::strong_order(v[3], v[3]) == std::strong_ordering::equal); |
195 | assert(std::strong_order(v[3], v[4]) == std::strong_ordering::less); |
196 | assert(std::strong_order(v[3], v[5]) == std::strong_ordering::less); |
197 | assert(std::strong_order(v[3], v[6]) == std::strong_ordering::less); |
198 | assert(std::strong_order(v[3], v[7]) == std::strong_ordering::less); |
199 | assert(std::strong_order(v[3], v[8]) == std::strong_ordering::less); |
200 | assert(std::strong_order(v[3], v[9]) == std::strong_ordering::less); |
201 | assert(std::strong_order(v[3], v[10]) == std::strong_ordering::less); |
202 | assert(std::strong_order(v[3], v[11]) == std::strong_ordering::less); |
203 | assert(std::strong_order(v[3], v[12]) == std::strong_ordering::less); |
204 | assert(std::strong_order(v[3], v[13]) == std::strong_ordering::less); |
205 | assert(std::strong_order(v[4], v[0]) == std::strong_ordering::greater); |
206 | assert(std::strong_order(v[4], v[1]) == std::strong_ordering::greater); |
207 | assert(std::strong_order(v[4], v[2]) == std::strong_ordering::greater); |
208 | assert(std::strong_order(v[4], v[3]) == std::strong_ordering::greater); |
209 | assert(std::strong_order(v[4], v[4]) == std::strong_ordering::equal); |
210 | assert(std::strong_order(v[4], v[5]) == std::strong_ordering::less); |
211 | assert(std::strong_order(v[4], v[6]) == std::strong_ordering::less); |
212 | assert(std::strong_order(v[4], v[7]) == std::strong_ordering::less); |
213 | assert(std::strong_order(v[4], v[8]) == std::strong_ordering::less); |
214 | assert(std::strong_order(v[4], v[9]) == std::strong_ordering::less); |
215 | assert(std::strong_order(v[4], v[10]) == std::strong_ordering::less); |
216 | assert(std::strong_order(v[4], v[11]) == std::strong_ordering::less); |
217 | assert(std::strong_order(v[4], v[12]) == std::strong_ordering::less); |
218 | assert(std::strong_order(v[4], v[13]) == std::strong_ordering::less); |
219 | assert(std::strong_order(v[5], v[0]) == std::strong_ordering::greater); |
220 | assert(std::strong_order(v[5], v[1]) == std::strong_ordering::greater); |
221 | assert(std::strong_order(v[5], v[2]) == std::strong_ordering::greater); |
222 | assert(std::strong_order(v[5], v[3]) == std::strong_ordering::greater); |
223 | assert(std::strong_order(v[5], v[4]) == std::strong_ordering::greater); |
224 | assert(std::strong_order(v[5], v[5]) == std::strong_ordering::equal); |
225 | assert(std::strong_order(v[5], v[6]) == std::strong_ordering::less); |
226 | assert(std::strong_order(v[5], v[7]) == std::strong_ordering::less); |
227 | assert(std::strong_order(v[5], v[8]) == std::strong_ordering::less); |
228 | assert(std::strong_order(v[5], v[9]) == std::strong_ordering::less); |
229 | assert(std::strong_order(v[5], v[10]) == std::strong_ordering::less); |
230 | assert(std::strong_order(v[5], v[11]) == std::strong_ordering::less); |
231 | assert(std::strong_order(v[5], v[12]) == std::strong_ordering::less); |
232 | assert(std::strong_order(v[5], v[13]) == std::strong_ordering::less); |
233 | assert(std::strong_order(v[6], v[0]) == std::strong_ordering::greater); |
234 | assert(std::strong_order(v[6], v[1]) == std::strong_ordering::greater); |
235 | assert(std::strong_order(v[6], v[2]) == std::strong_ordering::greater); |
236 | assert(std::strong_order(v[6], v[3]) == std::strong_ordering::greater); |
237 | assert(std::strong_order(v[6], v[4]) == std::strong_ordering::greater); |
238 | assert(std::strong_order(v[6], v[5]) == std::strong_ordering::greater); |
239 | assert(std::strong_order(v[6], v[6]) == std::strong_ordering::equal); |
240 | assert(std::strong_order(v[6], v[7]) == std::strong_ordering::less); |
241 | assert(std::strong_order(v[6], v[8]) == std::strong_ordering::less); |
242 | assert(std::strong_order(v[6], v[9]) == std::strong_ordering::less); |
243 | assert(std::strong_order(v[6], v[10]) == std::strong_ordering::less); |
244 | assert(std::strong_order(v[6], v[11]) == std::strong_ordering::less); |
245 | assert(std::strong_order(v[6], v[12]) == std::strong_ordering::less); |
246 | assert(std::strong_order(v[6], v[13]) == std::strong_ordering::less); |
247 | assert(std::strong_order(v[7], v[0]) == std::strong_ordering::greater); |
248 | assert(std::strong_order(v[7], v[1]) == std::strong_ordering::greater); |
249 | assert(std::strong_order(v[7], v[2]) == std::strong_ordering::greater); |
250 | assert(std::strong_order(v[7], v[3]) == std::strong_ordering::greater); |
251 | assert(std::strong_order(v[7], v[4]) == std::strong_ordering::greater); |
252 | assert(std::strong_order(v[7], v[5]) == std::strong_ordering::greater); |
253 | assert(std::strong_order(v[7], v[6]) == std::strong_ordering::greater); |
254 | assert(std::strong_order(v[7], v[7]) == std::strong_ordering::equal); |
255 | assert(std::strong_order(v[7], v[8]) == std::strong_ordering::less); |
256 | assert(std::strong_order(v[7], v[9]) == std::strong_ordering::less); |
257 | assert(std::strong_order(v[7], v[10]) == std::strong_ordering::less); |
258 | assert(std::strong_order(v[7], v[11]) == std::strong_ordering::less); |
259 | assert(std::strong_order(v[7], v[12]) == std::strong_ordering::less); |
260 | assert(std::strong_order(v[7], v[13]) == std::strong_ordering::less); |
261 | assert(std::strong_order(v[8], v[0]) == std::strong_ordering::greater); |
262 | assert(std::strong_order(v[8], v[1]) == std::strong_ordering::greater); |
263 | assert(std::strong_order(v[8], v[2]) == std::strong_ordering::greater); |
264 | assert(std::strong_order(v[8], v[3]) == std::strong_ordering::greater); |
265 | assert(std::strong_order(v[8], v[4]) == std::strong_ordering::greater); |
266 | assert(std::strong_order(v[8], v[5]) == std::strong_ordering::greater); |
267 | assert(std::strong_order(v[8], v[6]) == std::strong_ordering::greater); |
268 | assert(std::strong_order(v[8], v[7]) == std::strong_ordering::greater); |
269 | assert(std::strong_order(v[8], v[8]) == std::strong_ordering::equal); |
270 | assert(std::strong_order(v[8], v[9]) == std::strong_ordering::less); |
271 | assert(std::strong_order(v[8], v[10]) == std::strong_ordering::less); |
272 | assert(std::strong_order(v[8], v[11]) == std::strong_ordering::less); |
273 | assert(std::strong_order(v[8], v[12]) == std::strong_ordering::less); |
274 | assert(std::strong_order(v[8], v[13]) == std::strong_ordering::less); |
275 | assert(std::strong_order(v[9], v[0]) == std::strong_ordering::greater); |
276 | assert(std::strong_order(v[9], v[1]) == std::strong_ordering::greater); |
277 | assert(std::strong_order(v[9], v[2]) == std::strong_ordering::greater); |
278 | assert(std::strong_order(v[9], v[3]) == std::strong_ordering::greater); |
279 | assert(std::strong_order(v[9], v[4]) == std::strong_ordering::greater); |
280 | assert(std::strong_order(v[9], v[5]) == std::strong_ordering::greater); |
281 | assert(std::strong_order(v[9], v[6]) == std::strong_ordering::greater); |
282 | assert(std::strong_order(v[9], v[7]) == std::strong_ordering::greater); |
283 | assert(std::strong_order(v[9], v[8]) == std::strong_ordering::greater); |
284 | assert(std::strong_order(v[9], v[9]) == std::strong_ordering::equal); |
285 | assert(std::strong_order(v[9], v[10]) == std::strong_ordering::less); |
286 | assert(std::strong_order(v[9], v[11]) == std::strong_ordering::less); |
287 | assert(std::strong_order(v[9], v[12]) == std::strong_ordering::less); |
288 | assert(std::strong_order(v[9], v[13]) == std::strong_ordering::less); |
289 | assert(std::strong_order(v[10], v[0]) == std::strong_ordering::greater); |
290 | assert(std::strong_order(v[10], v[1]) == std::strong_ordering::greater); |
291 | assert(std::strong_order(v[10], v[2]) == std::strong_ordering::greater); |
292 | assert(std::strong_order(v[10], v[3]) == std::strong_ordering::greater); |
293 | assert(std::strong_order(v[10], v[4]) == std::strong_ordering::greater); |
294 | assert(std::strong_order(v[10], v[5]) == std::strong_ordering::greater); |
295 | assert(std::strong_order(v[10], v[6]) == std::strong_ordering::greater); |
296 | assert(std::strong_order(v[10], v[7]) == std::strong_ordering::greater); |
297 | assert(std::strong_order(v[10], v[8]) == std::strong_ordering::greater); |
298 | assert(std::strong_order(v[10], v[9]) == std::strong_ordering::greater); |
299 | assert(std::strong_order(v[10], v[10]) == std::strong_ordering::equal); |
300 | assert(std::strong_order(v[10], v[11]) == std::strong_ordering::less); |
301 | assert(std::strong_order(v[10], v[12]) == std::strong_ordering::less); |
302 | assert(std::strong_order(v[10], v[13]) == std::strong_ordering::less); |
303 | assert(std::strong_order(v[11], v[0]) == std::strong_ordering::greater); |
304 | assert(std::strong_order(v[11], v[1]) == std::strong_ordering::greater); |
305 | assert(std::strong_order(v[11], v[2]) == std::strong_ordering::greater); |
306 | assert(std::strong_order(v[11], v[3]) == std::strong_ordering::greater); |
307 | assert(std::strong_order(v[11], v[4]) == std::strong_ordering::greater); |
308 | assert(std::strong_order(v[11], v[5]) == std::strong_ordering::greater); |
309 | assert(std::strong_order(v[11], v[6]) == std::strong_ordering::greater); |
310 | assert(std::strong_order(v[11], v[7]) == std::strong_ordering::greater); |
311 | assert(std::strong_order(v[11], v[8]) == std::strong_ordering::greater); |
312 | assert(std::strong_order(v[11], v[9]) == std::strong_ordering::greater); |
313 | assert(std::strong_order(v[11], v[10]) == std::strong_ordering::greater); |
314 | assert(std::strong_order(v[11], v[11]) == std::strong_ordering::equal); |
315 | assert(std::strong_order(v[11], v[12]) == std::strong_ordering::less); |
316 | assert(std::strong_order(v[11], v[13]) == std::strong_ordering::less); |
317 | assert(std::strong_order(v[12], v[0]) == std::strong_ordering::greater); |
318 | assert(std::strong_order(v[12], v[1]) == std::strong_ordering::greater); |
319 | assert(std::strong_order(v[12], v[2]) == std::strong_ordering::greater); |
320 | assert(std::strong_order(v[12], v[3]) == std::strong_ordering::greater); |
321 | assert(std::strong_order(v[12], v[4]) == std::strong_ordering::greater); |
322 | assert(std::strong_order(v[12], v[5]) == std::strong_ordering::greater); |
323 | assert(std::strong_order(v[12], v[6]) == std::strong_ordering::greater); |
324 | assert(std::strong_order(v[12], v[7]) == std::strong_ordering::greater); |
325 | assert(std::strong_order(v[12], v[8]) == std::strong_ordering::greater); |
326 | assert(std::strong_order(v[12], v[9]) == std::strong_ordering::greater); |
327 | assert(std::strong_order(v[12], v[10]) == std::strong_ordering::greater); |
328 | assert(std::strong_order(v[12], v[11]) == std::strong_ordering::greater); |
329 | assert(std::strong_order(v[12], v[12]) == std::strong_ordering::equal); |
330 | assert(std::strong_order(v[12], v[13]) == std::strong_ordering::less); |
331 | assert(std::strong_order(v[13], v[0]) == std::strong_ordering::greater); |
332 | assert(std::strong_order(v[13], v[1]) == std::strong_ordering::greater); |
333 | assert(std::strong_order(v[13], v[2]) == std::strong_ordering::greater); |
334 | assert(std::strong_order(v[13], v[3]) == std::strong_ordering::greater); |
335 | assert(std::strong_order(v[13], v[4]) == std::strong_ordering::greater); |
336 | assert(std::strong_order(v[13], v[5]) == std::strong_ordering::greater); |
337 | assert(std::strong_order(v[13], v[6]) == std::strong_ordering::greater); |
338 | assert(std::strong_order(v[13], v[7]) == std::strong_ordering::greater); |
339 | assert(std::strong_order(v[13], v[8]) == std::strong_ordering::greater); |
340 | assert(std::strong_order(v[13], v[9]) == std::strong_ordering::greater); |
341 | assert(std::strong_order(v[13], v[10]) == std::strong_ordering::greater); |
342 | assert(std::strong_order(v[13], v[11]) == std::strong_ordering::greater); |
343 | assert(std::strong_order(v[13], v[12]) == std::strong_ordering::greater); |
344 | assert(std::strong_order(v[13], v[13]) == std::strong_ordering::equal); |
345 | |
346 | |
347 | // There's no way to produce a specifically positive or negative NAN |
348 | // at compile-time, so the NAN-related tests must be runtime-only. |
349 | // Also, x86-32 (x87 floating point) cannot handle signaling NANs; |
350 | // see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57484 for context. |
351 | |
352 | if (!std::is_constant_evaluated()) { |
353 | F nq = std::copysign(std::numeric_limits<F>::quiet_NaN(), F(-1)); |
354 | F ns = std::copysign(std::numeric_limits<F>::signaling_NaN(), F(-1)); |
355 | F ps = std::copysign(std::numeric_limits<F>::signaling_NaN(), F(+1)); |
356 | F pq = std::copysign(std::numeric_limits<F>::quiet_NaN(), F(+1)); |
357 | |
358 | assert(std::strong_order(nq, nq) == std::strong_ordering::equal); |
359 | #ifndef TEST_BUGGY_SIGNALING_NAN |
360 | assert(std::strong_order(nq, ns) == std::strong_ordering::less); |
361 | #endif |
362 | for (int i=0; i < 14; ++i) { |
363 | assert(std::strong_order(nq, v[i]) == std::strong_ordering::less); |
364 | } |
365 | assert(std::strong_order(nq, ps) == std::strong_ordering::less); |
366 | assert(std::strong_order(nq, pq) == std::strong_ordering::less); |
367 | |
368 | #ifndef TEST_BUGGY_SIGNALING_NAN |
369 | assert(std::strong_order(ns, nq) == std::strong_ordering::greater); |
370 | #endif |
371 | assert(std::strong_order(ns, ns) == std::strong_ordering::equal); |
372 | for (int i=0; i < 14; ++i) { |
373 | assert(std::strong_order(ns, v[i]) == std::strong_ordering::less); |
374 | } |
375 | assert(std::strong_order(ns, ps) == std::strong_ordering::less); |
376 | assert(std::strong_order(ns, pq) == std::strong_ordering::less); |
377 | |
378 | assert(std::strong_order(ps, nq) == std::strong_ordering::greater); |
379 | assert(std::strong_order(ps, ns) == std::strong_ordering::greater); |
380 | for (int i=0; i < 14; ++i) { |
381 | assert(std::strong_order(ps, v[i]) == std::strong_ordering::greater); |
382 | } |
383 | assert(std::strong_order(ps, ps) == std::strong_ordering::equal); |
384 | #ifndef TEST_BUGGY_SIGNALING_NAN |
385 | assert(std::strong_order(ps, pq) == std::strong_ordering::less); |
386 | #endif |
387 | |
388 | assert(std::strong_order(pq, nq) == std::strong_ordering::greater); |
389 | assert(std::strong_order(pq, ns) == std::strong_ordering::greater); |
390 | for (int i=0; i < 14; ++i) { |
391 | assert(std::strong_order(pq, v[i]) == std::strong_ordering::greater); |
392 | } |
393 | #ifndef TEST_BUGGY_SIGNALING_NAN |
394 | assert(std::strong_order(pq, ps) == std::strong_ordering::greater); |
395 | #endif |
396 | assert(std::strong_order(pq, pq) == std::strong_ordering::equal); |
397 | } |
398 | |
399 | return true; |
400 | } |
401 | |
402 | namespace N14 { |
403 | // Compare to N12::A. |
404 | struct A {}; |
405 | bool operator==(const A&, const A&); |
406 | constexpr std::strong_ordering operator<=>(A&, A&&) { return std::strong_ordering::less; } |
407 | constexpr std::strong_ordering operator<=>(A&&, A&&) { return std::strong_ordering::equal; } |
408 | std::strong_ordering operator<=>(const A&, const A&); |
409 | static_assert(std::three_way_comparable<A>); |
410 | |
411 | struct B { |
412 | std::strong_ordering operator<=>(const B&) const; // lacks operator== |
413 | }; |
414 | static_assert(!std::three_way_comparable<B>); |
415 | |
416 | struct C { |
417 | bool *touched; |
418 | bool operator==(const C&) const; |
419 | constexpr std::strong_ordering operator<=>(const C& rhs) const { |
420 | *rhs.touched = true; |
421 | return std::strong_ordering::equal; |
422 | } |
423 | }; |
424 | static_assert(std::three_way_comparable<C>); |
425 | } |
426 | |
427 | constexpr bool test_1_4() |
428 | { |
429 | // Otherwise, strong_ordering(compare_three_way()(E, F)) if it is a well-formed expression. |
430 | |
431 | // Test neither strong_order nor compare_three_way const-qualify the forwarded arguments. |
432 | N14::A a; |
433 | assert(std::strong_order(a, std::move(a)) == std::strong_ordering::less); |
434 | assert(std::strong_order(std::move(a), std::move(a)) == std::strong_ordering::equal); |
435 | |
436 | N14::B b; |
437 | static_assert(!has_strong_order(b, b)); |
438 | |
439 | // Test that the arguments are passed to <=> in the correct order. |
440 | bool c1_touched = false; |
441 | bool c2_touched = false; |
442 | N14::C c1 = {.touched: &c1_touched}; |
443 | N14::C c2 = {.touched: &c2_touched}; |
444 | assert(std::strong_order(c1, c2) == std::strong_ordering::equal); |
445 | assert(!c1_touched); |
446 | assert(c2_touched); |
447 | |
448 | return true; |
449 | } |
450 | |
451 | int main(int, char**) |
452 | { |
453 | test_1_1(); |
454 | test_1_2(); |
455 | test_1_3<float>(); |
456 | test_1_3<double>(); |
457 | // test_1_3<long double>(); // UNIMPLEMENTED |
458 | test_1_4(); |
459 | |
460 | static_assert(test_1_3<float>()); |
461 | static_assert(test_1_3<double>()); |
462 | // static_assert(test_1_3<long double>()); // UNIMPLEMENTED |
463 | static_assert(test_1_4()); |
464 | |
465 | return 0; |
466 | } |
467 | |