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 // class weak_ordering
14 
15 
16 #include <compare>
17 #include <type_traits>
18 #include <cassert>
19 
20 #include "test_macros.h"
21 
22 const volatile void* volatile sink;
23 
24 void test_static_members() {
25   DoNotOptimize(&std::weak_ordering::less);
26   DoNotOptimize(&std::weak_ordering::equivalent);
27   DoNotOptimize(&std::weak_ordering::greater);
28 }
29 
30 void test_signatures() {
31   auto& Eq = std::weak_ordering::equivalent;
32 
33   ASSERT_NOEXCEPT(Eq == 0);
34   ASSERT_NOEXCEPT(0 == Eq);
35   ASSERT_NOEXCEPT(Eq != 0);
36   ASSERT_NOEXCEPT(0 != Eq);
37   ASSERT_NOEXCEPT(0 < Eq);
38   ASSERT_NOEXCEPT(Eq < 0);
39   ASSERT_NOEXCEPT(0 <= Eq);
40   ASSERT_NOEXCEPT(Eq <= 0);
41   ASSERT_NOEXCEPT(0 > Eq);
42   ASSERT_NOEXCEPT(Eq > 0);
43   ASSERT_NOEXCEPT(0 >= Eq);
44   ASSERT_NOEXCEPT(Eq >= 0);
45 #ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
46   ASSERT_NOEXCEPT(0 <=> Eq);
47   ASSERT_NOEXCEPT(Eq <=> 0);
48   ASSERT_SAME_TYPE(decltype(Eq <=> 0), std::weak_ordering);
49   ASSERT_SAME_TYPE(decltype(0 <=> Eq), std::weak_ordering);
50 #endif
51 }
52 
53 constexpr bool test_conversion() {
54   static_assert(std::is_convertible<const std::weak_ordering&,
55       std::partial_ordering>::value, "");
56   { // value == 0
57     auto V = std::weak_ordering::equivalent;
58     std::partial_ordering WV = V;
59     assert(WV == 0);
60   }
61   { // value < 0
62     auto V = std::weak_ordering::less;
63     std::partial_ordering WV = V;
64     assert(WV < 0);
65   }
66   { // value > 0
67     auto V = std::weak_ordering::greater;
68     std::partial_ordering WV = V;
69     assert(WV > 0);
70   }
71   return true;
72 }
73 
74 constexpr bool test_constexpr() {
75   auto& Eq = std::weak_ordering::equivalent;
76   auto& Less = std::weak_ordering::less;
77   auto& Greater = std::weak_ordering::greater;
78   struct {
79     std::weak_ordering Value;
80     bool ExpectEq;
81     bool ExpectNeq;
82     bool ExpectLess;
83     bool ExpectGreater;
84   } TestCases[] = {
85       {Eq, true, false, false, false},
86       {Less, false, true, true, false},
87       {Greater, false, true, false, true},
88   };
89   for (auto TC : TestCases) {
90     auto V = TC.Value;
91     assert((V == 0) == TC.ExpectEq);
92     assert((0 == V) == TC.ExpectEq);
93     assert((V != 0) == TC.ExpectNeq);
94     assert((0 != V) == TC.ExpectNeq);
95 
96     assert((V < 0) == TC.ExpectLess);
97     assert((V > 0) == TC.ExpectGreater);
98     assert((V <= 0) == (TC.ExpectLess || TC.ExpectEq));
99     assert((V >= 0) == (TC.ExpectGreater || TC.ExpectEq));
100 
101     assert((0 < V) == TC.ExpectGreater);
102     assert((0 > V) == TC.ExpectLess);
103     assert((0 <= V) == (TC.ExpectGreater || TC.ExpectEq));
104     assert((0 >= V) == (TC.ExpectLess || TC.ExpectEq));
105   }
106 #ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
107   {
108     std::weak_ordering res = (Eq <=> 0);
109     ((void)res);
110     res = (0 <=> Eq);
111     ((void)res);
112   }
113   enum ExpectRes {
114     ER_Greater,
115     ER_Less,
116     ER_Equiv
117   };
118   struct {
119     std::weak_ordering Value;
120     ExpectRes Expect;
121   } SpaceshipTestCases[] = {
122       {std::weak_ordering::equivalent, ER_Equiv},
123       {std::weak_ordering::less, ER_Less},
124       {std::weak_ordering::greater, ER_Greater},
125   };
126   for (auto TC : SpaceshipTestCases)
127   {
128     std::weak_ordering Res = (TC.Value <=> 0);
129     switch (TC.Expect) {
130     case ER_Equiv:
131       assert(Res == 0);
132       assert(0 == Res);
133       break;
134     case ER_Less:
135       assert(Res < 0);
136       break;
137     case ER_Greater:
138       assert(Res > 0);
139       break;
140     }
141   }
142 
143   {
144     static_assert(std::weak_ordering::less == std::weak_ordering::less);
145     static_assert(std::weak_ordering::less != std::weak_ordering::equivalent);
146     static_assert(std::weak_ordering::less != std::weak_ordering::greater);
147 
148     static_assert(std::weak_ordering::equivalent != std::weak_ordering::less);
149     static_assert(std::weak_ordering::equivalent ==
150                   std::weak_ordering::equivalent);
151     static_assert(std::weak_ordering::equivalent !=
152                   std::weak_ordering::greater);
153 
154     static_assert(std::weak_ordering::greater != std::weak_ordering::less);
155     static_assert(std::weak_ordering::greater !=
156                   std::weak_ordering::equivalent);
157     static_assert(std::weak_ordering::greater == std::weak_ordering::greater);
158   }
159 #endif
160 
161   return true;
162 }
163 
164 int main(int, char**) {
165   test_static_members();
166   test_signatures();
167   static_assert(test_conversion(), "conversion test failed");
168   static_assert(test_constexpr(), "constexpr test failed");
169 
170   return 0;
171 }
172