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