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 #ifndef _LIBCPP___COMPARE_ORDERING_H 10 #define _LIBCPP___COMPARE_ORDERING_H 11 12 #include <__config> 13 #include <type_traits> 14 15 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 16 #pragma GCC system_header 17 #endif 18 19 _LIBCPP_BEGIN_NAMESPACE_STD 20 21 #if _LIBCPP_STD_VER > 17 22 23 // exposition only 24 enum class _LIBCPP_ENUM_VIS _OrdResult : signed char { 25 __less = -1, 26 __equiv = 0, 27 __greater = 1 28 }; 29 30 enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char { 31 __unordered = -127 32 }; 33 34 class partial_ordering; 35 class weak_ordering; 36 class strong_ordering; 37 38 template<class _Tp, class... _Args> 39 inline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...); 40 41 struct _CmpUnspecifiedParam { 42 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEVAL 43 _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} 44 45 template<class _Tp, class = enable_if_t<!__one_of_v<_Tp, int, partial_ordering, weak_ordering, strong_ordering>>> 46 _CmpUnspecifiedParam(_Tp) = delete; 47 }; 48 49 class partial_ordering { 50 using _ValueT = signed char; 51 52 _LIBCPP_HIDE_FROM_ABI 53 explicit constexpr partial_ordering(_OrdResult __v) noexcept 54 : __value_(_ValueT(__v)) {} 55 56 _LIBCPP_HIDE_FROM_ABI 57 explicit constexpr partial_ordering(_NCmpResult __v) noexcept 58 : __value_(_ValueT(__v)) {} 59 60 _LIBCPP_HIDE_FROM_ABI 61 constexpr bool __is_ordered() const noexcept { 62 return __value_ != _ValueT(_NCmpResult::__unordered); 63 } 64 public: 65 // valid values 66 static const partial_ordering less; 67 static const partial_ordering equivalent; 68 static const partial_ordering greater; 69 static const partial_ordering unordered; 70 71 // comparisons 72 _LIBCPP_HIDE_FROM_ABI 73 friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default; 74 75 _LIBCPP_HIDE_FROM_ABI 76 friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 77 return __v.__is_ordered() && __v.__value_ == 0; 78 } 79 80 _LIBCPP_HIDE_FROM_ABI 81 friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept { 82 return __v.__is_ordered() && __v.__value_ < 0; 83 } 84 85 _LIBCPP_HIDE_FROM_ABI 86 friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 87 return __v.__is_ordered() && __v.__value_ <= 0; 88 } 89 90 _LIBCPP_HIDE_FROM_ABI 91 friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept { 92 return __v.__is_ordered() && __v.__value_ > 0; 93 } 94 95 _LIBCPP_HIDE_FROM_ABI 96 friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 97 return __v.__is_ordered() && __v.__value_ >= 0; 98 } 99 100 _LIBCPP_HIDE_FROM_ABI 101 friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept { 102 return __v.__is_ordered() && 0 < __v.__value_; 103 } 104 105 _LIBCPP_HIDE_FROM_ABI 106 friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 107 return __v.__is_ordered() && 0 <= __v.__value_; 108 } 109 110 _LIBCPP_HIDE_FROM_ABI 111 friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept { 112 return __v.__is_ordered() && 0 > __v.__value_; 113 } 114 115 _LIBCPP_HIDE_FROM_ABI 116 friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 117 return __v.__is_ordered() && 0 >= __v.__value_; 118 } 119 120 _LIBCPP_HIDE_FROM_ABI 121 friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 122 return __v; 123 } 124 125 _LIBCPP_HIDE_FROM_ABI 126 friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 127 return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v); 128 } 129 private: 130 _ValueT __value_; 131 }; 132 133 inline constexpr partial_ordering partial_ordering::less(_OrdResult::__less); 134 inline constexpr partial_ordering partial_ordering::equivalent(_OrdResult::__equiv); 135 inline constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater); 136 inline constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered); 137 138 class weak_ordering { 139 using _ValueT = signed char; 140 141 _LIBCPP_HIDE_FROM_ABI 142 explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} 143 144 public: 145 static const weak_ordering less; 146 static const weak_ordering equivalent; 147 static const weak_ordering greater; 148 149 _LIBCPP_HIDE_FROM_ABI 150 constexpr operator partial_ordering() const noexcept { 151 return __value_ == 0 ? partial_ordering::equivalent 152 : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); 153 } 154 155 // comparisons 156 _LIBCPP_HIDE_FROM_ABI 157 friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default; 158 159 _LIBCPP_HIDE_FROM_ABI 160 friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 161 return __v.__value_ == 0; 162 } 163 164 _LIBCPP_HIDE_FROM_ABI 165 friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept { 166 return __v.__value_ < 0; 167 } 168 169 _LIBCPP_HIDE_FROM_ABI 170 friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 171 return __v.__value_ <= 0; 172 } 173 174 _LIBCPP_HIDE_FROM_ABI 175 friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept { 176 return __v.__value_ > 0; 177 } 178 179 _LIBCPP_HIDE_FROM_ABI 180 friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 181 return __v.__value_ >= 0; 182 } 183 184 _LIBCPP_HIDE_FROM_ABI 185 friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept { 186 return 0 < __v.__value_; 187 } 188 189 _LIBCPP_HIDE_FROM_ABI 190 friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 191 return 0 <= __v.__value_; 192 } 193 194 _LIBCPP_HIDE_FROM_ABI 195 friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept { 196 return 0 > __v.__value_; 197 } 198 199 _LIBCPP_HIDE_FROM_ABI 200 friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 201 return 0 >= __v.__value_; 202 } 203 204 _LIBCPP_HIDE_FROM_ABI 205 friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 206 return __v; 207 } 208 209 _LIBCPP_HIDE_FROM_ABI 210 friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 211 return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v); 212 } 213 214 private: 215 _ValueT __value_; 216 }; 217 218 inline constexpr weak_ordering weak_ordering::less(_OrdResult::__less); 219 inline constexpr weak_ordering weak_ordering::equivalent(_OrdResult::__equiv); 220 inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater); 221 222 class strong_ordering { 223 using _ValueT = signed char; 224 225 _LIBCPP_HIDE_FROM_ABI 226 explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} 227 228 public: 229 static const strong_ordering less; 230 static const strong_ordering equal; 231 static const strong_ordering equivalent; 232 static const strong_ordering greater; 233 234 // conversions 235 _LIBCPP_HIDE_FROM_ABI 236 constexpr operator partial_ordering() const noexcept { 237 return __value_ == 0 ? partial_ordering::equivalent 238 : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); 239 } 240 241 _LIBCPP_HIDE_FROM_ABI 242 constexpr operator weak_ordering() const noexcept { 243 return __value_ == 0 ? weak_ordering::equivalent 244 : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater); 245 } 246 247 // comparisons 248 _LIBCPP_HIDE_FROM_ABI 249 friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default; 250 251 _LIBCPP_HIDE_FROM_ABI 252 friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 253 return __v.__value_ == 0; 254 } 255 256 _LIBCPP_HIDE_FROM_ABI 257 friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept { 258 return __v.__value_ < 0; 259 } 260 261 _LIBCPP_HIDE_FROM_ABI 262 friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 263 return __v.__value_ <= 0; 264 } 265 266 _LIBCPP_HIDE_FROM_ABI 267 friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept { 268 return __v.__value_ > 0; 269 } 270 271 _LIBCPP_HIDE_FROM_ABI 272 friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 273 return __v.__value_ >= 0; 274 } 275 276 _LIBCPP_HIDE_FROM_ABI 277 friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept { 278 return 0 < __v.__value_; 279 } 280 281 _LIBCPP_HIDE_FROM_ABI 282 friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 283 return 0 <= __v.__value_; 284 } 285 286 _LIBCPP_HIDE_FROM_ABI 287 friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept { 288 return 0 > __v.__value_; 289 } 290 291 _LIBCPP_HIDE_FROM_ABI 292 friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 293 return 0 >= __v.__value_; 294 } 295 296 _LIBCPP_HIDE_FROM_ABI 297 friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 298 return __v; 299 } 300 301 _LIBCPP_HIDE_FROM_ABI 302 friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 303 return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v); 304 } 305 306 private: 307 _ValueT __value_; 308 }; 309 310 inline constexpr strong_ordering strong_ordering::less(_OrdResult::__less); 311 inline constexpr strong_ordering strong_ordering::equal(_OrdResult::__equiv); 312 inline constexpr strong_ordering strong_ordering::equivalent(_OrdResult::__equiv); 313 inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater); 314 315 #endif // _LIBCPP_STD_VER > 17 316 317 _LIBCPP_END_NAMESPACE_STD 318 319 #endif // _LIBCPP___COMPARE_ORDERING_H 320