Commit 192e959b by Benjamin Barenblat Committed by Copybara-Service

Add `operator<=>` support to `absl::int128` and `absl::uint128`

PiperOrigin-RevId: 626080616
Change-Id: If434be2371c1e28f9fd0133f411596bdc38bd222
parent 9a61b00d
......@@ -89,6 +89,7 @@ cc_library(
":bits",
"//absl/base:config",
"//absl/base:core_headers",
"//absl/types:compare",
],
)
......@@ -107,6 +108,7 @@ cc_test(
"//absl/hash:hash_testing",
"//absl/meta:type_traits",
"//absl/strings",
"//absl/types:compare",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
......
......@@ -53,6 +53,7 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::compare
absl::config
absl::core_headers
absl::bits
......@@ -70,6 +71,7 @@ absl_cc_test(
DEPS
absl::int128
absl::base
absl::compare
absl::hash_testing
absl::type_traits
absl::strings
......
......@@ -38,6 +38,7 @@
#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/base/port.h"
#include "absl/types/compare.h"
#if defined(_MSC_VER)
// In very old versions of MSVC and when the /Zc:wchar_t flag is off, wchar_t is
......@@ -819,6 +820,36 @@ constexpr bool operator<=(uint128 lhs, uint128 rhs) { return !(rhs < lhs); }
constexpr bool operator>=(uint128 lhs, uint128 rhs) { return !(lhs < rhs); }
#ifdef __cpp_impl_three_way_comparison
constexpr absl::strong_ordering operator<=>(uint128 lhs, uint128 rhs) {
#if defined(ABSL_HAVE_INTRINSIC_INT128)
if (auto lhs_128 = static_cast<unsigned __int128>(lhs),
rhs_128 = static_cast<unsigned __int128>(rhs);
lhs_128 < rhs_128) {
return absl::strong_ordering::less;
} else if (lhs_128 > rhs_128) {
return absl::strong_ordering::greater;
} else {
return absl::strong_ordering::equal;
}
#else
if (uint64_t lhs_high = Uint128High64(lhs), rhs_high = Uint128High64(rhs);
lhs_high < rhs_high) {
return absl::strong_ordering::less;
} else if (lhs_high > rhs_high) {
return absl::strong_ordering::greater;
} else if (uint64_t lhs_low = Uint128Low64(lhs), rhs_low = Uint128Low64(rhs);
lhs_low < rhs_low) {
return absl::strong_ordering::less;
} else if (lhs_low > rhs_low) {
return absl::strong_ordering::greater;
} else {
return absl::strong_ordering::equal;
}
#endif
}
#endif
// Unary operators.
constexpr inline uint128 operator+(uint128 val) { return val; }
......
......@@ -220,6 +220,20 @@ constexpr bool operator>=(int128 lhs, int128 rhs) {
return static_cast<__int128>(lhs) >= static_cast<__int128>(rhs);
}
#ifdef __cpp_impl_three_way_comparison
constexpr absl::strong_ordering operator<=>(int128 lhs, int128 rhs) {
if (auto lhs_128 = static_cast<__int128>(lhs),
rhs_128 = static_cast<__int128>(rhs);
lhs_128 < rhs_128) {
return absl::strong_ordering::less;
} else if (lhs_128 > rhs_128) {
return absl::strong_ordering::greater;
} else {
return absl::strong_ordering::equal;
}
}
#endif
// Unary operators.
constexpr int128 operator-(int128 v) { return -static_cast<__int128>(v); }
......
......@@ -186,6 +186,24 @@ constexpr bool operator<=(int128 lhs, int128 rhs) { return !(lhs > rhs); }
constexpr bool operator>=(int128 lhs, int128 rhs) { return !(lhs < rhs); }
#ifdef __cpp_impl_three_way_comparison
constexpr absl::strong_ordering operator<=>(int128 lhs, int128 rhs) {
if (int64_t lhs_high = Int128High64(lhs), rhs_high = Int128High64(rhs);
lhs_high < rhs_high) {
return absl::strong_ordering::less;
} else if (lhs_high > rhs_high) {
return absl::strong_ordering::greater;
} else if (uint64_t lhs_low = Uint128Low64(lhs), rhs_low = Uint128Low64(rhs);
lhs_low < rhs_low) {
return absl::strong_ordering::less;
} else if (lhs_low > rhs_low) {
return absl::strong_ordering::greater;
} else {
return absl::strong_ordering::equal;
}
}
#endif
// Unary operators.
constexpr int128 operator-(int128 v) {
......
......@@ -25,6 +25,7 @@
#include "absl/base/internal/cycleclock.h"
#include "absl/hash/hash_testing.h"
#include "absl/meta/type_traits.h"
#include "absl/types/compare.h"
#define MAKE_INT128(HI, LO) absl::MakeInt128(static_cast<int64_t>(HI), LO)
......@@ -784,6 +785,13 @@ TEST(Int128, ComparisonTest) {
EXPECT_FALSE(pair.smaller >= pair.larger); // NOLINT(readability/check)
EXPECT_TRUE(pair.smaller >= pair.smaller); // NOLINT(readability/check)
EXPECT_TRUE(pair.larger >= pair.larger); // NOLINT(readability/check)
#ifdef __cpp_impl_three_way_comparison
EXPECT_EQ(pair.smaller <=> pair.larger, absl::strong_ordering::less);
EXPECT_EQ(pair.larger <=> pair.smaller, absl::strong_ordering::greater);
EXPECT_EQ(pair.smaller <=> pair.smaller, absl::strong_ordering::equal);
EXPECT_EQ(pair.larger <=> pair.larger, absl::strong_ordering::equal);
#endif
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment