File indexing completed on 2025-10-30 08:09:28
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 #ifndef ABSL_NUMERIC_INT128_H_
0027 #define ABSL_NUMERIC_INT128_H_
0028 
0029 #include <cassert>
0030 #include <cmath>
0031 #include <cstdint>
0032 #include <cstring>
0033 #include <iosfwd>
0034 #include <limits>
0035 #include <string>
0036 #include <utility>
0037 
0038 #include "absl/base/config.h"
0039 #include "absl/base/macros.h"
0040 #include "absl/base/port.h"
0041 #include "absl/types/compare.h"
0042 
0043 #if defined(_MSC_VER)
0044 
0045 
0046 
0047 
0048 #define ABSL_INTERNAL_WCHAR_T __wchar_t
0049 #if defined(_M_X64) && !defined(_M_ARM64EC)
0050 #include <intrin.h>
0051 #pragma intrinsic(_umul128)
0052 #endif  
0053 #else   
0054 #define ABSL_INTERNAL_WCHAR_T wchar_t
0055 #endif  
0056 
0057 namespace absl {
0058 ABSL_NAMESPACE_BEGIN
0059 
0060 class int128;
0061 
0062 
0063 
0064 
0065 
0066 
0067 
0068 
0069 
0070 
0071 
0072 
0073 
0074 
0075 
0076 
0077 
0078 
0079 
0080 
0081 
0082 
0083 
0084 
0085 
0086 
0087 
0088 
0089 
0090 
0091 
0092 
0093 
0094 
0095 
0096 
0097 
0098 
0099 
0100 
0101 
0102 
0103 
0104 
0105 
0106 class
0107 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0108     alignas(unsigned __int128)
0109 #endif  
0110         uint128 {
0111  public:
0112   uint128() = default;
0113 
0114   
0115   constexpr uint128(int v);                 
0116   constexpr uint128(unsigned int v);        
0117   constexpr uint128(long v);                
0118   constexpr uint128(unsigned long v);       
0119   constexpr uint128(long long v);           
0120   constexpr uint128(unsigned long long v);  
0121 #ifdef ABSL_HAVE_INTRINSIC_INT128
0122   constexpr uint128(__int128 v);           
0123   constexpr uint128(unsigned __int128 v);  
0124 #endif                                     
0125   constexpr uint128(int128 v);             
0126   explicit uint128(float v);
0127   explicit uint128(double v);
0128   explicit uint128(long double v);
0129 
0130   
0131   uint128& operator=(int v);
0132   uint128& operator=(unsigned int v);
0133   uint128& operator=(long v);                
0134   uint128& operator=(unsigned long v);       
0135   uint128& operator=(long long v);           
0136   uint128& operator=(unsigned long long v);  
0137 #ifdef ABSL_HAVE_INTRINSIC_INT128
0138   uint128& operator=(__int128 v);
0139   uint128& operator=(unsigned __int128 v);
0140 #endif  
0141   uint128& operator=(int128 v);
0142 
0143   
0144   constexpr explicit operator bool() const;
0145   constexpr explicit operator char() const;
0146   constexpr explicit operator signed char() const;
0147   constexpr explicit operator unsigned char() const;
0148   constexpr explicit operator char16_t() const;
0149   constexpr explicit operator char32_t() const;
0150   constexpr explicit operator ABSL_INTERNAL_WCHAR_T() const;
0151   constexpr explicit operator short() const;  
0152   
0153   constexpr explicit operator unsigned short() const;
0154   constexpr explicit operator int() const;
0155   constexpr explicit operator unsigned int() const;
0156   constexpr explicit operator long() const;  
0157   
0158   constexpr explicit operator unsigned long() const;
0159   
0160   constexpr explicit operator long long() const;
0161   
0162   constexpr explicit operator unsigned long long() const;
0163 #ifdef ABSL_HAVE_INTRINSIC_INT128
0164   constexpr explicit operator __int128() const;
0165   constexpr explicit operator unsigned __int128() const;
0166 #endif  
0167   explicit operator float() const;
0168   explicit operator double() const;
0169   explicit operator long double() const;
0170 
0171   
0172 
0173   
0174   uint128& operator+=(uint128 other);
0175   uint128& operator-=(uint128 other);
0176   uint128& operator*=(uint128 other);
0177   
0178   uint128& operator/=(uint128 other);
0179   uint128& operator%=(uint128 other);
0180   uint128 operator++(int);
0181   uint128 operator--(int);
0182   uint128& operator<<=(int);
0183   uint128& operator>>=(int);
0184   uint128& operator&=(uint128 other);
0185   uint128& operator|=(uint128 other);
0186   uint128& operator^=(uint128 other);
0187   uint128& operator++();
0188   uint128& operator--();
0189 
0190   
0191   
0192   
0193   friend constexpr uint64_t Uint128Low64(uint128 v);
0194 
0195   
0196   
0197   
0198   friend constexpr uint64_t Uint128High64(uint128 v);
0199 
0200   
0201   
0202   
0203   
0204   
0205   
0206   
0207   
0208   
0209   friend constexpr uint128 MakeUint128(uint64_t high, uint64_t low);
0210 
0211   
0212   
0213   
0214   friend constexpr uint128 Uint128Max();
0215 
0216   
0217   template <typename H>
0218   friend H AbslHashValue(H h, uint128 v) {
0219     return H::combine(std::move(h), Uint128High64(v), Uint128Low64(v));
0220   }
0221 
0222   
0223   template <typename Sink>
0224   friend void AbslStringify(Sink& sink, uint128 v) {
0225     sink.Append(v.ToString());
0226   }
0227 
0228  private:
0229   constexpr uint128(uint64_t high, uint64_t low);
0230 
0231   std::string ToString() const;
0232 
0233   
0234   
0235   
0236   
0237 #if defined(ABSL_IS_LITTLE_ENDIAN)
0238   uint64_t lo_;
0239   uint64_t hi_;
0240 #elif defined(ABSL_IS_BIG_ENDIAN)
0241   uint64_t hi_;
0242   uint64_t lo_;
0243 #else  
0244 #error "Unsupported byte order: must be little-endian or big-endian."
0245 #endif  
0246 };
0247 
0248 
0249 std::ostream& operator<<(std::ostream& os, uint128 v);
0250 
0251 
0252 
0253 constexpr uint128 Uint128Max() {
0254   return uint128((std::numeric_limits<uint64_t>::max)(),
0255                  (std::numeric_limits<uint64_t>::max)());
0256 }
0257 
0258 ABSL_NAMESPACE_END
0259 }  
0260 
0261 
0262 namespace std {
0263 template <>
0264 class numeric_limits<absl::uint128> {
0265  public:
0266   static constexpr bool is_specialized = true;
0267   static constexpr bool is_signed = false;
0268   static constexpr bool is_integer = true;
0269   static constexpr bool is_exact = true;
0270   static constexpr bool has_infinity = false;
0271   static constexpr bool has_quiet_NaN = false;
0272   static constexpr bool has_signaling_NaN = false;
0273   ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
0274   static constexpr float_denorm_style has_denorm = denorm_absent;
0275   ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
0276   static constexpr bool has_denorm_loss = false;
0277   static constexpr float_round_style round_style = round_toward_zero;
0278   static constexpr bool is_iec559 = false;
0279   static constexpr bool is_bounded = true;
0280   static constexpr bool is_modulo = true;
0281   static constexpr int digits = 128;
0282   static constexpr int digits10 = 38;
0283   static constexpr int max_digits10 = 0;
0284   static constexpr int radix = 2;
0285   static constexpr int min_exponent = 0;
0286   static constexpr int min_exponent10 = 0;
0287   static constexpr int max_exponent = 0;
0288   static constexpr int max_exponent10 = 0;
0289 #ifdef ABSL_HAVE_INTRINSIC_INT128
0290   static constexpr bool traps = numeric_limits<unsigned __int128>::traps;
0291 #else   
0292   static constexpr bool traps = numeric_limits<uint64_t>::traps;
0293 #endif  
0294   static constexpr bool tinyness_before = false;
0295 
0296   static constexpr absl::uint128(min)() { return 0; }
0297   static constexpr absl::uint128 lowest() { return 0; }
0298   static constexpr absl::uint128(max)() { return absl::Uint128Max(); }
0299   static constexpr absl::uint128 epsilon() { return 0; }
0300   static constexpr absl::uint128 round_error() { return 0; }
0301   static constexpr absl::uint128 infinity() { return 0; }
0302   static constexpr absl::uint128 quiet_NaN() { return 0; }
0303   static constexpr absl::uint128 signaling_NaN() { return 0; }
0304   static constexpr absl::uint128 denorm_min() { return 0; }
0305 };
0306 }  
0307 
0308 namespace absl {
0309 ABSL_NAMESPACE_BEGIN
0310 
0311 
0312 
0313 
0314 
0315 
0316 
0317 
0318 
0319 
0320 
0321 
0322 
0323 
0324 
0325 
0326 
0327 
0328 
0329 
0330 
0331 
0332 
0333 
0334 
0335 
0336 
0337 
0338 
0339 
0340 
0341 
0342 
0343 
0344 
0345 class int128 {
0346  public:
0347   int128() = default;
0348 
0349   
0350   constexpr int128(int v);                 
0351   constexpr int128(unsigned int v);        
0352   constexpr int128(long v);                
0353   constexpr int128(unsigned long v);       
0354   constexpr int128(long long v);           
0355   constexpr int128(unsigned long long v);  
0356 #ifdef ABSL_HAVE_INTRINSIC_INT128
0357   constexpr int128(__int128 v);  
0358   constexpr explicit int128(unsigned __int128 v);
0359 #endif  
0360   constexpr explicit int128(uint128 v);
0361   explicit int128(float v);
0362   explicit int128(double v);
0363   explicit int128(long double v);
0364 
0365   
0366   int128& operator=(int v);
0367   int128& operator=(unsigned int v);
0368   int128& operator=(long v);                
0369   int128& operator=(unsigned long v);       
0370   int128& operator=(long long v);           
0371   int128& operator=(unsigned long long v);  
0372 #ifdef ABSL_HAVE_INTRINSIC_INT128
0373   int128& operator=(__int128 v);
0374 #endif  
0375 
0376   
0377   constexpr explicit operator bool() const;
0378   constexpr explicit operator char() const;
0379   constexpr explicit operator signed char() const;
0380   constexpr explicit operator unsigned char() const;
0381   constexpr explicit operator char16_t() const;
0382   constexpr explicit operator char32_t() const;
0383   constexpr explicit operator ABSL_INTERNAL_WCHAR_T() const;
0384   constexpr explicit operator short() const;  
0385   
0386   constexpr explicit operator unsigned short() const;
0387   constexpr explicit operator int() const;
0388   constexpr explicit operator unsigned int() const;
0389   constexpr explicit operator long() const;  
0390   
0391   constexpr explicit operator unsigned long() const;
0392   
0393   constexpr explicit operator long long() const;
0394   
0395   constexpr explicit operator unsigned long long() const;
0396 #ifdef ABSL_HAVE_INTRINSIC_INT128
0397   constexpr explicit operator __int128() const;
0398   constexpr explicit operator unsigned __int128() const;
0399 #endif  
0400   explicit operator float() const;
0401   explicit operator double() const;
0402   explicit operator long double() const;
0403 
0404   
0405 
0406   
0407   int128& operator+=(int128 other);
0408   int128& operator-=(int128 other);
0409   int128& operator*=(int128 other);
0410   int128& operator/=(int128 other);
0411   int128& operator%=(int128 other);
0412   int128 operator++(int);  
0413   int128 operator--(int);  
0414   int128& operator++();    
0415   int128& operator--();    
0416   int128& operator&=(int128 other);
0417   int128& operator|=(int128 other);
0418   int128& operator^=(int128 other);
0419   int128& operator<<=(int amount);
0420   int128& operator>>=(int amount);
0421 
0422   
0423   
0424   
0425   friend constexpr uint64_t Int128Low64(int128 v);
0426 
0427   
0428   
0429   
0430   friend constexpr int64_t Int128High64(int128 v);
0431 
0432   
0433   
0434   
0435   
0436   
0437   
0438   
0439   
0440   
0441   
0442   
0443   
0444   
0445   
0446   friend constexpr int128 MakeInt128(int64_t high, uint64_t low);
0447 
0448   
0449   
0450   
0451   friend constexpr int128 Int128Max();
0452 
0453   
0454   
0455   
0456   friend constexpr int128 Int128Min();
0457 
0458   
0459   template <typename H>
0460   friend H AbslHashValue(H h, int128 v) {
0461     return H::combine(std::move(h), Int128High64(v), Int128Low64(v));
0462   }
0463 
0464   
0465   template <typename Sink>
0466   friend void AbslStringify(Sink& sink, int128 v) {
0467     sink.Append(v.ToString());
0468   }
0469 
0470  private:
0471   constexpr int128(int64_t high, uint64_t low);
0472 
0473   std::string ToString() const;
0474 
0475 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0476   __int128 v_;
0477 #else  
0478 #if defined(ABSL_IS_LITTLE_ENDIAN)
0479   uint64_t lo_;
0480   int64_t hi_;
0481 #elif defined(ABSL_IS_BIG_ENDIAN)
0482   int64_t hi_;
0483   uint64_t lo_;
0484 #else  
0485 #error "Unsupported byte order: must be little-endian or big-endian."
0486 #endif  
0487 #endif  
0488 };
0489 
0490 std::ostream& operator<<(std::ostream& os, int128 v);
0491 
0492 
0493 
0494 constexpr int128 Int128Max() {
0495   return int128((std::numeric_limits<int64_t>::max)(),
0496                 (std::numeric_limits<uint64_t>::max)());
0497 }
0498 
0499 constexpr int128 Int128Min() {
0500   return int128((std::numeric_limits<int64_t>::min)(), 0);
0501 }
0502 
0503 ABSL_NAMESPACE_END
0504 }  
0505 
0506 
0507 namespace std {
0508 template <>
0509 class numeric_limits<absl::int128> {
0510  public:
0511   static constexpr bool is_specialized = true;
0512   static constexpr bool is_signed = true;
0513   static constexpr bool is_integer = true;
0514   static constexpr bool is_exact = true;
0515   static constexpr bool has_infinity = false;
0516   static constexpr bool has_quiet_NaN = false;
0517   static constexpr bool has_signaling_NaN = false;
0518   ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
0519   static constexpr float_denorm_style has_denorm = denorm_absent;
0520   ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
0521   static constexpr bool has_denorm_loss = false;
0522   static constexpr float_round_style round_style = round_toward_zero;
0523   static constexpr bool is_iec559 = false;
0524   static constexpr bool is_bounded = true;
0525   static constexpr bool is_modulo = false;
0526   static constexpr int digits = 127;
0527   static constexpr int digits10 = 38;
0528   static constexpr int max_digits10 = 0;
0529   static constexpr int radix = 2;
0530   static constexpr int min_exponent = 0;
0531   static constexpr int min_exponent10 = 0;
0532   static constexpr int max_exponent = 0;
0533   static constexpr int max_exponent10 = 0;
0534 #ifdef ABSL_HAVE_INTRINSIC_INT128
0535   static constexpr bool traps = numeric_limits<__int128>::traps;
0536 #else   
0537   static constexpr bool traps = numeric_limits<uint64_t>::traps;
0538 #endif  
0539   static constexpr bool tinyness_before = false;
0540 
0541   static constexpr absl::int128(min)() { return absl::Int128Min(); }
0542   static constexpr absl::int128 lowest() { return absl::Int128Min(); }
0543   static constexpr absl::int128(max)() { return absl::Int128Max(); }
0544   static constexpr absl::int128 epsilon() { return 0; }
0545   static constexpr absl::int128 round_error() { return 0; }
0546   static constexpr absl::int128 infinity() { return 0; }
0547   static constexpr absl::int128 quiet_NaN() { return 0; }
0548   static constexpr absl::int128 signaling_NaN() { return 0; }
0549   static constexpr absl::int128 denorm_min() { return 0; }
0550 };
0551 }  
0552 
0553 
0554 
0555 
0556 namespace absl {
0557 ABSL_NAMESPACE_BEGIN
0558 
0559 constexpr uint128 MakeUint128(uint64_t high, uint64_t low) {
0560   return uint128(high, low);
0561 }
0562 
0563 
0564 
0565 inline uint128& uint128::operator=(int v) { return *this = uint128(v); }
0566 
0567 inline uint128& uint128::operator=(unsigned int v) {
0568   return *this = uint128(v);
0569 }
0570 
0571 inline uint128& uint128::operator=(long v) {  
0572   return *this = uint128(v);
0573 }
0574 
0575 
0576 inline uint128& uint128::operator=(unsigned long v) {
0577   return *this = uint128(v);
0578 }
0579 
0580 
0581 inline uint128& uint128::operator=(long long v) { return *this = uint128(v); }
0582 
0583 
0584 inline uint128& uint128::operator=(unsigned long long v) {
0585   return *this = uint128(v);
0586 }
0587 
0588 #ifdef ABSL_HAVE_INTRINSIC_INT128
0589 inline uint128& uint128::operator=(__int128 v) { return *this = uint128(v); }
0590 
0591 inline uint128& uint128::operator=(unsigned __int128 v) {
0592   return *this = uint128(v);
0593 }
0594 #endif  
0595 
0596 inline uint128& uint128::operator=(int128 v) { return *this = uint128(v); }
0597 
0598 
0599 
0600 constexpr uint128 operator<<(uint128 lhs, int amount);
0601 constexpr uint128 operator>>(uint128 lhs, int amount);
0602 constexpr uint128 operator+(uint128 lhs, uint128 rhs);
0603 constexpr uint128 operator-(uint128 lhs, uint128 rhs);
0604 uint128 operator*(uint128 lhs, uint128 rhs);
0605 uint128 operator/(uint128 lhs, uint128 rhs);
0606 uint128 operator%(uint128 lhs, uint128 rhs);
0607 
0608 inline uint128& uint128::operator<<=(int amount) {
0609   *this = *this << amount;
0610   return *this;
0611 }
0612 
0613 inline uint128& uint128::operator>>=(int amount) {
0614   *this = *this >> amount;
0615   return *this;
0616 }
0617 
0618 inline uint128& uint128::operator+=(uint128 other) {
0619   *this = *this + other;
0620   return *this;
0621 }
0622 
0623 inline uint128& uint128::operator-=(uint128 other) {
0624   *this = *this - other;
0625   return *this;
0626 }
0627 
0628 inline uint128& uint128::operator*=(uint128 other) {
0629   *this = *this * other;
0630   return *this;
0631 }
0632 
0633 inline uint128& uint128::operator/=(uint128 other) {
0634   *this = *this / other;
0635   return *this;
0636 }
0637 
0638 inline uint128& uint128::operator%=(uint128 other) {
0639   *this = *this % other;
0640   return *this;
0641 }
0642 
0643 constexpr uint64_t Uint128Low64(uint128 v) { return v.lo_; }
0644 
0645 constexpr uint64_t Uint128High64(uint128 v) { return v.hi_; }
0646 
0647 
0648 
0649 #if defined(ABSL_IS_LITTLE_ENDIAN)
0650 
0651 constexpr uint128::uint128(uint64_t high, uint64_t low) : lo_{low}, hi_{high} {}
0652 
0653 constexpr uint128::uint128(int v)
0654     : lo_{static_cast<uint64_t>(v)},
0655       hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {}
0656 constexpr uint128::uint128(long v)  
0657     : lo_{static_cast<uint64_t>(v)},
0658       hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {}
0659 constexpr uint128::uint128(long long v)  
0660     : lo_{static_cast<uint64_t>(v)},
0661       hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {}
0662 
0663 constexpr uint128::uint128(unsigned int v) : lo_{v}, hi_{0} {}
0664 
0665 constexpr uint128::uint128(unsigned long v) : lo_{v}, hi_{0} {}
0666 
0667 constexpr uint128::uint128(unsigned long long v) : lo_{v}, hi_{0} {}
0668 
0669 #ifdef ABSL_HAVE_INTRINSIC_INT128
0670 constexpr uint128::uint128(__int128 v)
0671     : lo_{static_cast<uint64_t>(v & ~uint64_t{0})},
0672       hi_{static_cast<uint64_t>(static_cast<unsigned __int128>(v) >> 64)} {}
0673 constexpr uint128::uint128(unsigned __int128 v)
0674     : lo_{static_cast<uint64_t>(v & ~uint64_t{0})},
0675       hi_{static_cast<uint64_t>(v >> 64)} {}
0676 #endif  
0677 
0678 constexpr uint128::uint128(int128 v)
0679     : lo_{Int128Low64(v)}, hi_{static_cast<uint64_t>(Int128High64(v))} {}
0680 
0681 #elif defined(ABSL_IS_BIG_ENDIAN)
0682 
0683 constexpr uint128::uint128(uint64_t high, uint64_t low) : hi_{high}, lo_{low} {}
0684 
0685 constexpr uint128::uint128(int v)
0686     : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0},
0687       lo_{static_cast<uint64_t>(v)} {}
0688 constexpr uint128::uint128(long v)  
0689     : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0},
0690       lo_{static_cast<uint64_t>(v)} {}
0691 constexpr uint128::uint128(long long v)  
0692     : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0},
0693       lo_{static_cast<uint64_t>(v)} {}
0694 
0695 constexpr uint128::uint128(unsigned int v) : hi_{0}, lo_{v} {}
0696 
0697 constexpr uint128::uint128(unsigned long v) : hi_{0}, lo_{v} {}
0698 
0699 constexpr uint128::uint128(unsigned long long v) : hi_{0}, lo_{v} {}
0700 
0701 #ifdef ABSL_HAVE_INTRINSIC_INT128
0702 constexpr uint128::uint128(__int128 v)
0703     : hi_{static_cast<uint64_t>(static_cast<unsigned __int128>(v) >> 64)},
0704       lo_{static_cast<uint64_t>(v & ~uint64_t{0})} {}
0705 constexpr uint128::uint128(unsigned __int128 v)
0706     : hi_{static_cast<uint64_t>(v >> 64)},
0707       lo_{static_cast<uint64_t>(v & ~uint64_t{0})} {}
0708 #endif  
0709 
0710 constexpr uint128::uint128(int128 v)
0711     : hi_{static_cast<uint64_t>(Int128High64(v))}, lo_{Int128Low64(v)} {}
0712 
0713 #else  
0714 #error "Unsupported byte order: must be little-endian or big-endian."
0715 #endif  
0716 
0717 
0718 
0719 constexpr uint128::operator bool() const { return lo_ || hi_; }
0720 
0721 constexpr uint128::operator char() const { return static_cast<char>(lo_); }
0722 
0723 constexpr uint128::operator signed char() const {
0724   return static_cast<signed char>(lo_);
0725 }
0726 
0727 constexpr uint128::operator unsigned char() const {
0728   return static_cast<unsigned char>(lo_);
0729 }
0730 
0731 constexpr uint128::operator char16_t() const {
0732   return static_cast<char16_t>(lo_);
0733 }
0734 
0735 constexpr uint128::operator char32_t() const {
0736   return static_cast<char32_t>(lo_);
0737 }
0738 
0739 constexpr uint128::operator ABSL_INTERNAL_WCHAR_T() const {
0740   return static_cast<ABSL_INTERNAL_WCHAR_T>(lo_);
0741 }
0742 
0743 
0744 constexpr uint128::operator short() const { return static_cast<short>(lo_); }
0745 
0746 constexpr uint128::operator unsigned short() const {  
0747   return static_cast<unsigned short>(lo_);            
0748 }
0749 
0750 constexpr uint128::operator int() const { return static_cast<int>(lo_); }
0751 
0752 constexpr uint128::operator unsigned int() const {
0753   return static_cast<unsigned int>(lo_);
0754 }
0755 
0756 
0757 constexpr uint128::operator long() const { return static_cast<long>(lo_); }
0758 
0759 constexpr uint128::operator unsigned long() const {  
0760   return static_cast<unsigned long>(lo_);            
0761 }
0762 
0763 constexpr uint128::operator long long() const {  
0764   return static_cast<long long>(lo_);            
0765 }
0766 
0767 constexpr uint128::operator unsigned long long() const {  
0768   return static_cast<unsigned long long>(lo_);            
0769 }
0770 
0771 #ifdef ABSL_HAVE_INTRINSIC_INT128
0772 constexpr uint128::operator __int128() const {
0773   return (static_cast<__int128>(hi_) << 64) + lo_;
0774 }
0775 
0776 constexpr uint128::operator unsigned __int128() const {
0777   return (static_cast<unsigned __int128>(hi_) << 64) + lo_;
0778 }
0779 #endif  
0780 
0781 
0782 
0783 inline uint128::operator float() const {
0784   return static_cast<float>(lo_) + std::ldexp(static_cast<float>(hi_), 64);
0785 }
0786 
0787 inline uint128::operator double() const {
0788   return static_cast<double>(lo_) + std::ldexp(static_cast<double>(hi_), 64);
0789 }
0790 
0791 inline uint128::operator long double() const {
0792   return static_cast<long double>(lo_) +
0793          std::ldexp(static_cast<long double>(hi_), 64);
0794 }
0795 
0796 
0797 
0798 constexpr bool operator==(uint128 lhs, uint128 rhs) {
0799 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0800   return static_cast<unsigned __int128>(lhs) ==
0801          static_cast<unsigned __int128>(rhs);
0802 #else
0803   return (Uint128Low64(lhs) == Uint128Low64(rhs) &&
0804           Uint128High64(lhs) == Uint128High64(rhs));
0805 #endif
0806 }
0807 
0808 constexpr bool operator!=(uint128 lhs, uint128 rhs) { return !(lhs == rhs); }
0809 
0810 constexpr bool operator<(uint128 lhs, uint128 rhs) {
0811 #ifdef ABSL_HAVE_INTRINSIC_INT128
0812   return static_cast<unsigned __int128>(lhs) <
0813          static_cast<unsigned __int128>(rhs);
0814 #else
0815   return (Uint128High64(lhs) == Uint128High64(rhs))
0816              ? (Uint128Low64(lhs) < Uint128Low64(rhs))
0817              : (Uint128High64(lhs) < Uint128High64(rhs));
0818 #endif
0819 }
0820 
0821 constexpr bool operator>(uint128 lhs, uint128 rhs) { return rhs < lhs; }
0822 
0823 constexpr bool operator<=(uint128 lhs, uint128 rhs) { return !(rhs < lhs); }
0824 
0825 constexpr bool operator>=(uint128 lhs, uint128 rhs) { return !(lhs < rhs); }
0826 
0827 #ifdef __cpp_impl_three_way_comparison
0828 constexpr absl::strong_ordering operator<=>(uint128 lhs, uint128 rhs) {
0829 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0830   if (auto lhs_128 = static_cast<unsigned __int128>(lhs),
0831       rhs_128 = static_cast<unsigned __int128>(rhs);
0832       lhs_128 < rhs_128) {
0833     return absl::strong_ordering::less;
0834   } else if (lhs_128 > rhs_128) {
0835     return absl::strong_ordering::greater;
0836   } else {
0837     return absl::strong_ordering::equal;
0838   }
0839 #else
0840   if (uint64_t lhs_high = Uint128High64(lhs), rhs_high = Uint128High64(rhs);
0841       lhs_high < rhs_high) {
0842     return absl::strong_ordering::less;
0843   } else if (lhs_high > rhs_high) {
0844     return absl::strong_ordering::greater;
0845   } else if (uint64_t lhs_low = Uint128Low64(lhs), rhs_low = Uint128Low64(rhs);
0846              lhs_low < rhs_low) {
0847     return absl::strong_ordering::less;
0848   } else if (lhs_low > rhs_low) {
0849     return absl::strong_ordering::greater;
0850   } else {
0851     return absl::strong_ordering::equal;
0852   }
0853 #endif
0854 }
0855 #endif
0856 
0857 
0858 
0859 constexpr inline uint128 operator+(uint128 val) { return val; }
0860 
0861 constexpr inline int128 operator+(int128 val) { return val; }
0862 
0863 constexpr uint128 operator-(uint128 val) {
0864 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0865   return -static_cast<unsigned __int128>(val);
0866 #else
0867   return MakeUint128(
0868       ~Uint128High64(val) + static_cast<unsigned long>(Uint128Low64(val) == 0),
0869       ~Uint128Low64(val) + 1);
0870 #endif
0871 }
0872 
0873 constexpr inline bool operator!(uint128 val) {
0874 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0875   return !static_cast<unsigned __int128>(val);
0876 #else
0877   return !Uint128High64(val) && !Uint128Low64(val);
0878 #endif
0879 }
0880 
0881 
0882 
0883 constexpr inline uint128 operator~(uint128 val) {
0884 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0885   return ~static_cast<unsigned __int128>(val);
0886 #else
0887   return MakeUint128(~Uint128High64(val), ~Uint128Low64(val));
0888 #endif
0889 }
0890 
0891 constexpr inline uint128 operator|(uint128 lhs, uint128 rhs) {
0892 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0893   return static_cast<unsigned __int128>(lhs) |
0894          static_cast<unsigned __int128>(rhs);
0895 #else
0896   return MakeUint128(Uint128High64(lhs) | Uint128High64(rhs),
0897                      Uint128Low64(lhs) | Uint128Low64(rhs));
0898 #endif
0899 }
0900 
0901 constexpr inline uint128 operator&(uint128 lhs, uint128 rhs) {
0902 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0903   return static_cast<unsigned __int128>(lhs) &
0904          static_cast<unsigned __int128>(rhs);
0905 #else
0906   return MakeUint128(Uint128High64(lhs) & Uint128High64(rhs),
0907                      Uint128Low64(lhs) & Uint128Low64(rhs));
0908 #endif
0909 }
0910 
0911 constexpr inline uint128 operator^(uint128 lhs, uint128 rhs) {
0912 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0913   return static_cast<unsigned __int128>(lhs) ^
0914          static_cast<unsigned __int128>(rhs);
0915 #else
0916   return MakeUint128(Uint128High64(lhs) ^ Uint128High64(rhs),
0917                      Uint128Low64(lhs) ^ Uint128Low64(rhs));
0918 #endif
0919 }
0920 
0921 inline uint128& uint128::operator|=(uint128 other) {
0922   *this = *this | other;
0923   return *this;
0924 }
0925 
0926 inline uint128& uint128::operator&=(uint128 other) {
0927   *this = *this & other;
0928   return *this;
0929 }
0930 
0931 inline uint128& uint128::operator^=(uint128 other) {
0932   *this = *this ^ other;
0933   return *this;
0934 }
0935 
0936 
0937 
0938 constexpr uint128 operator<<(uint128 lhs, int amount) {
0939 #ifdef ABSL_HAVE_INTRINSIC_INT128
0940   return static_cast<unsigned __int128>(lhs) << amount;
0941 #else
0942   
0943   
0944   return amount >= 64  ? MakeUint128(Uint128Low64(lhs) << (amount - 64), 0)
0945          : amount == 0 ? lhs
0946                        : MakeUint128((Uint128High64(lhs) << amount) |
0947                                          (Uint128Low64(lhs) >> (64 - amount)),
0948                                      Uint128Low64(lhs) << amount);
0949 #endif
0950 }
0951 
0952 constexpr uint128 operator>>(uint128 lhs, int amount) {
0953 #ifdef ABSL_HAVE_INTRINSIC_INT128
0954   return static_cast<unsigned __int128>(lhs) >> amount;
0955 #else
0956   
0957   
0958   return amount >= 64  ? MakeUint128(0, Uint128High64(lhs) >> (amount - 64))
0959          : amount == 0 ? lhs
0960                        : MakeUint128(Uint128High64(lhs) >> amount,
0961                                      (Uint128Low64(lhs) >> amount) |
0962                                          (Uint128High64(lhs) << (64 - amount)));
0963 #endif
0964 }
0965 
0966 #if !defined(ABSL_HAVE_INTRINSIC_INT128)
0967 namespace int128_internal {
0968 constexpr uint128 AddResult(uint128 result, uint128 lhs) {
0969   
0970   return (Uint128Low64(result) < Uint128Low64(lhs))
0971              ? MakeUint128(Uint128High64(result) + 1, Uint128Low64(result))
0972              : result;
0973 }
0974 }  
0975 #endif
0976 
0977 constexpr uint128 operator+(uint128 lhs, uint128 rhs) {
0978 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0979   return static_cast<unsigned __int128>(lhs) +
0980          static_cast<unsigned __int128>(rhs);
0981 #else
0982   return int128_internal::AddResult(
0983       MakeUint128(Uint128High64(lhs) + Uint128High64(rhs),
0984                   Uint128Low64(lhs) + Uint128Low64(rhs)),
0985       lhs);
0986 #endif
0987 }
0988 
0989 #if !defined(ABSL_HAVE_INTRINSIC_INT128)
0990 namespace int128_internal {
0991 constexpr uint128 SubstructResult(uint128 result, uint128 lhs, uint128 rhs) {
0992   
0993   return (Uint128Low64(lhs) < Uint128Low64(rhs))
0994              ? MakeUint128(Uint128High64(result) - 1, Uint128Low64(result))
0995              : result;
0996 }
0997 }  
0998 #endif
0999 
1000 constexpr uint128 operator-(uint128 lhs, uint128 rhs) {
1001 #if defined(ABSL_HAVE_INTRINSIC_INT128)
1002   return static_cast<unsigned __int128>(lhs) -
1003          static_cast<unsigned __int128>(rhs);
1004 #else
1005   return int128_internal::SubstructResult(
1006       MakeUint128(Uint128High64(lhs) - Uint128High64(rhs),
1007                   Uint128Low64(lhs) - Uint128Low64(rhs)),
1008       lhs, rhs);
1009 #endif
1010 }
1011 
1012 inline uint128 operator*(uint128 lhs, uint128 rhs) {
1013 #if defined(ABSL_HAVE_INTRINSIC_INT128)
1014   
1015   
1016   return static_cast<unsigned __int128>(lhs) *
1017          static_cast<unsigned __int128>(rhs);
1018 #elif defined(_MSC_VER) && defined(_M_X64) && !defined(_M_ARM64EC)
1019   uint64_t carry;
1020   uint64_t low = _umul128(Uint128Low64(lhs), Uint128Low64(rhs), &carry);
1021   return MakeUint128(Uint128Low64(lhs) * Uint128High64(rhs) +
1022                          Uint128High64(lhs) * Uint128Low64(rhs) + carry,
1023                      low);
1024 #else   
1025   uint64_t a32 = Uint128Low64(lhs) >> 32;
1026   uint64_t a00 = Uint128Low64(lhs) & 0xffffffff;
1027   uint64_t b32 = Uint128Low64(rhs) >> 32;
1028   uint64_t b00 = Uint128Low64(rhs) & 0xffffffff;
1029   uint128 result =
1030       MakeUint128(Uint128High64(lhs) * Uint128Low64(rhs) +
1031                       Uint128Low64(lhs) * Uint128High64(rhs) + a32 * b32,
1032                   a00 * b00);
1033   result += uint128(a32 * b00) << 32;
1034   result += uint128(a00 * b32) << 32;
1035   return result;
1036 #endif  
1037 }
1038 
1039 #if defined(ABSL_HAVE_INTRINSIC_INT128)
1040 inline uint128 operator/(uint128 lhs, uint128 rhs) {
1041   return static_cast<unsigned __int128>(lhs) /
1042          static_cast<unsigned __int128>(rhs);
1043 }
1044 
1045 inline uint128 operator%(uint128 lhs, uint128 rhs) {
1046   return static_cast<unsigned __int128>(lhs) %
1047          static_cast<unsigned __int128>(rhs);
1048 }
1049 #endif
1050 
1051 
1052 
1053 inline uint128 uint128::operator++(int) {
1054   uint128 tmp(*this);
1055   *this += 1;
1056   return tmp;
1057 }
1058 
1059 inline uint128 uint128::operator--(int) {
1060   uint128 tmp(*this);
1061   *this -= 1;
1062   return tmp;
1063 }
1064 
1065 inline uint128& uint128::operator++() {
1066   *this += 1;
1067   return *this;
1068 }
1069 
1070 inline uint128& uint128::operator--() {
1071   *this -= 1;
1072   return *this;
1073 }
1074 
1075 constexpr int128 MakeInt128(int64_t high, uint64_t low) {
1076   return int128(high, low);
1077 }
1078 
1079 
1080 inline int128& int128::operator=(int v) { return *this = int128(v); }
1081 
1082 inline int128& int128::operator=(unsigned int v) { return *this = int128(v); }
1083 
1084 inline int128& int128::operator=(long v) {  
1085   return *this = int128(v);
1086 }
1087 
1088 
1089 inline int128& int128::operator=(unsigned long v) { return *this = int128(v); }
1090 
1091 
1092 inline int128& int128::operator=(long long v) { return *this = int128(v); }
1093 
1094 
1095 inline int128& int128::operator=(unsigned long long v) {
1096   return *this = int128(v);
1097 }
1098 
1099 
1100 constexpr int128 operator-(int128 v);
1101 constexpr int128 operator+(int128 lhs, int128 rhs);
1102 constexpr int128 operator-(int128 lhs, int128 rhs);
1103 int128 operator*(int128 lhs, int128 rhs);
1104 int128 operator/(int128 lhs, int128 rhs);
1105 int128 operator%(int128 lhs, int128 rhs);
1106 constexpr int128 operator|(int128 lhs, int128 rhs);
1107 constexpr int128 operator&(int128 lhs, int128 rhs);
1108 constexpr int128 operator^(int128 lhs, int128 rhs);
1109 constexpr int128 operator<<(int128 lhs, int amount);
1110 constexpr int128 operator>>(int128 lhs, int amount);
1111 
1112 inline int128& int128::operator+=(int128 other) {
1113   *this = *this + other;
1114   return *this;
1115 }
1116 
1117 inline int128& int128::operator-=(int128 other) {
1118   *this = *this - other;
1119   return *this;
1120 }
1121 
1122 inline int128& int128::operator*=(int128 other) {
1123   *this = *this * other;
1124   return *this;
1125 }
1126 
1127 inline int128& int128::operator/=(int128 other) {
1128   *this = *this / other;
1129   return *this;
1130 }
1131 
1132 inline int128& int128::operator%=(int128 other) {
1133   *this = *this % other;
1134   return *this;
1135 }
1136 
1137 inline int128& int128::operator|=(int128 other) {
1138   *this = *this | other;
1139   return *this;
1140 }
1141 
1142 inline int128& int128::operator&=(int128 other) {
1143   *this = *this & other;
1144   return *this;
1145 }
1146 
1147 inline int128& int128::operator^=(int128 other) {
1148   *this = *this ^ other;
1149   return *this;
1150 }
1151 
1152 inline int128& int128::operator<<=(int amount) {
1153   *this = *this << amount;
1154   return *this;
1155 }
1156 
1157 inline int128& int128::operator>>=(int amount) {
1158   *this = *this >> amount;
1159   return *this;
1160 }
1161 
1162 
1163 constexpr bool operator!=(int128 lhs, int128 rhs);
1164 
1165 namespace int128_internal {
1166 
1167 
1168 
1169 constexpr int64_t BitCastToSigned(uint64_t v) {
1170   
1171   
1172   
1173   
1174   
1175   return v & (uint64_t{1} << 63) ? ~static_cast<int64_t>(~v)
1176                                  : static_cast<int64_t>(v);
1177 }
1178 
1179 }  
1180 
1181 #if defined(ABSL_HAVE_INTRINSIC_INT128)
1182 #include "absl/numeric/int128_have_intrinsic.inc"  // IWYU pragma: export
1183 #else  
1184 #include "absl/numeric/int128_no_intrinsic.inc"  // IWYU pragma: export
1185 #endif  
1186 
1187 ABSL_NAMESPACE_END
1188 }  
1189 
1190 #undef ABSL_INTERNAL_WCHAR_T
1191 
1192 #endif