1 // Test with all operators explicitly defaulted.
2 // { dg-do run { target c++2a } }
3 
4 #include <compare>
5 
6 template <class T>
7 struct D
8 {
9   T i;
10   auto operator<=>(const D& x) const = default;
11   bool operator==(const D& x) const = default;
12   bool operator!=(const D& x) const = default;
13   bool operator<(const D& x) const = default;
14   bool operator<=(const D& x) const = default;
15   bool operator>(const D& x) const = default;
16   bool operator>=(const D& x) const = default;
17 };
18 
19 template <class T>
20 struct E
21 {
22   T i;
23   auto operator<=>(const E& x) const = default;
24   // auto operator==(const E& x) const = default;
25   // auto operator!=(const E& x) const = default;
26   // auto operator<(const E& x) const = default;
27   // auto operator<=(const E& x) const = default;
28   // auto operator>(const E& x) const = default;
29   // auto operator>=(const E& x) const = default;
30 };
31 
32 template <class T>
33 struct F
34 {
35   T i;
36   constexpr auto operator<=>(T x) const { return i<=>x; }
37   constexpr bool operator== (T x) const { return i==x;  }
38 };
39 
40 #define assert(X) do { if (!(X)) __builtin_abort(); } while (0)
41 
42 template <class T, class U>
check_eq(T d,U d2)43 constexpr bool check_eq (T d, U d2)
44 {
45   return is_eq (d <=> d2)
46     && is_eq (d2 <=> d)
47     && is_lteq (d <=> d2)
48     && is_lteq (d2 <=> d)
49     && !is_lt (d <=> d2)
50     && !is_lt (d2 <=> d)
51     && is_gteq (d <=> d2)
52     && is_gteq (d2 <=> d)
53     && !is_gt (d <=> d2)
54     && !is_gt (d2 <=> d)
55     && d == d2
56     && d2 == d
57     && !(d != d2)
58     && !(d2 != d)
59     && d >= d2
60     && d <= d2
61     && d2 >= d
62     && d2 <= d
63     && !(d < d2)
64     && !(d2 < d)
65     && !(d > d2)
66     && !(d2 > d);
67 }
68 
69 template <class T, class U>
check_less(T d,U d2)70 constexpr bool check_less (T d, U d2)
71 {
72   return !is_eq (d <=> d2)
73     && !is_eq (d2 <=> d)
74     && is_lteq (d <=> d2)
75     && !is_lteq (d2 <=> d)
76     && is_lt (d <=> d2)
77     && !is_lt (d2 <=> d)
78     && !is_gteq (d <=> d2)
79     && is_gteq (d2 <=> d)
80     && !is_gt (d <=> d2)
81     && is_gt (d2 <=> d)
82     && !(d == d2)
83     && !(d2 == d)
84     && (d != d2)
85     && (d2 != d)
86     && !(d >= d2)
87     && (d <= d2)
88     && (d2 >= d)
89     && !(d2 <= d)
90     && (d < d2)
91     && !(d2 < d)
92     && !(d > d2)
93     && (d2 > d);
94 }
95 
main()96 int main()
97 {
98   constexpr D<int> d{42};
99   constexpr D<int> d2{24};
100 
101   static_assert (check_eq (d, d));
102   static_assert (check_less (d2, d));
103 
104   constexpr E<float> e { 3.14 };
105   constexpr E<float> ee { 2.72 };
106   static_assert (check_eq (e, e));
107   static_assert (check_less (ee, e));
108 
109   constexpr F<char> f { 'b' };
110   static_assert (check_eq (f, 'b'));
111   static_assert (check_less (f, 'c'));
112   static_assert (check_less ('a', f));
113 }
114