1*9356374aSAndroid Build Coastguard Worker //
2*9356374aSAndroid Build Coastguard Worker // Copyright 2017 The Abseil Authors.
3*9356374aSAndroid Build Coastguard Worker //
4*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
5*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
6*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
7*9356374aSAndroid Build Coastguard Worker //
8*9356374aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0
9*9356374aSAndroid Build Coastguard Worker //
10*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
11*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
12*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
14*9356374aSAndroid Build Coastguard Worker // limitations under the License.
15*9356374aSAndroid Build Coastguard Worker //
16*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
17*9356374aSAndroid Build Coastguard Worker // File: int128.h
18*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
19*9356374aSAndroid Build Coastguard Worker //
20*9356374aSAndroid Build Coastguard Worker // This header file defines 128-bit integer types, `uint128` and `int128`.
21*9356374aSAndroid Build Coastguard Worker //
22*9356374aSAndroid Build Coastguard Worker // TODO(absl-team): This module is inconsistent as many inline `uint128` methods
23*9356374aSAndroid Build Coastguard Worker // are defined in this file, while many inline `int128` methods are defined in
24*9356374aSAndroid Build Coastguard Worker // the `int128_*_intrinsic.inc` files.
25*9356374aSAndroid Build Coastguard Worker
26*9356374aSAndroid Build Coastguard Worker #ifndef ABSL_NUMERIC_INT128_H_
27*9356374aSAndroid Build Coastguard Worker #define ABSL_NUMERIC_INT128_H_
28*9356374aSAndroid Build Coastguard Worker
29*9356374aSAndroid Build Coastguard Worker #include <cassert>
30*9356374aSAndroid Build Coastguard Worker #include <cmath>
31*9356374aSAndroid Build Coastguard Worker #include <cstdint>
32*9356374aSAndroid Build Coastguard Worker #include <cstring>
33*9356374aSAndroid Build Coastguard Worker #include <iosfwd>
34*9356374aSAndroid Build Coastguard Worker #include <limits>
35*9356374aSAndroid Build Coastguard Worker #include <string>
36*9356374aSAndroid Build Coastguard Worker #include <utility>
37*9356374aSAndroid Build Coastguard Worker
38*9356374aSAndroid Build Coastguard Worker #include "absl/base/config.h"
39*9356374aSAndroid Build Coastguard Worker #include "absl/base/macros.h"
40*9356374aSAndroid Build Coastguard Worker #include "absl/base/port.h"
41*9356374aSAndroid Build Coastguard Worker #include "absl/types/compare.h"
42*9356374aSAndroid Build Coastguard Worker
43*9356374aSAndroid Build Coastguard Worker #if defined(_MSC_VER)
44*9356374aSAndroid Build Coastguard Worker // In very old versions of MSVC and when the /Zc:wchar_t flag is off, wchar_t is
45*9356374aSAndroid Build Coastguard Worker // a typedef for unsigned short. Otherwise wchar_t is mapped to the __wchar_t
46*9356374aSAndroid Build Coastguard Worker // builtin type. We need to make sure not to define operator wchar_t()
47*9356374aSAndroid Build Coastguard Worker // alongside operator unsigned short() in these instances.
48*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_WCHAR_T __wchar_t
49*9356374aSAndroid Build Coastguard Worker #if defined(_M_X64) && !defined(_M_ARM64EC)
50*9356374aSAndroid Build Coastguard Worker #include <intrin.h>
51*9356374aSAndroid Build Coastguard Worker #pragma intrinsic(_umul128)
52*9356374aSAndroid Build Coastguard Worker #endif // defined(_M_X64)
53*9356374aSAndroid Build Coastguard Worker #else // defined(_MSC_VER)
54*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_WCHAR_T wchar_t
55*9356374aSAndroid Build Coastguard Worker #endif // defined(_MSC_VER)
56*9356374aSAndroid Build Coastguard Worker
57*9356374aSAndroid Build Coastguard Worker namespace absl {
58*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN
59*9356374aSAndroid Build Coastguard Worker
60*9356374aSAndroid Build Coastguard Worker class int128;
61*9356374aSAndroid Build Coastguard Worker
62*9356374aSAndroid Build Coastguard Worker // uint128
63*9356374aSAndroid Build Coastguard Worker //
64*9356374aSAndroid Build Coastguard Worker // An unsigned 128-bit integer type. The API is meant to mimic an intrinsic type
65*9356374aSAndroid Build Coastguard Worker // as closely as is practical, including exhibiting undefined behavior in
66*9356374aSAndroid Build Coastguard Worker // analogous cases (e.g. division by zero). This type is intended to be a
67*9356374aSAndroid Build Coastguard Worker // drop-in replacement once C++ supports an intrinsic `uint128_t` type; when
68*9356374aSAndroid Build Coastguard Worker // that occurs, existing well-behaved uses of `uint128` will continue to work
69*9356374aSAndroid Build Coastguard Worker // using that new type.
70*9356374aSAndroid Build Coastguard Worker //
71*9356374aSAndroid Build Coastguard Worker // Note: code written with this type will continue to compile once `uint128_t`
72*9356374aSAndroid Build Coastguard Worker // is introduced, provided the replacement helper functions
73*9356374aSAndroid Build Coastguard Worker // `Uint128(Low|High)64()` and `MakeUint128()` are made.
74*9356374aSAndroid Build Coastguard Worker //
75*9356374aSAndroid Build Coastguard Worker // A `uint128` supports the following:
76*9356374aSAndroid Build Coastguard Worker //
77*9356374aSAndroid Build Coastguard Worker // * Implicit construction from integral types
78*9356374aSAndroid Build Coastguard Worker // * Explicit conversion to integral types
79*9356374aSAndroid Build Coastguard Worker //
80*9356374aSAndroid Build Coastguard Worker // Additionally, if your compiler supports `__int128`, `uint128` is
81*9356374aSAndroid Build Coastguard Worker // interoperable with that type. (Abseil checks for this compatibility through
82*9356374aSAndroid Build Coastguard Worker // the `ABSL_HAVE_INTRINSIC_INT128` macro.)
83*9356374aSAndroid Build Coastguard Worker //
84*9356374aSAndroid Build Coastguard Worker // However, a `uint128` differs from intrinsic integral types in the following
85*9356374aSAndroid Build Coastguard Worker // ways:
86*9356374aSAndroid Build Coastguard Worker //
87*9356374aSAndroid Build Coastguard Worker // * Errors on implicit conversions that do not preserve value (such as
88*9356374aSAndroid Build Coastguard Worker // loss of precision when converting to float values).
89*9356374aSAndroid Build Coastguard Worker // * Requires explicit construction from and conversion to floating point
90*9356374aSAndroid Build Coastguard Worker // types.
91*9356374aSAndroid Build Coastguard Worker // * Conversion to integral types requires an explicit static_cast() to
92*9356374aSAndroid Build Coastguard Worker // mimic use of the `-Wnarrowing` compiler flag.
93*9356374aSAndroid Build Coastguard Worker // * The alignment requirement of `uint128` may differ from that of an
94*9356374aSAndroid Build Coastguard Worker // intrinsic 128-bit integer type depending on platform and build
95*9356374aSAndroid Build Coastguard Worker // configuration.
96*9356374aSAndroid Build Coastguard Worker //
97*9356374aSAndroid Build Coastguard Worker // Example:
98*9356374aSAndroid Build Coastguard Worker //
99*9356374aSAndroid Build Coastguard Worker // float y = absl::Uint128Max(); // Error. uint128 cannot be implicitly
100*9356374aSAndroid Build Coastguard Worker // // converted to float.
101*9356374aSAndroid Build Coastguard Worker //
102*9356374aSAndroid Build Coastguard Worker // absl::uint128 v;
103*9356374aSAndroid Build Coastguard Worker // uint64_t i = v; // Error
104*9356374aSAndroid Build Coastguard Worker // uint64_t i = static_cast<uint64_t>(v); // OK
105*9356374aSAndroid Build Coastguard Worker //
106*9356374aSAndroid Build Coastguard Worker class
107*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_HAVE_INTRINSIC_INT128)
108*9356374aSAndroid Build Coastguard Worker alignas(unsigned __int128)
109*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_INTRINSIC_INT128
110*9356374aSAndroid Build Coastguard Worker uint128 {
111*9356374aSAndroid Build Coastguard Worker public:
112*9356374aSAndroid Build Coastguard Worker uint128() = default;
113*9356374aSAndroid Build Coastguard Worker
114*9356374aSAndroid Build Coastguard Worker // Constructors from arithmetic types
115*9356374aSAndroid Build Coastguard Worker constexpr uint128(int v); // NOLINT(runtime/explicit)
116*9356374aSAndroid Build Coastguard Worker constexpr uint128(unsigned int v); // NOLINT(runtime/explicit)
117*9356374aSAndroid Build Coastguard Worker constexpr uint128(long v); // NOLINT(runtime/int)
118*9356374aSAndroid Build Coastguard Worker constexpr uint128(unsigned long v); // NOLINT(runtime/int)
119*9356374aSAndroid Build Coastguard Worker constexpr uint128(long long v); // NOLINT(runtime/int)
120*9356374aSAndroid Build Coastguard Worker constexpr uint128(unsigned long long v); // NOLINT(runtime/int)
121*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_INTRINSIC_INT128
122*9356374aSAndroid Build Coastguard Worker constexpr uint128(__int128 v); // NOLINT(runtime/explicit)
123*9356374aSAndroid Build Coastguard Worker constexpr uint128(unsigned __int128 v); // NOLINT(runtime/explicit)
124*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_INTRINSIC_INT128
125*9356374aSAndroid Build Coastguard Worker constexpr uint128(int128 v); // NOLINT(runtime/explicit)
126*9356374aSAndroid Build Coastguard Worker explicit uint128(float v);
127*9356374aSAndroid Build Coastguard Worker explicit uint128(double v);
128*9356374aSAndroid Build Coastguard Worker explicit uint128(long double v);
129*9356374aSAndroid Build Coastguard Worker
130*9356374aSAndroid Build Coastguard Worker // Assignment operators from arithmetic types
131*9356374aSAndroid Build Coastguard Worker uint128& operator=(int v);
132*9356374aSAndroid Build Coastguard Worker uint128& operator=(unsigned int v);
133*9356374aSAndroid Build Coastguard Worker uint128& operator=(long v); // NOLINT(runtime/int)
134*9356374aSAndroid Build Coastguard Worker uint128& operator=(unsigned long v); // NOLINT(runtime/int)
135*9356374aSAndroid Build Coastguard Worker uint128& operator=(long long v); // NOLINT(runtime/int)
136*9356374aSAndroid Build Coastguard Worker uint128& operator=(unsigned long long v); // NOLINT(runtime/int)
137*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_INTRINSIC_INT128
138*9356374aSAndroid Build Coastguard Worker uint128& operator=(__int128 v);
139*9356374aSAndroid Build Coastguard Worker uint128& operator=(unsigned __int128 v);
140*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_INTRINSIC_INT128
141*9356374aSAndroid Build Coastguard Worker uint128& operator=(int128 v);
142*9356374aSAndroid Build Coastguard Worker
143*9356374aSAndroid Build Coastguard Worker // Conversion operators to other arithmetic types
144*9356374aSAndroid Build Coastguard Worker constexpr explicit operator bool() const;
145*9356374aSAndroid Build Coastguard Worker constexpr explicit operator char() const;
146*9356374aSAndroid Build Coastguard Worker constexpr explicit operator signed char() const;
147*9356374aSAndroid Build Coastguard Worker constexpr explicit operator unsigned char() const;
148*9356374aSAndroid Build Coastguard Worker constexpr explicit operator char16_t() const;
149*9356374aSAndroid Build Coastguard Worker constexpr explicit operator char32_t() const;
150*9356374aSAndroid Build Coastguard Worker constexpr explicit operator ABSL_INTERNAL_WCHAR_T() const;
151*9356374aSAndroid Build Coastguard Worker constexpr explicit operator short() const; // NOLINT(runtime/int)
152*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
153*9356374aSAndroid Build Coastguard Worker constexpr explicit operator unsigned short() const;
154*9356374aSAndroid Build Coastguard Worker constexpr explicit operator int() const;
155*9356374aSAndroid Build Coastguard Worker constexpr explicit operator unsigned int() const;
156*9356374aSAndroid Build Coastguard Worker constexpr explicit operator long() const; // NOLINT(runtime/int)
157*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
158*9356374aSAndroid Build Coastguard Worker constexpr explicit operator unsigned long() const;
159*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
160*9356374aSAndroid Build Coastguard Worker constexpr explicit operator long long() const;
161*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
162*9356374aSAndroid Build Coastguard Worker constexpr explicit operator unsigned long long() const;
163*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_INTRINSIC_INT128
164*9356374aSAndroid Build Coastguard Worker constexpr explicit operator __int128() const;
165*9356374aSAndroid Build Coastguard Worker constexpr explicit operator unsigned __int128() const;
166*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_INTRINSIC_INT128
167*9356374aSAndroid Build Coastguard Worker explicit operator float() const;
168*9356374aSAndroid Build Coastguard Worker explicit operator double() const;
169*9356374aSAndroid Build Coastguard Worker explicit operator long double() const;
170*9356374aSAndroid Build Coastguard Worker
171*9356374aSAndroid Build Coastguard Worker // Trivial copy constructor, assignment operator and destructor.
172*9356374aSAndroid Build Coastguard Worker
173*9356374aSAndroid Build Coastguard Worker // Arithmetic operators.
174*9356374aSAndroid Build Coastguard Worker uint128& operator+=(uint128 other);
175*9356374aSAndroid Build Coastguard Worker uint128& operator-=(uint128 other);
176*9356374aSAndroid Build Coastguard Worker uint128& operator*=(uint128 other);
177*9356374aSAndroid Build Coastguard Worker // Long division/modulo for uint128.
178*9356374aSAndroid Build Coastguard Worker uint128& operator/=(uint128 other);
179*9356374aSAndroid Build Coastguard Worker uint128& operator%=(uint128 other);
180*9356374aSAndroid Build Coastguard Worker uint128 operator++(int);
181*9356374aSAndroid Build Coastguard Worker uint128 operator--(int);
182*9356374aSAndroid Build Coastguard Worker uint128& operator<<=(int);
183*9356374aSAndroid Build Coastguard Worker uint128& operator>>=(int);
184*9356374aSAndroid Build Coastguard Worker uint128& operator&=(uint128 other);
185*9356374aSAndroid Build Coastguard Worker uint128& operator|=(uint128 other);
186*9356374aSAndroid Build Coastguard Worker uint128& operator^=(uint128 other);
187*9356374aSAndroid Build Coastguard Worker uint128& operator++();
188*9356374aSAndroid Build Coastguard Worker uint128& operator--();
189*9356374aSAndroid Build Coastguard Worker
190*9356374aSAndroid Build Coastguard Worker // Uint128Low64()
191*9356374aSAndroid Build Coastguard Worker //
192*9356374aSAndroid Build Coastguard Worker // Returns the lower 64-bit value of a `uint128` value.
193*9356374aSAndroid Build Coastguard Worker friend constexpr uint64_t Uint128Low64(uint128 v);
194*9356374aSAndroid Build Coastguard Worker
195*9356374aSAndroid Build Coastguard Worker // Uint128High64()
196*9356374aSAndroid Build Coastguard Worker //
197*9356374aSAndroid Build Coastguard Worker // Returns the higher 64-bit value of a `uint128` value.
198*9356374aSAndroid Build Coastguard Worker friend constexpr uint64_t Uint128High64(uint128 v);
199*9356374aSAndroid Build Coastguard Worker
200*9356374aSAndroid Build Coastguard Worker // MakeUInt128()
201*9356374aSAndroid Build Coastguard Worker //
202*9356374aSAndroid Build Coastguard Worker // Constructs a `uint128` numeric value from two 64-bit unsigned integers.
203*9356374aSAndroid Build Coastguard Worker // Note that this factory function is the only way to construct a `uint128`
204*9356374aSAndroid Build Coastguard Worker // from integer values greater than 2^64.
205*9356374aSAndroid Build Coastguard Worker //
206*9356374aSAndroid Build Coastguard Worker // Example:
207*9356374aSAndroid Build Coastguard Worker //
208*9356374aSAndroid Build Coastguard Worker // absl::uint128 big = absl::MakeUint128(1, 0);
209*9356374aSAndroid Build Coastguard Worker friend constexpr uint128 MakeUint128(uint64_t high, uint64_t low);
210*9356374aSAndroid Build Coastguard Worker
211*9356374aSAndroid Build Coastguard Worker // Uint128Max()
212*9356374aSAndroid Build Coastguard Worker //
213*9356374aSAndroid Build Coastguard Worker // Returns the highest value for a 128-bit unsigned integer.
214*9356374aSAndroid Build Coastguard Worker friend constexpr uint128 Uint128Max();
215*9356374aSAndroid Build Coastguard Worker
216*9356374aSAndroid Build Coastguard Worker // Support for absl::Hash.
217*9356374aSAndroid Build Coastguard Worker template <typename H>
AbslHashValue(H h,uint128 v)218*9356374aSAndroid Build Coastguard Worker friend H AbslHashValue(H h, uint128 v) {
219*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(h), Uint128High64(v), Uint128Low64(v));
220*9356374aSAndroid Build Coastguard Worker }
221*9356374aSAndroid Build Coastguard Worker
222*9356374aSAndroid Build Coastguard Worker // Support for absl::StrCat() etc.
223*9356374aSAndroid Build Coastguard Worker template <typename Sink>
AbslStringify(Sink & sink,uint128 v)224*9356374aSAndroid Build Coastguard Worker friend void AbslStringify(Sink& sink, uint128 v) {
225*9356374aSAndroid Build Coastguard Worker sink.Append(v.ToString());
226*9356374aSAndroid Build Coastguard Worker }
227*9356374aSAndroid Build Coastguard Worker
228*9356374aSAndroid Build Coastguard Worker private:
229*9356374aSAndroid Build Coastguard Worker constexpr uint128(uint64_t high, uint64_t low);
230*9356374aSAndroid Build Coastguard Worker
231*9356374aSAndroid Build Coastguard Worker std::string ToString() const;
232*9356374aSAndroid Build Coastguard Worker
233*9356374aSAndroid Build Coastguard Worker // TODO(strel) Update implementation to use __int128 once all users of
234*9356374aSAndroid Build Coastguard Worker // uint128 are fixed to not depend on alignof(uint128) == 8. Also add
235*9356374aSAndroid Build Coastguard Worker // alignas(16) to class definition to keep alignment consistent across
236*9356374aSAndroid Build Coastguard Worker // platforms.
237*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_IS_LITTLE_ENDIAN)
238*9356374aSAndroid Build Coastguard Worker uint64_t lo_;
239*9356374aSAndroid Build Coastguard Worker uint64_t hi_;
240*9356374aSAndroid Build Coastguard Worker #elif defined(ABSL_IS_BIG_ENDIAN)
241*9356374aSAndroid Build Coastguard Worker uint64_t hi_;
242*9356374aSAndroid Build Coastguard Worker uint64_t lo_;
243*9356374aSAndroid Build Coastguard Worker #else // byte order
244*9356374aSAndroid Build Coastguard Worker #error "Unsupported byte order: must be little-endian or big-endian."
245*9356374aSAndroid Build Coastguard Worker #endif // byte order
246*9356374aSAndroid Build Coastguard Worker };
247*9356374aSAndroid Build Coastguard Worker
248*9356374aSAndroid Build Coastguard Worker // allow uint128 to be logged
249*9356374aSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, uint128 v);
250*9356374aSAndroid Build Coastguard Worker
251*9356374aSAndroid Build Coastguard Worker // TODO(strel) add operator>>(std::istream&, uint128)
252*9356374aSAndroid Build Coastguard Worker
Uint128Max()253*9356374aSAndroid Build Coastguard Worker constexpr uint128 Uint128Max() {
254*9356374aSAndroid Build Coastguard Worker return uint128((std::numeric_limits<uint64_t>::max)(),
255*9356374aSAndroid Build Coastguard Worker (std::numeric_limits<uint64_t>::max)());
256*9356374aSAndroid Build Coastguard Worker }
257*9356374aSAndroid Build Coastguard Worker
258*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END
259*9356374aSAndroid Build Coastguard Worker } // namespace absl
260*9356374aSAndroid Build Coastguard Worker
261*9356374aSAndroid Build Coastguard Worker // Specialized numeric_limits for uint128.
262*9356374aSAndroid Build Coastguard Worker namespace std {
263*9356374aSAndroid Build Coastguard Worker template <>
264*9356374aSAndroid Build Coastguard Worker class numeric_limits<absl::uint128> {
265*9356374aSAndroid Build Coastguard Worker public:
266*9356374aSAndroid Build Coastguard Worker static constexpr bool is_specialized = true;
267*9356374aSAndroid Build Coastguard Worker static constexpr bool is_signed = false;
268*9356374aSAndroid Build Coastguard Worker static constexpr bool is_integer = true;
269*9356374aSAndroid Build Coastguard Worker static constexpr bool is_exact = true;
270*9356374aSAndroid Build Coastguard Worker static constexpr bool has_infinity = false;
271*9356374aSAndroid Build Coastguard Worker static constexpr bool has_quiet_NaN = false;
272*9356374aSAndroid Build Coastguard Worker static constexpr bool has_signaling_NaN = false;
273*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
274*9356374aSAndroid Build Coastguard Worker static constexpr float_denorm_style has_denorm = denorm_absent;
275*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
276*9356374aSAndroid Build Coastguard Worker static constexpr bool has_denorm_loss = false;
277*9356374aSAndroid Build Coastguard Worker static constexpr float_round_style round_style = round_toward_zero;
278*9356374aSAndroid Build Coastguard Worker static constexpr bool is_iec559 = false;
279*9356374aSAndroid Build Coastguard Worker static constexpr bool is_bounded = true;
280*9356374aSAndroid Build Coastguard Worker static constexpr bool is_modulo = true;
281*9356374aSAndroid Build Coastguard Worker static constexpr int digits = 128;
282*9356374aSAndroid Build Coastguard Worker static constexpr int digits10 = 38;
283*9356374aSAndroid Build Coastguard Worker static constexpr int max_digits10 = 0;
284*9356374aSAndroid Build Coastguard Worker static constexpr int radix = 2;
285*9356374aSAndroid Build Coastguard Worker static constexpr int min_exponent = 0;
286*9356374aSAndroid Build Coastguard Worker static constexpr int min_exponent10 = 0;
287*9356374aSAndroid Build Coastguard Worker static constexpr int max_exponent = 0;
288*9356374aSAndroid Build Coastguard Worker static constexpr int max_exponent10 = 0;
289*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_INTRINSIC_INT128
290*9356374aSAndroid Build Coastguard Worker static constexpr bool traps = numeric_limits<unsigned __int128>::traps;
291*9356374aSAndroid Build Coastguard Worker #else // ABSL_HAVE_INTRINSIC_INT128
292*9356374aSAndroid Build Coastguard Worker static constexpr bool traps = numeric_limits<uint64_t>::traps;
293*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_INTRINSIC_INT128
294*9356374aSAndroid Build Coastguard Worker static constexpr bool tinyness_before = false;
295*9356374aSAndroid Build Coastguard Worker
uint128(min)296*9356374aSAndroid Build Coastguard Worker static constexpr absl::uint128(min)() { return 0; }
lowest()297*9356374aSAndroid Build Coastguard Worker static constexpr absl::uint128 lowest() { return 0; }
uint128(max)298*9356374aSAndroid Build Coastguard Worker static constexpr absl::uint128(max)() { return absl::Uint128Max(); }
epsilon()299*9356374aSAndroid Build Coastguard Worker static constexpr absl::uint128 epsilon() { return 0; }
round_error()300*9356374aSAndroid Build Coastguard Worker static constexpr absl::uint128 round_error() { return 0; }
infinity()301*9356374aSAndroid Build Coastguard Worker static constexpr absl::uint128 infinity() { return 0; }
quiet_NaN()302*9356374aSAndroid Build Coastguard Worker static constexpr absl::uint128 quiet_NaN() { return 0; }
signaling_NaN()303*9356374aSAndroid Build Coastguard Worker static constexpr absl::uint128 signaling_NaN() { return 0; }
denorm_min()304*9356374aSAndroid Build Coastguard Worker static constexpr absl::uint128 denorm_min() { return 0; }
305*9356374aSAndroid Build Coastguard Worker };
306*9356374aSAndroid Build Coastguard Worker } // namespace std
307*9356374aSAndroid Build Coastguard Worker
308*9356374aSAndroid Build Coastguard Worker namespace absl {
309*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN
310*9356374aSAndroid Build Coastguard Worker
311*9356374aSAndroid Build Coastguard Worker // int128
312*9356374aSAndroid Build Coastguard Worker //
313*9356374aSAndroid Build Coastguard Worker // A signed 128-bit integer type. The API is meant to mimic an intrinsic
314*9356374aSAndroid Build Coastguard Worker // integral type as closely as is practical, including exhibiting undefined
315*9356374aSAndroid Build Coastguard Worker // behavior in analogous cases (e.g. division by zero).
316*9356374aSAndroid Build Coastguard Worker //
317*9356374aSAndroid Build Coastguard Worker // An `int128` supports the following:
318*9356374aSAndroid Build Coastguard Worker //
319*9356374aSAndroid Build Coastguard Worker // * Implicit construction from integral types
320*9356374aSAndroid Build Coastguard Worker // * Explicit conversion to integral types
321*9356374aSAndroid Build Coastguard Worker //
322*9356374aSAndroid Build Coastguard Worker // However, an `int128` differs from intrinsic integral types in the following
323*9356374aSAndroid Build Coastguard Worker // ways:
324*9356374aSAndroid Build Coastguard Worker //
325*9356374aSAndroid Build Coastguard Worker // * It is not implicitly convertible to other integral types.
326*9356374aSAndroid Build Coastguard Worker // * Requires explicit construction from and conversion to floating point
327*9356374aSAndroid Build Coastguard Worker // types.
328*9356374aSAndroid Build Coastguard Worker
329*9356374aSAndroid Build Coastguard Worker // Additionally, if your compiler supports `__int128`, `int128` is
330*9356374aSAndroid Build Coastguard Worker // interoperable with that type. (Abseil checks for this compatibility through
331*9356374aSAndroid Build Coastguard Worker // the `ABSL_HAVE_INTRINSIC_INT128` macro.)
332*9356374aSAndroid Build Coastguard Worker //
333*9356374aSAndroid Build Coastguard Worker // The design goal for `int128` is that it will be compatible with a future
334*9356374aSAndroid Build Coastguard Worker // `int128_t`, if that type becomes a part of the standard.
335*9356374aSAndroid Build Coastguard Worker //
336*9356374aSAndroid Build Coastguard Worker // Example:
337*9356374aSAndroid Build Coastguard Worker //
338*9356374aSAndroid Build Coastguard Worker // float y = absl::int128(17); // Error. int128 cannot be implicitly
339*9356374aSAndroid Build Coastguard Worker // // converted to float.
340*9356374aSAndroid Build Coastguard Worker //
341*9356374aSAndroid Build Coastguard Worker // absl::int128 v;
342*9356374aSAndroid Build Coastguard Worker // int64_t i = v; // Error
343*9356374aSAndroid Build Coastguard Worker // int64_t i = static_cast<int64_t>(v); // OK
344*9356374aSAndroid Build Coastguard Worker //
345*9356374aSAndroid Build Coastguard Worker class int128 {
346*9356374aSAndroid Build Coastguard Worker public:
347*9356374aSAndroid Build Coastguard Worker int128() = default;
348*9356374aSAndroid Build Coastguard Worker
349*9356374aSAndroid Build Coastguard Worker // Constructors from arithmetic types
350*9356374aSAndroid Build Coastguard Worker constexpr int128(int v); // NOLINT(runtime/explicit)
351*9356374aSAndroid Build Coastguard Worker constexpr int128(unsigned int v); // NOLINT(runtime/explicit)
352*9356374aSAndroid Build Coastguard Worker constexpr int128(long v); // NOLINT(runtime/int)
353*9356374aSAndroid Build Coastguard Worker constexpr int128(unsigned long v); // NOLINT(runtime/int)
354*9356374aSAndroid Build Coastguard Worker constexpr int128(long long v); // NOLINT(runtime/int)
355*9356374aSAndroid Build Coastguard Worker constexpr int128(unsigned long long v); // NOLINT(runtime/int)
356*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_INTRINSIC_INT128
357*9356374aSAndroid Build Coastguard Worker constexpr int128(__int128 v); // NOLINT(runtime/explicit)
358*9356374aSAndroid Build Coastguard Worker constexpr explicit int128(unsigned __int128 v);
359*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_INTRINSIC_INT128
360*9356374aSAndroid Build Coastguard Worker constexpr explicit int128(uint128 v);
361*9356374aSAndroid Build Coastguard Worker explicit int128(float v);
362*9356374aSAndroid Build Coastguard Worker explicit int128(double v);
363*9356374aSAndroid Build Coastguard Worker explicit int128(long double v);
364*9356374aSAndroid Build Coastguard Worker
365*9356374aSAndroid Build Coastguard Worker // Assignment operators from arithmetic types
366*9356374aSAndroid Build Coastguard Worker int128& operator=(int v);
367*9356374aSAndroid Build Coastguard Worker int128& operator=(unsigned int v);
368*9356374aSAndroid Build Coastguard Worker int128& operator=(long v); // NOLINT(runtime/int)
369*9356374aSAndroid Build Coastguard Worker int128& operator=(unsigned long v); // NOLINT(runtime/int)
370*9356374aSAndroid Build Coastguard Worker int128& operator=(long long v); // NOLINT(runtime/int)
371*9356374aSAndroid Build Coastguard Worker int128& operator=(unsigned long long v); // NOLINT(runtime/int)
372*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_INTRINSIC_INT128
373*9356374aSAndroid Build Coastguard Worker int128& operator=(__int128 v);
374*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_INTRINSIC_INT128
375*9356374aSAndroid Build Coastguard Worker
376*9356374aSAndroid Build Coastguard Worker // Conversion operators to other arithmetic types
377*9356374aSAndroid Build Coastguard Worker constexpr explicit operator bool() const;
378*9356374aSAndroid Build Coastguard Worker constexpr explicit operator char() const;
379*9356374aSAndroid Build Coastguard Worker constexpr explicit operator signed char() const;
380*9356374aSAndroid Build Coastguard Worker constexpr explicit operator unsigned char() const;
381*9356374aSAndroid Build Coastguard Worker constexpr explicit operator char16_t() const;
382*9356374aSAndroid Build Coastguard Worker constexpr explicit operator char32_t() const;
383*9356374aSAndroid Build Coastguard Worker constexpr explicit operator ABSL_INTERNAL_WCHAR_T() const;
384*9356374aSAndroid Build Coastguard Worker constexpr explicit operator short() const; // NOLINT(runtime/int)
385*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
386*9356374aSAndroid Build Coastguard Worker constexpr explicit operator unsigned short() const;
387*9356374aSAndroid Build Coastguard Worker constexpr explicit operator int() const;
388*9356374aSAndroid Build Coastguard Worker constexpr explicit operator unsigned int() const;
389*9356374aSAndroid Build Coastguard Worker constexpr explicit operator long() const; // NOLINT(runtime/int)
390*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
391*9356374aSAndroid Build Coastguard Worker constexpr explicit operator unsigned long() const;
392*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
393*9356374aSAndroid Build Coastguard Worker constexpr explicit operator long long() const;
394*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
395*9356374aSAndroid Build Coastguard Worker constexpr explicit operator unsigned long long() const;
396*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_INTRINSIC_INT128
397*9356374aSAndroid Build Coastguard Worker constexpr explicit operator __int128() const;
398*9356374aSAndroid Build Coastguard Worker constexpr explicit operator unsigned __int128() const;
399*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_INTRINSIC_INT128
400*9356374aSAndroid Build Coastguard Worker explicit operator float() const;
401*9356374aSAndroid Build Coastguard Worker explicit operator double() const;
402*9356374aSAndroid Build Coastguard Worker explicit operator long double() const;
403*9356374aSAndroid Build Coastguard Worker
404*9356374aSAndroid Build Coastguard Worker // Trivial copy constructor, assignment operator and destructor.
405*9356374aSAndroid Build Coastguard Worker
406*9356374aSAndroid Build Coastguard Worker // Arithmetic operators
407*9356374aSAndroid Build Coastguard Worker int128& operator+=(int128 other);
408*9356374aSAndroid Build Coastguard Worker int128& operator-=(int128 other);
409*9356374aSAndroid Build Coastguard Worker int128& operator*=(int128 other);
410*9356374aSAndroid Build Coastguard Worker int128& operator/=(int128 other);
411*9356374aSAndroid Build Coastguard Worker int128& operator%=(int128 other);
412*9356374aSAndroid Build Coastguard Worker int128 operator++(int); // postfix increment: i++
413*9356374aSAndroid Build Coastguard Worker int128 operator--(int); // postfix decrement: i--
414*9356374aSAndroid Build Coastguard Worker int128& operator++(); // prefix increment: ++i
415*9356374aSAndroid Build Coastguard Worker int128& operator--(); // prefix decrement: --i
416*9356374aSAndroid Build Coastguard Worker int128& operator&=(int128 other);
417*9356374aSAndroid Build Coastguard Worker int128& operator|=(int128 other);
418*9356374aSAndroid Build Coastguard Worker int128& operator^=(int128 other);
419*9356374aSAndroid Build Coastguard Worker int128& operator<<=(int amount);
420*9356374aSAndroid Build Coastguard Worker int128& operator>>=(int amount);
421*9356374aSAndroid Build Coastguard Worker
422*9356374aSAndroid Build Coastguard Worker // Int128Low64()
423*9356374aSAndroid Build Coastguard Worker //
424*9356374aSAndroid Build Coastguard Worker // Returns the lower 64-bit value of a `int128` value.
425*9356374aSAndroid Build Coastguard Worker friend constexpr uint64_t Int128Low64(int128 v);
426*9356374aSAndroid Build Coastguard Worker
427*9356374aSAndroid Build Coastguard Worker // Int128High64()
428*9356374aSAndroid Build Coastguard Worker //
429*9356374aSAndroid Build Coastguard Worker // Returns the higher 64-bit value of a `int128` value.
430*9356374aSAndroid Build Coastguard Worker friend constexpr int64_t Int128High64(int128 v);
431*9356374aSAndroid Build Coastguard Worker
432*9356374aSAndroid Build Coastguard Worker // MakeInt128()
433*9356374aSAndroid Build Coastguard Worker //
434*9356374aSAndroid Build Coastguard Worker // Constructs a `int128` numeric value from two 64-bit integers. Note that
435*9356374aSAndroid Build Coastguard Worker // signedness is conveyed in the upper `high` value.
436*9356374aSAndroid Build Coastguard Worker //
437*9356374aSAndroid Build Coastguard Worker // (absl::int128(1) << 64) * high + low
438*9356374aSAndroid Build Coastguard Worker //
439*9356374aSAndroid Build Coastguard Worker // Note that this factory function is the only way to construct a `int128`
440*9356374aSAndroid Build Coastguard Worker // from integer values greater than 2^64 or less than -2^64.
441*9356374aSAndroid Build Coastguard Worker //
442*9356374aSAndroid Build Coastguard Worker // Example:
443*9356374aSAndroid Build Coastguard Worker //
444*9356374aSAndroid Build Coastguard Worker // absl::int128 big = absl::MakeInt128(1, 0);
445*9356374aSAndroid Build Coastguard Worker // absl::int128 big_n = absl::MakeInt128(-1, 0);
446*9356374aSAndroid Build Coastguard Worker friend constexpr int128 MakeInt128(int64_t high, uint64_t low);
447*9356374aSAndroid Build Coastguard Worker
448*9356374aSAndroid Build Coastguard Worker // Int128Max()
449*9356374aSAndroid Build Coastguard Worker //
450*9356374aSAndroid Build Coastguard Worker // Returns the maximum value for a 128-bit signed integer.
451*9356374aSAndroid Build Coastguard Worker friend constexpr int128 Int128Max();
452*9356374aSAndroid Build Coastguard Worker
453*9356374aSAndroid Build Coastguard Worker // Int128Min()
454*9356374aSAndroid Build Coastguard Worker //
455*9356374aSAndroid Build Coastguard Worker // Returns the minimum value for a 128-bit signed integer.
456*9356374aSAndroid Build Coastguard Worker friend constexpr int128 Int128Min();
457*9356374aSAndroid Build Coastguard Worker
458*9356374aSAndroid Build Coastguard Worker // Support for absl::Hash.
459*9356374aSAndroid Build Coastguard Worker template <typename H>
AbslHashValue(H h,int128 v)460*9356374aSAndroid Build Coastguard Worker friend H AbslHashValue(H h, int128 v) {
461*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(h), Int128High64(v), Int128Low64(v));
462*9356374aSAndroid Build Coastguard Worker }
463*9356374aSAndroid Build Coastguard Worker
464*9356374aSAndroid Build Coastguard Worker // Support for absl::StrCat() etc.
465*9356374aSAndroid Build Coastguard Worker template <typename Sink>
AbslStringify(Sink & sink,int128 v)466*9356374aSAndroid Build Coastguard Worker friend void AbslStringify(Sink& sink, int128 v) {
467*9356374aSAndroid Build Coastguard Worker sink.Append(v.ToString());
468*9356374aSAndroid Build Coastguard Worker }
469*9356374aSAndroid Build Coastguard Worker
470*9356374aSAndroid Build Coastguard Worker private:
471*9356374aSAndroid Build Coastguard Worker constexpr int128(int64_t high, uint64_t low);
472*9356374aSAndroid Build Coastguard Worker
473*9356374aSAndroid Build Coastguard Worker std::string ToString() const;
474*9356374aSAndroid Build Coastguard Worker
475*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_HAVE_INTRINSIC_INT128)
476*9356374aSAndroid Build Coastguard Worker __int128 v_;
477*9356374aSAndroid Build Coastguard Worker #else // ABSL_HAVE_INTRINSIC_INT128
478*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_IS_LITTLE_ENDIAN)
479*9356374aSAndroid Build Coastguard Worker uint64_t lo_;
480*9356374aSAndroid Build Coastguard Worker int64_t hi_;
481*9356374aSAndroid Build Coastguard Worker #elif defined(ABSL_IS_BIG_ENDIAN)
482*9356374aSAndroid Build Coastguard Worker int64_t hi_;
483*9356374aSAndroid Build Coastguard Worker uint64_t lo_;
484*9356374aSAndroid Build Coastguard Worker #else // byte order
485*9356374aSAndroid Build Coastguard Worker #error "Unsupported byte order: must be little-endian or big-endian."
486*9356374aSAndroid Build Coastguard Worker #endif // byte order
487*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_INTRINSIC_INT128
488*9356374aSAndroid Build Coastguard Worker };
489*9356374aSAndroid Build Coastguard Worker
490*9356374aSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, int128 v);
491*9356374aSAndroid Build Coastguard Worker
492*9356374aSAndroid Build Coastguard Worker // TODO(absl-team) add operator>>(std::istream&, int128)
493*9356374aSAndroid Build Coastguard Worker
Int128Max()494*9356374aSAndroid Build Coastguard Worker constexpr int128 Int128Max() {
495*9356374aSAndroid Build Coastguard Worker return int128((std::numeric_limits<int64_t>::max)(),
496*9356374aSAndroid Build Coastguard Worker (std::numeric_limits<uint64_t>::max)());
497*9356374aSAndroid Build Coastguard Worker }
498*9356374aSAndroid Build Coastguard Worker
Int128Min()499*9356374aSAndroid Build Coastguard Worker constexpr int128 Int128Min() {
500*9356374aSAndroid Build Coastguard Worker return int128((std::numeric_limits<int64_t>::min)(), 0);
501*9356374aSAndroid Build Coastguard Worker }
502*9356374aSAndroid Build Coastguard Worker
503*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END
504*9356374aSAndroid Build Coastguard Worker } // namespace absl
505*9356374aSAndroid Build Coastguard Worker
506*9356374aSAndroid Build Coastguard Worker // Specialized numeric_limits for int128.
507*9356374aSAndroid Build Coastguard Worker namespace std {
508*9356374aSAndroid Build Coastguard Worker template <>
509*9356374aSAndroid Build Coastguard Worker class numeric_limits<absl::int128> {
510*9356374aSAndroid Build Coastguard Worker public:
511*9356374aSAndroid Build Coastguard Worker static constexpr bool is_specialized = true;
512*9356374aSAndroid Build Coastguard Worker static constexpr bool is_signed = true;
513*9356374aSAndroid Build Coastguard Worker static constexpr bool is_integer = true;
514*9356374aSAndroid Build Coastguard Worker static constexpr bool is_exact = true;
515*9356374aSAndroid Build Coastguard Worker static constexpr bool has_infinity = false;
516*9356374aSAndroid Build Coastguard Worker static constexpr bool has_quiet_NaN = false;
517*9356374aSAndroid Build Coastguard Worker static constexpr bool has_signaling_NaN = false;
518*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
519*9356374aSAndroid Build Coastguard Worker static constexpr float_denorm_style has_denorm = denorm_absent;
520*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
521*9356374aSAndroid Build Coastguard Worker static constexpr bool has_denorm_loss = false;
522*9356374aSAndroid Build Coastguard Worker static constexpr float_round_style round_style = round_toward_zero;
523*9356374aSAndroid Build Coastguard Worker static constexpr bool is_iec559 = false;
524*9356374aSAndroid Build Coastguard Worker static constexpr bool is_bounded = true;
525*9356374aSAndroid Build Coastguard Worker static constexpr bool is_modulo = false;
526*9356374aSAndroid Build Coastguard Worker static constexpr int digits = 127;
527*9356374aSAndroid Build Coastguard Worker static constexpr int digits10 = 38;
528*9356374aSAndroid Build Coastguard Worker static constexpr int max_digits10 = 0;
529*9356374aSAndroid Build Coastguard Worker static constexpr int radix = 2;
530*9356374aSAndroid Build Coastguard Worker static constexpr int min_exponent = 0;
531*9356374aSAndroid Build Coastguard Worker static constexpr int min_exponent10 = 0;
532*9356374aSAndroid Build Coastguard Worker static constexpr int max_exponent = 0;
533*9356374aSAndroid Build Coastguard Worker static constexpr int max_exponent10 = 0;
534*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_INTRINSIC_INT128
535*9356374aSAndroid Build Coastguard Worker static constexpr bool traps = numeric_limits<__int128>::traps;
536*9356374aSAndroid Build Coastguard Worker #else // ABSL_HAVE_INTRINSIC_INT128
537*9356374aSAndroid Build Coastguard Worker static constexpr bool traps = numeric_limits<uint64_t>::traps;
538*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_INTRINSIC_INT128
539*9356374aSAndroid Build Coastguard Worker static constexpr bool tinyness_before = false;
540*9356374aSAndroid Build Coastguard Worker
int128(min)541*9356374aSAndroid Build Coastguard Worker static constexpr absl::int128(min)() { return absl::Int128Min(); }
lowest()542*9356374aSAndroid Build Coastguard Worker static constexpr absl::int128 lowest() { return absl::Int128Min(); }
int128(max)543*9356374aSAndroid Build Coastguard Worker static constexpr absl::int128(max)() { return absl::Int128Max(); }
epsilon()544*9356374aSAndroid Build Coastguard Worker static constexpr absl::int128 epsilon() { return 0; }
round_error()545*9356374aSAndroid Build Coastguard Worker static constexpr absl::int128 round_error() { return 0; }
infinity()546*9356374aSAndroid Build Coastguard Worker static constexpr absl::int128 infinity() { return 0; }
quiet_NaN()547*9356374aSAndroid Build Coastguard Worker static constexpr absl::int128 quiet_NaN() { return 0; }
signaling_NaN()548*9356374aSAndroid Build Coastguard Worker static constexpr absl::int128 signaling_NaN() { return 0; }
denorm_min()549*9356374aSAndroid Build Coastguard Worker static constexpr absl::int128 denorm_min() { return 0; }
550*9356374aSAndroid Build Coastguard Worker };
551*9356374aSAndroid Build Coastguard Worker } // namespace std
552*9356374aSAndroid Build Coastguard Worker
553*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------------
554*9356374aSAndroid Build Coastguard Worker // Implementation details follow
555*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------------
556*9356374aSAndroid Build Coastguard Worker namespace absl {
557*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN
558*9356374aSAndroid Build Coastguard Worker
MakeUint128(uint64_t high,uint64_t low)559*9356374aSAndroid Build Coastguard Worker constexpr uint128 MakeUint128(uint64_t high, uint64_t low) {
560*9356374aSAndroid Build Coastguard Worker return uint128(high, low);
561*9356374aSAndroid Build Coastguard Worker }
562*9356374aSAndroid Build Coastguard Worker
563*9356374aSAndroid Build Coastguard Worker // Assignment from integer types.
564*9356374aSAndroid Build Coastguard Worker
565*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator=(int v) { return *this = uint128(v); }
566*9356374aSAndroid Build Coastguard Worker
567*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator=(unsigned int v) {
568*9356374aSAndroid Build Coastguard Worker return *this = uint128(v);
569*9356374aSAndroid Build Coastguard Worker }
570*9356374aSAndroid Build Coastguard Worker
571*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator=(long v) { // NOLINT(runtime/int)
572*9356374aSAndroid Build Coastguard Worker return *this = uint128(v);
573*9356374aSAndroid Build Coastguard Worker }
574*9356374aSAndroid Build Coastguard Worker
575*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
576*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator=(unsigned long v) {
577*9356374aSAndroid Build Coastguard Worker return *this = uint128(v);
578*9356374aSAndroid Build Coastguard Worker }
579*9356374aSAndroid Build Coastguard Worker
580*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
581*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator=(long long v) { return *this = uint128(v); }
582*9356374aSAndroid Build Coastguard Worker
583*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
584*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator=(unsigned long long v) {
585*9356374aSAndroid Build Coastguard Worker return *this = uint128(v);
586*9356374aSAndroid Build Coastguard Worker }
587*9356374aSAndroid Build Coastguard Worker
588*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_INTRINSIC_INT128
589*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator=(__int128 v) { return *this = uint128(v); }
590*9356374aSAndroid Build Coastguard Worker
591*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator=(unsigned __int128 v) {
592*9356374aSAndroid Build Coastguard Worker return *this = uint128(v);
593*9356374aSAndroid Build Coastguard Worker }
594*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_INTRINSIC_INT128
595*9356374aSAndroid Build Coastguard Worker
596*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator=(int128 v) { return *this = uint128(v); }
597*9356374aSAndroid Build Coastguard Worker
598*9356374aSAndroid Build Coastguard Worker // Arithmetic operators.
599*9356374aSAndroid Build Coastguard Worker
600*9356374aSAndroid Build Coastguard Worker constexpr uint128 operator<<(uint128 lhs, int amount);
601*9356374aSAndroid Build Coastguard Worker constexpr uint128 operator>>(uint128 lhs, int amount);
602*9356374aSAndroid Build Coastguard Worker constexpr uint128 operator+(uint128 lhs, uint128 rhs);
603*9356374aSAndroid Build Coastguard Worker constexpr uint128 operator-(uint128 lhs, uint128 rhs);
604*9356374aSAndroid Build Coastguard Worker uint128 operator*(uint128 lhs, uint128 rhs);
605*9356374aSAndroid Build Coastguard Worker uint128 operator/(uint128 lhs, uint128 rhs);
606*9356374aSAndroid Build Coastguard Worker uint128 operator%(uint128 lhs, uint128 rhs);
607*9356374aSAndroid Build Coastguard Worker
608*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator<<=(int amount) {
609*9356374aSAndroid Build Coastguard Worker *this = *this << amount;
610*9356374aSAndroid Build Coastguard Worker return *this;
611*9356374aSAndroid Build Coastguard Worker }
612*9356374aSAndroid Build Coastguard Worker
613*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator>>=(int amount) {
614*9356374aSAndroid Build Coastguard Worker *this = *this >> amount;
615*9356374aSAndroid Build Coastguard Worker return *this;
616*9356374aSAndroid Build Coastguard Worker }
617*9356374aSAndroid Build Coastguard Worker
618*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator+=(uint128 other) {
619*9356374aSAndroid Build Coastguard Worker *this = *this + other;
620*9356374aSAndroid Build Coastguard Worker return *this;
621*9356374aSAndroid Build Coastguard Worker }
622*9356374aSAndroid Build Coastguard Worker
623*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator-=(uint128 other) {
624*9356374aSAndroid Build Coastguard Worker *this = *this - other;
625*9356374aSAndroid Build Coastguard Worker return *this;
626*9356374aSAndroid Build Coastguard Worker }
627*9356374aSAndroid Build Coastguard Worker
628*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator*=(uint128 other) {
629*9356374aSAndroid Build Coastguard Worker *this = *this * other;
630*9356374aSAndroid Build Coastguard Worker return *this;
631*9356374aSAndroid Build Coastguard Worker }
632*9356374aSAndroid Build Coastguard Worker
633*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator/=(uint128 other) {
634*9356374aSAndroid Build Coastguard Worker *this = *this / other;
635*9356374aSAndroid Build Coastguard Worker return *this;
636*9356374aSAndroid Build Coastguard Worker }
637*9356374aSAndroid Build Coastguard Worker
638*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator%=(uint128 other) {
639*9356374aSAndroid Build Coastguard Worker *this = *this % other;
640*9356374aSAndroid Build Coastguard Worker return *this;
641*9356374aSAndroid Build Coastguard Worker }
642*9356374aSAndroid Build Coastguard Worker
Uint128Low64(uint128 v)643*9356374aSAndroid Build Coastguard Worker constexpr uint64_t Uint128Low64(uint128 v) { return v.lo_; }
644*9356374aSAndroid Build Coastguard Worker
Uint128High64(uint128 v)645*9356374aSAndroid Build Coastguard Worker constexpr uint64_t Uint128High64(uint128 v) { return v.hi_; }
646*9356374aSAndroid Build Coastguard Worker
647*9356374aSAndroid Build Coastguard Worker // Constructors from integer types.
648*9356374aSAndroid Build Coastguard Worker
649*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_IS_LITTLE_ENDIAN)
650*9356374aSAndroid Build Coastguard Worker
uint128(uint64_t high,uint64_t low)651*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(uint64_t high, uint64_t low) : lo_{low}, hi_{high} {}
652*9356374aSAndroid Build Coastguard Worker
uint128(int v)653*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(int v)
654*9356374aSAndroid Build Coastguard Worker : lo_{static_cast<uint64_t>(v)},
655*9356374aSAndroid Build Coastguard Worker hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {}
uint128(long v)656*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(long v) // NOLINT(runtime/int)
657*9356374aSAndroid Build Coastguard Worker : lo_{static_cast<uint64_t>(v)},
658*9356374aSAndroid Build Coastguard Worker hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {}
uint128(long long v)659*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(long long v) // NOLINT(runtime/int)
660*9356374aSAndroid Build Coastguard Worker : lo_{static_cast<uint64_t>(v)},
661*9356374aSAndroid Build Coastguard Worker hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {}
662*9356374aSAndroid Build Coastguard Worker
uint128(unsigned int v)663*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(unsigned int v) : lo_{v}, hi_{0} {}
664*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
uint128(unsigned long v)665*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(unsigned long v) : lo_{v}, hi_{0} {}
666*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
uint128(unsigned long long v)667*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(unsigned long long v) : lo_{v}, hi_{0} {}
668*9356374aSAndroid Build Coastguard Worker
669*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_INTRINSIC_INT128
uint128(__int128 v)670*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(__int128 v)
671*9356374aSAndroid Build Coastguard Worker : lo_{static_cast<uint64_t>(v & ~uint64_t{0})},
672*9356374aSAndroid Build Coastguard Worker hi_{static_cast<uint64_t>(static_cast<unsigned __int128>(v) >> 64)} {}
uint128(unsigned __int128 v)673*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(unsigned __int128 v)
674*9356374aSAndroid Build Coastguard Worker : lo_{static_cast<uint64_t>(v & ~uint64_t{0})},
675*9356374aSAndroid Build Coastguard Worker hi_{static_cast<uint64_t>(v >> 64)} {}
676*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_INTRINSIC_INT128
677*9356374aSAndroid Build Coastguard Worker
uint128(int128 v)678*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(int128 v)
679*9356374aSAndroid Build Coastguard Worker : lo_{Int128Low64(v)}, hi_{static_cast<uint64_t>(Int128High64(v))} {}
680*9356374aSAndroid Build Coastguard Worker
681*9356374aSAndroid Build Coastguard Worker #elif defined(ABSL_IS_BIG_ENDIAN)
682*9356374aSAndroid Build Coastguard Worker
uint128(uint64_t high,uint64_t low)683*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(uint64_t high, uint64_t low) : hi_{high}, lo_{low} {}
684*9356374aSAndroid Build Coastguard Worker
uint128(int v)685*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(int v)
686*9356374aSAndroid Build Coastguard Worker : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0},
687*9356374aSAndroid Build Coastguard Worker lo_{static_cast<uint64_t>(v)} {}
uint128(long v)688*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(long v) // NOLINT(runtime/int)
689*9356374aSAndroid Build Coastguard Worker : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0},
690*9356374aSAndroid Build Coastguard Worker lo_{static_cast<uint64_t>(v)} {}
uint128(long long v)691*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(long long v) // NOLINT(runtime/int)
692*9356374aSAndroid Build Coastguard Worker : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0},
693*9356374aSAndroid Build Coastguard Worker lo_{static_cast<uint64_t>(v)} {}
694*9356374aSAndroid Build Coastguard Worker
uint128(unsigned int v)695*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(unsigned int v) : hi_{0}, lo_{v} {}
696*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
uint128(unsigned long v)697*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(unsigned long v) : hi_{0}, lo_{v} {}
698*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
uint128(unsigned long long v)699*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(unsigned long long v) : hi_{0}, lo_{v} {}
700*9356374aSAndroid Build Coastguard Worker
701*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_INTRINSIC_INT128
uint128(__int128 v)702*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(__int128 v)
703*9356374aSAndroid Build Coastguard Worker : hi_{static_cast<uint64_t>(static_cast<unsigned __int128>(v) >> 64)},
704*9356374aSAndroid Build Coastguard Worker lo_{static_cast<uint64_t>(v & ~uint64_t{0})} {}
uint128(unsigned __int128 v)705*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(unsigned __int128 v)
706*9356374aSAndroid Build Coastguard Worker : hi_{static_cast<uint64_t>(v >> 64)},
707*9356374aSAndroid Build Coastguard Worker lo_{static_cast<uint64_t>(v & ~uint64_t{0})} {}
708*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_INTRINSIC_INT128
709*9356374aSAndroid Build Coastguard Worker
uint128(int128 v)710*9356374aSAndroid Build Coastguard Worker constexpr uint128::uint128(int128 v)
711*9356374aSAndroid Build Coastguard Worker : hi_{static_cast<uint64_t>(Int128High64(v))}, lo_{Int128Low64(v)} {}
712*9356374aSAndroid Build Coastguard Worker
713*9356374aSAndroid Build Coastguard Worker #else // byte order
714*9356374aSAndroid Build Coastguard Worker #error "Unsupported byte order: must be little-endian or big-endian."
715*9356374aSAndroid Build Coastguard Worker #endif // byte order
716*9356374aSAndroid Build Coastguard Worker
717*9356374aSAndroid Build Coastguard Worker // Conversion operators to integer types.
718*9356374aSAndroid Build Coastguard Worker
719*9356374aSAndroid Build Coastguard Worker constexpr uint128::operator bool() const { return lo_ || hi_; }
720*9356374aSAndroid Build Coastguard Worker
721*9356374aSAndroid Build Coastguard Worker constexpr uint128::operator char() const { return static_cast<char>(lo_); }
722*9356374aSAndroid Build Coastguard Worker
723*9356374aSAndroid Build Coastguard Worker constexpr uint128::operator signed char() const {
724*9356374aSAndroid Build Coastguard Worker return static_cast<signed char>(lo_);
725*9356374aSAndroid Build Coastguard Worker }
726*9356374aSAndroid Build Coastguard Worker
727*9356374aSAndroid Build Coastguard Worker constexpr uint128::operator unsigned char() const {
728*9356374aSAndroid Build Coastguard Worker return static_cast<unsigned char>(lo_);
729*9356374aSAndroid Build Coastguard Worker }
730*9356374aSAndroid Build Coastguard Worker
char16_t()731*9356374aSAndroid Build Coastguard Worker constexpr uint128::operator char16_t() const {
732*9356374aSAndroid Build Coastguard Worker return static_cast<char16_t>(lo_);
733*9356374aSAndroid Build Coastguard Worker }
734*9356374aSAndroid Build Coastguard Worker
char32_t()735*9356374aSAndroid Build Coastguard Worker constexpr uint128::operator char32_t() const {
736*9356374aSAndroid Build Coastguard Worker return static_cast<char32_t>(lo_);
737*9356374aSAndroid Build Coastguard Worker }
738*9356374aSAndroid Build Coastguard Worker
ABSL_INTERNAL_WCHAR_T()739*9356374aSAndroid Build Coastguard Worker constexpr uint128::operator ABSL_INTERNAL_WCHAR_T() const {
740*9356374aSAndroid Build Coastguard Worker return static_cast<ABSL_INTERNAL_WCHAR_T>(lo_);
741*9356374aSAndroid Build Coastguard Worker }
742*9356374aSAndroid Build Coastguard Worker
743*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
744*9356374aSAndroid Build Coastguard Worker constexpr uint128::operator short() const { return static_cast<short>(lo_); }
745*9356374aSAndroid Build Coastguard Worker
746*9356374aSAndroid Build Coastguard Worker constexpr uint128::operator unsigned short() const { // NOLINT(runtime/int)
747*9356374aSAndroid Build Coastguard Worker return static_cast<unsigned short>(lo_); // NOLINT(runtime/int)
748*9356374aSAndroid Build Coastguard Worker }
749*9356374aSAndroid Build Coastguard Worker
750*9356374aSAndroid Build Coastguard Worker constexpr uint128::operator int() const { return static_cast<int>(lo_); }
751*9356374aSAndroid Build Coastguard Worker
752*9356374aSAndroid Build Coastguard Worker constexpr uint128::operator unsigned int() const {
753*9356374aSAndroid Build Coastguard Worker return static_cast<unsigned int>(lo_);
754*9356374aSAndroid Build Coastguard Worker }
755*9356374aSAndroid Build Coastguard Worker
756*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
757*9356374aSAndroid Build Coastguard Worker constexpr uint128::operator long() const { return static_cast<long>(lo_); }
758*9356374aSAndroid Build Coastguard Worker
759*9356374aSAndroid Build Coastguard Worker constexpr uint128::operator unsigned long() const { // NOLINT(runtime/int)
760*9356374aSAndroid Build Coastguard Worker return static_cast<unsigned long>(lo_); // NOLINT(runtime/int)
761*9356374aSAndroid Build Coastguard Worker }
762*9356374aSAndroid Build Coastguard Worker
763*9356374aSAndroid Build Coastguard Worker constexpr uint128::operator long long() const { // NOLINT(runtime/int)
764*9356374aSAndroid Build Coastguard Worker return static_cast<long long>(lo_); // NOLINT(runtime/int)
765*9356374aSAndroid Build Coastguard Worker }
766*9356374aSAndroid Build Coastguard Worker
767*9356374aSAndroid Build Coastguard Worker constexpr uint128::operator unsigned long long() const { // NOLINT(runtime/int)
768*9356374aSAndroid Build Coastguard Worker return static_cast<unsigned long long>(lo_); // NOLINT(runtime/int)
769*9356374aSAndroid Build Coastguard Worker }
770*9356374aSAndroid Build Coastguard Worker
771*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_INTRINSIC_INT128
__int128()772*9356374aSAndroid Build Coastguard Worker constexpr uint128::operator __int128() const {
773*9356374aSAndroid Build Coastguard Worker return (static_cast<__int128>(hi_) << 64) + lo_;
774*9356374aSAndroid Build Coastguard Worker }
775*9356374aSAndroid Build Coastguard Worker
__int128()776*9356374aSAndroid Build Coastguard Worker constexpr uint128::operator unsigned __int128() const {
777*9356374aSAndroid Build Coastguard Worker return (static_cast<unsigned __int128>(hi_) << 64) + lo_;
778*9356374aSAndroid Build Coastguard Worker }
779*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_INTRINSIC_INT128
780*9356374aSAndroid Build Coastguard Worker
781*9356374aSAndroid Build Coastguard Worker // Conversion operators to floating point types.
782*9356374aSAndroid Build Coastguard Worker
783*9356374aSAndroid Build Coastguard Worker inline uint128::operator float() const {
784*9356374aSAndroid Build Coastguard Worker return static_cast<float>(lo_) + std::ldexp(static_cast<float>(hi_), 64);
785*9356374aSAndroid Build Coastguard Worker }
786*9356374aSAndroid Build Coastguard Worker
787*9356374aSAndroid Build Coastguard Worker inline uint128::operator double() const {
788*9356374aSAndroid Build Coastguard Worker return static_cast<double>(lo_) + std::ldexp(static_cast<double>(hi_), 64);
789*9356374aSAndroid Build Coastguard Worker }
790*9356374aSAndroid Build Coastguard Worker
791*9356374aSAndroid Build Coastguard Worker inline uint128::operator long double() const {
792*9356374aSAndroid Build Coastguard Worker return static_cast<long double>(lo_) +
793*9356374aSAndroid Build Coastguard Worker std::ldexp(static_cast<long double>(hi_), 64);
794*9356374aSAndroid Build Coastguard Worker }
795*9356374aSAndroid Build Coastguard Worker
796*9356374aSAndroid Build Coastguard Worker // Comparison operators.
797*9356374aSAndroid Build Coastguard Worker
798*9356374aSAndroid Build Coastguard Worker constexpr bool operator==(uint128 lhs, uint128 rhs) {
799*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_HAVE_INTRINSIC_INT128)
800*9356374aSAndroid Build Coastguard Worker return static_cast<unsigned __int128>(lhs) ==
801*9356374aSAndroid Build Coastguard Worker static_cast<unsigned __int128>(rhs);
802*9356374aSAndroid Build Coastguard Worker #else
803*9356374aSAndroid Build Coastguard Worker return (Uint128Low64(lhs) == Uint128Low64(rhs) &&
804*9356374aSAndroid Build Coastguard Worker Uint128High64(lhs) == Uint128High64(rhs));
805*9356374aSAndroid Build Coastguard Worker #endif
806*9356374aSAndroid Build Coastguard Worker }
807*9356374aSAndroid Build Coastguard Worker
808*9356374aSAndroid Build Coastguard Worker constexpr bool operator!=(uint128 lhs, uint128 rhs) { return !(lhs == rhs); }
809*9356374aSAndroid Build Coastguard Worker
810*9356374aSAndroid Build Coastguard Worker constexpr bool operator<(uint128 lhs, uint128 rhs) {
811*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_INTRINSIC_INT128
812*9356374aSAndroid Build Coastguard Worker return static_cast<unsigned __int128>(lhs) <
813*9356374aSAndroid Build Coastguard Worker static_cast<unsigned __int128>(rhs);
814*9356374aSAndroid Build Coastguard Worker #else
815*9356374aSAndroid Build Coastguard Worker return (Uint128High64(lhs) == Uint128High64(rhs))
816*9356374aSAndroid Build Coastguard Worker ? (Uint128Low64(lhs) < Uint128Low64(rhs))
817*9356374aSAndroid Build Coastguard Worker : (Uint128High64(lhs) < Uint128High64(rhs));
818*9356374aSAndroid Build Coastguard Worker #endif
819*9356374aSAndroid Build Coastguard Worker }
820*9356374aSAndroid Build Coastguard Worker
821*9356374aSAndroid Build Coastguard Worker constexpr bool operator>(uint128 lhs, uint128 rhs) { return rhs < lhs; }
822*9356374aSAndroid Build Coastguard Worker
823*9356374aSAndroid Build Coastguard Worker constexpr bool operator<=(uint128 lhs, uint128 rhs) { return !(rhs < lhs); }
824*9356374aSAndroid Build Coastguard Worker
825*9356374aSAndroid Build Coastguard Worker constexpr bool operator>=(uint128 lhs, uint128 rhs) { return !(lhs < rhs); }
826*9356374aSAndroid Build Coastguard Worker
827*9356374aSAndroid Build Coastguard Worker #ifdef __cpp_impl_three_way_comparison
828*9356374aSAndroid Build Coastguard Worker constexpr absl::strong_ordering operator<=>(uint128 lhs, uint128 rhs) {
829*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_HAVE_INTRINSIC_INT128)
830*9356374aSAndroid Build Coastguard Worker if (auto lhs_128 = static_cast<unsigned __int128>(lhs),
831*9356374aSAndroid Build Coastguard Worker rhs_128 = static_cast<unsigned __int128>(rhs);
832*9356374aSAndroid Build Coastguard Worker lhs_128 < rhs_128) {
833*9356374aSAndroid Build Coastguard Worker return absl::strong_ordering::less;
834*9356374aSAndroid Build Coastguard Worker } else if (lhs_128 > rhs_128) {
835*9356374aSAndroid Build Coastguard Worker return absl::strong_ordering::greater;
836*9356374aSAndroid Build Coastguard Worker } else {
837*9356374aSAndroid Build Coastguard Worker return absl::strong_ordering::equal;
838*9356374aSAndroid Build Coastguard Worker }
839*9356374aSAndroid Build Coastguard Worker #else
840*9356374aSAndroid Build Coastguard Worker if (uint64_t lhs_high = Uint128High64(lhs), rhs_high = Uint128High64(rhs);
841*9356374aSAndroid Build Coastguard Worker lhs_high < rhs_high) {
842*9356374aSAndroid Build Coastguard Worker return absl::strong_ordering::less;
843*9356374aSAndroid Build Coastguard Worker } else if (lhs_high > rhs_high) {
844*9356374aSAndroid Build Coastguard Worker return absl::strong_ordering::greater;
845*9356374aSAndroid Build Coastguard Worker } else if (uint64_t lhs_low = Uint128Low64(lhs), rhs_low = Uint128Low64(rhs);
846*9356374aSAndroid Build Coastguard Worker lhs_low < rhs_low) {
847*9356374aSAndroid Build Coastguard Worker return absl::strong_ordering::less;
848*9356374aSAndroid Build Coastguard Worker } else if (lhs_low > rhs_low) {
849*9356374aSAndroid Build Coastguard Worker return absl::strong_ordering::greater;
850*9356374aSAndroid Build Coastguard Worker } else {
851*9356374aSAndroid Build Coastguard Worker return absl::strong_ordering::equal;
852*9356374aSAndroid Build Coastguard Worker }
853*9356374aSAndroid Build Coastguard Worker #endif
854*9356374aSAndroid Build Coastguard Worker }
855*9356374aSAndroid Build Coastguard Worker #endif
856*9356374aSAndroid Build Coastguard Worker
857*9356374aSAndroid Build Coastguard Worker // Unary operators.
858*9356374aSAndroid Build Coastguard Worker
859*9356374aSAndroid Build Coastguard Worker constexpr inline uint128 operator+(uint128 val) { return val; }
860*9356374aSAndroid Build Coastguard Worker
861*9356374aSAndroid Build Coastguard Worker constexpr inline int128 operator+(int128 val) { return val; }
862*9356374aSAndroid Build Coastguard Worker
863*9356374aSAndroid Build Coastguard Worker constexpr uint128 operator-(uint128 val) {
864*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_HAVE_INTRINSIC_INT128)
865*9356374aSAndroid Build Coastguard Worker return -static_cast<unsigned __int128>(val);
866*9356374aSAndroid Build Coastguard Worker #else
867*9356374aSAndroid Build Coastguard Worker return MakeUint128(
868*9356374aSAndroid Build Coastguard Worker ~Uint128High64(val) + static_cast<unsigned long>(Uint128Low64(val) == 0),
869*9356374aSAndroid Build Coastguard Worker ~Uint128Low64(val) + 1);
870*9356374aSAndroid Build Coastguard Worker #endif
871*9356374aSAndroid Build Coastguard Worker }
872*9356374aSAndroid Build Coastguard Worker
873*9356374aSAndroid Build Coastguard Worker constexpr inline bool operator!(uint128 val) {
874*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_HAVE_INTRINSIC_INT128)
875*9356374aSAndroid Build Coastguard Worker return !static_cast<unsigned __int128>(val);
876*9356374aSAndroid Build Coastguard Worker #else
877*9356374aSAndroid Build Coastguard Worker return !Uint128High64(val) && !Uint128Low64(val);
878*9356374aSAndroid Build Coastguard Worker #endif
879*9356374aSAndroid Build Coastguard Worker }
880*9356374aSAndroid Build Coastguard Worker
881*9356374aSAndroid Build Coastguard Worker // Logical operators.
882*9356374aSAndroid Build Coastguard Worker
883*9356374aSAndroid Build Coastguard Worker constexpr inline uint128 operator~(uint128 val) {
884*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_HAVE_INTRINSIC_INT128)
885*9356374aSAndroid Build Coastguard Worker return ~static_cast<unsigned __int128>(val);
886*9356374aSAndroid Build Coastguard Worker #else
887*9356374aSAndroid Build Coastguard Worker return MakeUint128(~Uint128High64(val), ~Uint128Low64(val));
888*9356374aSAndroid Build Coastguard Worker #endif
889*9356374aSAndroid Build Coastguard Worker }
890*9356374aSAndroid Build Coastguard Worker
891*9356374aSAndroid Build Coastguard Worker constexpr inline uint128 operator|(uint128 lhs, uint128 rhs) {
892*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_HAVE_INTRINSIC_INT128)
893*9356374aSAndroid Build Coastguard Worker return static_cast<unsigned __int128>(lhs) |
894*9356374aSAndroid Build Coastguard Worker static_cast<unsigned __int128>(rhs);
895*9356374aSAndroid Build Coastguard Worker #else
896*9356374aSAndroid Build Coastguard Worker return MakeUint128(Uint128High64(lhs) | Uint128High64(rhs),
897*9356374aSAndroid Build Coastguard Worker Uint128Low64(lhs) | Uint128Low64(rhs));
898*9356374aSAndroid Build Coastguard Worker #endif
899*9356374aSAndroid Build Coastguard Worker }
900*9356374aSAndroid Build Coastguard Worker
901*9356374aSAndroid Build Coastguard Worker constexpr inline uint128 operator&(uint128 lhs, uint128 rhs) {
902*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_HAVE_INTRINSIC_INT128)
903*9356374aSAndroid Build Coastguard Worker return static_cast<unsigned __int128>(lhs) &
904*9356374aSAndroid Build Coastguard Worker static_cast<unsigned __int128>(rhs);
905*9356374aSAndroid Build Coastguard Worker #else
906*9356374aSAndroid Build Coastguard Worker return MakeUint128(Uint128High64(lhs) & Uint128High64(rhs),
907*9356374aSAndroid Build Coastguard Worker Uint128Low64(lhs) & Uint128Low64(rhs));
908*9356374aSAndroid Build Coastguard Worker #endif
909*9356374aSAndroid Build Coastguard Worker }
910*9356374aSAndroid Build Coastguard Worker
911*9356374aSAndroid Build Coastguard Worker constexpr inline uint128 operator^(uint128 lhs, uint128 rhs) {
912*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_HAVE_INTRINSIC_INT128)
913*9356374aSAndroid Build Coastguard Worker return static_cast<unsigned __int128>(lhs) ^
914*9356374aSAndroid Build Coastguard Worker static_cast<unsigned __int128>(rhs);
915*9356374aSAndroid Build Coastguard Worker #else
916*9356374aSAndroid Build Coastguard Worker return MakeUint128(Uint128High64(lhs) ^ Uint128High64(rhs),
917*9356374aSAndroid Build Coastguard Worker Uint128Low64(lhs) ^ Uint128Low64(rhs));
918*9356374aSAndroid Build Coastguard Worker #endif
919*9356374aSAndroid Build Coastguard Worker }
920*9356374aSAndroid Build Coastguard Worker
921*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator|=(uint128 other) {
922*9356374aSAndroid Build Coastguard Worker *this = *this | other;
923*9356374aSAndroid Build Coastguard Worker return *this;
924*9356374aSAndroid Build Coastguard Worker }
925*9356374aSAndroid Build Coastguard Worker
926*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator&=(uint128 other) {
927*9356374aSAndroid Build Coastguard Worker *this = *this & other;
928*9356374aSAndroid Build Coastguard Worker return *this;
929*9356374aSAndroid Build Coastguard Worker }
930*9356374aSAndroid Build Coastguard Worker
931*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator^=(uint128 other) {
932*9356374aSAndroid Build Coastguard Worker *this = *this ^ other;
933*9356374aSAndroid Build Coastguard Worker return *this;
934*9356374aSAndroid Build Coastguard Worker }
935*9356374aSAndroid Build Coastguard Worker
936*9356374aSAndroid Build Coastguard Worker // Arithmetic operators.
937*9356374aSAndroid Build Coastguard Worker
938*9356374aSAndroid Build Coastguard Worker constexpr uint128 operator<<(uint128 lhs, int amount) {
939*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_INTRINSIC_INT128
940*9356374aSAndroid Build Coastguard Worker return static_cast<unsigned __int128>(lhs) << amount;
941*9356374aSAndroid Build Coastguard Worker #else
942*9356374aSAndroid Build Coastguard Worker // uint64_t shifts of >= 64 are undefined, so we will need some
943*9356374aSAndroid Build Coastguard Worker // special-casing.
944*9356374aSAndroid Build Coastguard Worker return amount >= 64 ? MakeUint128(Uint128Low64(lhs) << (amount - 64), 0)
945*9356374aSAndroid Build Coastguard Worker : amount == 0 ? lhs
946*9356374aSAndroid Build Coastguard Worker : MakeUint128((Uint128High64(lhs) << amount) |
947*9356374aSAndroid Build Coastguard Worker (Uint128Low64(lhs) >> (64 - amount)),
948*9356374aSAndroid Build Coastguard Worker Uint128Low64(lhs) << amount);
949*9356374aSAndroid Build Coastguard Worker #endif
950*9356374aSAndroid Build Coastguard Worker }
951*9356374aSAndroid Build Coastguard Worker
952*9356374aSAndroid Build Coastguard Worker constexpr uint128 operator>>(uint128 lhs, int amount) {
953*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_INTRINSIC_INT128
954*9356374aSAndroid Build Coastguard Worker return static_cast<unsigned __int128>(lhs) >> amount;
955*9356374aSAndroid Build Coastguard Worker #else
956*9356374aSAndroid Build Coastguard Worker // uint64_t shifts of >= 64 are undefined, so we will need some
957*9356374aSAndroid Build Coastguard Worker // special-casing.
958*9356374aSAndroid Build Coastguard Worker return amount >= 64 ? MakeUint128(0, Uint128High64(lhs) >> (amount - 64))
959*9356374aSAndroid Build Coastguard Worker : amount == 0 ? lhs
960*9356374aSAndroid Build Coastguard Worker : MakeUint128(Uint128High64(lhs) >> amount,
961*9356374aSAndroid Build Coastguard Worker (Uint128Low64(lhs) >> amount) |
962*9356374aSAndroid Build Coastguard Worker (Uint128High64(lhs) << (64 - amount)));
963*9356374aSAndroid Build Coastguard Worker #endif
964*9356374aSAndroid Build Coastguard Worker }
965*9356374aSAndroid Build Coastguard Worker
966*9356374aSAndroid Build Coastguard Worker #if !defined(ABSL_HAVE_INTRINSIC_INT128)
967*9356374aSAndroid Build Coastguard Worker namespace int128_internal {
AddResult(uint128 result,uint128 lhs)968*9356374aSAndroid Build Coastguard Worker constexpr uint128 AddResult(uint128 result, uint128 lhs) {
969*9356374aSAndroid Build Coastguard Worker // check for carry
970*9356374aSAndroid Build Coastguard Worker return (Uint128Low64(result) < Uint128Low64(lhs))
971*9356374aSAndroid Build Coastguard Worker ? MakeUint128(Uint128High64(result) + 1, Uint128Low64(result))
972*9356374aSAndroid Build Coastguard Worker : result;
973*9356374aSAndroid Build Coastguard Worker }
974*9356374aSAndroid Build Coastguard Worker } // namespace int128_internal
975*9356374aSAndroid Build Coastguard Worker #endif
976*9356374aSAndroid Build Coastguard Worker
977*9356374aSAndroid Build Coastguard Worker constexpr uint128 operator+(uint128 lhs, uint128 rhs) {
978*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_HAVE_INTRINSIC_INT128)
979*9356374aSAndroid Build Coastguard Worker return static_cast<unsigned __int128>(lhs) +
980*9356374aSAndroid Build Coastguard Worker static_cast<unsigned __int128>(rhs);
981*9356374aSAndroid Build Coastguard Worker #else
982*9356374aSAndroid Build Coastguard Worker return int128_internal::AddResult(
983*9356374aSAndroid Build Coastguard Worker MakeUint128(Uint128High64(lhs) + Uint128High64(rhs),
984*9356374aSAndroid Build Coastguard Worker Uint128Low64(lhs) + Uint128Low64(rhs)),
985*9356374aSAndroid Build Coastguard Worker lhs);
986*9356374aSAndroid Build Coastguard Worker #endif
987*9356374aSAndroid Build Coastguard Worker }
988*9356374aSAndroid Build Coastguard Worker
989*9356374aSAndroid Build Coastguard Worker #if !defined(ABSL_HAVE_INTRINSIC_INT128)
990*9356374aSAndroid Build Coastguard Worker namespace int128_internal {
SubstructResult(uint128 result,uint128 lhs,uint128 rhs)991*9356374aSAndroid Build Coastguard Worker constexpr uint128 SubstructResult(uint128 result, uint128 lhs, uint128 rhs) {
992*9356374aSAndroid Build Coastguard Worker // check for carry
993*9356374aSAndroid Build Coastguard Worker return (Uint128Low64(lhs) < Uint128Low64(rhs))
994*9356374aSAndroid Build Coastguard Worker ? MakeUint128(Uint128High64(result) - 1, Uint128Low64(result))
995*9356374aSAndroid Build Coastguard Worker : result;
996*9356374aSAndroid Build Coastguard Worker }
997*9356374aSAndroid Build Coastguard Worker } // namespace int128_internal
998*9356374aSAndroid Build Coastguard Worker #endif
999*9356374aSAndroid Build Coastguard Worker
1000*9356374aSAndroid Build Coastguard Worker constexpr uint128 operator-(uint128 lhs, uint128 rhs) {
1001*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_HAVE_INTRINSIC_INT128)
1002*9356374aSAndroid Build Coastguard Worker return static_cast<unsigned __int128>(lhs) -
1003*9356374aSAndroid Build Coastguard Worker static_cast<unsigned __int128>(rhs);
1004*9356374aSAndroid Build Coastguard Worker #else
1005*9356374aSAndroid Build Coastguard Worker return int128_internal::SubstructResult(
1006*9356374aSAndroid Build Coastguard Worker MakeUint128(Uint128High64(lhs) - Uint128High64(rhs),
1007*9356374aSAndroid Build Coastguard Worker Uint128Low64(lhs) - Uint128Low64(rhs)),
1008*9356374aSAndroid Build Coastguard Worker lhs, rhs);
1009*9356374aSAndroid Build Coastguard Worker #endif
1010*9356374aSAndroid Build Coastguard Worker }
1011*9356374aSAndroid Build Coastguard Worker
1012*9356374aSAndroid Build Coastguard Worker inline uint128 operator*(uint128 lhs, uint128 rhs) {
1013*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_HAVE_INTRINSIC_INT128)
1014*9356374aSAndroid Build Coastguard Worker // TODO(strel) Remove once alignment issues are resolved and unsigned __int128
1015*9356374aSAndroid Build Coastguard Worker // can be used for uint128 storage.
1016*9356374aSAndroid Build Coastguard Worker return static_cast<unsigned __int128>(lhs) *
1017*9356374aSAndroid Build Coastguard Worker static_cast<unsigned __int128>(rhs);
1018*9356374aSAndroid Build Coastguard Worker #elif defined(_MSC_VER) && defined(_M_X64) && !defined(_M_ARM64EC)
1019*9356374aSAndroid Build Coastguard Worker uint64_t carry;
1020*9356374aSAndroid Build Coastguard Worker uint64_t low = _umul128(Uint128Low64(lhs), Uint128Low64(rhs), &carry);
1021*9356374aSAndroid Build Coastguard Worker return MakeUint128(Uint128Low64(lhs) * Uint128High64(rhs) +
1022*9356374aSAndroid Build Coastguard Worker Uint128High64(lhs) * Uint128Low64(rhs) + carry,
1023*9356374aSAndroid Build Coastguard Worker low);
1024*9356374aSAndroid Build Coastguard Worker #else // ABSL_HAVE_INTRINSIC128
1025*9356374aSAndroid Build Coastguard Worker uint64_t a32 = Uint128Low64(lhs) >> 32;
1026*9356374aSAndroid Build Coastguard Worker uint64_t a00 = Uint128Low64(lhs) & 0xffffffff;
1027*9356374aSAndroid Build Coastguard Worker uint64_t b32 = Uint128Low64(rhs) >> 32;
1028*9356374aSAndroid Build Coastguard Worker uint64_t b00 = Uint128Low64(rhs) & 0xffffffff;
1029*9356374aSAndroid Build Coastguard Worker uint128 result =
1030*9356374aSAndroid Build Coastguard Worker MakeUint128(Uint128High64(lhs) * Uint128Low64(rhs) +
1031*9356374aSAndroid Build Coastguard Worker Uint128Low64(lhs) * Uint128High64(rhs) + a32 * b32,
1032*9356374aSAndroid Build Coastguard Worker a00 * b00);
1033*9356374aSAndroid Build Coastguard Worker result += uint128(a32 * b00) << 32;
1034*9356374aSAndroid Build Coastguard Worker result += uint128(a00 * b32) << 32;
1035*9356374aSAndroid Build Coastguard Worker return result;
1036*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_INTRINSIC128
1037*9356374aSAndroid Build Coastguard Worker }
1038*9356374aSAndroid Build Coastguard Worker
1039*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_HAVE_INTRINSIC_INT128)
1040*9356374aSAndroid Build Coastguard Worker inline uint128 operator/(uint128 lhs, uint128 rhs) {
1041*9356374aSAndroid Build Coastguard Worker return static_cast<unsigned __int128>(lhs) /
1042*9356374aSAndroid Build Coastguard Worker static_cast<unsigned __int128>(rhs);
1043*9356374aSAndroid Build Coastguard Worker }
1044*9356374aSAndroid Build Coastguard Worker
1045*9356374aSAndroid Build Coastguard Worker inline uint128 operator%(uint128 lhs, uint128 rhs) {
1046*9356374aSAndroid Build Coastguard Worker return static_cast<unsigned __int128>(lhs) %
1047*9356374aSAndroid Build Coastguard Worker static_cast<unsigned __int128>(rhs);
1048*9356374aSAndroid Build Coastguard Worker }
1049*9356374aSAndroid Build Coastguard Worker #endif
1050*9356374aSAndroid Build Coastguard Worker
1051*9356374aSAndroid Build Coastguard Worker // Increment/decrement operators.
1052*9356374aSAndroid Build Coastguard Worker
1053*9356374aSAndroid Build Coastguard Worker inline uint128 uint128::operator++(int) {
1054*9356374aSAndroid Build Coastguard Worker uint128 tmp(*this);
1055*9356374aSAndroid Build Coastguard Worker *this += 1;
1056*9356374aSAndroid Build Coastguard Worker return tmp;
1057*9356374aSAndroid Build Coastguard Worker }
1058*9356374aSAndroid Build Coastguard Worker
1059*9356374aSAndroid Build Coastguard Worker inline uint128 uint128::operator--(int) {
1060*9356374aSAndroid Build Coastguard Worker uint128 tmp(*this);
1061*9356374aSAndroid Build Coastguard Worker *this -= 1;
1062*9356374aSAndroid Build Coastguard Worker return tmp;
1063*9356374aSAndroid Build Coastguard Worker }
1064*9356374aSAndroid Build Coastguard Worker
1065*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator++() {
1066*9356374aSAndroid Build Coastguard Worker *this += 1;
1067*9356374aSAndroid Build Coastguard Worker return *this;
1068*9356374aSAndroid Build Coastguard Worker }
1069*9356374aSAndroid Build Coastguard Worker
1070*9356374aSAndroid Build Coastguard Worker inline uint128& uint128::operator--() {
1071*9356374aSAndroid Build Coastguard Worker *this -= 1;
1072*9356374aSAndroid Build Coastguard Worker return *this;
1073*9356374aSAndroid Build Coastguard Worker }
1074*9356374aSAndroid Build Coastguard Worker
MakeInt128(int64_t high,uint64_t low)1075*9356374aSAndroid Build Coastguard Worker constexpr int128 MakeInt128(int64_t high, uint64_t low) {
1076*9356374aSAndroid Build Coastguard Worker return int128(high, low);
1077*9356374aSAndroid Build Coastguard Worker }
1078*9356374aSAndroid Build Coastguard Worker
1079*9356374aSAndroid Build Coastguard Worker // Assignment from integer types.
1080*9356374aSAndroid Build Coastguard Worker inline int128& int128::operator=(int v) { return *this = int128(v); }
1081*9356374aSAndroid Build Coastguard Worker
1082*9356374aSAndroid Build Coastguard Worker inline int128& int128::operator=(unsigned int v) { return *this = int128(v); }
1083*9356374aSAndroid Build Coastguard Worker
1084*9356374aSAndroid Build Coastguard Worker inline int128& int128::operator=(long v) { // NOLINT(runtime/int)
1085*9356374aSAndroid Build Coastguard Worker return *this = int128(v);
1086*9356374aSAndroid Build Coastguard Worker }
1087*9356374aSAndroid Build Coastguard Worker
1088*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
1089*9356374aSAndroid Build Coastguard Worker inline int128& int128::operator=(unsigned long v) { return *this = int128(v); }
1090*9356374aSAndroid Build Coastguard Worker
1091*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
1092*9356374aSAndroid Build Coastguard Worker inline int128& int128::operator=(long long v) { return *this = int128(v); }
1093*9356374aSAndroid Build Coastguard Worker
1094*9356374aSAndroid Build Coastguard Worker // NOLINTNEXTLINE(runtime/int)
1095*9356374aSAndroid Build Coastguard Worker inline int128& int128::operator=(unsigned long long v) {
1096*9356374aSAndroid Build Coastguard Worker return *this = int128(v);
1097*9356374aSAndroid Build Coastguard Worker }
1098*9356374aSAndroid Build Coastguard Worker
1099*9356374aSAndroid Build Coastguard Worker // Arithmetic operators.
1100*9356374aSAndroid Build Coastguard Worker constexpr int128 operator-(int128 v);
1101*9356374aSAndroid Build Coastguard Worker constexpr int128 operator+(int128 lhs, int128 rhs);
1102*9356374aSAndroid Build Coastguard Worker constexpr int128 operator-(int128 lhs, int128 rhs);
1103*9356374aSAndroid Build Coastguard Worker int128 operator*(int128 lhs, int128 rhs);
1104*9356374aSAndroid Build Coastguard Worker int128 operator/(int128 lhs, int128 rhs);
1105*9356374aSAndroid Build Coastguard Worker int128 operator%(int128 lhs, int128 rhs);
1106*9356374aSAndroid Build Coastguard Worker constexpr int128 operator|(int128 lhs, int128 rhs);
1107*9356374aSAndroid Build Coastguard Worker constexpr int128 operator&(int128 lhs, int128 rhs);
1108*9356374aSAndroid Build Coastguard Worker constexpr int128 operator^(int128 lhs, int128 rhs);
1109*9356374aSAndroid Build Coastguard Worker constexpr int128 operator<<(int128 lhs, int amount);
1110*9356374aSAndroid Build Coastguard Worker constexpr int128 operator>>(int128 lhs, int amount);
1111*9356374aSAndroid Build Coastguard Worker
1112*9356374aSAndroid Build Coastguard Worker inline int128& int128::operator+=(int128 other) {
1113*9356374aSAndroid Build Coastguard Worker *this = *this + other;
1114*9356374aSAndroid Build Coastguard Worker return *this;
1115*9356374aSAndroid Build Coastguard Worker }
1116*9356374aSAndroid Build Coastguard Worker
1117*9356374aSAndroid Build Coastguard Worker inline int128& int128::operator-=(int128 other) {
1118*9356374aSAndroid Build Coastguard Worker *this = *this - other;
1119*9356374aSAndroid Build Coastguard Worker return *this;
1120*9356374aSAndroid Build Coastguard Worker }
1121*9356374aSAndroid Build Coastguard Worker
1122*9356374aSAndroid Build Coastguard Worker inline int128& int128::operator*=(int128 other) {
1123*9356374aSAndroid Build Coastguard Worker *this = *this * other;
1124*9356374aSAndroid Build Coastguard Worker return *this;
1125*9356374aSAndroid Build Coastguard Worker }
1126*9356374aSAndroid Build Coastguard Worker
1127*9356374aSAndroid Build Coastguard Worker inline int128& int128::operator/=(int128 other) {
1128*9356374aSAndroid Build Coastguard Worker *this = *this / other;
1129*9356374aSAndroid Build Coastguard Worker return *this;
1130*9356374aSAndroid Build Coastguard Worker }
1131*9356374aSAndroid Build Coastguard Worker
1132*9356374aSAndroid Build Coastguard Worker inline int128& int128::operator%=(int128 other) {
1133*9356374aSAndroid Build Coastguard Worker *this = *this % other;
1134*9356374aSAndroid Build Coastguard Worker return *this;
1135*9356374aSAndroid Build Coastguard Worker }
1136*9356374aSAndroid Build Coastguard Worker
1137*9356374aSAndroid Build Coastguard Worker inline int128& int128::operator|=(int128 other) {
1138*9356374aSAndroid Build Coastguard Worker *this = *this | other;
1139*9356374aSAndroid Build Coastguard Worker return *this;
1140*9356374aSAndroid Build Coastguard Worker }
1141*9356374aSAndroid Build Coastguard Worker
1142*9356374aSAndroid Build Coastguard Worker inline int128& int128::operator&=(int128 other) {
1143*9356374aSAndroid Build Coastguard Worker *this = *this & other;
1144*9356374aSAndroid Build Coastguard Worker return *this;
1145*9356374aSAndroid Build Coastguard Worker }
1146*9356374aSAndroid Build Coastguard Worker
1147*9356374aSAndroid Build Coastguard Worker inline int128& int128::operator^=(int128 other) {
1148*9356374aSAndroid Build Coastguard Worker *this = *this ^ other;
1149*9356374aSAndroid Build Coastguard Worker return *this;
1150*9356374aSAndroid Build Coastguard Worker }
1151*9356374aSAndroid Build Coastguard Worker
1152*9356374aSAndroid Build Coastguard Worker inline int128& int128::operator<<=(int amount) {
1153*9356374aSAndroid Build Coastguard Worker *this = *this << amount;
1154*9356374aSAndroid Build Coastguard Worker return *this;
1155*9356374aSAndroid Build Coastguard Worker }
1156*9356374aSAndroid Build Coastguard Worker
1157*9356374aSAndroid Build Coastguard Worker inline int128& int128::operator>>=(int amount) {
1158*9356374aSAndroid Build Coastguard Worker *this = *this >> amount;
1159*9356374aSAndroid Build Coastguard Worker return *this;
1160*9356374aSAndroid Build Coastguard Worker }
1161*9356374aSAndroid Build Coastguard Worker
1162*9356374aSAndroid Build Coastguard Worker // Forward declaration for comparison operators.
1163*9356374aSAndroid Build Coastguard Worker constexpr bool operator!=(int128 lhs, int128 rhs);
1164*9356374aSAndroid Build Coastguard Worker
1165*9356374aSAndroid Build Coastguard Worker namespace int128_internal {
1166*9356374aSAndroid Build Coastguard Worker
1167*9356374aSAndroid Build Coastguard Worker // Casts from unsigned to signed while preserving the underlying binary
1168*9356374aSAndroid Build Coastguard Worker // representation.
BitCastToSigned(uint64_t v)1169*9356374aSAndroid Build Coastguard Worker constexpr int64_t BitCastToSigned(uint64_t v) {
1170*9356374aSAndroid Build Coastguard Worker // Casting an unsigned integer to a signed integer of the same
1171*9356374aSAndroid Build Coastguard Worker // width is implementation defined behavior if the source value would not fit
1172*9356374aSAndroid Build Coastguard Worker // in the destination type. We step around it with a roundtrip bitwise not
1173*9356374aSAndroid Build Coastguard Worker // operation to make sure this function remains constexpr. Clang, GCC, and
1174*9356374aSAndroid Build Coastguard Worker // MSVC optimize this to a no-op on x86-64.
1175*9356374aSAndroid Build Coastguard Worker return v & (uint64_t{1} << 63) ? ~static_cast<int64_t>(~v)
1176*9356374aSAndroid Build Coastguard Worker : static_cast<int64_t>(v);
1177*9356374aSAndroid Build Coastguard Worker }
1178*9356374aSAndroid Build Coastguard Worker
1179*9356374aSAndroid Build Coastguard Worker } // namespace int128_internal
1180*9356374aSAndroid Build Coastguard Worker
1181*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_HAVE_INTRINSIC_INT128)
1182*9356374aSAndroid Build Coastguard Worker #include "absl/numeric/int128_have_intrinsic.inc" // IWYU pragma: export
1183*9356374aSAndroid Build Coastguard Worker #else // ABSL_HAVE_INTRINSIC_INT128
1184*9356374aSAndroid Build Coastguard Worker #include "absl/numeric/int128_no_intrinsic.inc" // IWYU pragma: export
1185*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_INTRINSIC_INT128
1186*9356374aSAndroid Build Coastguard Worker
1187*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END
1188*9356374aSAndroid Build Coastguard Worker } // namespace absl
1189*9356374aSAndroid Build Coastguard Worker
1190*9356374aSAndroid Build Coastguard Worker #undef ABSL_INTERNAL_WCHAR_T
1191*9356374aSAndroid Build Coastguard Worker
1192*9356374aSAndroid Build Coastguard Worker #endif // ABSL_NUMERIC_INT128_H_
1193