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