xref: /aosp_15_r20/external/llvm-libc/src/__support/big_int.h (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1 //===-- A class to manipulate wide integers. --------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_LIBC_SRC___SUPPORT_BIG_INT_H
10 #define LLVM_LIBC_SRC___SUPPORT_BIG_INT_H
11 
12 #include "src/__support/CPP/array.h"
13 #include "src/__support/CPP/bit.h" // countl_zero
14 #include "src/__support/CPP/limits.h"
15 #include "src/__support/CPP/optional.h"
16 #include "src/__support/CPP/type_traits.h"
17 #include "src/__support/macros/attributes.h" // LIBC_INLINE
18 #include "src/__support/macros/config.h"
19 #include "src/__support/macros/optimization.h"        // LIBC_UNLIKELY
20 #include "src/__support/macros/properties/compiler.h" // LIBC_COMPILER_IS_CLANG
21 #include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128, LIBC_TYPES_HAS_INT64
22 #include "src/__support/math_extras.h" // add_with_carry, sub_with_borrow
23 #include "src/__support/number_pair.h"
24 
25 #include <stddef.h> // For size_t
26 #include <stdint.h>
27 
28 namespace LIBC_NAMESPACE_DECL {
29 
30 namespace multiword {
31 
32 // A type trait mapping unsigned integers to their half-width unsigned
33 // counterparts.
34 template <typename T> struct half_width;
35 template <> struct half_width<uint16_t> : cpp::type_identity<uint8_t> {};
36 template <> struct half_width<uint32_t> : cpp::type_identity<uint16_t> {};
37 #ifdef LIBC_TYPES_HAS_INT64
38 template <> struct half_width<uint64_t> : cpp::type_identity<uint32_t> {};
39 #ifdef LIBC_TYPES_HAS_INT128
40 template <> struct half_width<__uint128_t> : cpp::type_identity<uint64_t> {};
41 #endif // LIBC_TYPES_HAS_INT128
42 #endif // LIBC_TYPES_HAS_INT64
43 template <typename T> using half_width_t = typename half_width<T>::type;
44 
45 // An array of two elements that can be used in multiword operations.
46 template <typename T> struct DoubleWide final : cpp::array<T, 2> {
47   using UP = cpp::array<T, 2>;
48   using UP::UP;
49   LIBC_INLINE constexpr DoubleWide(T lo, T hi) : UP({lo, hi}) {}
50 };
51 
52 // Converts an unsigned value into a DoubleWide<half_width_t<T>>.
53 template <typename T> LIBC_INLINE constexpr auto split(T value) {
54   static_assert(cpp::is_unsigned_v<T>);
55   using half_type = half_width_t<T>;
56   return DoubleWide<half_type>(
57       half_type(value),
58       half_type(value >> cpp::numeric_limits<half_type>::digits));
59 }
60 
61 // The low part of a DoubleWide value.
62 template <typename T> LIBC_INLINE constexpr T lo(const DoubleWide<T> &value) {
63   return value[0];
64 }
65 // The high part of a DoubleWide value.
66 template <typename T> LIBC_INLINE constexpr T hi(const DoubleWide<T> &value) {
67   return value[1];
68 }
69 // The low part of an unsigned value.
70 template <typename T> LIBC_INLINE constexpr half_width_t<T> lo(T value) {
71   return lo(split(value));
72 }
73 // The high part of an unsigned value.
74 template <typename T> LIBC_INLINE constexpr half_width_t<T> hi(T value) {
75   return hi(split(value));
76 }
77 
78 // Returns 'a' times 'b' in a DoubleWide<word>. Cannot overflow by construction.
79 template <typename word>
80 LIBC_INLINE constexpr DoubleWide<word> mul2(word a, word b) {
81   if constexpr (cpp::is_same_v<word, uint8_t>) {
82     return split<uint16_t>(uint16_t(a) * uint16_t(b));
83   } else if constexpr (cpp::is_same_v<word, uint16_t>) {
84     return split<uint32_t>(uint32_t(a) * uint32_t(b));
85   }
86 #ifdef LIBC_TYPES_HAS_INT64
87   else if constexpr (cpp::is_same_v<word, uint32_t>) {
88     return split<uint64_t>(uint64_t(a) * uint64_t(b));
89   }
90 #endif
91 #ifdef LIBC_TYPES_HAS_INT128
92   else if constexpr (cpp::is_same_v<word, uint64_t>) {
93     return split<__uint128_t>(__uint128_t(a) * __uint128_t(b));
94   }
95 #endif
96   else {
97     using half_word = half_width_t<word>;
98     const auto shiftl = [](word value) -> word {
99       return value << cpp::numeric_limits<half_word>::digits;
100     };
101     const auto shiftr = [](word value) -> word {
102       return value >> cpp::numeric_limits<half_word>::digits;
103     };
104     // Here we do a one digit multiplication where 'a' and 'b' are of type
105     // word. We split 'a' and 'b' into half words and perform the classic long
106     // multiplication with 'a' and 'b' being two-digit numbers.
107 
108     //    a      a_hi a_lo
109     //  x b => x b_hi b_lo
110     // ----    -----------
111     //    c         result
112     // We convert 'lo' and 'hi' from 'half_word' to 'word' so multiplication
113     // doesn't overflow.
114     const word a_lo = lo(a);
115     const word b_lo = lo(b);
116     const word a_hi = hi(a);
117     const word b_hi = hi(b);
118     const word step1 = b_lo * a_lo; // no overflow;
119     const word step2 = b_lo * a_hi; // no overflow;
120     const word step3 = b_hi * a_lo; // no overflow;
121     const word step4 = b_hi * a_hi; // no overflow;
122     word lo_digit = step1;
123     word hi_digit = step4;
124     const word no_carry = 0;
125     word carry;
126     word _; // unused carry variable.
127     lo_digit = add_with_carry<word>(lo_digit, shiftl(step2), no_carry, carry);
128     hi_digit = add_with_carry<word>(hi_digit, shiftr(step2), carry, _);
129     lo_digit = add_with_carry<word>(lo_digit, shiftl(step3), no_carry, carry);
130     hi_digit = add_with_carry<word>(hi_digit, shiftr(step3), carry, _);
131     return DoubleWide<word>(lo_digit, hi_digit);
132   }
133 }
134 
135 // In-place 'dst op= rhs' with operation with carry propagation. Returns carry.
136 template <typename Function, typename word, size_t N, size_t M>
137 LIBC_INLINE constexpr word inplace_binop(Function op_with_carry,
138                                          cpp::array<word, N> &dst,
139                                          const cpp::array<word, M> &rhs) {
140   static_assert(N >= M);
141   word carry_out = 0;
142   for (size_t i = 0; i < N; ++i) {
143     const bool has_rhs_value = i < M;
144     const word rhs_value = has_rhs_value ? rhs[i] : 0;
145     const word carry_in = carry_out;
146     dst[i] = op_with_carry(dst[i], rhs_value, carry_in, carry_out);
147     // stop early when rhs is over and no carry is to be propagated.
148     if (!has_rhs_value && carry_out == 0)
149       break;
150   }
151   return carry_out;
152 }
153 
154 // In-place addition. Returns carry.
155 template <typename word, size_t N, size_t M>
156 LIBC_INLINE constexpr word add_with_carry(cpp::array<word, N> &dst,
157                                           const cpp::array<word, M> &rhs) {
158   return inplace_binop(LIBC_NAMESPACE::add_with_carry<word>, dst, rhs);
159 }
160 
161 // In-place subtraction. Returns borrow.
162 template <typename word, size_t N, size_t M>
163 LIBC_INLINE constexpr word sub_with_borrow(cpp::array<word, N> &dst,
164                                            const cpp::array<word, M> &rhs) {
165   return inplace_binop(LIBC_NAMESPACE::sub_with_borrow<word>, dst, rhs);
166 }
167 
168 // In-place multiply-add. Returns carry.
169 // i.e., 'dst += b * c'
170 template <typename word, size_t N>
171 LIBC_INLINE constexpr word mul_add_with_carry(cpp::array<word, N> &dst, word b,
172                                               word c) {
173   return add_with_carry(dst, mul2(b, c));
174 }
175 
176 // An array of two elements serving as an accumulator during multiword
177 // computations.
178 template <typename T> struct Accumulator final : cpp::array<T, 2> {
179   using UP = cpp::array<T, 2>;
180   LIBC_INLINE constexpr Accumulator() : UP({0, 0}) {}
181   LIBC_INLINE constexpr T advance(T carry_in) {
182     auto result = UP::front();
183     UP::front() = UP::back();
184     UP::back() = carry_in;
185     return result;
186   }
187   LIBC_INLINE constexpr T sum() const { return UP::front(); }
188   LIBC_INLINE constexpr T carry() const { return UP::back(); }
189 };
190 
191 // In-place multiplication by a single word. Returns carry.
192 template <typename word, size_t N>
193 LIBC_INLINE constexpr word scalar_multiply_with_carry(cpp::array<word, N> &dst,
194                                                       word x) {
195   Accumulator<word> acc;
196   for (auto &val : dst) {
197     const word carry = mul_add_with_carry(acc, val, x);
198     val = acc.advance(carry);
199   }
200   return acc.carry();
201 }
202 
203 // Multiplication of 'lhs' by 'rhs' into 'dst'. Returns carry.
204 // This function is safe to use for signed numbers.
205 // https://stackoverflow.com/a/20793834
206 // https://pages.cs.wisc.edu/%7Emarkhill/cs354/Fall2008/beyond354/int.mult.html
207 template <typename word, size_t O, size_t M, size_t N>
208 LIBC_INLINE constexpr word multiply_with_carry(cpp::array<word, O> &dst,
209                                                const cpp::array<word, M> &lhs,
210                                                const cpp::array<word, N> &rhs) {
211   static_assert(O >= M + N);
212   Accumulator<word> acc;
213   for (size_t i = 0; i < O; ++i) {
214     const size_t lower_idx = i < N ? 0 : i - N + 1;
215     const size_t upper_idx = i < M ? i : M - 1;
216     word carry = 0;
217     for (size_t j = lower_idx; j <= upper_idx; ++j)
218       carry += mul_add_with_carry(acc, lhs[j], rhs[i - j]);
219     dst[i] = acc.advance(carry);
220   }
221   return acc.carry();
222 }
223 
224 template <typename word, size_t N>
225 LIBC_INLINE constexpr void quick_mul_hi(cpp::array<word, N> &dst,
226                                         const cpp::array<word, N> &lhs,
227                                         const cpp::array<word, N> &rhs) {
228   Accumulator<word> acc;
229   word carry = 0;
230   // First round of accumulation for those at N - 1 in the full product.
231   for (size_t i = 0; i < N; ++i)
232     carry += mul_add_with_carry(acc, lhs[i], rhs[N - 1 - i]);
233   for (size_t i = N; i < 2 * N - 1; ++i) {
234     acc.advance(carry);
235     carry = 0;
236     for (size_t j = i - N + 1; j < N; ++j)
237       carry += mul_add_with_carry(acc, lhs[j], rhs[i - j]);
238     dst[i - N] = acc.sum();
239   }
240   dst.back() = acc.carry();
241 }
242 
243 template <typename word, size_t N>
244 LIBC_INLINE constexpr bool is_negative(cpp::array<word, N> &array) {
245   using signed_word = cpp::make_signed_t<word>;
246   return cpp::bit_cast<signed_word>(array.back()) < 0;
247 }
248 
249 // An enum for the shift function below.
250 enum Direction { LEFT, RIGHT };
251 
252 // A bitwise shift on an array of elements.
253 // 'offset' must be less than TOTAL_BITS (i.e., sizeof(word) * CHAR_BIT * N)
254 // otherwise the behavior is undefined.
255 template <Direction direction, bool is_signed, typename word, size_t N>
256 LIBC_INLINE constexpr cpp::array<word, N> shift(cpp::array<word, N> array,
257                                                 size_t offset) {
258   static_assert(direction == LEFT || direction == RIGHT);
259   constexpr size_t WORD_BITS = cpp::numeric_limits<word>::digits;
260 #ifdef LIBC_TYPES_HAS_INT128
261   constexpr size_t TOTAL_BITS = N * WORD_BITS;
262   if constexpr (TOTAL_BITS == 128) {
263     using type = cpp::conditional_t<is_signed, __int128_t, __uint128_t>;
264     auto tmp = cpp::bit_cast<type>(array);
265     if constexpr (direction == LEFT)
266       tmp <<= offset;
267     else
268       tmp >>= offset;
269     return cpp::bit_cast<cpp::array<word, N>>(tmp);
270   }
271 #endif
272   if (LIBC_UNLIKELY(offset == 0))
273     return array;
274   const bool is_neg = is_signed && is_negative(array);
275   constexpr auto at = [](size_t index) -> int {
276     // reverse iteration when direction == LEFT.
277     if constexpr (direction == LEFT)
278       return int(N) - int(index) - 1;
279     return int(index);
280   };
281   const auto safe_get_at = [&](size_t index) -> word {
282     // return appropriate value when accessing out of bound elements.
283     const int i = at(index);
284     if (i < 0)
285       return 0;
286     if (i >= int(N))
287       return is_neg ? -1 : 0;
288     return array[i];
289   };
290   const size_t index_offset = offset / WORD_BITS;
291   const size_t bit_offset = offset % WORD_BITS;
292 #ifdef LIBC_COMPILER_IS_CLANG
293   __builtin_assume(index_offset < N);
294 #endif
295   cpp::array<word, N> out = {};
296   for (size_t index = 0; index < N; ++index) {
297     const word part1 = safe_get_at(index + index_offset);
298     const word part2 = safe_get_at(index + index_offset + 1);
299     word &dst = out[at(index)];
300     if (bit_offset == 0)
301       dst = part1; // no crosstalk between parts.
302     else if constexpr (direction == LEFT)
303       dst = static_cast<word>((part1 << bit_offset) |
304                               (part2 >> (WORD_BITS - bit_offset)));
305     else
306       dst = static_cast<word>((part1 >> bit_offset) |
307                               (part2 << (WORD_BITS - bit_offset)));
308   }
309   return out;
310 }
311 
312 #define DECLARE_COUNTBIT(NAME, INDEX_EXPR)                                     \
313   template <typename word, size_t N>                                           \
314   LIBC_INLINE constexpr int NAME(const cpp::array<word, N> &val) {             \
315     int bit_count = 0;                                                         \
316     for (size_t i = 0; i < N; ++i) {                                           \
317       const int word_count = cpp::NAME<word>(val[INDEX_EXPR]);                 \
318       bit_count += word_count;                                                 \
319       if (word_count != cpp::numeric_limits<word>::digits)                     \
320         break;                                                                 \
321     }                                                                          \
322     return bit_count;                                                          \
323   }
324 
325 DECLARE_COUNTBIT(countr_zero, i)         // iterating forward
326 DECLARE_COUNTBIT(countr_one, i)          // iterating forward
327 DECLARE_COUNTBIT(countl_zero, N - i - 1) // iterating backward
328 DECLARE_COUNTBIT(countl_one, N - i - 1)  // iterating backward
329 
330 } // namespace multiword
331 
332 template <size_t Bits, bool Signed, typename WordType = uint64_t>
333 struct BigInt {
334 private:
335   static_assert(cpp::is_integral_v<WordType> && cpp::is_unsigned_v<WordType>,
336                 "WordType must be unsigned integer.");
337 
338   struct Division {
339     BigInt quotient;
340     BigInt remainder;
341   };
342 
343 public:
344   using word_type = WordType;
345   using unsigned_type = BigInt<Bits, false, word_type>;
346   using signed_type = BigInt<Bits, true, word_type>;
347 
348   LIBC_INLINE_VAR static constexpr bool SIGNED = Signed;
349   LIBC_INLINE_VAR static constexpr size_t BITS = Bits;
350   LIBC_INLINE_VAR
351   static constexpr size_t WORD_SIZE = sizeof(WordType) * CHAR_BIT;
352 
353   static_assert(Bits > 0 && Bits % WORD_SIZE == 0,
354                 "Number of bits in BigInt should be a multiple of WORD_SIZE.");
355 
356   LIBC_INLINE_VAR static constexpr size_t WORD_COUNT = Bits / WORD_SIZE;
357 
358   cpp::array<WordType, WORD_COUNT> val{}; // zero initialized.
359 
360   LIBC_INLINE constexpr BigInt() = default;
361 
362   LIBC_INLINE constexpr BigInt(const BigInt &other) = default;
363 
364   template <size_t OtherBits, bool OtherSigned, typename OtherWordType>
365   LIBC_INLINE constexpr BigInt(
366       const BigInt<OtherBits, OtherSigned, OtherWordType> &other) {
367     using BigIntOther = BigInt<OtherBits, OtherSigned, OtherWordType>;
368     const bool should_sign_extend = Signed && other.is_neg();
369 
370     static_assert(!(Bits == OtherBits && WORD_SIZE != BigIntOther::WORD_SIZE) &&
371                   "This is currently untested for casting between bigints with "
372                   "the same bit width but different word sizes.");
373 
374     if constexpr (BigIntOther::WORD_SIZE < WORD_SIZE) {
375       // OtherWordType is smaller
376       constexpr size_t WORD_SIZE_RATIO = WORD_SIZE / BigIntOther::WORD_SIZE;
377       static_assert(
378           (WORD_SIZE % BigIntOther::WORD_SIZE) == 0 &&
379           "Word types must be multiples of each other for correct conversion.");
380       if constexpr (OtherBits >= Bits) { // truncate
381         // for each big word
382         for (size_t i = 0; i < WORD_COUNT; ++i) {
383           WordType cur_word = 0;
384           // combine WORD_SIZE_RATIO small words into a big word
385           for (size_t j = 0; j < WORD_SIZE_RATIO; ++j)
386             cur_word |= static_cast<WordType>(other[(i * WORD_SIZE_RATIO) + j])
387                         << (BigIntOther::WORD_SIZE * j);
388 
389           val[i] = cur_word;
390         }
391       } else { // zero or sign extend
392         size_t i = 0;
393         WordType cur_word = 0;
394         // for each small word
395         for (; i < BigIntOther::WORD_COUNT; ++i) {
396           // combine WORD_SIZE_RATIO small words into a big word
397           cur_word |= static_cast<WordType>(other[i])
398                       << (BigIntOther::WORD_SIZE * (i % WORD_SIZE_RATIO));
399           // if we've completed a big word, copy it into place and reset
400           if ((i % WORD_SIZE_RATIO) == WORD_SIZE_RATIO - 1) {
401             val[i / WORD_SIZE_RATIO] = cur_word;
402             cur_word = 0;
403           }
404         }
405         // Pretend there are extra words of the correct sign extension as needed
406 
407         const WordType extension_bits =
408             should_sign_extend ? cpp::numeric_limits<WordType>::max()
409                                : cpp::numeric_limits<WordType>::min();
410         if ((i % WORD_SIZE_RATIO) != 0) {
411           cur_word |= static_cast<WordType>(extension_bits)
412                       << (BigIntOther::WORD_SIZE * (i % WORD_SIZE_RATIO));
413         }
414         // Copy the last word into place.
415         val[(i / WORD_SIZE_RATIO)] = cur_word;
416         extend((i / WORD_SIZE_RATIO) + 1, should_sign_extend);
417       }
418     } else if constexpr (BigIntOther::WORD_SIZE == WORD_SIZE) {
419       if constexpr (OtherBits >= Bits) { // truncate
420         for (size_t i = 0; i < WORD_COUNT; ++i)
421           val[i] = other[i];
422       } else { // zero or sign extend
423         size_t i = 0;
424         for (; i < BigIntOther::WORD_COUNT; ++i)
425           val[i] = other[i];
426         extend(i, should_sign_extend);
427       }
428     } else {
429       // OtherWordType is bigger.
430       constexpr size_t WORD_SIZE_RATIO = BigIntOther::WORD_SIZE / WORD_SIZE;
431       static_assert(
432           (BigIntOther::WORD_SIZE % WORD_SIZE) == 0 &&
433           "Word types must be multiples of each other for correct conversion.");
434       if constexpr (OtherBits >= Bits) { // truncate
435         // for each small word
436         for (size_t i = 0; i < WORD_COUNT; ++i) {
437           // split each big word into WORD_SIZE_RATIO small words
438           val[i] = static_cast<WordType>(other[i / WORD_SIZE_RATIO] >>
439                                          ((i % WORD_SIZE_RATIO) * WORD_SIZE));
440         }
441       } else { // zero or sign extend
442         size_t i = 0;
443         // for each big word
444         for (; i < BigIntOther::WORD_COUNT; ++i) {
445           // split each big word into WORD_SIZE_RATIO small words
446           for (size_t j = 0; j < WORD_SIZE_RATIO; ++j)
447             val[(i * WORD_SIZE_RATIO) + j] =
448                 static_cast<WordType>(other[i] >> (j * WORD_SIZE));
449         }
450         extend(i * WORD_SIZE_RATIO, should_sign_extend);
451       }
452     }
453   }
454 
455   // Construct a BigInt from a C array.
456   template <size_t N> LIBC_INLINE constexpr BigInt(const WordType (&nums)[N]) {
457     static_assert(N == WORD_COUNT);
458     for (size_t i = 0; i < WORD_COUNT; ++i)
459       val[i] = nums[i];
460   }
461 
462   LIBC_INLINE constexpr explicit BigInt(
463       const cpp::array<WordType, WORD_COUNT> &words) {
464     val = words;
465   }
466 
467   // Initialize the first word to |v| and the rest to 0.
468   template <typename T, typename = cpp::enable_if_t<cpp::is_integral_v<T> &&
469                                                     !cpp::is_same_v<T, bool>>>
470   LIBC_INLINE constexpr BigInt(T v) {
471     constexpr size_t T_SIZE = sizeof(T) * CHAR_BIT;
472     const bool is_neg = v < 0;
473     for (size_t i = 0; i < WORD_COUNT; ++i) {
474       if (v == 0) {
475         extend(i, is_neg);
476         return;
477       }
478       val[i] = static_cast<WordType>(v);
479       if constexpr (T_SIZE > WORD_SIZE)
480         v >>= WORD_SIZE;
481       else
482         v = 0;
483     }
484   }
485   LIBC_INLINE constexpr BigInt &operator=(const BigInt &other) = default;
486 
487   // constants
488   LIBC_INLINE static constexpr BigInt zero() { return BigInt(); }
489   LIBC_INLINE static constexpr BigInt one() { return BigInt(1); }
490   LIBC_INLINE static constexpr BigInt all_ones() { return ~zero(); }
491   LIBC_INLINE static constexpr BigInt min() {
492     BigInt out;
493     if constexpr (SIGNED)
494       out.set_msb();
495     return out;
496   }
497   LIBC_INLINE static constexpr BigInt max() {
498     BigInt out = all_ones();
499     if constexpr (SIGNED)
500       out.clear_msb();
501     return out;
502   }
503 
504   // TODO: Reuse the Sign type.
505   LIBC_INLINE constexpr bool is_neg() const { return SIGNED && get_msb(); }
506 
507   template <size_t OtherBits, bool OtherSigned, typename OtherWordType>
508   LIBC_INLINE constexpr explicit
509   operator BigInt<OtherBits, OtherSigned, OtherWordType>() const {
510     return BigInt<OtherBits, OtherSigned, OtherWordType>(this);
511   }
512 
513   template <typename T> LIBC_INLINE constexpr explicit operator T() const {
514     return to<T>();
515   }
516 
517   template <typename T>
518   LIBC_INLINE constexpr cpp::enable_if_t<
519       cpp::is_integral_v<T> && !cpp::is_same_v<T, bool>, T>
520   to() const {
521     constexpr size_t T_SIZE = sizeof(T) * CHAR_BIT;
522     T lo = static_cast<T>(val[0]);
523     if constexpr (T_SIZE <= WORD_SIZE)
524       return lo;
525     constexpr size_t MAX_COUNT =
526         T_SIZE > Bits ? WORD_COUNT : T_SIZE / WORD_SIZE;
527     for (size_t i = 1; i < MAX_COUNT; ++i)
528       lo += static_cast<T>(static_cast<T>(val[i]) << (WORD_SIZE * i));
529     if constexpr (Signed && (T_SIZE > Bits)) {
530       // Extend sign for negative numbers.
531       constexpr T MASK = (~T(0) << Bits);
532       if (is_neg())
533         lo |= MASK;
534     }
535     return lo;
536   }
537 
538   LIBC_INLINE constexpr explicit operator bool() const { return !is_zero(); }
539 
540   LIBC_INLINE constexpr bool is_zero() const {
541     for (auto part : val)
542       if (part != 0)
543         return false;
544     return true;
545   }
546 
547   // Add 'rhs' to this number and store the result in this number.
548   // Returns the carry value produced by the addition operation.
549   LIBC_INLINE constexpr WordType add_overflow(const BigInt &rhs) {
550     return multiword::add_with_carry(val, rhs.val);
551   }
552 
553   LIBC_INLINE constexpr BigInt operator+(const BigInt &other) const {
554     BigInt result = *this;
555     result.add_overflow(other);
556     return result;
557   }
558 
559   // This will only apply when initializing a variable from constant values, so
560   // it will always use the constexpr version of add_with_carry.
561   LIBC_INLINE constexpr BigInt operator+(BigInt &&other) const {
562     // We use addition commutativity to reuse 'other' and prevent allocation.
563     other.add_overflow(*this); // Returned carry value is ignored.
564     return other;
565   }
566 
567   LIBC_INLINE constexpr BigInt &operator+=(const BigInt &other) {
568     add_overflow(other); // Returned carry value is ignored.
569     return *this;
570   }
571 
572   // Subtract 'rhs' to this number and store the result in this number.
573   // Returns the carry value produced by the subtraction operation.
574   LIBC_INLINE constexpr WordType sub_overflow(const BigInt &rhs) {
575     return multiword::sub_with_borrow(val, rhs.val);
576   }
577 
578   LIBC_INLINE constexpr BigInt operator-(const BigInt &other) const {
579     BigInt result = *this;
580     result.sub_overflow(other); // Returned carry value is ignored.
581     return result;
582   }
583 
584   LIBC_INLINE constexpr BigInt operator-(BigInt &&other) const {
585     BigInt result = *this;
586     result.sub_overflow(other); // Returned carry value is ignored.
587     return result;
588   }
589 
590   LIBC_INLINE constexpr BigInt &operator-=(const BigInt &other) {
591     // TODO(lntue): Set overflow flag / errno when carry is true.
592     sub_overflow(other); // Returned carry value is ignored.
593     return *this;
594   }
595 
596   // Multiply this number with x and store the result in this number.
597   LIBC_INLINE constexpr WordType mul(WordType x) {
598     return multiword::scalar_multiply_with_carry(val, x);
599   }
600 
601   // Return the full product.
602   template <size_t OtherBits>
603   LIBC_INLINE constexpr auto
604   ful_mul(const BigInt<OtherBits, Signed, WordType> &other) const {
605     BigInt<Bits + OtherBits, Signed, WordType> result;
606     multiword::multiply_with_carry(result.val, val, other.val);
607     return result;
608   }
609 
610   LIBC_INLINE constexpr BigInt operator*(const BigInt &other) const {
611     // Perform full mul and truncate.
612     return BigInt(ful_mul(other));
613   }
614 
615   // Fast hi part of the full product.  The normal product `operator*` returns
616   // `Bits` least significant bits of the full product, while this function will
617   // approximate `Bits` most significant bits of the full product with errors
618   // bounded by:
619   //   0 <= (a.full_mul(b) >> Bits) - a.quick_mul_hi(b)) <= WORD_COUNT - 1.
620   //
621   // An example usage of this is to quickly (but less accurately) compute the
622   // product of (normalized) mantissas of floating point numbers:
623   //   (mant_1, mant_2) -> quick_mul_hi -> normalize leading bit
624   // is much more efficient than:
625   //   (mant_1, mant_2) -> ful_mul -> normalize leading bit
626   //                    -> convert back to same Bits width by shifting/rounding,
627   // especially for higher precisions.
628   //
629   // Performance summary:
630   //   Number of 64-bit x 64-bit -> 128-bit multiplications performed.
631   //   Bits  WORD_COUNT  ful_mul  quick_mul_hi  Error bound
632   //    128      2         4           3            1
633   //    196      3         9           6            2
634   //    256      4        16          10            3
635   //    512      8        64          36            7
636   LIBC_INLINE constexpr BigInt quick_mul_hi(const BigInt &other) const {
637     BigInt result;
638     multiword::quick_mul_hi(result.val, val, other.val);
639     return result;
640   }
641 
642   // BigInt(x).pow_n(n) computes x ^ n.
643   // Note 0 ^ 0 == 1.
644   LIBC_INLINE constexpr void pow_n(uint64_t power) {
645     static_assert(!Signed);
646     BigInt result = one();
647     BigInt cur_power = *this;
648     while (power > 0) {
649       if ((power % 2) > 0)
650         result *= cur_power;
651       power >>= 1;
652       cur_power *= cur_power;
653     }
654     *this = result;
655   }
656 
657   // Performs inplace signed / unsigned division. Returns remainder if not
658   // dividing by zero.
659   // For signed numbers it behaves like C++ signed integer division.
660   // That is by truncating the fractionnal part
661   // https://stackoverflow.com/a/3602857
662   LIBC_INLINE constexpr cpp::optional<BigInt> div(const BigInt &divider) {
663     if (LIBC_UNLIKELY(divider.is_zero()))
664       return cpp::nullopt;
665     if (LIBC_UNLIKELY(divider == BigInt::one()))
666       return BigInt::zero();
667     Division result;
668     if constexpr (SIGNED)
669       result = divide_signed(*this, divider);
670     else
671       result = divide_unsigned(*this, divider);
672     *this = result.quotient;
673     return result.remainder;
674   }
675 
676   // Efficiently perform BigInt / (x * 2^e), where x is a half-word-size
677   // unsigned integer, and return the remainder. The main idea is as follow:
678   //   Let q = y / (x * 2^e) be the quotient, and
679   //       r = y % (x * 2^e) be the remainder.
680   //   First, notice that:
681   //     r % (2^e) = y % (2^e),
682   // so we just need to focus on all the bits of y that is >= 2^e.
683   //   To speed up the shift-and-add steps, we only use x as the divisor, and
684   // performing 32-bit shiftings instead of bit-by-bit shiftings.
685   //   Since the remainder of each division step < x < 2^(WORD_SIZE / 2), the
686   // computation of each step is now properly contained within WordType.
687   //   And finally we perform some extra alignment steps for the remaining bits.
688   LIBC_INLINE constexpr cpp::optional<BigInt>
689   div_uint_half_times_pow_2(multiword::half_width_t<WordType> x, size_t e) {
690     BigInt remainder;
691     if (x == 0)
692       return cpp::nullopt;
693     if (e >= Bits) {
694       remainder = *this;
695       *this = BigInt<Bits, false, WordType>();
696       return remainder;
697     }
698     BigInt quotient;
699     WordType x_word = static_cast<WordType>(x);
700     constexpr size_t LOG2_WORD_SIZE = cpp::bit_width(WORD_SIZE) - 1;
701     constexpr size_t HALF_WORD_SIZE = WORD_SIZE >> 1;
702     constexpr WordType HALF_MASK = ((WordType(1) << HALF_WORD_SIZE) - 1);
703     // lower = smallest multiple of WORD_SIZE that is >= e.
704     size_t lower = ((e >> LOG2_WORD_SIZE) + ((e & (WORD_SIZE - 1)) != 0))
705                    << LOG2_WORD_SIZE;
706     // lower_pos is the index of the closest WORD_SIZE-bit chunk >= 2^e.
707     size_t lower_pos = lower / WORD_SIZE;
708     // Keep track of current remainder mod x * 2^(32*i)
709     WordType rem = 0;
710     // pos is the index of the current 64-bit chunk that we are processing.
711     size_t pos = WORD_COUNT;
712 
713     // TODO: look into if constexpr(Bits > 256) skip leading zeroes.
714 
715     for (size_t q_pos = WORD_COUNT - lower_pos; q_pos > 0; --q_pos) {
716       // q_pos is 1 + the index of the current WORD_SIZE-bit chunk of the
717       // quotient being processed. Performing the division / modulus with
718       // divisor:
719       //   x * 2^(WORD_SIZE*q_pos - WORD_SIZE/2),
720       // i.e. using the upper (WORD_SIZE/2)-bit of the current WORD_SIZE-bit
721       // chunk.
722       rem <<= HALF_WORD_SIZE;
723       rem += val[--pos] >> HALF_WORD_SIZE;
724       WordType q_tmp = rem / x_word;
725       rem %= x_word;
726 
727       // Performing the division / modulus with divisor:
728       //   x * 2^(WORD_SIZE*(q_pos - 1)),
729       // i.e. using the lower (WORD_SIZE/2)-bit of the current WORD_SIZE-bit
730       // chunk.
731       rem <<= HALF_WORD_SIZE;
732       rem += val[pos] & HALF_MASK;
733       quotient.val[q_pos - 1] = (q_tmp << HALF_WORD_SIZE) + rem / x_word;
734       rem %= x_word;
735     }
736 
737     // So far, what we have is:
738     //   quotient = y / (x * 2^lower), and
739     //        rem = (y % (x * 2^lower)) / 2^lower.
740     // If (lower > e), we will need to perform an extra adjustment of the
741     // quotient and remainder, namely:
742     //   y / (x * 2^e) = [ y / (x * 2^lower) ] * 2^(lower - e) +
743     //                   + (rem * 2^(lower - e)) / x
744     //   (y % (x * 2^e)) / 2^e = (rem * 2^(lower - e)) % x
745     size_t last_shift = lower - e;
746 
747     if (last_shift > 0) {
748       // quotient * 2^(lower - e)
749       quotient <<= last_shift;
750       WordType q_tmp = 0;
751       WordType d = val[--pos];
752       if (last_shift >= HALF_WORD_SIZE) {
753         // The shifting (rem * 2^(lower - e)) might overflow WordTyoe, so we
754         // perform a HALF_WORD_SIZE-bit shift first.
755         rem <<= HALF_WORD_SIZE;
756         rem += d >> HALF_WORD_SIZE;
757         d &= HALF_MASK;
758         q_tmp = rem / x_word;
759         rem %= x_word;
760         last_shift -= HALF_WORD_SIZE;
761       } else {
762         // Only use the upper HALF_WORD_SIZE-bit of the current WORD_SIZE-bit
763         // chunk.
764         d >>= HALF_WORD_SIZE;
765       }
766 
767       if (last_shift > 0) {
768         rem <<= HALF_WORD_SIZE;
769         rem += d;
770         q_tmp <<= last_shift;
771         x_word <<= HALF_WORD_SIZE - last_shift;
772         q_tmp += rem / x_word;
773         rem %= x_word;
774       }
775 
776       quotient.val[0] += q_tmp;
777 
778       if (lower - e <= HALF_WORD_SIZE) {
779         // The remainder rem * 2^(lower - e) might overflow to the higher
780         // WORD_SIZE-bit chunk.
781         if (pos < WORD_COUNT - 1) {
782           remainder[pos + 1] = rem >> HALF_WORD_SIZE;
783         }
784         remainder[pos] = (rem << HALF_WORD_SIZE) + (val[pos] & HALF_MASK);
785       } else {
786         remainder[pos] = rem;
787       }
788 
789     } else {
790       remainder[pos] = rem;
791     }
792 
793     // Set the remaining lower bits of the remainder.
794     for (; pos > 0; --pos) {
795       remainder[pos - 1] = val[pos - 1];
796     }
797 
798     *this = quotient;
799     return remainder;
800   }
801 
802   LIBC_INLINE constexpr BigInt operator/(const BigInt &other) const {
803     BigInt result(*this);
804     result.div(other);
805     return result;
806   }
807 
808   LIBC_INLINE constexpr BigInt &operator/=(const BigInt &other) {
809     div(other);
810     return *this;
811   }
812 
813   LIBC_INLINE constexpr BigInt operator%(const BigInt &other) const {
814     BigInt result(*this);
815     return *result.div(other);
816   }
817 
818   LIBC_INLINE constexpr BigInt operator%=(const BigInt &other) {
819     *this = *this % other;
820     return *this;
821   }
822 
823   LIBC_INLINE constexpr BigInt &operator*=(const BigInt &other) {
824     *this = *this * other;
825     return *this;
826   }
827 
828   LIBC_INLINE constexpr BigInt &operator<<=(size_t s) {
829     val = multiword::shift<multiword::LEFT, SIGNED>(val, s);
830     return *this;
831   }
832 
833   LIBC_INLINE constexpr BigInt operator<<(size_t s) const {
834     return BigInt(multiword::shift<multiword::LEFT, SIGNED>(val, s));
835   }
836 
837   LIBC_INLINE constexpr BigInt &operator>>=(size_t s) {
838     val = multiword::shift<multiword::RIGHT, SIGNED>(val, s);
839     return *this;
840   }
841 
842   LIBC_INLINE constexpr BigInt operator>>(size_t s) const {
843     return BigInt(multiword::shift<multiword::RIGHT, SIGNED>(val, s));
844   }
845 
846 #define DEFINE_BINOP(OP)                                                       \
847   LIBC_INLINE friend constexpr BigInt operator OP(const BigInt &lhs,           \
848                                                   const BigInt &rhs) {         \
849     BigInt result;                                                             \
850     for (size_t i = 0; i < WORD_COUNT; ++i)                                    \
851       result[i] = lhs[i] OP rhs[i];                                            \
852     return result;                                                             \
853   }                                                                            \
854   LIBC_INLINE friend constexpr BigInt operator OP##=(BigInt &lhs,              \
855                                                      const BigInt &rhs) {      \
856     for (size_t i = 0; i < WORD_COUNT; ++i)                                    \
857       lhs[i] OP## = rhs[i];                                                    \
858     return lhs;                                                                \
859   }
860 
861   DEFINE_BINOP(&) // & and &=
862   DEFINE_BINOP(|) // | and |=
863   DEFINE_BINOP(^) // ^ and ^=
864 #undef DEFINE_BINOP
865 
866   LIBC_INLINE constexpr BigInt operator~() const {
867     BigInt result;
868     for (size_t i = 0; i < WORD_COUNT; ++i)
869       result[i] = ~val[i];
870     return result;
871   }
872 
873   LIBC_INLINE constexpr BigInt operator-() const {
874     BigInt result(*this);
875     result.negate();
876     return result;
877   }
878 
879   LIBC_INLINE friend constexpr bool operator==(const BigInt &lhs,
880                                                const BigInt &rhs) {
881     for (size_t i = 0; i < WORD_COUNT; ++i)
882       if (lhs.val[i] != rhs.val[i])
883         return false;
884     return true;
885   }
886 
887   LIBC_INLINE friend constexpr bool operator!=(const BigInt &lhs,
888                                                const BigInt &rhs) {
889     return !(lhs == rhs);
890   }
891 
892   LIBC_INLINE friend constexpr bool operator>(const BigInt &lhs,
893                                               const BigInt &rhs) {
894     return cmp(lhs, rhs) > 0;
895   }
896   LIBC_INLINE friend constexpr bool operator>=(const BigInt &lhs,
897                                                const BigInt &rhs) {
898     return cmp(lhs, rhs) >= 0;
899   }
900   LIBC_INLINE friend constexpr bool operator<(const BigInt &lhs,
901                                               const BigInt &rhs) {
902     return cmp(lhs, rhs) < 0;
903   }
904   LIBC_INLINE friend constexpr bool operator<=(const BigInt &lhs,
905                                                const BigInt &rhs) {
906     return cmp(lhs, rhs) <= 0;
907   }
908 
909   LIBC_INLINE constexpr BigInt &operator++() {
910     increment();
911     return *this;
912   }
913 
914   LIBC_INLINE constexpr BigInt operator++(int) {
915     BigInt oldval(*this);
916     increment();
917     return oldval;
918   }
919 
920   LIBC_INLINE constexpr BigInt &operator--() {
921     decrement();
922     return *this;
923   }
924 
925   LIBC_INLINE constexpr BigInt operator--(int) {
926     BigInt oldval(*this);
927     decrement();
928     return oldval;
929   }
930 
931   // Return the i-th word of the number.
932   LIBC_INLINE constexpr const WordType &operator[](size_t i) const {
933     return val[i];
934   }
935 
936   // Return the i-th word of the number.
937   LIBC_INLINE constexpr WordType &operator[](size_t i) { return val[i]; }
938 
939 private:
940   LIBC_INLINE friend constexpr int cmp(const BigInt &lhs, const BigInt &rhs) {
941     constexpr auto compare = [](WordType a, WordType b) {
942       return a == b ? 0 : a > b ? 1 : -1;
943     };
944     if constexpr (Signed) {
945       const bool lhs_is_neg = lhs.is_neg();
946       const bool rhs_is_neg = rhs.is_neg();
947       if (lhs_is_neg != rhs_is_neg)
948         return rhs_is_neg ? 1 : -1;
949     }
950     for (size_t i = WORD_COUNT; i-- > 0;)
951       if (auto cmp = compare(lhs[i], rhs[i]); cmp != 0)
952         return cmp;
953     return 0;
954   }
955 
956   LIBC_INLINE constexpr void bitwise_not() {
957     for (auto &part : val)
958       part = ~part;
959   }
960 
961   LIBC_INLINE constexpr void negate() {
962     bitwise_not();
963     increment();
964   }
965 
966   LIBC_INLINE constexpr void increment() {
967     multiword::add_with_carry(val, cpp::array<WordType, 1>{1});
968   }
969 
970   LIBC_INLINE constexpr void decrement() {
971     multiword::add_with_carry(val, cpp::array<WordType, 1>{1});
972   }
973 
974   LIBC_INLINE constexpr void extend(size_t index, bool is_neg) {
975     const WordType value = is_neg ? cpp::numeric_limits<WordType>::max()
976                                   : cpp::numeric_limits<WordType>::min();
977     for (size_t i = index; i < WORD_COUNT; ++i)
978       val[i] = value;
979   }
980 
981   LIBC_INLINE constexpr bool get_msb() const {
982     return val.back() >> (WORD_SIZE - 1);
983   }
984 
985   LIBC_INLINE constexpr void set_msb() {
986     val.back() |= mask_leading_ones<WordType, 1>();
987   }
988 
989   LIBC_INLINE constexpr void clear_msb() {
990     val.back() &= mask_trailing_ones<WordType, WORD_SIZE - 1>();
991   }
992 
993   LIBC_INLINE constexpr void set_bit(size_t i) {
994     const size_t word_index = i / WORD_SIZE;
995     val[word_index] |= WordType(1) << (i % WORD_SIZE);
996   }
997 
998   LIBC_INLINE constexpr static Division divide_unsigned(const BigInt &dividend,
999                                                         const BigInt &divider) {
1000     BigInt remainder = dividend;
1001     BigInt quotient;
1002     if (remainder >= divider) {
1003       BigInt subtractor = divider;
1004       int cur_bit = multiword::countl_zero(subtractor.val) -
1005                     multiword::countl_zero(remainder.val);
1006       subtractor <<= cur_bit;
1007       for (; cur_bit >= 0 && remainder > 0; --cur_bit, subtractor >>= 1) {
1008         if (remainder < subtractor)
1009           continue;
1010         remainder -= subtractor;
1011         quotient.set_bit(cur_bit);
1012       }
1013     }
1014     return Division{quotient, remainder};
1015   }
1016 
1017   LIBC_INLINE constexpr static Division divide_signed(const BigInt &dividend,
1018                                                       const BigInt &divider) {
1019     // Special case because it is not possible to negate the min value of a
1020     // signed integer.
1021     if (dividend == min() && divider == min())
1022       return Division{one(), zero()};
1023     // 1. Convert the dividend and divisor to unsigned representation.
1024     unsigned_type udividend(dividend);
1025     unsigned_type udivider(divider);
1026     // 2. Negate the dividend if it's negative, and similarly for the divisor.
1027     const bool dividend_is_neg = dividend.is_neg();
1028     const bool divider_is_neg = divider.is_neg();
1029     if (dividend_is_neg)
1030       udividend.negate();
1031     if (divider_is_neg)
1032       udivider.negate();
1033     // 3. Use unsigned multiword division algorithm.
1034     const auto unsigned_result = divide_unsigned(udividend, udivider);
1035     // 4. Convert the quotient and remainder to signed representation.
1036     Division result;
1037     result.quotient = signed_type(unsigned_result.quotient);
1038     result.remainder = signed_type(unsigned_result.remainder);
1039     // 5. Negate the quotient if the dividend and divisor had opposite signs.
1040     if (dividend_is_neg != divider_is_neg)
1041       result.quotient.negate();
1042     // 6. Negate the remainder if the dividend was negative.
1043     if (dividend_is_neg)
1044       result.remainder.negate();
1045     return result;
1046   }
1047 
1048   friend signed_type;
1049   friend unsigned_type;
1050 };
1051 
1052 namespace internal {
1053 // We default BigInt's WordType to 'uint64_t' or 'uint32_t' depending on type
1054 // availability.
1055 template <size_t Bits>
1056 struct WordTypeSelector : cpp::type_identity<
1057 #ifdef LIBC_TYPES_HAS_INT64
1058                               uint64_t
1059 #else
1060                               uint32_t
1061 #endif // LIBC_TYPES_HAS_INT64
1062                               > {
1063 };
1064 // Except if we request 16 or 32 bits explicitly.
1065 template <> struct WordTypeSelector<16> : cpp::type_identity<uint16_t> {};
1066 template <> struct WordTypeSelector<32> : cpp::type_identity<uint32_t> {};
1067 template <> struct WordTypeSelector<96> : cpp::type_identity<uint32_t> {};
1068 
1069 template <size_t Bits>
1070 using WordTypeSelectorT = typename WordTypeSelector<Bits>::type;
1071 } // namespace internal
1072 
1073 template <size_t Bits>
1074 using UInt = BigInt<Bits, false, internal::WordTypeSelectorT<Bits>>;
1075 
1076 template <size_t Bits>
1077 using Int = BigInt<Bits, true, internal::WordTypeSelectorT<Bits>>;
1078 
1079 // Provides limits of BigInt.
1080 template <size_t Bits, bool Signed, typename T>
1081 struct cpp::numeric_limits<BigInt<Bits, Signed, T>> {
1082   LIBC_INLINE static constexpr BigInt<Bits, Signed, T> max() {
1083     return BigInt<Bits, Signed, T>::max();
1084   }
1085   LIBC_INLINE static constexpr BigInt<Bits, Signed, T> min() {
1086     return BigInt<Bits, Signed, T>::min();
1087   }
1088   // Meant to match std::numeric_limits interface.
1089   // NOLINTNEXTLINE(readability-identifier-naming)
1090   LIBC_INLINE_VAR static constexpr int digits = Bits - Signed;
1091 };
1092 
1093 // type traits to determine whether a T is a BigInt.
1094 template <typename T> struct is_big_int : cpp::false_type {};
1095 
1096 template <size_t Bits, bool Signed, typename T>
1097 struct is_big_int<BigInt<Bits, Signed, T>> : cpp::true_type {};
1098 
1099 template <class T>
1100 LIBC_INLINE_VAR constexpr bool is_big_int_v = is_big_int<T>::value;
1101 
1102 // extensions of type traits to include BigInt
1103 
1104 // is_integral_or_big_int
1105 template <typename T>
1106 struct is_integral_or_big_int
1107     : cpp::bool_constant<(cpp::is_integral_v<T> || is_big_int_v<T>)> {};
1108 
1109 template <typename T>
1110 LIBC_INLINE_VAR constexpr bool is_integral_or_big_int_v =
1111     is_integral_or_big_int<T>::value;
1112 
1113 // make_big_int_unsigned
1114 template <typename T> struct make_big_int_unsigned;
1115 
1116 template <size_t Bits, bool Signed, typename T>
1117 struct make_big_int_unsigned<BigInt<Bits, Signed, T>>
1118     : cpp::type_identity<BigInt<Bits, false, T>> {};
1119 
1120 template <typename T>
1121 using make_big_int_unsigned_t = typename make_big_int_unsigned<T>::type;
1122 
1123 // make_big_int_signed
1124 template <typename T> struct make_big_int_signed;
1125 
1126 template <size_t Bits, bool Signed, typename T>
1127 struct make_big_int_signed<BigInt<Bits, Signed, T>>
1128     : cpp::type_identity<BigInt<Bits, true, T>> {};
1129 
1130 template <typename T>
1131 using make_big_int_signed_t = typename make_big_int_signed<T>::type;
1132 
1133 // make_integral_or_big_int_unsigned
1134 template <typename T, class = void> struct make_integral_or_big_int_unsigned;
1135 
1136 template <typename T>
1137 struct make_integral_or_big_int_unsigned<
1138     T, cpp::enable_if_t<cpp::is_integral_v<T>>> : cpp::make_unsigned<T> {};
1139 
1140 template <typename T>
1141 struct make_integral_or_big_int_unsigned<T, cpp::enable_if_t<is_big_int_v<T>>>
1142     : make_big_int_unsigned<T> {};
1143 
1144 template <typename T>
1145 using make_integral_or_big_int_unsigned_t =
1146     typename make_integral_or_big_int_unsigned<T>::type;
1147 
1148 // make_integral_or_big_int_signed
1149 template <typename T, class = void> struct make_integral_or_big_int_signed;
1150 
1151 template <typename T>
1152 struct make_integral_or_big_int_signed<T,
1153                                        cpp::enable_if_t<cpp::is_integral_v<T>>>
1154     : cpp::make_signed<T> {};
1155 
1156 template <typename T>
1157 struct make_integral_or_big_int_signed<T, cpp::enable_if_t<is_big_int_v<T>>>
1158     : make_big_int_signed<T> {};
1159 
1160 template <typename T>
1161 using make_integral_or_big_int_signed_t =
1162     typename make_integral_or_big_int_signed<T>::type;
1163 
1164 // is_unsigned_integral_or_big_int
1165 template <typename T>
1166 struct is_unsigned_integral_or_big_int
1167     : cpp::bool_constant<
1168           cpp::is_same_v<T, make_integral_or_big_int_unsigned_t<T>>> {};
1169 
1170 template <typename T>
1171 // Meant to look like <type_traits> helper variable templates.
1172 // NOLINTNEXTLINE(readability-identifier-naming)
1173 LIBC_INLINE_VAR constexpr bool is_unsigned_integral_or_big_int_v =
1174     is_unsigned_integral_or_big_int<T>::value;
1175 
1176 namespace cpp {
1177 
1178 // Specialization of cpp::bit_cast ('bit.h') from T to BigInt.
1179 template <typename To, typename From>
1180 LIBC_INLINE constexpr cpp::enable_if_t<
1181     (sizeof(To) == sizeof(From)) && cpp::is_trivially_copyable<To>::value &&
1182         cpp::is_trivially_copyable<From>::value && is_big_int<To>::value,
1183     To>
1184 bit_cast(const From &from) {
1185   To out;
1186   using Storage = decltype(out.val);
1187   out.val = cpp::bit_cast<Storage>(from);
1188   return out;
1189 }
1190 
1191 // Specialization of cpp::bit_cast ('bit.h') from BigInt to T.
1192 template <typename To, size_t Bits>
1193 LIBC_INLINE constexpr cpp::enable_if_t<
1194     sizeof(To) == sizeof(UInt<Bits>) &&
1195         cpp::is_trivially_constructible<To>::value &&
1196         cpp::is_trivially_copyable<To>::value &&
1197         cpp::is_trivially_copyable<UInt<Bits>>::value,
1198     To>
1199 bit_cast(const UInt<Bits> &from) {
1200   return cpp::bit_cast<To>(from.val);
1201 }
1202 
1203 // Specialization of cpp::popcount ('bit.h') for BigInt.
1204 template <typename T>
1205 [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
1206 popcount(T value) {
1207   int bits = 0;
1208   for (auto word : value.val)
1209     if (word)
1210       bits += popcount(word);
1211   return bits;
1212 }
1213 
1214 // Specialization of cpp::has_single_bit ('bit.h') for BigInt.
1215 template <typename T>
1216 [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, bool>
1217 has_single_bit(T value) {
1218   int bits = 0;
1219   for (auto word : value.val) {
1220     if (word == 0)
1221       continue;
1222     bits += popcount(word);
1223     if (bits > 1)
1224       return false;
1225   }
1226   return bits == 1;
1227 }
1228 
1229 // Specialization of cpp::countr_zero ('bit.h') for BigInt.
1230 template <typename T>
1231 [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
1232 countr_zero(const T &value) {
1233   return multiword::countr_zero(value.val);
1234 }
1235 
1236 // Specialization of cpp::countl_zero ('bit.h') for BigInt.
1237 template <typename T>
1238 [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
1239 countl_zero(const T &value) {
1240   return multiword::countl_zero(value.val);
1241 }
1242 
1243 // Specialization of cpp::countl_one ('bit.h') for BigInt.
1244 template <typename T>
1245 [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
1246 countl_one(T value) {
1247   return multiword::countl_one(value.val);
1248 }
1249 
1250 // Specialization of cpp::countr_one ('bit.h') for BigInt.
1251 template <typename T>
1252 [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
1253 countr_one(T value) {
1254   return multiword::countr_one(value.val);
1255 }
1256 
1257 // Specialization of cpp::bit_width ('bit.h') for BigInt.
1258 template <typename T>
1259 [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
1260 bit_width(T value) {
1261   return cpp::numeric_limits<T>::digits - cpp::countl_zero(value);
1262 }
1263 
1264 // Forward-declare rotr so that rotl can use it.
1265 template <typename T>
1266 [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T>
1267 rotr(T value, int rotate);
1268 
1269 // Specialization of cpp::rotl ('bit.h') for BigInt.
1270 template <typename T>
1271 [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T>
1272 rotl(T value, int rotate) {
1273   constexpr unsigned N = cpp::numeric_limits<T>::digits;
1274   rotate = rotate % N;
1275   if (!rotate)
1276     return value;
1277   if (rotate < 0)
1278     return cpp::rotr<T>(value, -rotate);
1279   return (value << rotate) | (value >> (N - rotate));
1280 }
1281 
1282 // Specialization of cpp::rotr ('bit.h') for BigInt.
1283 template <typename T>
1284 [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T>
1285 rotr(T value, int rotate) {
1286   constexpr unsigned N = cpp::numeric_limits<T>::digits;
1287   rotate = rotate % N;
1288   if (!rotate)
1289     return value;
1290   if (rotate < 0)
1291     return cpp::rotl<T>(value, -rotate);
1292   return (value >> rotate) | (value << (N - rotate));
1293 }
1294 
1295 } // namespace cpp
1296 
1297 // Specialization of mask_trailing_ones ('math_extras.h') for BigInt.
1298 template <typename T, size_t count>
1299 LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T>
1300 mask_trailing_ones() {
1301   static_assert(!T::SIGNED && count <= T::BITS);
1302   if (count == T::BITS)
1303     return T::all_ones();
1304   constexpr size_t QUOTIENT = count / T::WORD_SIZE;
1305   constexpr size_t REMAINDER = count % T::WORD_SIZE;
1306   T out; // zero initialized
1307   for (size_t i = 0; i <= QUOTIENT; ++i)
1308     out[i] = i < QUOTIENT
1309                  ? -1
1310                  : mask_trailing_ones<typename T::word_type, REMAINDER>();
1311   return out;
1312 }
1313 
1314 // Specialization of mask_leading_ones ('math_extras.h') for BigInt.
1315 template <typename T, size_t count>
1316 LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T> mask_leading_ones() {
1317   static_assert(!T::SIGNED && count <= T::BITS);
1318   if (count == T::BITS)
1319     return T::all_ones();
1320   constexpr size_t QUOTIENT = (T::BITS - count - 1U) / T::WORD_SIZE;
1321   constexpr size_t REMAINDER = count % T::WORD_SIZE;
1322   T out; // zero initialized
1323   for (size_t i = QUOTIENT; i < T::WORD_COUNT; ++i)
1324     out[i] = i > QUOTIENT
1325                  ? -1
1326                  : mask_leading_ones<typename T::word_type, REMAINDER>();
1327   return out;
1328 }
1329 
1330 // Specialization of mask_trailing_zeros ('math_extras.h') for BigInt.
1331 template <typename T, size_t count>
1332 LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T>
1333 mask_trailing_zeros() {
1334   return mask_leading_ones<T, T::BITS - count>();
1335 }
1336 
1337 // Specialization of mask_leading_zeros ('math_extras.h') for BigInt.
1338 template <typename T, size_t count>
1339 LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T>
1340 mask_leading_zeros() {
1341   return mask_trailing_ones<T, T::BITS - count>();
1342 }
1343 
1344 // Specialization of count_zeros ('math_extras.h') for BigInt.
1345 template <typename T>
1346 [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
1347 count_zeros(T value) {
1348   return cpp::popcount(~value);
1349 }
1350 
1351 // Specialization of first_leading_zero ('math_extras.h') for BigInt.
1352 template <typename T>
1353 [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
1354 first_leading_zero(T value) {
1355   return value == cpp::numeric_limits<T>::max() ? 0
1356                                                 : cpp::countl_one(value) + 1;
1357 }
1358 
1359 // Specialization of first_leading_one ('math_extras.h') for BigInt.
1360 template <typename T>
1361 [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
1362 first_leading_one(T value) {
1363   return first_leading_zero(~value);
1364 }
1365 
1366 // Specialization of first_trailing_zero ('math_extras.h') for BigInt.
1367 template <typename T>
1368 [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
1369 first_trailing_zero(T value) {
1370   return value == cpp::numeric_limits<T>::max() ? 0
1371                                                 : cpp::countr_zero(~value) + 1;
1372 }
1373 
1374 // Specialization of first_trailing_one ('math_extras.h') for BigInt.
1375 template <typename T>
1376 [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
1377 first_trailing_one(T value) {
1378   return value == cpp::numeric_limits<T>::max() ? 0
1379                                                 : cpp::countr_zero(value) + 1;
1380 }
1381 
1382 } // namespace LIBC_NAMESPACE_DECL
1383 
1384 #endif // LLVM_LIBC_SRC___SUPPORT_BIG_INT_H
1385