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