summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/cpp2a/spaceship-synth1a.C
blob: 899a83c80b31a523f90f4a63085f149853148e02 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// Test with all operators explicitly defaulted.
// { dg-do run { target c++20 } }

#include <compare>

template <class T>
struct D
{
  T i;
  auto operator<=>(const D& x) const = default;
  bool operator==(const D& x) const = default;
  bool operator!=(const D& x) const = default;
  bool operator<(const D& x) const = default;
  bool operator<=(const D& x) const = default;
  bool operator>(const D& x) const = default;
  bool operator>=(const D& x) const = default;
};

template <class T>
struct E
{
  T i;
  auto operator<=>(const E& x) const = default;
  // auto operator==(const E& x) const = default;
  // auto operator!=(const E& x) const = default;
  // auto operator<(const E& x) const = default;
  // auto operator<=(const E& x) const = default;
  // auto operator>(const E& x) const = default;
  // auto operator>=(const E& x) const = default;
};

template <class T>
struct F
{
  T i;
  constexpr auto operator<=>(T x) const { return i<=>x; }
  constexpr bool operator== (T x) const { return i==x;  }
};

#define assert(X) do { if (!(X)) __builtin_abort(); } while (0)

template <class T, class U>
constexpr bool check_eq (T d, U d2)
{
  return is_eq (d <=> d2)
    && is_eq (d2 <=> d)
    && is_lteq (d <=> d2)
    && is_lteq (d2 <=> d)
    && !is_lt (d <=> d2)
    && !is_lt (d2 <=> d)
    && is_gteq (d <=> d2)
    && is_gteq (d2 <=> d)
    && !is_gt (d <=> d2)
    && !is_gt (d2 <=> d)
    && d == d2
    && d2 == d
    && !(d != d2)
    && !(d2 != d)
    && d >= d2
    && d <= d2
    && d2 >= d
    && d2 <= d
    && !(d < d2)
    && !(d2 < d)
    && !(d > d2)
    && !(d2 > d);
}

template <class T, class U>
constexpr bool check_less (T d, U d2)
{
  return !is_eq (d <=> d2)
    && !is_eq (d2 <=> d)
    && is_lteq (d <=> d2)
    && !is_lteq (d2 <=> d)
    && is_lt (d <=> d2)
    && !is_lt (d2 <=> d)
    && !is_gteq (d <=> d2)
    && is_gteq (d2 <=> d)
    && !is_gt (d <=> d2)
    && is_gt (d2 <=> d)
    && !(d == d2)
    && !(d2 == d)
    && (d != d2)
    && (d2 != d)
    && !(d >= d2)
    && (d <= d2)
    && (d2 >= d)
    && !(d2 <= d)
    && (d < d2)
    && !(d2 < d)
    && !(d > d2)
    && (d2 > d);
}

int main()
{
  constexpr D<int> d{42};
  constexpr D<int> d2{24};

  static_assert (check_eq (d, d));
  static_assert (check_less (d2, d));

  constexpr E<float> e { 3.14 };
  constexpr E<float> ee { 2.72 };
  static_assert (check_eq (e, e));
  static_assert (check_less (ee, e));

  constexpr F<char> f { 'b' };
  static_assert (check_eq (f, 'b'));
  static_assert (check_less (f, 'c'));
  static_assert (check_less ('a', f));
}