00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 #ifndef ABSL_NUMERIC_INT128_H_
00026 #define ABSL_NUMERIC_INT128_H_
00027 
00028 #include <cassert>
00029 #include <cmath>
00030 #include <cstdint>
00031 #include <cstring>
00032 #include <iosfwd>
00033 #include <limits>
00034 #include <utility>
00035 
00036 #include "absl/base/config.h"
00037 #include "absl/base/macros.h"
00038 #include "absl/base/port.h"
00039 
00040 #if defined(_MSC_VER)
00041 
00042 
00043 
00044 
00045 #define ABSL_INTERNAL_WCHAR_T __wchar_t
00046 #if defined(_M_X64)
00047 #include <intrin.h>
00048 #pragma intrinsic(_umul128)
00049 #endif  // defined(_M_X64)
00050 #else   // defined(_MSC_VER)
00051 #define ABSL_INTERNAL_WCHAR_T wchar_t
00052 #endif  // defined(_MSC_VER)
00053 
00054 namespace absl {
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 class
00101 #if defined(ABSL_HAVE_INTRINSIC_INT128)
00102     alignas(unsigned __int128)
00103 #endif  // ABSL_HAVE_INTRINSIC_INT128
00104         uint128 {
00105  public:
00106   uint128() = default;
00107 
00108   
00109   constexpr uint128(int v);                 
00110   constexpr uint128(unsigned int v);        
00111   constexpr uint128(long v);                
00112   constexpr uint128(unsigned long v);       
00113   constexpr uint128(long long v);           
00114   constexpr uint128(unsigned long long v);  
00115 #ifdef ABSL_HAVE_INTRINSIC_INT128
00116   constexpr uint128(__int128 v);           
00117   constexpr uint128(unsigned __int128 v);  
00118 #endif  // ABSL_HAVE_INTRINSIC_INT128
00119   explicit uint128(float v);
00120   explicit uint128(double v);
00121   explicit uint128(long double v);
00122 
00123   
00124   uint128& operator=(int v);
00125   uint128& operator=(unsigned int v);
00126   uint128& operator=(long v);                
00127   uint128& operator=(unsigned long v);       
00128   uint128& operator=(long long v);           
00129   uint128& operator=(unsigned long long v);  
00130 #ifdef ABSL_HAVE_INTRINSIC_INT128
00131   uint128& operator=(__int128 v);
00132   uint128& operator=(unsigned __int128 v);
00133 #endif  // ABSL_HAVE_INTRINSIC_INT128
00134 
00135   
00136   constexpr explicit operator bool() const;
00137   constexpr explicit operator char() const;
00138   constexpr explicit operator signed char() const;
00139   constexpr explicit operator unsigned char() const;
00140   constexpr explicit operator char16_t() const;
00141   constexpr explicit operator char32_t() const;
00142   constexpr explicit operator ABSL_INTERNAL_WCHAR_T() const;
00143   constexpr explicit operator short() const;  
00144   
00145   constexpr explicit operator unsigned short() const;
00146   constexpr explicit operator int() const;
00147   constexpr explicit operator unsigned int() const;
00148   constexpr explicit operator long() const;  
00149   
00150   constexpr explicit operator unsigned long() const;
00151   
00152   constexpr explicit operator long long() const;
00153   
00154   constexpr explicit operator unsigned long long() const;
00155 #ifdef ABSL_HAVE_INTRINSIC_INT128
00156   constexpr explicit operator __int128() const;
00157   constexpr explicit operator unsigned __int128() const;
00158 #endif  // ABSL_HAVE_INTRINSIC_INT128
00159   explicit operator float() const;
00160   explicit operator double() const;
00161   explicit operator long double() const;
00162 
00163   
00164 
00165   
00166   uint128& operator+=(uint128 other);
00167   uint128& operator-=(uint128 other);
00168   uint128& operator*=(uint128 other);
00169   
00170   uint128& operator/=(uint128 other);
00171   uint128& operator%=(uint128 other);
00172   uint128 operator++(int);
00173   uint128 operator--(int);
00174   uint128& operator<<=(int);
00175   uint128& operator>>=(int);
00176   uint128& operator&=(uint128 other);
00177   uint128& operator|=(uint128 other);
00178   uint128& operator^=(uint128 other);
00179   uint128& operator++();
00180   uint128& operator--();
00181 
00182   
00183   
00184   
00185   friend constexpr uint64_t Uint128Low64(uint128 v);
00186 
00187   
00188   
00189   
00190   friend constexpr uint64_t Uint128High64(uint128 v);
00191 
00192   
00193   
00194   
00195   
00196   
00197   
00198   
00199   
00200   
00201   friend constexpr uint128 MakeUint128(uint64_t high, uint64_t low);
00202 
00203   
00204   
00205   
00206   friend constexpr uint128 Uint128Max();
00207 
00208   
00209   template <typename H>
00210   friend H AbslHashValue(H h, uint128 v) {
00211     return H::combine(std::move(h), Uint128High64(v), Uint128Low64(v));
00212   }
00213 
00214  private:
00215   constexpr uint128(uint64_t high, uint64_t low);
00216 
00217   
00218   
00219   
00220   
00221 #if defined(ABSL_IS_LITTLE_ENDIAN)
00222   uint64_t lo_;
00223   uint64_t hi_;
00224 #elif defined(ABSL_IS_BIG_ENDIAN)
00225   uint64_t hi_;
00226   uint64_t lo_;
00227 #else  // byte order
00228 #error "Unsupported byte order: must be little-endian or big-endian."
00229 #endif  // byte order
00230 };
00231 
00232 
00233 
00234 
00235 extern const uint128 kuint128max;
00236 
00237 
00238 std::ostream& operator<<(std::ostream& os, uint128 v);
00239 
00240 
00241 
00242 constexpr uint128 Uint128Max() {
00243   return uint128((std::numeric_limits<uint64_t>::max)(),
00244                  (std::numeric_limits<uint64_t>::max)());
00245 }
00246 
00247 }  
00248 
00249 
00250 namespace std {
00251 template <>
00252 class numeric_limits<absl::uint128> {
00253  public:
00254   static constexpr bool is_specialized = true;
00255   static constexpr bool is_signed = false;
00256   static constexpr bool is_integer = true;
00257   static constexpr bool is_exact = true;
00258   static constexpr bool has_infinity = false;
00259   static constexpr bool has_quiet_NaN = false;
00260   static constexpr bool has_signaling_NaN = false;
00261   static constexpr float_denorm_style has_denorm = denorm_absent;
00262   static constexpr bool has_denorm_loss = false;
00263   static constexpr float_round_style round_style = round_toward_zero;
00264   static constexpr bool is_iec559 = false;
00265   static constexpr bool is_bounded = true;
00266   static constexpr bool is_modulo = true;
00267   static constexpr int digits = 128;
00268   static constexpr int digits10 = 38;
00269   static constexpr int max_digits10 = 0;
00270   static constexpr int radix = 2;
00271   static constexpr int min_exponent = 0;
00272   static constexpr int min_exponent10 = 0;
00273   static constexpr int max_exponent = 0;
00274   static constexpr int max_exponent10 = 0;
00275 #ifdef ABSL_HAVE_INTRINSIC_INT128
00276   static constexpr bool traps = numeric_limits<unsigned __int128>::traps;
00277 #else   // ABSL_HAVE_INTRINSIC_INT128
00278   static constexpr bool traps = numeric_limits<uint64_t>::traps;
00279 #endif  // ABSL_HAVE_INTRINSIC_INT128
00280   static constexpr bool tinyness_before = false;
00281 
00282   static constexpr absl::uint128 (min)() { return 0; }
00283   static constexpr absl::uint128 lowest() { return 0; }
00284   static constexpr absl::uint128 (max)() { return absl::Uint128Max(); }
00285   static constexpr absl::uint128 epsilon() { return 0; }
00286   static constexpr absl::uint128 round_error() { return 0; }
00287   static constexpr absl::uint128 infinity() { return 0; }
00288   static constexpr absl::uint128 quiet_NaN() { return 0; }
00289   static constexpr absl::uint128 signaling_NaN() { return 0; }
00290   static constexpr absl::uint128 denorm_min() { return 0; }
00291 };
00292 }  
00293 
00294 
00295 
00296 
00297 
00298 
00299 namespace absl {
00300 
00301 constexpr uint128 MakeUint128(uint64_t high, uint64_t low) {
00302   return uint128(high, low);
00303 }
00304 
00305 
00306 
00307 inline uint128& uint128::operator=(int v) { return *this = uint128(v); }
00308 
00309 inline uint128& uint128::operator=(unsigned int v) {
00310   return *this = uint128(v);
00311 }
00312 
00313 inline uint128& uint128::operator=(long v) {  
00314   return *this = uint128(v);
00315 }
00316 
00317 
00318 inline uint128& uint128::operator=(unsigned long v) {
00319   return *this = uint128(v);
00320 }
00321 
00322 
00323 inline uint128& uint128::operator=(long long v) {
00324   return *this = uint128(v);
00325 }
00326 
00327 
00328 inline uint128& uint128::operator=(unsigned long long v) {
00329   return *this = uint128(v);
00330 }
00331 
00332 #ifdef ABSL_HAVE_INTRINSIC_INT128
00333 inline uint128& uint128::operator=(__int128 v) {
00334   return *this = uint128(v);
00335 }
00336 
00337 inline uint128& uint128::operator=(unsigned __int128 v) {
00338   return *this = uint128(v);
00339 }
00340 #endif  // ABSL_HAVE_INTRINSIC_INT128
00341 
00342 
00343 
00344 uint128 operator<<(uint128 lhs, int amount);
00345 uint128 operator>>(uint128 lhs, int amount);
00346 uint128 operator+(uint128 lhs, uint128 rhs);
00347 uint128 operator-(uint128 lhs, uint128 rhs);
00348 uint128 operator*(uint128 lhs, uint128 rhs);
00349 uint128 operator/(uint128 lhs, uint128 rhs);
00350 uint128 operator%(uint128 lhs, uint128 rhs);
00351 
00352 inline uint128& uint128::operator<<=(int amount) {
00353   *this = *this << amount;
00354   return *this;
00355 }
00356 
00357 inline uint128& uint128::operator>>=(int amount) {
00358   *this = *this >> amount;
00359   return *this;
00360 }
00361 
00362 inline uint128& uint128::operator+=(uint128 other) {
00363   *this = *this + other;
00364   return *this;
00365 }
00366 
00367 inline uint128& uint128::operator-=(uint128 other) {
00368   *this = *this - other;
00369   return *this;
00370 }
00371 
00372 inline uint128& uint128::operator*=(uint128 other) {
00373   *this = *this * other;
00374   return *this;
00375 }
00376 
00377 inline uint128& uint128::operator/=(uint128 other) {
00378   *this = *this / other;
00379   return *this;
00380 }
00381 
00382 inline uint128& uint128::operator%=(uint128 other) {
00383   *this = *this % other;
00384   return *this;
00385 }
00386 
00387 constexpr uint64_t Uint128Low64(uint128 v) { return v.lo_; }
00388 
00389 constexpr uint64_t Uint128High64(uint128 v) { return v.hi_; }
00390 
00391 
00392 
00393 #if defined(ABSL_IS_LITTLE_ENDIAN)
00394 
00395 constexpr uint128::uint128(uint64_t high, uint64_t low)
00396     : lo_{low}, hi_{high} {}
00397 
00398 constexpr uint128::uint128(int v)
00399     : lo_{static_cast<uint64_t>(v)},
00400       hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {}
00401 constexpr uint128::uint128(long v)  
00402     : lo_{static_cast<uint64_t>(v)},
00403       hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {}
00404 constexpr uint128::uint128(long long v)  
00405     : lo_{static_cast<uint64_t>(v)},
00406       hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {}
00407 
00408 constexpr uint128::uint128(unsigned int v) : lo_{v}, hi_{0} {}
00409 
00410 constexpr uint128::uint128(unsigned long v) : lo_{v}, hi_{0} {}
00411 
00412 constexpr uint128::uint128(unsigned long long v) : lo_{v}, hi_{0} {}
00413 
00414 #ifdef ABSL_HAVE_INTRINSIC_INT128
00415 constexpr uint128::uint128(__int128 v)
00416     : lo_{static_cast<uint64_t>(v & ~uint64_t{0})},
00417       hi_{static_cast<uint64_t>(static_cast<unsigned __int128>(v) >> 64)} {}
00418 constexpr uint128::uint128(unsigned __int128 v)
00419     : lo_{static_cast<uint64_t>(v & ~uint64_t{0})},
00420       hi_{static_cast<uint64_t>(v >> 64)} {}
00421 #endif  // ABSL_HAVE_INTRINSIC_INT128
00422 
00423 #elif defined(ABSL_IS_BIG_ENDIAN)
00424 
00425 constexpr uint128::uint128(uint64_t high, uint64_t low)
00426     : hi_{high}, lo_{low} {}
00427 
00428 constexpr uint128::uint128(int v)
00429     : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0},
00430       lo_{static_cast<uint64_t>(v)} {}
00431 constexpr uint128::uint128(long v)  
00432     : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0},
00433       lo_{static_cast<uint64_t>(v)} {}
00434 constexpr uint128::uint128(long long v)  
00435     : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0},
00436       lo_{static_cast<uint64_t>(v)} {}
00437 
00438 constexpr uint128::uint128(unsigned int v) : hi_{0}, lo_{v} {}
00439 
00440 constexpr uint128::uint128(unsigned long v) : hi_{0}, lo_{v} {}
00441 
00442 constexpr uint128::uint128(unsigned long long v) : hi_{0}, lo_{v} {}
00443 
00444 #ifdef ABSL_HAVE_INTRINSIC_INT128
00445 constexpr uint128::uint128(__int128 v)
00446     : hi_{static_cast<uint64_t>(static_cast<unsigned __int128>(v) >> 64)},
00447       lo_{static_cast<uint64_t>(v & ~uint64_t{0})} {}
00448 constexpr uint128::uint128(unsigned __int128 v)
00449     : hi_{static_cast<uint64_t>(v >> 64)},
00450       lo_{static_cast<uint64_t>(v & ~uint64_t{0})} {}
00451 #endif  // ABSL_HAVE_INTRINSIC_INT128
00452 
00453 #else  // byte order
00454 #error "Unsupported byte order: must be little-endian or big-endian."
00455 #endif  // byte order
00456 
00457 
00458 
00459 constexpr uint128::operator bool() const { return lo_ || hi_; }
00460 
00461 constexpr uint128::operator char() const { return static_cast<char>(lo_); }
00462 
00463 constexpr uint128::operator signed char() const {
00464   return static_cast<signed char>(lo_);
00465 }
00466 
00467 constexpr uint128::operator unsigned char() const {
00468   return static_cast<unsigned char>(lo_);
00469 }
00470 
00471 constexpr uint128::operator char16_t() const {
00472   return static_cast<char16_t>(lo_);
00473 }
00474 
00475 constexpr uint128::operator char32_t() const {
00476   return static_cast<char32_t>(lo_);
00477 }
00478 
00479 constexpr uint128::operator ABSL_INTERNAL_WCHAR_T() const {
00480   return static_cast<ABSL_INTERNAL_WCHAR_T>(lo_);
00481 }
00482 
00483 
00484 constexpr uint128::operator short() const { return static_cast<short>(lo_); }
00485 
00486 constexpr uint128::operator unsigned short() const {  
00487   return static_cast<unsigned short>(lo_);            
00488 }
00489 
00490 constexpr uint128::operator int() const { return static_cast<int>(lo_); }
00491 
00492 constexpr uint128::operator unsigned int() const {
00493   return static_cast<unsigned int>(lo_);
00494 }
00495 
00496 
00497 constexpr uint128::operator long() const { return static_cast<long>(lo_); }
00498 
00499 constexpr uint128::operator unsigned long() const {  
00500   return static_cast<unsigned long>(lo_);            
00501 }
00502 
00503 constexpr uint128::operator long long() const {  
00504   return static_cast<long long>(lo_);            
00505 }
00506 
00507 constexpr uint128::operator unsigned long long() const {  
00508   return static_cast<unsigned long long>(lo_);            
00509 }
00510 
00511 #ifdef ABSL_HAVE_INTRINSIC_INT128
00512 constexpr uint128::operator __int128() const {
00513   return (static_cast<__int128>(hi_) << 64) + lo_;
00514 }
00515 
00516 constexpr uint128::operator unsigned __int128() const {
00517   return (static_cast<unsigned __int128>(hi_) << 64) + lo_;
00518 }
00519 #endif  // ABSL_HAVE_INTRINSIC_INT128
00520 
00521 
00522 
00523 inline uint128::operator float() const {
00524   return static_cast<float>(lo_) + std::ldexp(static_cast<float>(hi_), 64);
00525 }
00526 
00527 inline uint128::operator double() const {
00528   return static_cast<double>(lo_) + std::ldexp(static_cast<double>(hi_), 64);
00529 }
00530 
00531 inline uint128::operator long double() const {
00532   return static_cast<long double>(lo_) +
00533          std::ldexp(static_cast<long double>(hi_), 64);
00534 }
00535 
00536 
00537 
00538 inline bool operator==(uint128 lhs, uint128 rhs) {
00539   return (Uint128Low64(lhs) == Uint128Low64(rhs) &&
00540           Uint128High64(lhs) == Uint128High64(rhs));
00541 }
00542 
00543 inline bool operator!=(uint128 lhs, uint128 rhs) {
00544   return !(lhs == rhs);
00545 }
00546 
00547 inline bool operator<(uint128 lhs, uint128 rhs) {
00548   return (Uint128High64(lhs) == Uint128High64(rhs))
00549              ? (Uint128Low64(lhs) < Uint128Low64(rhs))
00550              : (Uint128High64(lhs) < Uint128High64(rhs));
00551 }
00552 
00553 inline bool operator>(uint128 lhs, uint128 rhs) {
00554   return (Uint128High64(lhs) == Uint128High64(rhs))
00555              ? (Uint128Low64(lhs) > Uint128Low64(rhs))
00556              : (Uint128High64(lhs) > Uint128High64(rhs));
00557 }
00558 
00559 inline bool operator<=(uint128 lhs, uint128 rhs) {
00560   return (Uint128High64(lhs) == Uint128High64(rhs))
00561              ? (Uint128Low64(lhs) <= Uint128Low64(rhs))
00562              : (Uint128High64(lhs) <= Uint128High64(rhs));
00563 }
00564 
00565 inline bool operator>=(uint128 lhs, uint128 rhs) {
00566   return (Uint128High64(lhs) == Uint128High64(rhs))
00567              ? (Uint128Low64(lhs) >= Uint128Low64(rhs))
00568              : (Uint128High64(lhs) >= Uint128High64(rhs));
00569 }
00570 
00571 
00572 
00573 inline uint128 operator-(uint128 val) {
00574   uint64_t hi = ~Uint128High64(val);
00575   uint64_t lo = ~Uint128Low64(val) + 1;
00576   if (lo == 0) ++hi;  
00577   return MakeUint128(hi, lo);
00578 }
00579 
00580 inline bool operator!(uint128 val) {
00581   return !Uint128High64(val) && !Uint128Low64(val);
00582 }
00583 
00584 
00585 
00586 inline uint128 operator~(uint128 val) {
00587   return MakeUint128(~Uint128High64(val), ~Uint128Low64(val));
00588 }
00589 
00590 inline uint128 operator|(uint128 lhs, uint128 rhs) {
00591   return MakeUint128(Uint128High64(lhs) | Uint128High64(rhs),
00592                            Uint128Low64(lhs) | Uint128Low64(rhs));
00593 }
00594 
00595 inline uint128 operator&(uint128 lhs, uint128 rhs) {
00596   return MakeUint128(Uint128High64(lhs) & Uint128High64(rhs),
00597                            Uint128Low64(lhs) & Uint128Low64(rhs));
00598 }
00599 
00600 inline uint128 operator^(uint128 lhs, uint128 rhs) {
00601   return MakeUint128(Uint128High64(lhs) ^ Uint128High64(rhs),
00602                            Uint128Low64(lhs) ^ Uint128Low64(rhs));
00603 }
00604 
00605 inline uint128& uint128::operator|=(uint128 other) {
00606   hi_ |= other.hi_;
00607   lo_ |= other.lo_;
00608   return *this;
00609 }
00610 
00611 inline uint128& uint128::operator&=(uint128 other) {
00612   hi_ &= other.hi_;
00613   lo_ &= other.lo_;
00614   return *this;
00615 }
00616 
00617 inline uint128& uint128::operator^=(uint128 other) {
00618   hi_ ^= other.hi_;
00619   lo_ ^= other.lo_;
00620   return *this;
00621 }
00622 
00623 
00624 
00625 inline uint128 operator<<(uint128 lhs, int amount) {
00626   
00627   
00628   if (amount < 64) {
00629     if (amount != 0) {
00630       return MakeUint128(
00631           (Uint128High64(lhs) << amount) | (Uint128Low64(lhs) >> (64 - amount)),
00632           Uint128Low64(lhs) << amount);
00633     }
00634     return lhs;
00635   }
00636   return MakeUint128(Uint128Low64(lhs) << (amount - 64), 0);
00637 }
00638 
00639 inline uint128 operator>>(uint128 lhs, int amount) {
00640   
00641   
00642   if (amount < 64) {
00643     if (amount != 0) {
00644       return MakeUint128(Uint128High64(lhs) >> amount,
00645                          (Uint128Low64(lhs) >> amount) |
00646                              (Uint128High64(lhs) << (64 - amount)));
00647     }
00648     return lhs;
00649   }
00650   return MakeUint128(0, Uint128High64(lhs) >> (amount - 64));
00651 }
00652 
00653 inline uint128 operator+(uint128 lhs, uint128 rhs) {
00654   uint128 result = MakeUint128(Uint128High64(lhs) + Uint128High64(rhs),
00655                                Uint128Low64(lhs) + Uint128Low64(rhs));
00656   if (Uint128Low64(result) < Uint128Low64(lhs)) {  
00657     return MakeUint128(Uint128High64(result) + 1, Uint128Low64(result));
00658   }
00659   return result;
00660 }
00661 
00662 inline uint128 operator-(uint128 lhs, uint128 rhs) {
00663   uint128 result = MakeUint128(Uint128High64(lhs) - Uint128High64(rhs),
00664                                Uint128Low64(lhs) - Uint128Low64(rhs));
00665   if (Uint128Low64(lhs) < Uint128Low64(rhs)) {  
00666     return MakeUint128(Uint128High64(result) - 1, Uint128Low64(result));
00667   }
00668   return result;
00669 }
00670 
00671 inline uint128 operator*(uint128 lhs, uint128 rhs) {
00672 #if defined(ABSL_HAVE_INTRINSIC_INT128)
00673   
00674   
00675   return static_cast<unsigned __int128>(lhs) *
00676          static_cast<unsigned __int128>(rhs);
00677 #elif defined(_MSC_VER) && defined(_M_X64)
00678   uint64_t carry;
00679   uint64_t low = _umul128(Uint128Low64(lhs), Uint128Low64(rhs), &carry);
00680   return MakeUint128(Uint128Low64(lhs) * Uint128High64(rhs) +
00681                          Uint128High64(lhs) * Uint128Low64(rhs) + carry,
00682                      low);
00683 #else   // ABSL_HAVE_INTRINSIC128
00684   uint64_t a32 = Uint128Low64(lhs) >> 32;
00685   uint64_t a00 = Uint128Low64(lhs) & 0xffffffff;
00686   uint64_t b32 = Uint128Low64(rhs) >> 32;
00687   uint64_t b00 = Uint128Low64(rhs) & 0xffffffff;
00688   uint128 result =
00689       MakeUint128(Uint128High64(lhs) * Uint128Low64(rhs) +
00690                       Uint128Low64(lhs) * Uint128High64(rhs) + a32 * b32,
00691                   a00 * b00);
00692   result += uint128(a32 * b00) << 32;
00693   result += uint128(a00 * b32) << 32;
00694   return result;
00695 #endif  // ABSL_HAVE_INTRINSIC128
00696 }
00697 
00698 
00699 
00700 inline uint128 uint128::operator++(int) {
00701   uint128 tmp(*this);
00702   *this += 1;
00703   return tmp;
00704 }
00705 
00706 inline uint128 uint128::operator--(int) {
00707   uint128 tmp(*this);
00708   *this -= 1;
00709   return tmp;
00710 }
00711 
00712 inline uint128& uint128::operator++() {
00713   *this += 1;
00714   return *this;
00715 }
00716 
00717 inline uint128& uint128::operator--() {
00718   *this -= 1;
00719   return *this;
00720 }
00721 
00722 #if defined(ABSL_HAVE_INTRINSIC_INT128)
00723 #include "absl/numeric/int128_have_intrinsic.inc"
00724 #else  // ABSL_HAVE_INTRINSIC_INT128
00725 #include "absl/numeric/int128_no_intrinsic.inc"
00726 #endif  // ABSL_HAVE_INTRINSIC_INT128
00727 
00728 }  
00729 
00730 #undef ABSL_INTERNAL_WCHAR_T
00731 
00732 #endif  // ABSL_NUMERIC_INT128_H_