aboutsummaryrefslogtreecommitdiff
path: root/absl/numeric/int128.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/numeric/int128.h')
-rw-r--r--absl/numeric/int128.h31
1 files changed, 31 insertions, 0 deletions
diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h
index a17d0e1b..562d5e58 100644
--- a/absl/numeric/int128.h
+++ b/absl/numeric/int128.h
@@ -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; }