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