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