1 //===----------------------------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
11
12 // <compare>
13
14 // class strong_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
test_static_members()25 void test_static_members() {
26 DoNotOptimize(&std::strong_ordering::less);
27 DoNotOptimize(&std::strong_ordering::equal);
28 DoNotOptimize(&std::strong_ordering::equivalent);
29 DoNotOptimize(&std::strong_ordering::greater);
30 }
31
test_signatures()32 void test_signatures() {
33 auto& Eq = std::strong_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::strong_ordering);
51 ASSERT_SAME_TYPE(decltype(0 <=> Eq), std::strong_ordering);
52 #endif
53 }
54
test_conversion()55 constexpr bool test_conversion() {
56 static_assert(std::is_convertible<const std::strong_ordering&,
57 std::weak_equality>::value, "");
58 { // value == 0
59 auto V = std::strong_ordering::equivalent;
60 std::weak_equality WV = V;
61 assert(WV == 0);
62 }
63 std::strong_ordering WeakTestCases[] = {
64 std::strong_ordering::less,
65 std::strong_ordering::greater,
66 };
67 for (auto V : WeakTestCases)
68 { // value != 0
69 std::weak_equality WV = V;
70 assert(WV != 0);
71 }
72 static_assert(std::is_convertible<const std::strong_ordering&,
73 std::strong_equality>::value, "");
74 { // value == 0
75 auto V = std::strong_ordering::equivalent;
76 std::strong_equality WV = V;
77 assert(WV == 0);
78 }
79 { // value == 0
80 auto V = std::strong_ordering::equal;
81 std::strong_equality WV = V;
82 assert(WV == 0);
83 }
84 std::strong_ordering StrongTestCases[] = {
85 std::strong_ordering::less,
86 std::strong_ordering::greater,
87 };
88 for (auto V : StrongTestCases)
89 { // value != 0
90 std::strong_equality WV = V;
91 assert(WV != 0);
92 }
93
94 static_assert(std::is_convertible<const std::strong_ordering&,
95 std::partial_ordering>::value, "");
96 { // value == 0
97 auto V = std::strong_ordering::equivalent;
98 std::partial_ordering WV = V;
99 assert(WV == 0);
100 }
101 { // value < 0
102 auto V = std::strong_ordering::less;
103 std::partial_ordering WV = V;
104 assert(WV < 0);
105 }
106 { // value > 0
107 auto V = std::strong_ordering::greater;
108 std::partial_ordering WV = V;
109 assert(WV > 0);
110 }
111
112 static_assert(std::is_convertible<const std::strong_ordering&,
113 std::weak_ordering>::value, "");
114 { // value == 0
115 auto V = std::strong_ordering::equivalent;
116 std::weak_ordering WV = V;
117 assert(WV == 0);
118 }
119 { // value < 0
120 auto V = std::strong_ordering::less;
121 std::weak_ordering WV = V;
122 assert(WV < 0);
123 }
124 { // value > 0
125 auto V = std::strong_ordering::greater;
126 std::weak_ordering WV = V;
127 assert(WV > 0);
128 }
129 return true;
130 }
131
test_constexpr()132 constexpr bool test_constexpr() {
133 auto& Eq = std::strong_ordering::equal;
134 auto& Equiv = std::strong_ordering::equivalent;
135 auto& Less = std::strong_ordering::less;
136 auto& Greater = std::strong_ordering::greater;
137 struct {
138 std::strong_ordering Value;
139 bool ExpectEq;
140 bool ExpectNeq;
141 bool ExpectLess;
142 bool ExpectGreater;
143 } TestCases[] = {
144 {Eq, true, false, false, false},
145 {Equiv, true, false, false, false},
146 {Less, false, true, true, false},
147 {Greater, false, true, false, true},
148 };
149 for (auto TC : TestCases) {
150 auto V = TC.Value;
151 assert((V == 0) == TC.ExpectEq);
152 assert((0 == V) == TC.ExpectEq);
153 assert((V != 0) == TC.ExpectNeq);
154 assert((0 != V) == TC.ExpectNeq);
155
156 assert((V < 0) == TC.ExpectLess);
157 assert((V > 0) == TC.ExpectGreater);
158 assert((V <= 0) == (TC.ExpectLess || TC.ExpectEq));
159 assert((V >= 0) == (TC.ExpectGreater || TC.ExpectEq));
160
161 assert((0 < V) == TC.ExpectGreater);
162 assert((0 > V) == TC.ExpectLess);
163 assert((0 <= V) == (TC.ExpectGreater || TC.ExpectEq));
164 assert((0 >= V) == (TC.ExpectLess || TC.ExpectEq));
165 }
166 #ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
167 {
168 std::strong_ordering res = (Eq <=> 0);
169 ((void)res);
170 res = (0 <=> Eq);
171 ((void)res);
172 }
173 enum ExpectRes {
174 ER_Greater,
175 ER_Less,
176 ER_Equiv
177 };
178 struct {
179 std::strong_ordering Value;
180 ExpectRes Expect;
181 } SpaceshipTestCases[] = {
182 {std::strong_ordering::equivalent, ER_Equiv},
183 {std::strong_ordering::less, ER_Less},
184 {std::strong_ordering::greater, ER_Greater},
185 };
186 for (auto TC : SpaceshipTestCases)
187 {
188 std::strong_ordering Res = (0 <=> TC.Value);
189 switch (TC.Expect) {
190 case ER_Equiv:
191 assert(Res == 0);
192 assert(0 == Res);
193 break;
194 case ER_Less:
195 assert(Res < 0);
196 break;
197 case ER_Greater:
198 assert(Res > 0);
199 break;
200 }
201 }
202 #endif
203
204 return true;
205 }
206
main()207 int main() {
208 test_static_members();
209 test_signatures();
210 static_assert(test_conversion(), "conversion test failed");
211 static_assert(test_constexpr(), "constexpr test failed");
212 }
213