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