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