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