TTKMusicPlayer  3.7.0.0
TTKMusicPlayer imitates Kugou UI, the music player uses of qmmp core library based on Qt for windows and linux
int128.h
Go to the documentation of this file.
1 #pragma once
2 /*
3 int128.h
4 An signed/unsigned 128 bit integer type for C++
5 
6 https://github.com/zhanhb/int128
7 
8 MIT License
9 
10 Copyright (c) 2018 zhanhb
11 
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18 
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21 
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29 */
30 
31 #include <cmath>
32 #include <iostream>
33 #include <cinttypes>
34 #include <type_traits>
35 
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__
44 # endif
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__
55 # endif
56 #else
57 # error "I don't know what architecture this is!"
58 #endif
59 
60 #if (defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16) || defined(_GLIBCXX_USE_INT128)
61 # define USE_BUILTIN_INT128
62 #endif
63 
64 #ifdef _MSC_VER
65 #include <intrin.h>
66 #pragma warning(disable:4804)
67 
68 static __inline int __builtin_clz(int x)
69 {
70  unsigned long r = 0;
71  _BitScanReverse(&r, x);
72  return 31 ^ static_cast<int>(r);
73 }
74 
75 static __inline int __builtin_clzll(const uint64_t x)
76 {
77  unsigned long r = 0;
78 #ifdef _WIN64
79  _BitScanReverse64(&r, x);
80 # else
81  // Scan the high 32 bits.
82  if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
83  return 63 ^ static_cast<int>(r + 32);
84  // Scan the low 32 bits.
85  _BitScanReverse(&r, static_cast<uint32_t>(x));
86 #endif
87  return 63 ^ static_cast<int>(r);
88 }
89 
90 static __inline int __builtin_clzl(uint32_t x)
91 {
92 #ifdef _WIN64
93  return __builtin_clzll(x);
94 #else
95  return __builtin_clz(x);
96 #endif
97 }
98 #endif
99 
100 
101 namespace large_int {
102  template<class, class>
103  class int128_base;
104 
107 
108  template<class _Tp>
109  struct half_mask : std::integral_constant<_Tp, (_Tp(1) << (4 * sizeof(_Tp))) - _Tp(1)> {
110  };
111 
112  template<bool= true>
113  struct detail_delegate;
114 
115  constexpr bool operator<(int128_t, int128_t);
116 
117  constexpr bool operator<(uint128_t, uint128_t);
118 
119  constexpr uint128_t operator>>(uint128_t, int);
120 
121  constexpr int128_t operator>>(int128_t, int);
122 
123  constexpr int128_t operator*(int128_t, int128_t);
124 
125  constexpr uint128_t operator*(uint128_t, uint128_t);
126 
127  constexpr uint128_t operator<<(uint128_t, int);
128 
129  constexpr int128_t operator<<(int128_t, int);
130 
131  inline uint128_t operator/(uint128_t, uint128_t);
132 
133  inline int128_t operator/(int128_t, int128_t);
134 
135  inline uint128_t operator%(uint128_t, uint128_t);
136 
137  inline int128_t operator%(int128_t, int128_t);
138 
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");
142 
143  public:
144 #ifdef __LITTLE_ENDIAN__
145  _Low low_{};
146  _Hi high_{};
147 
148  constexpr int128_base(_Hi high, _Low low) : low_(low), high_(high) {}
149 
150 #elif __BIG_ENDIAN__
151  _Hi high_{};
152  _Low low_{};
153 
154  constexpr int128_base(_Hi high, _Low low) : high_(high), low_(low) {}
155 
156 #else
157 #error endian not support
158 #endif
159 
160  private:
161  struct integral_tag {
162  };
163  struct signed_integral_tag : integral_tag {
164  };
165  struct unsigned_integral_tag : integral_tag {
166  };
167  struct float_tag {
168  };
169  template<size_t>
170  struct size_constant {
171  };
172 
173  template<class _Tp>
174  constexpr int128_base(_Tp value_, signed_integral_tag, size_constant<8>) :
175  int128_base(-(value_ < 0), value_) {}
176 
177  template<class _Tp>
178  constexpr int128_base(_Tp value_, unsigned_integral_tag, size_constant<8>) : int128_base(0, _Low(value_)) {}
179 
180  template<class _Tp>
181  constexpr int128_base(_Tp value_, integral_tag, size_constant<16>) : // NOLINT explicit
182  int128_base(_Hi(value_ >> 64U), _Low(value_)) {} // NOLINT signed shift
183 
184  public:
185 
186  constexpr int128_base() noexcept = default;
187 
188  constexpr int128_base(const int128_base &) noexcept = default;
189 
190  constexpr int128_base(int128_base &&) noexcept = default;
191 
192  int128_base &operator=(const int128_base &) noexcept = default;
193 
194  int128_base &operator=(int128_base &&) noexcept = default;
195 
196  template<class _Tp>
197  constexpr explicit int128_base(int128_base<_Tp, _Low> val_) : int128_base(val_.high_, val_.low_) {}
198 
199  template<class _Tp>
200  constexpr int128_base(_Tp val_, float_tag) :
201  int128_base(_Hi(std::ldexp(val_, -64)) - (val_ < 0), _Low(val_)) {}
202 
203  constexpr explicit int128_base(float val_) : int128_base(val_, float_tag()) {}
204 
205  constexpr explicit int128_base(double val_) : int128_base(val_, float_tag()) {}
206 
207  constexpr explicit int128_base(long double val_) : int128_base(val_, float_tag()) {}
208 
209  constexpr int128_base(long long val_) : // NOLINT explicit
210  int128_base(val_, signed_integral_tag(), size_constant<sizeof(val_)>()) {}
211 
212  constexpr int128_base(long val_) : int128_base(static_cast<long long>(val_)) {} // NOLINT explicit
213 
214  constexpr int128_base(int val_) : int128_base(long(val_)) {} // NOLINT explicit
215 
216  constexpr int128_base(unsigned long long val_) : // NOLINT explicit
217  int128_base(val_, unsigned_integral_tag(), size_constant<sizeof(val_)>()) {}
218 
219  constexpr int128_base(unsigned long val_) : // NOLINT explicit
220  int128_base(static_cast<unsigned long long>(val_)) {}
221 
222  constexpr int128_base(unsigned val_) : int128_base(static_cast<unsigned long>(val_)) {} // NOLINT explicit
223 
224  constexpr explicit operator bool() const { return high_ || low_; }
225 
226  constexpr explicit operator char() const { return char(low_); }
227 
228  constexpr explicit operator signed char() const { return static_cast<signed char>(low_); }
229 
230  constexpr explicit operator unsigned char() const { return static_cast<unsigned char>(low_); }
231 
232  constexpr explicit operator short() const { return short(low_); }
233 
234  constexpr explicit operator unsigned short() const { return static_cast<unsigned short>(low_); }
235 
236  constexpr explicit operator int() const { return int(low_); }
237 
238  constexpr explicit operator unsigned() const { return unsigned(low_); }
239 
240  constexpr explicit operator long() const { return long(low_); }
241 
242  constexpr explicit operator unsigned long() const { return static_cast<unsigned long>(low_); }
243 
244  constexpr explicit operator long long() const { return static_cast<long long>(low_); }
245 
246  constexpr explicit operator unsigned long long() const { return static_cast<unsigned long long>(low_); }
247 
248  constexpr explicit operator wchar_t() const { return wchar_t(low_); }
249 
250  constexpr explicit operator char16_t() const { return char16_t(low_); }
251 
252  constexpr explicit operator char32_t() const { return char32_t(low_); }
253 
254 #if USE_BUILTIN_INT128
255 
256  constexpr explicit int128_base(__int128 val_) :
257  int128_base(val_, signed_integral_tag(), size_constant<sizeof(val_)>()) {}
258 
259  constexpr explicit int128_base(unsigned __int128 val_) :
260  int128_base(val_, unsigned_integral_tag(), size_constant<sizeof(val_)>()) {}
261 
262  constexpr explicit operator unsigned __int128() const {
263  return static_cast<unsigned __int128>(high_) << 64U | static_cast<unsigned __int128>(low_);
264  }
265 
266  constexpr explicit operator __int128() const {
267  return static_cast<__int128>(static_cast<unsigned __int128>(*this));
268  }
269 
270 #endif
271 
272  private:
273  template<class _Tp>
274  constexpr _Tp cast_to_float() const;
275 
276  public:
277  constexpr explicit operator float() const { return cast_to_float<float>(); }
278 
279  constexpr explicit operator double() const { return cast_to_float<double>(); }
280 
281  constexpr explicit operator long double() const { return cast_to_float<long double>(); }
282 
283  constexpr int128_base operator+() const { return *this; }
284 
285  constexpr int128_base operator-() const { return int128_base(-high_ - (low_ != 0), -low_); }
286 
287  constexpr int128_base operator~() const { return int128_base(~high_, ~low_); }
288 
289  constexpr bool operator!() const { return !high_ && !low_; }
290 
291  // avoid self plus on rvalue
292  int128_base &operator++() &{ return *this = *this + int128_base(1); }
293 
294  int128_base &operator--() &{ return *this = *this - int128_base(1); }
295 
296  int128_base operator++(int) &{ // NOLINT returns non constant
297  int128_base tmp = *this;
298  ++*this;
299  return tmp;
300  }
301 
302  int128_base operator--(int) &{ // NOLINT returns non constant
303  int128_base tmp = *this;
304  --*this;
305  return tmp;
306  }
307 
308  friend constexpr int128_base operator+(int128_base lhs_, int128_base rhs_) {
309  // no worry for unsigned type, won't be optimized if overflow
310  return {_Hi(lhs_.high_ + rhs_.high_ + (lhs_.low_ + rhs_.low_ < lhs_.low_)), lhs_.low_ + rhs_.low_};
311  }
312 
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_};
315  }
316 
317  friend constexpr int128_base operator&(int128_base lhs_, int128_base rhs_) {
318  return {lhs_.high_ & rhs_.high_, lhs_.low_ & rhs_.low_};
319  }
320 
321  friend constexpr int128_base operator|(int128_base lhs_, int128_base rhs_) {
322  return {lhs_.high_ | rhs_.high_, lhs_.low_ | rhs_.low_};
323  }
324 
325  friend constexpr int128_base operator^(int128_base lhs_, int128_base rhs_) {
326  return {lhs_.high_ ^ rhs_.high_, lhs_.low_ ^ rhs_.low_};
327  }
328 
329  friend constexpr bool operator==(int128_base lhs_, int128_base rhs_) {
330  return lhs_.high_ == rhs_.high_ && lhs_.low_ == rhs_.low_;
331  }
332 
333  friend constexpr bool operator>(int128_base lhs_, int128_base rhs_) { return rhs_ < lhs_; }
334 
335  friend constexpr bool operator>=(int128_base lhs_, int128_base rhs_) { return !(lhs_ < rhs_); }
336 
337  friend constexpr bool operator<=(int128_base lhs_, int128_base rhs_) { return !(rhs_ < lhs_); }
338 
339  friend constexpr bool operator!=(int128_base lhs_, int128_base rhs_) { return !(lhs_ == rhs_); }
340 
341  friend constexpr int128_base operator<<(int128_base lhs_, int128_base rhs_) { return lhs_ << (int) rhs_.low_; }
342 
343  friend constexpr int128_base operator>>(int128_base lhs_, int128_base rhs_) { return lhs_ >> (int) rhs_.low_; }
344 
345  int128_base &operator+=(int128_base rhs_) &{ return *this = *this + rhs_; }
346 
347  int128_base &operator-=(int128_base rhs_) &{ return *this = *this - rhs_; }
348 
349  int128_base &operator*=(int128_base rhs_) &{ return *this = *this * rhs_; }
350 
351  int128_base &operator/=(int128_base rhs_) &{ return *this = *this / rhs_; }
352 
353  int128_base &operator%=(int128_base rhs_) &{ return *this = *this % rhs_; }
354 
355  int128_base &operator<<=(int128_base rhs_) &{ return *this = *this << rhs_; }
356 
357  int128_base &operator>>=(int128_base rhs_) &{ return *this = *this >> rhs_; }
358 
359  int128_base &operator<<=(int rhs_) &{ return *this = *this << rhs_; }
360 
361  int128_base &operator>>=(int rhs_) &{ return *this = *this >> rhs_; }
362 
363  int128_base &operator&=(int128_base rhs_) &{ return *this = *this & rhs_; }
364 
365  int128_base &operator|=(int128_base rhs_) &{ return *this = *this | rhs_; }
366 
367  int128_base &operator^=(int128_base rhs_) &{ return *this = *this ^ rhs_; }
368 
369  template<class, class>
370  friend
371  class int128_base;
372 
373  template<class>
374  friend
375  struct clz_helper;
377  template<bool>
378  friend
379  struct detail_delegate;
380  };
381 
382  inline namespace literals {
383  namespace impl_ {
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");
390  };
391 
392  template<class, int, char ...>
393  struct int128_literal_radix;
394 
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); } // NOLINT explicit
398 
399  constexpr _Tp operator()(_Tp v) const { return v * _Tp(_Rad) + *this; }
400  };
401 
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;
406 
407  constexpr operator _Tp() const { return _Tgt(_Cur); } // NOLINT explicit
408 
409  constexpr _Tp operator()(_Tp v) const { return _Tgt(_Cur(v)); }
410  };
411 
412  template<class _Tp, char ..._Args>
413  struct int128_literal : int128_literal_radix<_Tp, 10, _Args...> {
414  };
415  template<class _Tp>
416  struct int128_literal<_Tp, '0'> : int128_literal_radix<_Tp, 10, '0'> {
417  };
418  template<class _Tp, char ..._Args>
419  struct int128_literal<_Tp, '0', _Args...> : int128_literal_radix<_Tp, 8, _Args...> {
420  };
421  template<class _Tp, char ..._Args>
422  struct int128_literal<_Tp, '0', 'x', _Args...> : int128_literal_radix<_Tp, 16, _Args...> {
423  };
424  template<class _Tp, char ..._Args>
425  struct int128_literal<_Tp, '0', 'X', _Args...> : int128_literal_radix<_Tp, 16, _Args...> {
426  };
427  template<class _Tp, char ..._Args>
428  struct int128_literal<_Tp, '0', 'b', _Args...> : int128_literal_radix<_Tp, 2, _Args...> {
429  };
430  template<class _Tp, char ..._Args>
431  struct int128_literal<_Tp, '0', 'B', _Args...> : int128_literal_radix<_Tp, 2, _Args...> {
432  };
433  }
434 
435  template<char ..._Args>
436  constexpr uint128_t operator "" _u128() { return impl_::int128_literal<uint128_t, _Args...>(); }
437 
438  template<char ..._Args>
439  constexpr int128_t operator "" _l128() { return impl_::int128_literal<int128_t, _Args...>(); }
440 
441  template<char ..._Args>
442  constexpr uint128_t operator "" _U128() { return impl_::int128_literal<uint128_t, _Args...>(); }
443 
444  template<char ..._Args>
445  constexpr int128_t operator "" _L128() { return impl_::int128_literal<int128_t, _Args...>(); }
446  }
447 
448  template<class>
449  struct clz_helper;
450 
451  template<>
452  struct clz_helper<unsigned long> {
453  static int clz(unsigned long val_) { return __builtin_clzl(val_); }
454  };
455 
456  template<>
457  struct clz_helper<unsigned long long> {
458  static int clz(unsigned long long val_) { return __builtin_clzll(val_); }
459  };
460 
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_);
465  }
466  };
467 
468  template<bool>
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_);
473  }
474 
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_;
479  }
480 
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))) : // NOLINT
483  rhs_ & 63U ? int128_t(
484  lhs_.high_ >> (rhs_ & 63U), // NOLINT signed shift
485  (uint64_t(lhs_.high_) << (64 - (rhs_ & 63U)) | (lhs_.low_ >> (rhs_ & 63U)))) : lhs_;
486  }
487 
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);
495  }
496 
497  template<class _Hi, class _Low>
498  static constexpr int128_base<_Hi, _Low> shl(int128_base<_Hi, _Low> lhs_, unsigned rhs_) {
499  // [64,127], 64 {low_ << 0, 0}
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_;
504  }
505 
506  static uint128_t &slow_div_(uint128_t &dividend_, uint128_t divisor_, uint128_t &quot_) {
507  // assert(divisor != uint128_t(0));
508  quot_ = uint128_t(0);
509  if (cmp(dividend_, divisor_)) return dividend_;
510  if (dividend_.high_ == 0) { // (0,x) / ???
511  quot_.low_ = dividend_.low_ / divisor_.low_;
512  dividend_.low_ %= divisor_.low_;
513  return dividend_;
514  }
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);
521  }
522  if (!zsor_--) return dividend_;
523  }
524  }
525 
526  static uint128_t div(uint128_t dividend_, uint128_t divisor_) {
527  if (!divisor_) return {!!dividend_ / !!divisor_}; // raise signal SIGFPE
528  uint128_t quot_(0);
529  slow_div_(dividend_, divisor_, quot_);
530  return quot_;
531  }
532 
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_);
537  }
538 
539  static uint128_t mod(uint128_t dividend_, uint128_t divisor_) {
540  if (!divisor_) return {!!dividend_ % !!divisor_}; // raise signal SIGFPE
541  uint128_t quot_(0);
542  return slow_div_(dividend_, divisor_, quot_);
543  }
544 
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_);
550  }
551 
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_);
557  }
558 
559  template<class _Tp>
560  constexpr static _Tp cast_to_float(uint128_t val_) { return std::ldexp(_Tp(val_.high_), 64) + _Tp(val_.low_); }
561 
562  template<class _Tp>
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_));
565  }
566  };
567 
568 #if USE_BUILTIN_INT128
569 
570  template<>
571  struct detail_delegate<true> {
572  typedef __int128 ti_int_;
573  typedef unsigned __int128 tu_int_;
574 
575  static constexpr ti_int_ to_native(int128_t val_) { return static_cast<ti_int_>(val_); }
576 
577  static constexpr tu_int_ to_native(uint128_t val_) { return static_cast<tu_int_>(val_); }
578 
579  static constexpr int128_t from_native(ti_int_ val_) { return int128_t(val_); }
580 
581  static constexpr uint128_t from_native(tu_int_ val_) { return uint128_t(val_); }
582 
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_);
586  }
587 
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_));
590  }
591 
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_)); // NOLINT signed shift
594  }
595 
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_));
599  }
600 
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_)); // NOLINT signed shift
604  }
605 
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_));
609  }
610 
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_));
614  }
615 
616  static void part_div(uint128_t value_, uint64_t div_, uint64_t &high_, uint64_t &mid_, uint64_t &low_) {
617  // on some cpu, compiler won't do optimize for us
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_;
623  }
624 
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_));
628  }
629 
630  };
631 
632 #endif
633 
634  constexpr bool operator<(int128_t lhs_, int128_t rhs_) { return detail_delegate<>::cmp(lhs_, rhs_); }
635 
636  constexpr bool operator<(uint128_t lhs_, uint128_t rhs_) { return detail_delegate<>::cmp(lhs_, rhs_); }
637 
638  constexpr uint128_t operator>>(uint128_t lhs_, int rhs_) {
639  return detail_delegate<>::shr(lhs_, static_cast<unsigned>(rhs_));
640  }
641 
642  constexpr int128_t operator>>(int128_t lhs_, int rhs_) {
643  return detail_delegate<>::sar(lhs_, static_cast<unsigned>(rhs_));
644  }
645 
646  constexpr int128_t operator*(int128_t lhs_, int128_t rhs_) { return detail_delegate<>::imul(lhs_, rhs_); }
647 
648  constexpr uint128_t operator*(uint128_t lhs_, uint128_t rhs_) { return detail_delegate<>::imul(lhs_, rhs_); }
649 
650  constexpr uint128_t operator<<(uint128_t lhs_, int rhs_) {
651  return detail_delegate<>::shl(lhs_, static_cast<unsigned>(rhs_));
652  }
653 
654  constexpr int128_t operator<<(int128_t lhs_, int rhs_) {
655  return detail_delegate<>::shl(lhs_, static_cast<unsigned>(rhs_));
656  }
657 
658  inline uint128_t operator/(uint128_t lhs_, uint128_t rhs_) { return detail_delegate<>::div(lhs_, rhs_); }
659 
660  inline int128_t operator/(int128_t lhs_, int128_t rhs_) { return detail_delegate<>::div(lhs_, rhs_); }
661 
662  inline uint128_t operator%(uint128_t lhs_, uint128_t rhs_) { return detail_delegate<>::mod(lhs_, rhs_); }
663 
664  inline int128_t operator%(int128_t lhs_, int128_t rhs_) { return detail_delegate<>::mod(lhs_, rhs_); }
665 
666  template<class _Hi, class _Low>
667  template<class _Tp>
668  constexpr _Tp int128_base<_Hi, _Low>::cast_to_float() const {
669  return detail_delegate<>::cast_to_float<_Tp>(*this);
670  }
671 
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;
676 
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); // work not dec
682  auto show_pos_ = bool(flags_ & std::ios::showpos); // work only dec
683  auto upper_case_ = bool(flags_ & std::ios::uppercase); // work only hex
684  auto ns_ = out_.width(0);
685  auto fl_ = out_.fill();
686 
687  char buf_[buf_size_];
688  char const *prefix_ = nullptr;
689  int offset_ = 0;
690 
691  switch (base_flag_) {
692  case std::ios::hex: {
693  if (show_base_ && value_) prefix_ = upper_case_ ? "0X" : "0x";
694  if (value_ >> 64) {
695  offset_ = snprintf(buf_, buf_size_,
696  upper_case_ ? "%" PRIX64 "%016" PRIX64 : "%" PRIx64 "%016" PRIx64,
697  (uint64_t) (value_ >> 64), (uint64_t) value_);
698  } else {
699  offset_ = snprintf(buf_, buf_size_,
700  upper_case_ ? "%" PRIX64 : "%" PRIx64, (uint64_t) value_);
701  }
702  break;
703  }
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_;
710  if (x_) {
711  offset_ += snprintf(buf_ + offset_, buf_size_ - offset_, "%" PRIo64 "%021" PRIo64 "%021" PRIo64,
712  x_, y_, z_);
713  } else if (y_) {
714  offset_ += snprintf(buf_ + offset_, buf_size_ - offset_, "%" PRIo64 "%021" PRIo64, y_, z_);
715  } else {
716  offset_ += snprintf(buf_ + offset_, buf_size_ - offset_, "%" PRIo64, z_);
717  }
718  break;
719  }
720  default: {
721  if (signed_integral_) {
722  if (value_ >> 127) { // negative
723  prefix_ = "-";
724  value_ = -value_;
725  } else if (show_pos_) {
726  prefix_ = "+";
727  }
728  }
729  uint64_t high_, mid_, low_;
730  detail_delegate<>::part_div(value_, UINT64_C(10000000000000000000), high_, mid_, low_);
731  if (high_) {
732  offset_ = snprintf(buf_, buf_size_, "%" PRIu64 "%019" PRIu64 "%019" PRIu64,
733  high_, mid_, low_);
734  } else if (mid_) {
735  offset_ = snprintf(buf_, buf_size_, "%" PRIu64 "%019" PRIu64,
736  mid_, low_);
737  } else {
738  offset_ = snprintf(buf_, buf_size_, "%" PRIu64, low_);
739  }
740  break;
741  }
742  }
743 
744  _CharT o_[2 * buf_size_ - 3] = {};
745  _CharT *os_;
746  _CharT *op_; // prefix here
747  _CharT *oe_ = o_ + (sizeof(o_) / sizeof(o_[0])); // end of output
748 
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();
753 
754  // no worry group is not empty
755  auto limit_ = grouping_.size();
756  if (limit_ == 0) {
757  op_ = oe_ - offset_;
758  ct_.widen(buf_, buf_ + offset_, op_);
759  } else {
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;
764  --limit_;
765  op_ = oe_;
766  for (char *p_ = buf_ + offset_; p_ != buf_; ++dc_) {
767  if (cnt_ > 0 && dc_ == cnt_) {
768  *--op_ = thousands_sep_;
769  dc_ = 0;
770  if (dg_ < limit_) cnt_ = static_cast<unsigned char>(grouping_[++dg_]);
771  }
772  *--op_ = ct_.widen(*--p_);
773  }
774  }
775 
776  if (prefix_) {
777  auto prefix_len_ = strlen(prefix_);
778  os_ = op_ - prefix_len_;
779  ct_.widen(prefix_, prefix_ + prefix_len_, os_);
780  } else {
781  os_ = op_;
782  }
783 
784  auto sz_ = static_cast<std::streamsize>(oe_ - os_);
785  // assert(sz_ <= (sizeof(o_) / sizeof(o_[0])));
786 
787  if (ns_ > sz_) {
788  ns_ -= sz_;
789  std::basic_string<_CharT, _Traits> sp_(ns_, fl_);
790  switch (adjust_field_) {
791  case std::ios::left:
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_));
797  default:
798  return out_.write(sp_.data(), ns_).write(os_, sz_);
799  }
800  }
801  return out_.write(os_, sz_);
802  }
803 
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);
807  }
808 
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));
812  }
813 }
814 
815 #ifdef INT128_SPECIALIZATION
816 namespace std {
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)
827 #undef MAKE_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")
836 
837  template<class _Hi, class _Low>
838  struct numeric_limits<large_int::int128_base<_Hi, _Low> > {
839  private:
840  typedef large_int::int128_base<_Hi, _Low> _Tp;
841  public:
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;
865 
866  static constexpr _Tp min() { return is_signed ? _Tp(1) << digits : _Tp(0); }
867 
868  static constexpr _Tp lowest() { return min(); }
869 
870  static constexpr _Tp max() { return ~min(); }
871 
872  static constexpr _Tp epsilon() { return _Tp(0); }
873 
874  static constexpr _Tp round_error() { return _Tp(0); }
875 
876  static constexpr _Tp infinity() { return _Tp(0); }
877 
878  static constexpr _Tp quiet_NaN() { return _Tp(0); }
879 
880  static constexpr _Tp signaling_NaN() { return _Tp(0); }
881 
882  static constexpr _Tp denorm_min() { return _Tp(0); }
883  };
884 }
885 #endif /* INT128_SPECIALIZATION */
886 
887 #ifndef INT128_NO_EXPORT
888 #define INT128_C(val) val##_L128
889 #define UINT128_C(val) val##_U128
890 // add space between '""' and suffix identifier, or may compile failed
891 using namespace large_int::literals;
892 using large_int::uint128_t;
893 using large_int::int128_t;
894 #endif /* INT128_NO_EXPORT */
int128_base< uint64_t, uint64_t > uint128_t
Definition: int128.h:106
int128_base< int64_t, uint64_t > int128_t
Definition: int128.h:103