34 #include <type_traits>
36 #if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || \
37 defined(__BIG_ENDIAN__) || \
38 defined(__ARMEB__) || \
39 defined(__THUMBEB__) || \
40 defined(__AARCH64EB__) || \
41 defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__)
42 # ifndef __BIG_ENDIAN__
43 # define __BIG_ENDIAN__
45 #elif defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || \
46 defined(__LITTLE_ENDIAN__) || \
47 defined(__ARMEL__) || \
48 defined(__THUMBEL__) || \
49 defined(__AARCH64EL__) || \
50 defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) || \
51 defined(_WIN32) || defined(__i386__) || defined(__x86_64__) || \
52 defined(_X86_) || defined(_IA64_)
53 # ifndef __LITTLE_ENDIAN__
54 # define __LITTLE_ENDIAN__
57 # error "I don't know what architecture this is!"
60 #if (defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16) || defined(_GLIBCXX_USE_INT128)
61 # define USE_BUILTIN_INT128
66 #pragma warning(disable:4804)
68 static __inline
int __builtin_clz(
int x)
71 _BitScanReverse(&r, x);
72 return 31 ^
static_cast<int>(r);
75 static __inline
int __builtin_clzll(
const uint64_t x)
79 _BitScanReverse64(&r, x);
82 if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
83 return 63 ^
static_cast<int>(r + 32);
85 _BitScanReverse(&r, static_cast<uint32_t>(x));
87 return 63 ^
static_cast<int>(r);
90 static __inline
int __builtin_clzl(uint32_t x)
93 return __builtin_clzll(x);
95 return __builtin_clz(x);
102 template<
class,
class>
109 struct half_mask : std::integral_constant<_Tp, (_Tp(1) << (4 * sizeof(_Tp))) - _Tp(1)> {
113 struct detail_delegate;
115 constexpr bool operator<(int128_t, int128_t);
117 constexpr bool operator<(uint128_t, uint128_t);
119 constexpr uint128_t operator>>(uint128_t, int);
121 constexpr int128_t operator>>(int128_t, int);
123 constexpr int128_t operator*(int128_t, int128_t);
125 constexpr uint128_t operator*(uint128_t, uint128_t);
127 constexpr uint128_t operator<<(uint128_t, int);
129 constexpr int128_t operator<<(int128_t, int);
131 inline uint128_t operator/(uint128_t, uint128_t);
133 inline int128_t operator/(int128_t, int128_t);
135 inline uint128_t operator%(uint128_t, uint128_t);
137 inline int128_t operator%(int128_t, int128_t);
139 template<class _Hi, class _Low>
140 class alignas(sizeof(_Hi) * 2) int128_base final {
141 static_assert(sizeof(_Hi) == sizeof(_Low), "low type, high type should have same size");
144 #ifdef __LITTLE_ENDIAN__
148 constexpr int128_base(_Hi high, _Low low) : low_(low), high_(high) {}
154 constexpr int128_base(_Hi high, _Low low) : high_(high), low_(low) {}
157 #error endian not support
161 struct integral_tag {
163 struct signed_integral_tag : integral_tag {
165 struct unsigned_integral_tag : integral_tag {
170 struct size_constant {
174 constexpr int128_base(_Tp value_, signed_integral_tag, size_constant<8>) :
175 int128_base(-(value_ < 0), value_) {}
178 constexpr int128_base(_Tp value_, unsigned_integral_tag, size_constant<8>) : int128_base(0, _Low(value_)) {}
181 constexpr int128_base(_Tp value_, integral_tag, size_constant<16>) :
182 int128_base(_Hi(value_ >> 64U), _Low(value_)) {}
186 constexpr int128_base() noexcept = default;
188 constexpr int128_base(const int128_base &) noexcept = default;
190 constexpr int128_base(int128_base &&) noexcept = default;
192 int128_base &operator=(const int128_base &) noexcept = default;
194 int128_base &operator=(int128_base &&) noexcept = default;
197 constexpr explicit int128_base(int128_base<_Tp, _Low> val_) : int128_base(val_.high_, val_.low_) {}
200 constexpr int128_base(_Tp val_, float_tag) :
201 int128_base(_Hi(std::ldexp(val_, -64)) - (val_ < 0), _Low(val_)) {}
203 constexpr explicit int128_base(float val_) : int128_base(val_, float_tag()) {}
205 constexpr explicit int128_base(double val_) : int128_base(val_, float_tag()) {}
207 constexpr explicit int128_base(long double val_) : int128_base(val_, float_tag()) {}
209 constexpr int128_base(long long val_) :
210 int128_base(val_, signed_integral_tag(), size_constant<sizeof(val_)>()) {}
212 constexpr int128_base(long val_) : int128_base(static_cast<long long>(val_)) {}
214 constexpr int128_base(int val_) : int128_base(long(val_)) {}
216 constexpr int128_base(unsigned long long val_) :
217 int128_base(val_, unsigned_integral_tag(), size_constant<sizeof(val_)>()) {}
219 constexpr int128_base(unsigned long val_) :
220 int128_base(static_cast<unsigned long long>(val_)) {}
222 constexpr int128_base(unsigned val_) : int128_base(static_cast<unsigned long>(val_)) {}
224 constexpr explicit operator bool() const { return high_ || low_; }
226 constexpr explicit operator char() const { return char(low_); }
228 constexpr explicit operator signed char() const { return static_cast<signed char>(low_); }
230 constexpr explicit operator unsigned char() const { return static_cast<unsigned char>(low_); }
232 constexpr explicit operator short() const { return short(low_); }
234 constexpr explicit operator unsigned short() const { return static_cast<unsigned short>(low_); }
236 constexpr explicit operator int() const { return int(low_); }
238 constexpr explicit operator unsigned() const { return unsigned(low_); }
240 constexpr explicit operator long() const { return long(low_); }
242 constexpr explicit operator unsigned long() const { return static_cast<unsigned long>(low_); }
244 constexpr explicit operator long long() const { return static_cast<long long>(low_); }
246 constexpr explicit operator unsigned long long() const { return static_cast<unsigned long long>(low_); }
248 constexpr explicit operator wchar_t() const { return wchar_t(low_); }
250 constexpr explicit operator char16_t() const { return char16_t(low_); }
252 constexpr explicit operator char32_t() const { return char32_t(low_); }
254 #if USE_BUILTIN_INT128
256 constexpr explicit int128_base(__int128 val_) :
257 int128_base(val_, signed_integral_tag(), size_constant<sizeof(val_)>()) {}
259 constexpr explicit int128_base(unsigned __int128 val_) :
260 int128_base(val_, unsigned_integral_tag(), size_constant<sizeof(val_)>()) {}
262 constexpr explicit operator unsigned __int128() const {
263 return static_cast<unsigned __int128>(high_) << 64U | static_cast<unsigned __int128>(low_);
266 constexpr explicit operator __int128() const {
267 return static_cast<__int128>(static_cast<unsigned __int128>(*this));
274 constexpr _Tp cast_to_float() const;
277 constexpr explicit operator float() const { return cast_to_float<float>(); }
279 constexpr explicit operator double() const { return cast_to_float<double>(); }
281 constexpr explicit operator long double() const { return cast_to_float<long double>(); }
283 constexpr int128_base operator+() const { return *this; }
285 constexpr int128_base operator-() const { return int128_base(-high_ - (low_ != 0), -low_); }
287 constexpr int128_base operator~() const { return int128_base(~high_, ~low_); }
289 constexpr bool operator!() const { return !high_ && !low_; }
292 int128_base &operator++() &{ return *this = *this + int128_base(1); }
294 int128_base &operator--() &{ return *this = *this - int128_base(1); }
296 int128_base operator++(int) &{
297 int128_base tmp = *this;
302 int128_base operator--(int) &{
303 int128_base tmp = *this;
308 friend constexpr int128_base operator+(int128_base lhs_, int128_base rhs_) {
310 return {_Hi(lhs_.high_ + rhs_.high_ + (lhs_.low_ + rhs_.low_ < lhs_.low_)), lhs_.low_ + rhs_.low_};
313 friend constexpr int128_base operator-(int128_base lhs_, int128_base rhs_) {
314 return {_Hi(lhs_.high_ - rhs_.high_ - (lhs_.low_ < rhs_.low_)), lhs_.low_ - rhs_.low_};
317 friend constexpr int128_base operator&(int128_base lhs_, int128_base rhs_) {
318 return {lhs_.high_ & rhs_.high_, lhs_.low_ & rhs_.low_};
321 friend constexpr int128_base operator|(int128_base lhs_, int128_base rhs_) {
322 return {lhs_.high_ | rhs_.high_, lhs_.low_ | rhs_.low_};
325 friend constexpr int128_base operator^(int128_base lhs_, int128_base rhs_) {
326 return {lhs_.high_ ^ rhs_.high_, lhs_.low_ ^ rhs_.low_};
329 friend constexpr bool operator==(int128_base lhs_, int128_base rhs_) {
330 return lhs_.high_ == rhs_.high_ && lhs_.low_ == rhs_.low_;
333 friend constexpr bool operator>(int128_base lhs_, int128_base rhs_) { return rhs_ < lhs_; }
335 friend constexpr bool operator>=(int128_base lhs_, int128_base rhs_) { return !(lhs_ < rhs_); }
337 friend constexpr bool operator<=(int128_base lhs_, int128_base rhs_) { return !(rhs_ < lhs_); }
339 friend constexpr bool operator!=(int128_base lhs_, int128_base rhs_) { return !(lhs_ == rhs_); }
341 friend constexpr int128_base operator<<(int128_base lhs_, int128_base rhs_) { return lhs_ << (int) rhs_.low_; }
343 friend constexpr int128_base operator>>(int128_base lhs_, int128_base rhs_) { return lhs_ >> (int) rhs_.low_; }
345 int128_base &operator+=(int128_base rhs_) &{ return *this = *this + rhs_; }
347 int128_base &operator-=(int128_base rhs_) &{ return *this = *this - rhs_; }
349 int128_base &operator*=(int128_base rhs_) &{ return *this = *this * rhs_; }
351 int128_base &operator/=(int128_base rhs_) &{ return *this = *this / rhs_; }
353 int128_base &operator%=(int128_base rhs_) &{ return *this = *this % rhs_; }
355 int128_base &operator<<=(int128_base rhs_) &{ return *this = *this << rhs_; }
357 int128_base &operator>>=(int128_base rhs_) &{ return *this = *this >> rhs_; }
359 int128_base &operator<<=(int rhs_) &{ return *this = *this << rhs_; }
361 int128_base &operator>>=(int rhs_) &{ return *this = *this >> rhs_; }
363 int128_base &operator&=(int128_base rhs_) &{ return *this = *this & rhs_; }
365 int128_base &operator|=(int128_base rhs_) &{ return *this = *this | rhs_; }
367 int128_base &operator^=(int128_base rhs_) &{ return *this = *this ^ rhs_; }
369 template<class, class>
379 struct detail_delegate;
382 inline namespace literals {
384 template<char _Ch, int _Rad>
385 struct static_digit : std::integral_constant<int,
386 '0' <= _Ch && _Ch <= '9' ? _Ch - '0' :
387 'a' <= _Ch && _Ch <= 'z' ? _Ch - 'a' + 10 :
388 'A' <= _Ch && _Ch <= 'Z' ? _Ch - 'A' + 10 : _Rad> {
389 static_assert(_Rad > static_digit::value, "character not a digit");
392 template<class, int, char ...>
393 struct int128_literal_radix;
395 template<class _Tp, int _Rad, char _Ch>
396 struct int128_literal_radix<_Tp, _Rad, _Ch> {
397 constexpr operator _Tp() const { return _Tp(static_digit<_Ch, _Rad>::value); }
399 constexpr _Tp operator()(_Tp v) const { return v * _Tp(_Rad) + *this; }
402 template<class _Tp, int _Rad, char _Ch, char ..._Args>
403 struct int128_literal_radix<_Tp, _Rad, _Ch, _Args...> {
404 int128_literal_radix<_Tp, _Rad, _Ch> _Cur;
405 int128_literal_radix<_Tp, _Rad, _Args...> _Tgt;
407 constexpr operator _Tp() const { return _Tgt(_Cur); }
409 constexpr _Tp operator()(_Tp v) const { return _Tgt(_Cur(v)); }
412 template<class _Tp, char ..._Args>
413 struct int128_literal : int128_literal_radix<_Tp, 10, _Args...> {
416 struct int128_literal<_Tp, '0'> : int128_literal_radix<_Tp, 10, '0'> {
418 template<class _Tp, char ..._Args>
419 struct int128_literal<_Tp, '0', _Args...> : int128_literal_radix<_Tp, 8, _Args...> {
421 template<class _Tp, char ..._Args>
422 struct int128_literal<_Tp, '0', 'x', _Args...> : int128_literal_radix<_Tp, 16, _Args...> {
424 template<class _Tp, char ..._Args>
425 struct int128_literal<_Tp, '0', 'X', _Args...> : int128_literal_radix<_Tp, 16, _Args...> {
427 template<class _Tp, char ..._Args>
428 struct int128_literal<_Tp, '0', 'b', _Args...> : int128_literal_radix<_Tp, 2, _Args...> {
430 template<class _Tp, char ..._Args>
431 struct int128_literal<_Tp, '0', 'B', _Args...> : int128_literal_radix<_Tp, 2, _Args...> {
435 template<char ..._Args>
436 constexpr uint128_t operator "" _u128() { return impl_::int128_literal<uint128_t, _Args...>(); }
438 template<char ..._Args>
439 constexpr int128_t operator "" _l128() { return impl_::int128_literal<int128_t, _Args...>(); }
441 template<char ..._Args>
442 constexpr uint128_t operator "" _U128() { return impl_::int128_literal<uint128_t, _Args...>(); }
444 template<char ..._Args>
445 constexpr int128_t operator "" _L128() { return impl_::int128_literal<int128_t, _Args...>(); }
452 struct clz_helper<unsigned long> {
453 static int clz(unsigned long val_) { return __builtin_clzl(val_); }
457 struct clz_helper<unsigned long long> {
458 static int clz(unsigned long long val_) { return __builtin_clzll(val_); }
461 template<class _High, class _Low>
462 struct clz_helper<int128_base<_High, _Low> > {
463 static constexpr int clz(int128_base<_High, _Low> val_) {
464 return val_.high_ ? clz_helper<_Low>::clz(val_.high_) : 4 * sizeof(val_) + clz_helper<_Low>::clz(val_.low_);
469 struct detail_delegate {
470 template<class _Hi, class _Low>
471 static constexpr bool cmp(int128_base<_Hi, _Low> lhs_, int128_base<_Hi, _Low> rhs_) {
472 return lhs_.high_ < rhs_.high_ || (lhs_.high_ == rhs_.high_ && lhs_.low_ < rhs_.low_);
475 static constexpr uint128_t shr(uint128_t lhs_, unsigned rhs_) {
476 return rhs_ & 64U ? uint128_t(0, lhs_.high_ >> (rhs_ & 63U)) :
477 rhs_ & 63U ? uint128_t(lhs_.high_ >> (rhs_ & 63U),
478 (lhs_.high_ << (64 - (rhs_ & 63U)) | (lhs_.low_ >> (rhs_ & 63U)))) : lhs_;
481 static constexpr int128_t sar(int128_t lhs_, unsigned rhs_) {
482 return rhs_ & 64U ? int128_t(-(lhs_.high_ < 0), uint64_t(lhs_.high_ >> (rhs_ & 63U))) :
483 rhs_ & 63U ? int128_t(
484 lhs_.high_ >> (rhs_ & 63U),
485 (uint64_t(lhs_.high_) << (64 - (rhs_ & 63U)) | (lhs_.low_ >> (rhs_ & 63U)))) : lhs_;
488 template<class _Hi, class _Low>
489 static constexpr int128_base<_Hi, _Low> imul(int128_base<_Hi, _Low> lhs_, int128_base<_Hi, _Low> rhs_) {
490 return int128_base<_Hi, _Low>(
491 _Hi(lhs_.low_ * rhs_.high_ + rhs_.low_ * lhs_.high_) + (lhs_.low_ >> 32U) * (rhs_.low_ >> 32U),
492 (lhs_.low_ & half_mask<_Low>::value) * (rhs_.low_ & half_mask<_Low>::value))
493 + (int128_base<_Hi, _Low>((lhs_.low_ >> 32U) * (rhs_.low_ & half_mask<_Low>::value)) << 32U)
494 + (int128_base<_Hi, _Low>((rhs_.low_ >> 32U) * (lhs_.low_ & half_mask<_Low>::value)) << 32U);
497 template<class _Hi, class _Low>
498 static constexpr int128_base<_Hi, _Low> shl(int128_base<_Hi, _Low> lhs_, unsigned rhs_) {
500 return rhs_ & 64U ? int128_base<_Hi, _Low>(_Hi(lhs_.low_ << (rhs_ & 63U)), _Low(0)) :
501 rhs_ & 63U ? int128_base<_Hi, _Low>(
502 _Hi((_Low(lhs_.high_) << (rhs_ & 63U)) | (lhs_.low_ >> (64U - (rhs_ & 63U)))),
503 lhs_.low_ << (rhs_ & 63U)) : lhs_;
506 static uint128_t &slow_div_(uint128_t ÷nd_, uint128_t divisor_, uint128_t "_) {
508 quot_ = uint128_t(0);
509 if (cmp(dividend_, divisor_)) return dividend_;
510 if (dividend_.high_ == 0) {
511 quot_.low_ = dividend_.low_ / divisor_.low_;
512 dividend_.low_ %= divisor_.low_;
515 auto zend_ = clz_helper<uint128_t>::clz(dividend_), zsor_ = clz_helper<uint128_t>::clz(divisor_);
516 if (zend_ > zsor_) return dividend_;
517 for (zsor_ -= zend_, divisor_ <<= zsor_;; divisor_ >>= 1, quot_ <<= 1) {
518 if (dividend_ >= divisor_) {
519 dividend_ -= divisor_;
520 quot_ |= uint128_t(1);
522 if (!zsor_--) return dividend_;
526 static uint128_t div(uint128_t dividend_, uint128_t divisor_) {
527 if (!divisor_) return {!!dividend_ / !!divisor_};
529 slow_div_(dividend_, divisor_, quot_);
533 static int128_t div(int128_t dividend_, int128_t divisor_) {
534 bool nneg_ = dividend_.high_ < 0, dneg_ = divisor_.high_ < 0;
535 auto res_ = div(uint128_t(nneg_ ? -dividend_ : dividend_), uint128_t(dneg_ ? -divisor_ : divisor_));
536 return int128_t(nneg_ ^ dneg_ ? -res_ : res_);
539 static uint128_t mod(uint128_t dividend_, uint128_t divisor_) {
540 if (!divisor_) return {!!dividend_ % !!divisor_};
542 return slow_div_(dividend_, divisor_, quot_);
545 static int128_t mod(int128_t dividend_, int128_t divisor_) {
546 bool neg_ = dividend_.high_ < 0;
547 auto res_ = mod(uint128_t(neg_ ? -dividend_ : dividend_),
548 uint128_t(divisor_.high_ < 0 ? -divisor_ : divisor_));
549 return int128_t(neg_ ? -res_ : res_);
552 static void part_div(uint128_t value_, uint64_t div_, uint64_t &high_, uint64_t &mid_, uint64_t &low_) {
553 uint128_t hh_(0), md_(0);
554 low_ = static_cast<uint64_t>(slow_div_(value_, div_, md_));
555 mid_ = static_cast<uint64_t>(slow_div_(md_, div_, hh_));
556 high_ = static_cast<uint64_t>(hh_);
560 constexpr static _Tp cast_to_float(uint128_t val_) { return std::ldexp(_Tp(val_.high_), 64) + _Tp(val_.low_); }
563 constexpr static _Tp cast_to_float(int128_t val_) {
564 return val_.high_ < 0 ? -cast_to_float<_Tp>(uint128_t(-val_)) : cast_to_float<_Tp>(uint128_t(val_));
568 #if USE_BUILTIN_INT128
571 struct detail_delegate<true> {
572 typedef __int128 ti_int_;
573 typedef unsigned __int128 tu_int_;
575 static constexpr ti_int_ to_native(int128_t val_) { return static_cast<ti_int_>(val_); }
577 static constexpr tu_int_ to_native(uint128_t val_) { return static_cast<tu_int_>(val_); }
579 static constexpr int128_t from_native(ti_int_ val_) { return int128_t(val_); }
581 static constexpr uint128_t from_native(tu_int_ val_) { return uint128_t(val_); }
583 template<class _Hi, class _Low>
584 static constexpr bool cmp(int128_base<_Hi, _Low> lhs_, int128_base<_Hi, _Low> rhs_) {
585 return to_native(lhs_) < to_native(rhs_);
588 static constexpr uint128_t shr(uint128_t lhs_, unsigned rhs_) {
589 return from_native(to_native(lhs_) >> static_cast<decltype(to_native(lhs_))>(rhs_));
592 static constexpr int128_t sar(int128_t lhs_, unsigned rhs_) {
593 return from_native(to_native(lhs_) >> static_cast<decltype(to_native(lhs_))>(rhs_));
596 template<class _Hi, class _Low>
597 static constexpr int128_base<_Hi, _Low> imul(int128_base<_Hi, _Low> lhs_, int128_base<_Hi, _Low> rhs_) {
598 return from_native(to_native(lhs_) * to_native(rhs_));
601 template<class _Hi, class _Low>
602 static constexpr int128_base<_Hi, _Low> shl(int128_base<_Hi, _Low> lhs_, unsigned rhs_) {
603 return from_native(to_native(lhs_) << static_cast<decltype(to_native(lhs_))>(rhs_));
606 template<class _Hi, class _Low>
607 static constexpr int128_base<_Hi, _Low> div(int128_base<_Hi, _Low> lhs_, int128_base<_Hi, _Low> rhs_) {
608 return from_native(to_native(lhs_) / to_native(rhs_));
611 template<class _Hi, class _Low>
612 static constexpr int128_base<_Hi, _Low> mod(int128_base<_Hi, _Low> lhs_, int128_base<_Hi, _Low> rhs_) {
613 return from_native(to_native(lhs_) % to_native(rhs_));
616 static void part_div(uint128_t value_, uint64_t div_, uint64_t &high_, uint64_t &mid_, uint64_t &low_) {
618 auto vv_ = to_native(value_);
619 auto rest_ = vv_ / div_;
620 low_ = static_cast<uint64_t>(vv_) - div_ * static_cast<uint64_t>(rest_);
621 high_ = static_cast<uint64_t>(rest_ / div_);
622 mid_ = static_cast<uint64_t>(rest_) - div_ * high_;
625 template<class _Tp, class _Hi, class _Low>
626 static constexpr _Tp cast_to_float(int128_base<_Hi, _Low> value_) {
627 return static_cast<_Tp>(to_native(value_));
634 constexpr bool operator<(int128_t lhs_, int128_t rhs_) { return detail_delegate<>::cmp(lhs_, rhs_); }
636 constexpr bool operator<(uint128_t lhs_, uint128_t rhs_) { return detail_delegate<>::cmp(lhs_, rhs_); }
638 constexpr uint128_t operator>>(uint128_t lhs_, int rhs_) {
639 return detail_delegate<>::shr(lhs_, static_cast<unsigned>(rhs_));
642 constexpr int128_t operator>>(int128_t lhs_, int rhs_) {
643 return detail_delegate<>::sar(lhs_, static_cast<unsigned>(rhs_));
646 constexpr int128_t operator*(int128_t lhs_, int128_t rhs_) { return detail_delegate<>::imul(lhs_, rhs_); }
648 constexpr uint128_t operator*(uint128_t lhs_, uint128_t rhs_) { return detail_delegate<>::imul(lhs_, rhs_); }
650 constexpr uint128_t operator<<(uint128_t lhs_, int rhs_) {
651 return detail_delegate<>::shl(lhs_, static_cast<unsigned>(rhs_));
654 constexpr int128_t operator<<(int128_t lhs_, int rhs_) {
655 return detail_delegate<>::shl(lhs_, static_cast<unsigned>(rhs_));
658 inline uint128_t operator/(uint128_t lhs_, uint128_t rhs_) { return detail_delegate<>::div(lhs_, rhs_); }
660 inline int128_t operator/(int128_t lhs_, int128_t rhs_) { return detail_delegate<>::div(lhs_, rhs_); }
662 inline uint128_t operator%(uint128_t lhs_, uint128_t rhs_) { return detail_delegate<>::mod(lhs_, rhs_); }
664 inline int128_t operator%(int128_t lhs_, int128_t rhs_) { return detail_delegate<>::mod(lhs_, rhs_); }
666 template<class _Hi, class _Low>
668 constexpr _Tp int128_base<_Hi, _Low>::cast_to_float() const {
669 return detail_delegate<>::cast_to_float<_Tp>(*this);
672 template<class _CharT, class _Traits>
673 inline std::basic_ostream<_CharT, _Traits> &
674 print_value(std::basic_ostream<_CharT, _Traits> &out_, bool signed_integral_, uint128_t value_) {
675 constexpr std::size_t buf_size_ = 45;
677 typename std::basic_ostream<_CharT, _Traits>::sentry sentry_(out_);
678 if (!sentry_) return out_;
679 auto flags_ = out_.flags(), base_flag_ = flags_ & std::ios::basefield;
680 auto adjust_field_ = flags_ & std::ios::adjustfield;
681 auto show_base_ = bool(flags_ & std::ios::showbase);
682 auto show_pos_ = bool(flags_ & std::ios::showpos);
683 auto upper_case_ = bool(flags_ & std::ios::uppercase);
684 auto ns_ = out_.width(0);
685 auto fl_ = out_.fill();
687 char buf_[buf_size_];
688 char const *prefix_ = nullptr;
691 switch (base_flag_) {
692 case std::ios::hex: {
693 if (show_base_ && value_) prefix_ = upper_case_ ? "0X" : "0x";
695 offset_ = snprintf(buf_, buf_size_,
696 upper_case_ ? "%" PRIX64 "%016" PRIX64 : "%" PRIx64 "%016" PRIx64,
697 (uint64_t) (value_ >> 64), (uint64_t) value_);
699 offset_ = snprintf(buf_, buf_size_,
700 upper_case_ ? "%" PRIX64 : "%" PRIx64, (uint64_t) value_);
704 case std::ios::oct: {
705 constexpr uint64_t mask_ = (UINT64_C(1) << 63U) - 1;
706 if (show_base_ && value_) buf_[offset_++] = '0';
707 auto x_ = (uint64_t) (value_ >> 126U);
708 auto y_ = (uint64_t) (value_ >> 63U) & mask_;
709 auto z_ = (uint64_t) (value_) & mask_;
711 offset_ += snprintf(buf_ + offset_, buf_size_ - offset_, "%" PRIo64 "%021" PRIo64 "%021" PRIo64,
714 offset_ += snprintf(buf_ + offset_, buf_size_ - offset_, "%" PRIo64 "%021" PRIo64, y_, z_);
716 offset_ += snprintf(buf_ + offset_, buf_size_ - offset_, "%" PRIo64, z_);
721 if (signed_integral_) {
725 } else if (show_pos_) {
729 uint64_t high_, mid_, low_;
730 detail_delegate<>::part_div(value_, UINT64_C(10000000000000000000), high_, mid_, low_);
732 offset_ = snprintf(buf_, buf_size_, "%" PRIu64 "%019" PRIu64 "%019" PRIu64,
735 offset_ = snprintf(buf_, buf_size_, "%" PRIu64 "%019" PRIu64,
738 offset_ = snprintf(buf_, buf_size_, "%" PRIu64, low_);
744 _CharT o_[2 * buf_size_ - 3] = {};
747 _CharT *oe_ = o_ + (sizeof(o_) / sizeof(o_[0]));
749 auto loc_ = out_.getloc();
750 auto &ct_ = std::use_facet<std::ctype<_CharT> >(loc_);
751 auto &npt_ = std::use_facet<std::numpunct<_CharT> >(loc_);
752 std::string grouping_ = npt_.grouping();
755 auto limit_ = grouping_.size();
758 ct_.widen(buf_, buf_ + offset_, op_);
760 auto thousands_sep_ = npt_.thousands_sep();
761 decltype(limit_) dg_ = 0;
762 auto cnt_ = static_cast<unsigned char>(grouping_[dg_]);
763 unsigned char dc_ = 0;
766 for (char *p_ = buf_ + offset_; p_ != buf_; ++dc_) {
767 if (cnt_ > 0 && dc_ == cnt_) {
768 *--op_ = thousands_sep_;
770 if (dg_ < limit_) cnt_ = static_cast<unsigned char>(grouping_[++dg_]);
772 *--op_ = ct_.widen(*--p_);
777 auto prefix_len_ = strlen(prefix_);
778 os_ = op_ - prefix_len_;
779 ct_.widen(prefix_, prefix_ + prefix_len_, os_);
784 auto sz_ = static_cast<std::streamsize>(oe_ - os_);
789 std::basic_string<_CharT, _Traits> sp_(ns_, fl_);
790 switch (adjust_field_) {
792 return out_.write(os_, sz_).write(sp_.data(), ns_);
793 case std::ios::internal:
794 return out_.write(os_, static_cast<std::streamsize>(op_ - os_))
795 .write(sp_.data(), ns_)
796 .write(op_, static_cast<std::streamsize>(oe_ - op_));
798 return out_.write(sp_.data(), ns_).write(os_, sz_);
801 return out_.write(os_, sz_);
804 template<class _CharT, class _Traits>
805 inline std::basic_ostream<_CharT, _Traits> &operator<<(std::basic_ostream<_CharT, _Traits> &out, uint128_t _Val) {
806 return print_value(out, false, _Val);
809 template<class _CharT, class _Traits>
810 inline std::basic_ostream<_CharT, _Traits> &operator<<(std::basic_ostream<_CharT, _Traits> &out, int128_t _Val) {
811 return print_value(out, true, uint128_t(_Val));
815 #ifdef INT128_SPECIALIZATION
817 #pragma push_macro("MAKE_TYPE")
818 #define MAKE_TYPE(outter, inner, parent) \
819 template<> struct outter<large_int::inner> : std::parent {}; \
820 template<> struct outter<const large_int::inner> : std::parent {}; \
821 template<> struct outter<volatile large_int::inner> : std::parent {}; \
822 template<> struct outter<const volatile large_int::inner> : std::parent {};
823 MAKE_TYPE(is_integral, uint128_t, true_type)
824 MAKE_TYPE(is_integral, int128_t, true_type)
825 MAKE_TYPE(is_signed, uint128_t, false_type)
826 MAKE_TYPE(is_signed, int128_t, true_type)
828 #define MAKE_TYPE(outter, inner, target) \
829 template<> struct outter<large_int::inner> { typedef large_int::target type; }; \
830 template<> struct outter<const large_int::inner> { typedef const large_int::target type; }; \
831 template<> struct outter<volatile large_int::inner> { typedef volatile large_int::target type; }; \
832 template<> struct outter<const volatile large_int::inner> { typedef const volatile large_int::target type; };
833 MAKE_TYPE(make_signed, uint128_t, int128_t)
834 MAKE_TYPE(make_unsigned, int128_t, uint128_t)
835 #pragma pop_macro("MAKE_TYPE")
837 template<class _Hi, class _Low>
838 struct numeric_limits<large_int::int128_base<_Hi, _Low> > {
840 typedef large_int::int128_base<_Hi, _Low> _Tp;
842 static constexpr const bool is_specialized = true;
843 static constexpr const bool is_signed = numeric_limits<_Hi>::is_signed;
844 static constexpr const bool is_integer = true;
845 static constexpr const bool is_exact = true;
846 static constexpr const bool has_infinity = false;
847 static constexpr const bool has_quiet_NaN = false;
848 static constexpr const bool has_signaling_NaN = false;
849 static constexpr const std::float_denorm_style has_denorm = std::denorm_absent;
850 static constexpr const bool has_denorm_loss = false;
851 static constexpr const std::float_round_style round_style = std::round_toward_zero;
852 static constexpr const bool is_iec559 = false;
853 static constexpr const bool is_bounded = true;
854 static constexpr const bool is_modulo = numeric_limits<_Hi>::is_modulo;
855 static constexpr const int digits = static_cast<int>(sizeof(_Tp) * 8 - is_signed);
856 static constexpr const int digits10 = digits * 3 / 10;
857 static constexpr const int max_digits10 = 0;
858 static constexpr const int radix = 2;
859 static constexpr const int min_exponent = 0;
860 static constexpr const int min_exponent10 = 0;
861 static constexpr const int max_exponent = 0;
862 static constexpr const int max_exponent10 = 0;
863 static constexpr const bool traps = numeric_limits<_Hi>::traps;
864 static constexpr const bool tinyness_before = false;
866 static constexpr _Tp min() { return is_signed ? _Tp(1) << digits : _Tp(0); }
868 static constexpr _Tp lowest() { return min(); }
870 static constexpr _Tp max() { return ~min(); }
872 static constexpr _Tp epsilon() { return _Tp(0); }
874 static constexpr _Tp round_error() { return _Tp(0); }
876 static constexpr _Tp infinity() { return _Tp(0); }
878 static constexpr _Tp quiet_NaN() { return _Tp(0); }
880 static constexpr _Tp signaling_NaN() { return _Tp(0); }
882 static constexpr _Tp denorm_min() { return _Tp(0); }
887 #ifndef INT128_NO_EXPORT
888 #define INT128_C(val) val##_L128
889 #define UINT128_C(val) val##_U128
891 using namespace large_int::literals;
892 using large_int::uint128_t;
893 using large_int::int128_t;
int128_base< uint64_t, uint64_t > uint128_t
int128_base< int64_t, uint64_t > int128_t