xref: /llvm-project/libcxx/test/support/compare_types.h (revision 480cd780d63fd9c658cc2f51d0c54416b8b1a5c3)
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 #ifndef TEST_SUPPORT_COMPARE_TYPES_H
10 #define TEST_SUPPORT_COMPARE_TYPES_H
11 
12 #include <compare>
13 #include <concepts>
14 #include <type_traits>
15 
16 // `noexcept` specifiers deliberately imperfect since not all programmers bother to put the
17 // specifiers on their overloads.
18 
19 struct equality_comparable_with_ec1;
20 struct no_neq;
21 
22 struct cxx20_member_eq {
23   bool operator==(cxx20_member_eq const&) const = default;
24 };
25 
26 struct cxx20_friend_eq {
27   friend bool operator==(cxx20_friend_eq const&, cxx20_friend_eq const&) = default;
28 };
29 
30 struct member_three_way_comparable {
31   auto operator<=>(member_three_way_comparable const&) const = default;
32 };
33 
34 struct friend_three_way_comparable {
35   friend auto operator<=>(friend_three_way_comparable const&, friend_three_way_comparable const&) = default;
36 };
37 
38 struct explicit_operators {
39   friend bool operator==(explicit_operators, explicit_operators) noexcept;
40   friend bool operator!=(explicit_operators, explicit_operators) noexcept;
41   friend bool operator<(explicit_operators, explicit_operators) noexcept;
42   friend bool operator>(explicit_operators, explicit_operators) noexcept;
43   friend bool operator<=(explicit_operators, explicit_operators) noexcept;
44   friend bool operator>=(explicit_operators, explicit_operators) noexcept;
45 
46   friend bool operator==(explicit_operators const&, equality_comparable_with_ec1 const&) noexcept;
47   friend bool operator==(equality_comparable_with_ec1 const&, explicit_operators const&) noexcept;
48   friend bool operator!=(explicit_operators const&, equality_comparable_with_ec1 const&) noexcept;
49   friend bool operator!=(equality_comparable_with_ec1 const&, explicit_operators const&) noexcept;
50 };
51 
52 struct different_return_types {
53   bool operator==(different_return_types) const noexcept;
54   char operator!=(different_return_types) const noexcept;
55   short operator<(different_return_types) const noexcept;
56   int operator>(different_return_types) const noexcept;
57   long operator<=(different_return_types) const noexcept;
58   long long operator>=(different_return_types) const noexcept;
59 
60   friend signed char operator==(explicit_operators, different_return_types);
61   friend unsigned char operator==(different_return_types, explicit_operators);
62   friend float operator!=(explicit_operators, different_return_types);
63   friend double operator!=(different_return_types, explicit_operators);
64 
65   operator explicit_operators() const;
66 };
67 
68 struct boolean {
69   operator bool() const noexcept;
70 };
71 
72 struct one_member_one_friend {
73   friend boolean operator==(one_member_one_friend, one_member_one_friend) noexcept;
74   boolean operator!=(one_member_one_friend) const noexcept;
75 
76   operator explicit_operators() const noexcept;
77   operator different_return_types() const noexcept;
78 };
79 
80 struct equality_comparable_with_ec1 {
81   bool operator==(equality_comparable_with_ec1) const noexcept;
82   bool operator!=(equality_comparable_with_ec1) const noexcept;
83   operator explicit_operators() const noexcept;
84 };
85 
86 struct no_eq {
87   friend bool operator==(no_eq, no_eq) = delete;
88   friend bool operator!=(no_eq, no_eq) noexcept;
89   friend bool operator<(no_eq, no_eq) noexcept;
90   friend bool operator>(no_eq, no_eq) noexcept;
91   friend bool operator>=(no_eq, no_eq) noexcept;
92   friend bool operator<=(no_eq, no_eq) noexcept;
93 };
94 
95 struct no_neq {
96   friend bool operator==(no_neq, no_neq) noexcept;
97   friend bool operator!=(no_neq, no_neq) = delete;
98   friend bool operator<(no_eq, no_eq) noexcept;
99   friend bool operator>(no_eq, no_eq) noexcept;
100   friend bool operator>=(no_eq, no_eq) noexcept;
101   friend bool operator<=(no_eq, no_eq) noexcept;
102 };
103 
104 struct no_lt {
105   friend bool operator==(no_lt, no_lt) noexcept;
106   friend bool operator!=(no_lt, no_lt) noexcept;
107   friend bool operator<(no_lt, no_lt) = delete;
108   friend bool operator>(no_lt, no_lt) noexcept;
109   friend bool operator>=(no_lt, no_lt) noexcept;
110   friend bool operator<=(no_lt, no_lt) noexcept;
111 };
112 
113 struct no_gt {
114   friend bool operator==(no_gt, no_gt) noexcept;
115   friend bool operator!=(no_gt, no_gt) noexcept;
116   friend bool operator<(no_gt, no_gt) noexcept;
117   friend bool operator>(no_gt, no_gt) = delete;
118   friend bool operator>=(no_gt, no_gt) noexcept;
119   friend bool operator<=(no_gt, no_gt) noexcept;
120 };
121 
122 struct no_le {
123   friend bool operator==(no_le, no_le) noexcept;
124   friend bool operator!=(no_le, no_le) noexcept;
125   friend bool operator<(no_le, no_le) noexcept;
126   friend bool operator>(no_le, no_le) noexcept;
127   friend bool operator>=(no_le, no_le) = delete;
128   friend bool operator<=(no_le, no_le) noexcept;
129 };
130 
131 struct no_ge {
132   friend bool operator==(no_ge, no_ge) noexcept;
133   friend bool operator!=(no_ge, no_ge) noexcept;
134   friend bool operator<(no_ge, no_ge) noexcept;
135   friend bool operator>(no_ge, no_ge) noexcept;
136   friend bool operator>=(no_ge, no_ge) noexcept;
137   friend bool operator<=(no_ge, no_ge) = delete;
138 };
139 
140 struct wrong_return_type_eq {
141   void operator==(wrong_return_type_eq) const noexcept;
142   bool operator!=(wrong_return_type_eq) const noexcept;
143   bool operator<(wrong_return_type_eq) const noexcept;
144   bool operator>(wrong_return_type_eq) const noexcept;
145   bool operator>=(wrong_return_type_eq) const noexcept;
146   bool operator<=(wrong_return_type_eq) const noexcept;
147 };
148 
149 struct wrong_return_type_ne {
150   bool operator==(wrong_return_type_ne) const noexcept;
151   void operator!=(wrong_return_type_ne) const noexcept;
152   bool operator<(wrong_return_type_ne) const noexcept;
153   bool operator>(wrong_return_type_ne) const noexcept;
154   bool operator>=(wrong_return_type_ne) const noexcept;
155   bool operator<=(wrong_return_type_ne) const noexcept;
156 };
157 
158 struct wrong_return_type_lt {
159   bool operator==(wrong_return_type_lt) const noexcept;
160   bool operator!=(wrong_return_type_lt) const noexcept;
161   void operator<(wrong_return_type_lt) const noexcept;
162   bool operator>(wrong_return_type_lt) const noexcept;
163   bool operator>=(wrong_return_type_lt) const noexcept;
164   bool operator<=(wrong_return_type_lt) const noexcept;
165 };
166 
167 struct wrong_return_type_gt {
168   bool operator==(wrong_return_type_gt) const noexcept;
169   bool operator!=(wrong_return_type_gt) const noexcept;
170   bool operator<(wrong_return_type_gt) const noexcept;
171   void operator>(wrong_return_type_gt) const noexcept;
172   bool operator>=(wrong_return_type_gt) const noexcept;
173   bool operator<=(wrong_return_type_gt) const noexcept;
174 };
175 
176 struct wrong_return_type_le {
177   bool operator==(wrong_return_type_le) const noexcept;
178   bool operator!=(wrong_return_type_le) const noexcept;
179   bool operator<(wrong_return_type_le) const noexcept;
180   bool operator>(wrong_return_type_le) const noexcept;
181   void operator>=(wrong_return_type_le) const noexcept;
182   bool operator<=(wrong_return_type_le) const noexcept;
183 };
184 
185 struct wrong_return_type_ge {
186   bool operator==(wrong_return_type_ge) const noexcept;
187   bool operator!=(wrong_return_type_ge) const noexcept;
188   bool operator<(wrong_return_type_ge) const noexcept;
189   bool operator>(wrong_return_type_ge) const noexcept;
190   bool operator>=(wrong_return_type_ge) const noexcept;
191   void operator<=(wrong_return_type_ge) const noexcept;
192 };
193 
194 struct wrong_return_type {
195   void operator==(wrong_return_type) const noexcept;
196   void operator!=(wrong_return_type) const noexcept;
197   void operator<(wrong_return_type) const noexcept;
198   void operator>(wrong_return_type) const noexcept;
199   void operator>=(wrong_return_type) const noexcept;
200   void operator<=(wrong_return_type_ge) const noexcept;
201 };
202 
203 struct cxx20_member_eq_operator_with_deleted_ne {
204   bool operator==(cxx20_member_eq_operator_with_deleted_ne const&) const = default;
205   bool operator!=(cxx20_member_eq_operator_with_deleted_ne const&) const = delete;
206 };
207 
208 struct cxx20_friend_eq_operator_with_deleted_ne {
209   friend bool operator==(cxx20_friend_eq_operator_with_deleted_ne const&,
210                          cxx20_friend_eq_operator_with_deleted_ne const&) = default;
211   friend bool operator!=(cxx20_friend_eq_operator_with_deleted_ne const&,
212                          cxx20_friend_eq_operator_with_deleted_ne const&) = delete;
213 };
214 
215 struct member_three_way_comparable_with_deleted_eq {
216   auto operator<=>(member_three_way_comparable_with_deleted_eq const&) const = default;
217   bool operator==(member_three_way_comparable_with_deleted_eq const&) const = delete;
218 };
219 
220 struct member_three_way_comparable_with_deleted_ne {
221   auto operator<=>(member_three_way_comparable_with_deleted_ne const&) const = default;
222   bool operator!=(member_three_way_comparable_with_deleted_ne const&) const = delete;
223 };
224 
225 struct friend_three_way_comparable_with_deleted_eq {
226   friend auto operator<=>(friend_three_way_comparable_with_deleted_eq const&,
227                           friend_three_way_comparable_with_deleted_eq const&) = default;
228   friend bool operator==(friend_three_way_comparable_with_deleted_eq const&,
229                          friend_three_way_comparable_with_deleted_eq const&) = delete;
230 };
231 
232 struct friend_three_way_comparable_with_deleted_ne {
233   friend auto operator<=>(friend_three_way_comparable_with_deleted_ne const&,
234                           friend_three_way_comparable_with_deleted_ne const&) = default;
235   friend bool operator!=(friend_three_way_comparable_with_deleted_ne const&,
236                          friend_three_way_comparable_with_deleted_ne const&) = delete;
237 };
238 
239 struct one_way_eq {
240   bool operator==(one_way_eq const&) const = default;
241   friend bool operator==(one_way_eq, explicit_operators);
242   friend bool operator==(explicit_operators, one_way_eq) = delete;
243 
244   operator explicit_operators() const;
245 };
246 
247 struct one_way_ne {
248   bool operator==(one_way_ne const&) const = default;
249   friend bool operator==(one_way_ne, explicit_operators);
250   friend bool operator!=(one_way_ne, explicit_operators) = delete;
251 
252   operator explicit_operators() const;
253 };
254 static_assert(requires(explicit_operators const x, one_way_ne const y) { x != y; });
255 
256 struct explicit_bool {
257   explicit operator bool() const noexcept;
258 };
259 
260 struct totally_ordered_with_others {
261   auto operator<=>(totally_ordered_with_others const&) const = default;
262 };
263 
264 struct no_lt_not_totally_ordered_with {
265   bool operator==(no_lt_not_totally_ordered_with const&) const = default;
266   auto operator<=>(no_lt_not_totally_ordered_with const&) const = default;
267   operator totally_ordered_with_others() const noexcept;
268 
269   bool operator==(totally_ordered_with_others const&) const;
270   auto operator<=>(totally_ordered_with_others const&) const;
271   auto operator<(totally_ordered_with_others const&) const;
272 };
273 
274 struct no_gt_not_totally_ordered_with {
275   bool operator==(no_gt_not_totally_ordered_with const&) const = default;
276   auto operator<=>(no_gt_not_totally_ordered_with const&) const = default;
277   operator totally_ordered_with_others() const noexcept;
278 
279   bool operator==(totally_ordered_with_others const&) const;
280   auto operator<=>(totally_ordered_with_others const&) const;
281   auto operator>(totally_ordered_with_others const&) const;
282 };
283 
284 struct no_le_not_totally_ordered_with {
285   bool operator==(no_le_not_totally_ordered_with const&) const = default;
286   auto operator<=>(no_le_not_totally_ordered_with const&) const = default;
287   operator totally_ordered_with_others() const noexcept;
288 
289   bool operator==(totally_ordered_with_others const&) const;
290   auto operator<=>(totally_ordered_with_others const&) const;
291   auto operator<=(totally_ordered_with_others const&) const;
292 };
293 
294 struct no_ge_not_totally_ordered_with {
295   bool operator==(no_ge_not_totally_ordered_with const&) const = default;
296   auto operator<=>(no_ge_not_totally_ordered_with const&) const = default;
297   operator totally_ordered_with_others() const noexcept;
298 
299   bool operator==(totally_ordered_with_others const&) const;
300   auto operator<=>(totally_ordered_with_others const&) const;
301   auto operator>=(totally_ordered_with_others const&) const;
302 };
303 
304 struct partial_ordering_totally_ordered_with {
305   auto operator<=>(partial_ordering_totally_ordered_with const&) const noexcept = default;
306   std::partial_ordering operator<=>(totally_ordered_with_others const&) const noexcept;
307 
308   operator totally_ordered_with_others() const;
309 };
310 
311 struct weak_ordering_totally_ordered_with {
312   auto operator<=>(weak_ordering_totally_ordered_with const&) const noexcept = default;
313   std::weak_ordering operator<=>(totally_ordered_with_others const&) const noexcept;
314 
315   operator totally_ordered_with_others() const;
316 };
317 
318 struct strong_ordering_totally_ordered_with {
319   auto operator<=>(strong_ordering_totally_ordered_with const&) const noexcept = default;
320   std::strong_ordering operator<=>(totally_ordered_with_others const&) const noexcept;
321 
322   operator totally_ordered_with_others() const;
323 };
324 
325 struct eq_returns_explicit_bool {
326   friend explicit_bool operator==(eq_returns_explicit_bool, eq_returns_explicit_bool);
327   friend bool operator!=(eq_returns_explicit_bool, eq_returns_explicit_bool);
328   friend bool operator<(eq_returns_explicit_bool, eq_returns_explicit_bool);
329   friend bool operator>(eq_returns_explicit_bool, eq_returns_explicit_bool);
330   friend bool operator<=(eq_returns_explicit_bool, eq_returns_explicit_bool);
331   friend bool operator>=(eq_returns_explicit_bool, eq_returns_explicit_bool);
332 
333   operator totally_ordered_with_others() const;
334 
335   friend explicit_bool operator==(eq_returns_explicit_bool, totally_ordered_with_others);
336   friend explicit_bool operator==(totally_ordered_with_others, eq_returns_explicit_bool);
337   friend bool operator!=(eq_returns_explicit_bool, totally_ordered_with_others);
338   friend bool operator!=(totally_ordered_with_others, eq_returns_explicit_bool);
339   friend bool operator<(eq_returns_explicit_bool, totally_ordered_with_others);
340   friend bool operator<(totally_ordered_with_others, eq_returns_explicit_bool);
341   friend bool operator>(eq_returns_explicit_bool, totally_ordered_with_others);
342   friend bool operator>(totally_ordered_with_others, eq_returns_explicit_bool);
343   friend bool operator<=(eq_returns_explicit_bool, totally_ordered_with_others);
344   friend bool operator<=(totally_ordered_with_others, eq_returns_explicit_bool);
345   friend bool operator>=(eq_returns_explicit_bool, totally_ordered_with_others);
346   friend bool operator>=(totally_ordered_with_others, eq_returns_explicit_bool);
347 };
348 
349 struct ne_returns_explicit_bool {
350   friend bool operator==(ne_returns_explicit_bool, ne_returns_explicit_bool);
351   friend explicit_bool operator!=(ne_returns_explicit_bool, ne_returns_explicit_bool);
352   friend bool operator<(ne_returns_explicit_bool, ne_returns_explicit_bool);
353   friend bool operator>(ne_returns_explicit_bool, ne_returns_explicit_bool);
354   friend bool operator<=(ne_returns_explicit_bool, ne_returns_explicit_bool);
355   friend bool operator>=(ne_returns_explicit_bool, ne_returns_explicit_bool);
356 
357   operator totally_ordered_with_others() const;
358 
359   friend bool operator==(ne_returns_explicit_bool, totally_ordered_with_others);
360   friend explicit_bool operator!=(ne_returns_explicit_bool, totally_ordered_with_others);
361   friend explicit_bool operator!=(totally_ordered_with_others, ne_returns_explicit_bool);
362   friend bool operator<(ne_returns_explicit_bool, totally_ordered_with_others);
363   friend bool operator<(totally_ordered_with_others, ne_returns_explicit_bool);
364   friend bool operator>(ne_returns_explicit_bool, totally_ordered_with_others);
365   friend bool operator>(totally_ordered_with_others, ne_returns_explicit_bool);
366   friend bool operator<=(ne_returns_explicit_bool, totally_ordered_with_others);
367   friend bool operator<=(totally_ordered_with_others, ne_returns_explicit_bool);
368   friend bool operator>=(ne_returns_explicit_bool, totally_ordered_with_others);
369   friend bool operator>=(totally_ordered_with_others, ne_returns_explicit_bool);
370 };
371 
372 struct lt_returns_explicit_bool {
373   friend bool operator==(lt_returns_explicit_bool, lt_returns_explicit_bool);
374   friend bool operator!=(lt_returns_explicit_bool, lt_returns_explicit_bool);
375   friend explicit_bool operator<(lt_returns_explicit_bool, lt_returns_explicit_bool);
376   friend bool operator>(lt_returns_explicit_bool, lt_returns_explicit_bool);
377   friend bool operator<=(lt_returns_explicit_bool, lt_returns_explicit_bool);
378   friend bool operator>=(lt_returns_explicit_bool, lt_returns_explicit_bool);
379 
380   operator totally_ordered_with_others() const;
381 
382   friend bool operator==(lt_returns_explicit_bool, totally_ordered_with_others);
383   friend bool operator!=(lt_returns_explicit_bool, totally_ordered_with_others);
384   friend bool operator!=(totally_ordered_with_others, lt_returns_explicit_bool);
385   friend explicit_bool operator<(lt_returns_explicit_bool, totally_ordered_with_others);
386   friend bool operator<(totally_ordered_with_others, lt_returns_explicit_bool);
387   friend bool operator>(lt_returns_explicit_bool, totally_ordered_with_others);
388   friend bool operator>(totally_ordered_with_others, lt_returns_explicit_bool);
389   friend bool operator<=(lt_returns_explicit_bool, totally_ordered_with_others);
390   friend bool operator<=(totally_ordered_with_others, lt_returns_explicit_bool);
391   friend bool operator>=(lt_returns_explicit_bool, totally_ordered_with_others);
392   friend bool operator>=(totally_ordered_with_others, lt_returns_explicit_bool);
393 };
394 
395 struct gt_returns_explicit_bool {
396   friend bool operator==(gt_returns_explicit_bool, gt_returns_explicit_bool);
397   friend bool operator!=(gt_returns_explicit_bool, gt_returns_explicit_bool);
398   friend bool operator<(gt_returns_explicit_bool, gt_returns_explicit_bool);
399   friend explicit_bool operator>(gt_returns_explicit_bool, gt_returns_explicit_bool);
400   friend bool operator<=(gt_returns_explicit_bool, gt_returns_explicit_bool);
401   friend bool operator>=(gt_returns_explicit_bool, gt_returns_explicit_bool);
402 
403   operator totally_ordered_with_others() const;
404 
405   friend bool operator==(gt_returns_explicit_bool, totally_ordered_with_others);
406   friend bool operator!=(gt_returns_explicit_bool, totally_ordered_with_others);
407   friend bool operator!=(totally_ordered_with_others, gt_returns_explicit_bool);
408   friend bool operator<(gt_returns_explicit_bool, totally_ordered_with_others);
409   friend bool operator<(totally_ordered_with_others, gt_returns_explicit_bool);
410   friend explicit_bool operator>(gt_returns_explicit_bool, totally_ordered_with_others);
411   friend bool operator>(totally_ordered_with_others, gt_returns_explicit_bool);
412   friend bool operator<=(gt_returns_explicit_bool, totally_ordered_with_others);
413   friend bool operator<=(totally_ordered_with_others, gt_returns_explicit_bool);
414   friend bool operator>=(gt_returns_explicit_bool, totally_ordered_with_others);
415   friend bool operator>=(totally_ordered_with_others, gt_returns_explicit_bool);
416 };
417 
418 struct le_returns_explicit_bool {
419   friend bool operator==(le_returns_explicit_bool, le_returns_explicit_bool);
420   friend bool operator!=(le_returns_explicit_bool, le_returns_explicit_bool);
421   friend bool operator<(le_returns_explicit_bool, le_returns_explicit_bool);
422   friend bool operator>(le_returns_explicit_bool, le_returns_explicit_bool);
423   friend explicit_bool operator<=(le_returns_explicit_bool, le_returns_explicit_bool);
424   friend bool operator>=(le_returns_explicit_bool, le_returns_explicit_bool);
425 
426   operator totally_ordered_with_others() const;
427 
428   friend bool operator==(le_returns_explicit_bool, totally_ordered_with_others);
429   friend bool operator!=(le_returns_explicit_bool, totally_ordered_with_others);
430   friend bool operator!=(totally_ordered_with_others, le_returns_explicit_bool);
431   friend bool operator<(le_returns_explicit_bool, totally_ordered_with_others);
432   friend bool operator<(totally_ordered_with_others, le_returns_explicit_bool);
433   friend bool operator>(le_returns_explicit_bool, totally_ordered_with_others);
434   friend bool operator>(totally_ordered_with_others, le_returns_explicit_bool);
435   friend bool operator<=(le_returns_explicit_bool, totally_ordered_with_others);
436   friend explicit_bool operator<=(totally_ordered_with_others, le_returns_explicit_bool);
437   friend bool operator>=(le_returns_explicit_bool, totally_ordered_with_others);
438   friend bool operator>=(totally_ordered_with_others, le_returns_explicit_bool);
439 };
440 
441 struct ge_returns_explicit_bool {
442   friend bool operator==(ge_returns_explicit_bool, ge_returns_explicit_bool);
443   friend bool operator!=(ge_returns_explicit_bool, ge_returns_explicit_bool);
444   friend bool operator<(ge_returns_explicit_bool, ge_returns_explicit_bool);
445   friend bool operator>(ge_returns_explicit_bool, ge_returns_explicit_bool);
446   friend bool operator<=(ge_returns_explicit_bool, ge_returns_explicit_bool);
447   friend explicit_bool operator>=(ge_returns_explicit_bool, ge_returns_explicit_bool);
448 
449   operator totally_ordered_with_others() const;
450 
451   friend bool operator==(ge_returns_explicit_bool, totally_ordered_with_others);
452   friend bool operator!=(ge_returns_explicit_bool, totally_ordered_with_others);
453   friend bool operator!=(totally_ordered_with_others, ge_returns_explicit_bool);
454   friend bool operator<(ge_returns_explicit_bool, totally_ordered_with_others);
455   friend bool operator<(totally_ordered_with_others, ge_returns_explicit_bool);
456   friend bool operator>(ge_returns_explicit_bool, totally_ordered_with_others);
457   friend bool operator>(totally_ordered_with_others, ge_returns_explicit_bool);
458   friend bool operator<=(ge_returns_explicit_bool, totally_ordered_with_others);
459   friend bool operator<=(totally_ordered_with_others, ge_returns_explicit_bool);
460   friend bool operator>=(ge_returns_explicit_bool, totally_ordered_with_others);
461   friend explicit_bool operator>=(totally_ordered_with_others, ge_returns_explicit_bool);
462 };
463 
464 struct returns_true_type {
465   friend std::true_type operator==(returns_true_type, returns_true_type);
466   friend std::true_type operator!=(returns_true_type, returns_true_type);
467   friend std::true_type operator<(returns_true_type, returns_true_type);
468   friend std::true_type operator>(returns_true_type, returns_true_type);
469   friend std::true_type operator<=(returns_true_type, returns_true_type);
470   friend std::true_type operator>=(returns_true_type, returns_true_type);
471 
472   operator totally_ordered_with_others() const;
473 
474   friend std::true_type operator==(returns_true_type, totally_ordered_with_others);
475   friend std::true_type operator==(totally_ordered_with_others, returns_true_type);
476   friend std::true_type operator!=(returns_true_type, totally_ordered_with_others);
477   friend std::true_type operator!=(totally_ordered_with_others, returns_true_type);
478   friend std::true_type operator<(returns_true_type, totally_ordered_with_others);
479   friend std::true_type operator<(totally_ordered_with_others, returns_true_type);
480   friend std::true_type operator>(returns_true_type, totally_ordered_with_others);
481   friend std::true_type operator>(totally_ordered_with_others, returns_true_type);
482   friend std::true_type operator<=(returns_true_type, totally_ordered_with_others);
483   friend std::true_type operator<=(totally_ordered_with_others, returns_true_type);
484   friend std::true_type operator>=(returns_true_type, totally_ordered_with_others);
485   friend std::true_type operator>=(totally_ordered_with_others, returns_true_type);
486 };
487 
488 struct returns_int_ptr {
489   friend int* operator==(returns_int_ptr, returns_int_ptr);
490   friend int* operator!=(returns_int_ptr, returns_int_ptr);
491   friend int* operator<(returns_int_ptr, returns_int_ptr);
492   friend int* operator>(returns_int_ptr, returns_int_ptr);
493   friend int* operator<=(returns_int_ptr, returns_int_ptr);
494   friend int* operator>=(returns_int_ptr, returns_int_ptr);
495 
496   operator totally_ordered_with_others() const;
497 
498   friend int* operator==(returns_int_ptr, totally_ordered_with_others);
499   friend int* operator==(totally_ordered_with_others, returns_int_ptr);
500   friend int* operator!=(returns_int_ptr, totally_ordered_with_others);
501   friend int* operator!=(totally_ordered_with_others, returns_int_ptr);
502   friend int* operator<(returns_int_ptr, totally_ordered_with_others);
503   friend int* operator<(totally_ordered_with_others, returns_int_ptr);
504   friend int* operator>(returns_int_ptr, totally_ordered_with_others);
505   friend int* operator>(totally_ordered_with_others, returns_int_ptr);
506   friend int* operator<=(returns_int_ptr, totally_ordered_with_others);
507   friend int* operator<=(totally_ordered_with_others, returns_int_ptr);
508   friend int* operator>=(returns_int_ptr, totally_ordered_with_others);
509   friend int* operator>=(totally_ordered_with_others, returns_int_ptr);
510 };
511 
512 struct ForwardingTestObject {
513   constexpr bool operator<(ForwardingTestObject&&) && { return true; }
514   constexpr bool operator<(const ForwardingTestObject&) const& { return false; }
515 
516   constexpr bool operator==(ForwardingTestObject&&) && { return true; }
517   constexpr bool operator==(const ForwardingTestObject&) const& { return false; }
518 
519   constexpr bool operator!=(ForwardingTestObject&&) && { return true; }
520   constexpr bool operator!=(const ForwardingTestObject&) const& { return false; }
521 
522   constexpr bool operator<=(ForwardingTestObject&&) && { return true; }
523   constexpr bool operator<=(const ForwardingTestObject&) const& { return false; }
524 
525   constexpr bool operator>(ForwardingTestObject&&) && { return true; }
526   constexpr bool operator>(const ForwardingTestObject&) const& { return false; }
527 
528   constexpr bool operator>=(ForwardingTestObject&&) && { return true; }
529   constexpr bool operator>=(const ForwardingTestObject&) const& { return false; }
530 };
531 
532 #endif // TEST_SUPPORT_COMPARE_TYPES_H
533