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 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 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 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 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 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 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