1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
11 
12 // <compare>
13 
14 // class strong_ordering
15 
16 
17 #include <compare>
18 #include <type_traits>
19 #include <cassert>
20 
21 #include "test_macros.h"
22 
23 const volatile void* volatile sink;
24 
test_static_members()25 void test_static_members() {
26   DoNotOptimize(&std::strong_ordering::less);
27   DoNotOptimize(&std::strong_ordering::equal);
28   DoNotOptimize(&std::strong_ordering::equivalent);
29   DoNotOptimize(&std::strong_ordering::greater);
30 }
31 
test_signatures()32 void test_signatures() {
33   auto& Eq = std::strong_ordering::equivalent;
34 
35   ASSERT_NOEXCEPT(Eq == 0);
36   ASSERT_NOEXCEPT(0 == Eq);
37   ASSERT_NOEXCEPT(Eq != 0);
38   ASSERT_NOEXCEPT(0 != Eq);
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   ASSERT_NOEXCEPT(0 >= Eq);
46   ASSERT_NOEXCEPT(Eq >= 0);
47 #ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
48   ASSERT_NOEXCEPT(0 <=> Eq);
49   ASSERT_NOEXCEPT(Eq <=> 0);
50   ASSERT_SAME_TYPE(decltype(Eq <=> 0), std::strong_ordering);
51   ASSERT_SAME_TYPE(decltype(0 <=> Eq), std::strong_ordering);
52 #endif
53 }
54 
test_conversion()55 constexpr bool test_conversion() {
56   static_assert(std::is_convertible<const std::strong_ordering&,
57       std::weak_equality>::value, "");
58   { // value == 0
59     auto V = std::strong_ordering::equivalent;
60     std::weak_equality WV = V;
61     assert(WV == 0);
62   }
63   std::strong_ordering WeakTestCases[] = {
64       std::strong_ordering::less,
65       std::strong_ordering::greater,
66   };
67   for (auto V : WeakTestCases)
68   { // value != 0
69     std::weak_equality WV = V;
70     assert(WV != 0);
71   }
72   static_assert(std::is_convertible<const std::strong_ordering&,
73       std::strong_equality>::value, "");
74   { // value == 0
75     auto V = std::strong_ordering::equivalent;
76     std::strong_equality WV = V;
77     assert(WV == 0);
78   }
79   { // value == 0
80     auto V = std::strong_ordering::equal;
81     std::strong_equality WV = V;
82     assert(WV == 0);
83   }
84   std::strong_ordering StrongTestCases[] = {
85       std::strong_ordering::less,
86       std::strong_ordering::greater,
87   };
88   for (auto V : StrongTestCases)
89   { // value != 0
90     std::strong_equality WV = V;
91     assert(WV != 0);
92   }
93 
94   static_assert(std::is_convertible<const std::strong_ordering&,
95       std::partial_ordering>::value, "");
96   { // value == 0
97     auto V = std::strong_ordering::equivalent;
98     std::partial_ordering WV = V;
99     assert(WV == 0);
100   }
101   { // value < 0
102     auto V = std::strong_ordering::less;
103     std::partial_ordering WV = V;
104     assert(WV < 0);
105   }
106   { // value > 0
107     auto V = std::strong_ordering::greater;
108     std::partial_ordering WV = V;
109     assert(WV > 0);
110   }
111 
112   static_assert(std::is_convertible<const std::strong_ordering&,
113       std::weak_ordering>::value, "");
114   { // value == 0
115     auto V = std::strong_ordering::equivalent;
116     std::weak_ordering WV = V;
117     assert(WV == 0);
118   }
119   { // value < 0
120     auto V = std::strong_ordering::less;
121     std::weak_ordering WV = V;
122     assert(WV < 0);
123   }
124   { // value > 0
125     auto V = std::strong_ordering::greater;
126     std::weak_ordering WV = V;
127     assert(WV > 0);
128   }
129   return true;
130 }
131 
test_constexpr()132 constexpr bool test_constexpr() {
133   auto& Eq = std::strong_ordering::equal;
134   auto& Equiv = std::strong_ordering::equivalent;
135   auto& Less = std::strong_ordering::less;
136   auto& Greater = std::strong_ordering::greater;
137   struct {
138     std::strong_ordering Value;
139     bool ExpectEq;
140     bool ExpectNeq;
141     bool ExpectLess;
142     bool ExpectGreater;
143   } TestCases[] = {
144       {Eq, true, false, false, false},
145       {Equiv, true, false, false, false},
146       {Less, false, true, true, false},
147       {Greater, false, true, false, true},
148   };
149   for (auto TC : TestCases) {
150     auto V = TC.Value;
151     assert((V == 0) == TC.ExpectEq);
152     assert((0 == V) == TC.ExpectEq);
153     assert((V != 0) == TC.ExpectNeq);
154     assert((0 != V) == TC.ExpectNeq);
155 
156     assert((V < 0) == TC.ExpectLess);
157     assert((V > 0) == TC.ExpectGreater);
158     assert((V <= 0) == (TC.ExpectLess || TC.ExpectEq));
159     assert((V >= 0) == (TC.ExpectGreater || TC.ExpectEq));
160 
161     assert((0 < V) == TC.ExpectGreater);
162     assert((0 > V) == TC.ExpectLess);
163     assert((0 <= V) == (TC.ExpectGreater || TC.ExpectEq));
164     assert((0 >= V) == (TC.ExpectLess || TC.ExpectEq));
165   }
166 #ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
167   {
168     std::strong_ordering res = (Eq <=> 0);
169     ((void)res);
170     res = (0 <=> Eq);
171     ((void)res);
172   }
173   enum ExpectRes {
174     ER_Greater,
175     ER_Less,
176     ER_Equiv
177   };
178   struct {
179     std::strong_ordering Value;
180     ExpectRes Expect;
181   } SpaceshipTestCases[] = {
182       {std::strong_ordering::equivalent, ER_Equiv},
183       {std::strong_ordering::less, ER_Less},
184       {std::strong_ordering::greater, ER_Greater},
185   };
186   for (auto TC : SpaceshipTestCases)
187   {
188     std::strong_ordering Res = (0 <=> TC.Value);
189     switch (TC.Expect) {
190     case ER_Equiv:
191       assert(Res == 0);
192       assert(0 == Res);
193       break;
194     case ER_Less:
195       assert(Res < 0);
196       break;
197     case ER_Greater:
198       assert(Res > 0);
199       break;
200     }
201   }
202 #endif
203 
204   return true;
205 }
206 
main()207 int main() {
208   test_static_members();
209   test_signatures();
210   static_assert(test_conversion(), "conversion test failed");
211   static_assert(test_constexpr(), "constexpr test failed");
212 }
213