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