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++98, 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 
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 
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 
54 constexpr bool test_conversion() {
55   static_assert(std::is_convertible<const std::partial_ordering, std::weak_equality>::value, "");
56   { // value == 0
57     auto V = std::partial_ordering::equivalent;
58     std::weak_equality WV = V;
59     assert(WV == 0);
60   }
61   std::partial_ordering TestCases[] = {
62       std::partial_ordering::less,
63       std::partial_ordering::greater,
64       std::partial_ordering::unordered
65   };
66   for (auto V : TestCases)
67   { // value != 0
68     std::weak_equality WV = V;
69     assert(WV != 0);
70   }
71   return true;
72 }
73 
74 constexpr bool test_constexpr() {
75   auto& Eq = std::partial_ordering::equivalent;
76   auto& Less = std::partial_ordering::less;
77   auto& Greater = std::partial_ordering::greater;
78   auto& Unord = std::partial_ordering::unordered;
79   struct {
80     std::partial_ordering Value;
81     bool ExpectEq;
82     bool ExpectNeq;
83     bool ExpectLess;
84     bool ExpectGreater;
85   } TestCases[] = {
86       {Eq, true, false, false, false},
87       {Less, false, true, true, false},
88       {Greater, false, true, false, true},
89       {Unord, false, true, false, false}
90   };
91   for (auto TC : TestCases) {
92     auto V = TC.Value;
93     assert((V == 0) == TC.ExpectEq);
94     assert((0 == V) == TC.ExpectEq);
95     assert((V != 0) == TC.ExpectNeq);
96     assert((0 != V) == TC.ExpectNeq);
97 
98     assert((V < 0) == TC.ExpectLess);
99     assert((V > 0) == TC.ExpectGreater);
100     assert((V <= 0) == (TC.ExpectLess || TC.ExpectEq));
101     assert((V >= 0) == (TC.ExpectGreater || TC.ExpectEq));
102 
103     assert((0 < V) == TC.ExpectGreater);
104     assert((0 > V) == TC.ExpectLess);
105     assert((0 <= V) == (TC.ExpectGreater || TC.ExpectEq));
106     assert((0 >= V) == (TC.ExpectLess || TC.ExpectEq));
107   }
108 #ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
109   {
110     std::partial_ordering res = (Eq <=> 0);
111     ((void)res);
112     res = (0 <=> Eq);
113     ((void)res);
114   }
115   enum ExpectRes {
116     ER_Greater,
117     ER_Less,
118     ER_Equiv,
119     ER_Unord
120   };
121   struct {
122     std::partial_ordering Value;
123     ExpectRes Expect;
124   } SpaceshipTestCases[] = {
125       {std::partial_ordering::equivalent, ER_Equiv},
126       {std::partial_ordering::less, ER_Less},
127       {std::partial_ordering::greater, ER_Greater},
128       {std::partial_ordering::unordered, ER_Unord}
129   };
130   for (auto TC : SpaceshipTestCases)
131   {
132     std::partial_ordering Res = (TC.Value <=> 0);
133     switch (TC.Expect) {
134     case ER_Equiv:
135       assert(Res == 0);
136       assert(0 == Res);
137       break;
138     case ER_Less:
139       assert(Res < 0);
140       break;
141     case ER_Greater:
142       assert(Res > 0);
143       break;
144     case ER_Unord:
145       assert(Res != 0);
146       assert(0 != Res);
147       assert((Res < 0) == false);
148       assert((Res > 0) == false);
149       assert((Res == 0) == false);
150       break;
151     }
152   }
153 #endif
154 
155   return true;
156 }
157 
158 int main(int, char**) {
159   test_static_members();
160   test_signatures();
161   static_assert(test_conversion(), "conversion test failed");
162   static_assert(test_constexpr(), "constexpr test failed");
163 
164   return 0;
165 }
166