File indexing completed on 2025-01-18 09:27:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 #ifndef ABSL_TYPES_COMPARE_H_
0031 #define ABSL_TYPES_COMPARE_H_
0032
0033 #include "absl/base/config.h"
0034
0035 #ifdef ABSL_USES_STD_ORDERING
0036
0037 #include <compare> // IWYU pragma: export
0038 #include <type_traits>
0039
0040 #include "absl/meta/type_traits.h"
0041
0042 #else
0043
0044 #include <cstddef>
0045 #include <cstdint>
0046 #include <cstdlib>
0047 #include <type_traits>
0048
0049 #include "absl/base/attributes.h"
0050 #include "absl/base/macros.h"
0051 #include "absl/meta/type_traits.h"
0052
0053 #endif
0054
0055 namespace absl {
0056 ABSL_NAMESPACE_BEGIN
0057
0058 #ifdef ABSL_USES_STD_ORDERING
0059
0060 using std::partial_ordering;
0061 using std::strong_ordering;
0062 using std::weak_ordering;
0063
0064 #else
0065
0066 namespace compare_internal {
0067
0068 using value_type = int8_t;
0069
0070 class OnlyLiteralZero {
0071 public:
0072 #if ABSL_HAVE_ATTRIBUTE(enable_if)
0073
0074
0075
0076
0077 constexpr OnlyLiteralZero(int n)
0078 __attribute__((enable_if(n == 0, "Only literal `0` is allowed."))) {}
0079 #else
0080
0081
0082
0083
0084
0085
0086 constexpr OnlyLiteralZero(int OnlyLiteralZero::*) noexcept {}
0087 #endif
0088
0089
0090
0091
0092
0093
0094 template <typename T, typename = typename std::enable_if<
0095 std::is_same<T, std::nullptr_t>::value ||
0096 (std::is_integral<T>::value &&
0097 !std::is_same<T, int>::value)>::type>
0098 OnlyLiteralZero(T) {
0099 static_assert(sizeof(T) < 0, "Only literal `0` is allowed.");
0100 }
0101 };
0102
0103 enum class eq : value_type {
0104 equal = 0,
0105 equivalent = equal,
0106 nonequal = 1,
0107 nonequivalent = nonequal,
0108 };
0109
0110 enum class ord : value_type { less = -1, greater = 1 };
0111
0112 enum class ncmp : value_type { unordered = -127 };
0113
0114
0115
0116
0117
0118 #ifdef __cpp_inline_variables
0119
0120
0121 #define ABSL_COMPARE_INLINE_BASECLASS_DECL(name) static_assert(true, "")
0122
0123 #define ABSL_COMPARE_INLINE_SUBCLASS_DECL(type, name) \
0124 static const type name
0125
0126 #define ABSL_COMPARE_INLINE_INIT(type, name, init) \
0127 inline constexpr type type::name(init)
0128
0129 #else
0130
0131 #define ABSL_COMPARE_INLINE_BASECLASS_DECL(name) \
0132 ABSL_CONST_INIT static const T name
0133
0134
0135 #define ABSL_COMPARE_INLINE_SUBCLASS_DECL(type, name) static_assert(true, "")
0136
0137 #define ABSL_COMPARE_INLINE_INIT(type, name, init) \
0138 template <typename T> \
0139 const T compare_internal::type##_base<T>::name(init)
0140
0141 #endif
0142
0143
0144
0145
0146 template <typename T>
0147 struct partial_ordering_base {
0148 ABSL_COMPARE_INLINE_BASECLASS_DECL(less);
0149 ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
0150 ABSL_COMPARE_INLINE_BASECLASS_DECL(greater);
0151 ABSL_COMPARE_INLINE_BASECLASS_DECL(unordered);
0152 };
0153
0154 template <typename T>
0155 struct weak_ordering_base {
0156 ABSL_COMPARE_INLINE_BASECLASS_DECL(less);
0157 ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
0158 ABSL_COMPARE_INLINE_BASECLASS_DECL(greater);
0159 };
0160
0161 template <typename T>
0162 struct strong_ordering_base {
0163 ABSL_COMPARE_INLINE_BASECLASS_DECL(less);
0164 ABSL_COMPARE_INLINE_BASECLASS_DECL(equal);
0165 ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
0166 ABSL_COMPARE_INLINE_BASECLASS_DECL(greater);
0167 };
0168
0169 }
0170
0171 class partial_ordering
0172 : public compare_internal::partial_ordering_base<partial_ordering> {
0173 explicit constexpr partial_ordering(compare_internal::eq v) noexcept
0174 : value_(static_cast<compare_internal::value_type>(v)) {}
0175 explicit constexpr partial_ordering(compare_internal::ord v) noexcept
0176 : value_(static_cast<compare_internal::value_type>(v)) {}
0177 explicit constexpr partial_ordering(compare_internal::ncmp v) noexcept
0178 : value_(static_cast<compare_internal::value_type>(v)) {}
0179 friend struct compare_internal::partial_ordering_base<partial_ordering>;
0180
0181 constexpr bool is_ordered() const noexcept {
0182 return value_ !=
0183 compare_internal::value_type(compare_internal::ncmp::unordered);
0184 }
0185
0186 public:
0187 ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, less);
0188 ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, equivalent);
0189 ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, greater);
0190 ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, unordered);
0191
0192
0193 friend constexpr bool operator==(
0194 partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0195 return v.is_ordered() && v.value_ == 0;
0196 }
0197 friend constexpr bool operator!=(
0198 partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0199 return !v.is_ordered() || v.value_ != 0;
0200 }
0201 friend constexpr bool operator<(
0202 partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0203 return v.is_ordered() && v.value_ < 0;
0204 }
0205 friend constexpr bool operator<=(
0206 partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0207 return v.is_ordered() && v.value_ <= 0;
0208 }
0209 friend constexpr bool operator>(
0210 partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0211 return v.is_ordered() && v.value_ > 0;
0212 }
0213 friend constexpr bool operator>=(
0214 partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0215 return v.is_ordered() && v.value_ >= 0;
0216 }
0217 friend constexpr bool operator==(compare_internal::OnlyLiteralZero,
0218 partial_ordering v) noexcept {
0219 return v.is_ordered() && 0 == v.value_;
0220 }
0221 friend constexpr bool operator!=(compare_internal::OnlyLiteralZero,
0222 partial_ordering v) noexcept {
0223 return !v.is_ordered() || 0 != v.value_;
0224 }
0225 friend constexpr bool operator<(compare_internal::OnlyLiteralZero,
0226 partial_ordering v) noexcept {
0227 return v.is_ordered() && 0 < v.value_;
0228 }
0229 friend constexpr bool operator<=(compare_internal::OnlyLiteralZero,
0230 partial_ordering v) noexcept {
0231 return v.is_ordered() && 0 <= v.value_;
0232 }
0233 friend constexpr bool operator>(compare_internal::OnlyLiteralZero,
0234 partial_ordering v) noexcept {
0235 return v.is_ordered() && 0 > v.value_;
0236 }
0237 friend constexpr bool operator>=(compare_internal::OnlyLiteralZero,
0238 partial_ordering v) noexcept {
0239 return v.is_ordered() && 0 >= v.value_;
0240 }
0241 friend constexpr bool operator==(partial_ordering v1,
0242 partial_ordering v2) noexcept {
0243 return v1.value_ == v2.value_;
0244 }
0245 friend constexpr bool operator!=(partial_ordering v1,
0246 partial_ordering v2) noexcept {
0247 return v1.value_ != v2.value_;
0248 }
0249
0250 private:
0251 compare_internal::value_type value_;
0252 };
0253 ABSL_COMPARE_INLINE_INIT(partial_ordering, less, compare_internal::ord::less);
0254 ABSL_COMPARE_INLINE_INIT(partial_ordering, equivalent,
0255 compare_internal::eq::equivalent);
0256 ABSL_COMPARE_INLINE_INIT(partial_ordering, greater,
0257 compare_internal::ord::greater);
0258 ABSL_COMPARE_INLINE_INIT(partial_ordering, unordered,
0259 compare_internal::ncmp::unordered);
0260
0261 class weak_ordering
0262 : public compare_internal::weak_ordering_base<weak_ordering> {
0263 explicit constexpr weak_ordering(compare_internal::eq v) noexcept
0264 : value_(static_cast<compare_internal::value_type>(v)) {}
0265 explicit constexpr weak_ordering(compare_internal::ord v) noexcept
0266 : value_(static_cast<compare_internal::value_type>(v)) {}
0267 friend struct compare_internal::weak_ordering_base<weak_ordering>;
0268
0269 public:
0270 ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, less);
0271 ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, equivalent);
0272 ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, greater);
0273
0274
0275 constexpr operator partial_ordering() const noexcept {
0276 return value_ == 0 ? partial_ordering::equivalent
0277 : (value_ < 0 ? partial_ordering::less
0278 : partial_ordering::greater);
0279 }
0280
0281 friend constexpr bool operator==(
0282 weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0283 return v.value_ == 0;
0284 }
0285 friend constexpr bool operator!=(
0286 weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0287 return v.value_ != 0;
0288 }
0289 friend constexpr bool operator<(
0290 weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0291 return v.value_ < 0;
0292 }
0293 friend constexpr bool operator<=(
0294 weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0295 return v.value_ <= 0;
0296 }
0297 friend constexpr bool operator>(
0298 weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0299 return v.value_ > 0;
0300 }
0301 friend constexpr bool operator>=(
0302 weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0303 return v.value_ >= 0;
0304 }
0305 friend constexpr bool operator==(compare_internal::OnlyLiteralZero,
0306 weak_ordering v) noexcept {
0307 return 0 == v.value_;
0308 }
0309 friend constexpr bool operator!=(compare_internal::OnlyLiteralZero,
0310 weak_ordering v) noexcept {
0311 return 0 != v.value_;
0312 }
0313 friend constexpr bool operator<(compare_internal::OnlyLiteralZero,
0314 weak_ordering v) noexcept {
0315 return 0 < v.value_;
0316 }
0317 friend constexpr bool operator<=(compare_internal::OnlyLiteralZero,
0318 weak_ordering v) noexcept {
0319 return 0 <= v.value_;
0320 }
0321 friend constexpr bool operator>(compare_internal::OnlyLiteralZero,
0322 weak_ordering v) noexcept {
0323 return 0 > v.value_;
0324 }
0325 friend constexpr bool operator>=(compare_internal::OnlyLiteralZero,
0326 weak_ordering v) noexcept {
0327 return 0 >= v.value_;
0328 }
0329 friend constexpr bool operator==(weak_ordering v1,
0330 weak_ordering v2) noexcept {
0331 return v1.value_ == v2.value_;
0332 }
0333 friend constexpr bool operator!=(weak_ordering v1,
0334 weak_ordering v2) noexcept {
0335 return v1.value_ != v2.value_;
0336 }
0337
0338 private:
0339 compare_internal::value_type value_;
0340 };
0341 ABSL_COMPARE_INLINE_INIT(weak_ordering, less, compare_internal::ord::less);
0342 ABSL_COMPARE_INLINE_INIT(weak_ordering, equivalent,
0343 compare_internal::eq::equivalent);
0344 ABSL_COMPARE_INLINE_INIT(weak_ordering, greater,
0345 compare_internal::ord::greater);
0346
0347 class strong_ordering
0348 : public compare_internal::strong_ordering_base<strong_ordering> {
0349 explicit constexpr strong_ordering(compare_internal::eq v) noexcept
0350 : value_(static_cast<compare_internal::value_type>(v)) {}
0351 explicit constexpr strong_ordering(compare_internal::ord v) noexcept
0352 : value_(static_cast<compare_internal::value_type>(v)) {}
0353 friend struct compare_internal::strong_ordering_base<strong_ordering>;
0354
0355 public:
0356 ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, less);
0357 ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, equal);
0358 ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, equivalent);
0359 ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, greater);
0360
0361
0362 constexpr operator partial_ordering() const noexcept {
0363 return value_ == 0 ? partial_ordering::equivalent
0364 : (value_ < 0 ? partial_ordering::less
0365 : partial_ordering::greater);
0366 }
0367 constexpr operator weak_ordering() const noexcept {
0368 return value_ == 0
0369 ? weak_ordering::equivalent
0370 : (value_ < 0 ? weak_ordering::less : weak_ordering::greater);
0371 }
0372
0373 friend constexpr bool operator==(
0374 strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0375 return v.value_ == 0;
0376 }
0377 friend constexpr bool operator!=(
0378 strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0379 return v.value_ != 0;
0380 }
0381 friend constexpr bool operator<(
0382 strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0383 return v.value_ < 0;
0384 }
0385 friend constexpr bool operator<=(
0386 strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0387 return v.value_ <= 0;
0388 }
0389 friend constexpr bool operator>(
0390 strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0391 return v.value_ > 0;
0392 }
0393 friend constexpr bool operator>=(
0394 strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
0395 return v.value_ >= 0;
0396 }
0397 friend constexpr bool operator==(compare_internal::OnlyLiteralZero,
0398 strong_ordering v) noexcept {
0399 return 0 == v.value_;
0400 }
0401 friend constexpr bool operator!=(compare_internal::OnlyLiteralZero,
0402 strong_ordering v) noexcept {
0403 return 0 != v.value_;
0404 }
0405 friend constexpr bool operator<(compare_internal::OnlyLiteralZero,
0406 strong_ordering v) noexcept {
0407 return 0 < v.value_;
0408 }
0409 friend constexpr bool operator<=(compare_internal::OnlyLiteralZero,
0410 strong_ordering v) noexcept {
0411 return 0 <= v.value_;
0412 }
0413 friend constexpr bool operator>(compare_internal::OnlyLiteralZero,
0414 strong_ordering v) noexcept {
0415 return 0 > v.value_;
0416 }
0417 friend constexpr bool operator>=(compare_internal::OnlyLiteralZero,
0418 strong_ordering v) noexcept {
0419 return 0 >= v.value_;
0420 }
0421 friend constexpr bool operator==(strong_ordering v1,
0422 strong_ordering v2) noexcept {
0423 return v1.value_ == v2.value_;
0424 }
0425 friend constexpr bool operator!=(strong_ordering v1,
0426 strong_ordering v2) noexcept {
0427 return v1.value_ != v2.value_;
0428 }
0429
0430 private:
0431 compare_internal::value_type value_;
0432 };
0433 ABSL_COMPARE_INLINE_INIT(strong_ordering, less, compare_internal::ord::less);
0434 ABSL_COMPARE_INLINE_INIT(strong_ordering, equal, compare_internal::eq::equal);
0435 ABSL_COMPARE_INLINE_INIT(strong_ordering, equivalent,
0436 compare_internal::eq::equivalent);
0437 ABSL_COMPARE_INLINE_INIT(strong_ordering, greater,
0438 compare_internal::ord::greater);
0439
0440 #undef ABSL_COMPARE_INLINE_BASECLASS_DECL
0441 #undef ABSL_COMPARE_INLINE_SUBCLASS_DECL
0442 #undef ABSL_COMPARE_INLINE_INIT
0443
0444 #endif
0445
0446 namespace compare_internal {
0447
0448
0449
0450
0451
0452 template <typename BoolT,
0453 absl::enable_if_t<std::is_same<bool, BoolT>::value, int> = 0>
0454 constexpr bool compare_result_as_less_than(const BoolT r) { return r; }
0455 constexpr bool compare_result_as_less_than(const absl::weak_ordering r) {
0456 return r < 0;
0457 }
0458
0459 template <typename Compare, typename K, typename LK>
0460 constexpr bool do_less_than_comparison(const Compare &compare, const K &x,
0461 const LK &y) {
0462 return compare_result_as_less_than(compare(x, y));
0463 }
0464
0465
0466
0467
0468 template <typename Int,
0469 absl::enable_if_t<std::is_same<int, Int>::value, int> = 0>
0470 constexpr absl::weak_ordering compare_result_as_ordering(const Int c) {
0471 return c < 0 ? absl::weak_ordering::less
0472 : c == 0 ? absl::weak_ordering::equivalent
0473 : absl::weak_ordering::greater;
0474 }
0475 constexpr absl::weak_ordering compare_result_as_ordering(
0476 const absl::weak_ordering c) {
0477 return c;
0478 }
0479
0480 template <
0481 typename Compare, typename K, typename LK,
0482 absl::enable_if_t<!std::is_same<bool, absl::result_of_t<Compare(
0483 const K &, const LK &)>>::value,
0484 int> = 0>
0485 constexpr absl::weak_ordering do_three_way_comparison(const Compare &compare,
0486 const K &x, const LK &y) {
0487 return compare_result_as_ordering(compare(x, y));
0488 }
0489 template <
0490 typename Compare, typename K, typename LK,
0491 absl::enable_if_t<std::is_same<bool, absl::result_of_t<Compare(
0492 const K &, const LK &)>>::value,
0493 int> = 0>
0494 constexpr absl::weak_ordering do_three_way_comparison(const Compare &compare,
0495 const K &x, const LK &y) {
0496 return compare(x, y) ? absl::weak_ordering::less
0497 : compare(y, x) ? absl::weak_ordering::greater
0498 : absl::weak_ordering::equivalent;
0499 }
0500
0501 }
0502 ABSL_NAMESPACE_END
0503 }
0504
0505 #endif