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