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