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