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