30 #ifndef _GLIBCXX_MAX_SIZE_TYPE_H
31 #define _GLIBCXX_MAX_SIZE_TYPE_H 1
33 #ifdef _GLIBCXX_SYSHDR
34 #pragma GCC system_header
37 #if __cplusplus > 201703L && __cpp_lib_concepts
50 namespace std _GLIBCXX_VISIBILITY(default)
52 _GLIBCXX_BEGIN_NAMESPACE_VERSION
54 template<
typename _Tp>
55 struct numeric_limits;
64 __max_size_type() =
default;
66 template<
typename _Tp> requires integral<_Tp>
68 __max_size_type(_Tp __i) noexcept
69 : _M_val(__i), _M_msb(__i < 0)
73 __max_size_type(
const __max_diff_type& __d) noexcept;
75 template<
typename _Tp> requires integral<_Tp>
77 operator _Tp() const noexcept
81 operator bool() const noexcept
82 {
return _M_val != 0 || _M_msb != 0; }
84 constexpr __max_size_type
88 constexpr __max_size_type
89 operator~() const noexcept
90 {
return __max_size_type{~_M_val, !_M_msb}; }
92 constexpr __max_size_type
94 {
return operator~() + 1; }
96 constexpr __max_size_type&
98 {
return *
this += 1; }
100 constexpr __max_size_type
101 operator++(
int) noexcept
108 constexpr __max_size_type&
109 operator--() noexcept
110 {
return *
this -= 1; }
112 constexpr __max_size_type
113 operator--(
int) noexcept
120 constexpr __max_size_type&
121 operator+=(
const __max_size_type& __r) noexcept
123 const auto __sum = _M_val + __r._M_val;
124 const bool __overflow = (__sum < _M_val);
125 _M_msb = _M_msb ^ __r._M_msb ^ __overflow;
130 constexpr __max_size_type&
131 operator-=(
const __max_size_type& __r) noexcept
132 {
return *
this += -__r; }
134 constexpr __max_size_type&
135 operator*=(__max_size_type __r) noexcept
137 constexpr __max_size_type __threshold
138 = __rep(1) << (_S_rep_bits / 2 - 1);
139 if (_M_val < __threshold && __r < __threshold)
142 _M_val = _M_val * __r._M_val;
148 const bool __lsb = _M_val & 1;
149 const bool __rlsb = __r._M_val & 1;
152 _M_val = (2 * _M_val * __r._M_val
153 + _M_val * __rlsb + __r._M_val * __lsb);
155 *
this += __rlsb * __lsb;
161 constexpr __max_size_type&
162 operator/=(
const __max_size_type& __r) noexcept
164 __glibcxx_assert(__r != 0);
166 if (!_M_msb && !__r._M_msb) [[likely]]
167 _M_val /= __r._M_val;
168 else if (_M_msb && __r._M_msb)
170 _M_val = (_M_val >= __r._M_val);
173 else if (!_M_msb && __r._M_msb)
175 else if (_M_msb && !__r._M_msb)
181 const auto __orig = *
this;
183 _M_val /= __r._M_val;
185 if (__orig - *
this * __r >= __r)
191 constexpr __max_size_type&
192 operator%=(
const __max_size_type& __r) noexcept
194 if (!_M_msb && !__r._M_msb) [[likely]]
195 _M_val %= __r._M_val;
197 *
this -= (*
this / __r) * __r;
201 constexpr __max_size_type&
202 operator<<=(
const __max_size_type& __r) noexcept
204 __glibcxx_assert(__r <= _S_rep_bits);
207 _M_msb = (_M_val >> (_S_rep_bits - __r._M_val)) & 1;
209 if (__r._M_val == _S_rep_bits) [[unlikely]]
212 _M_val <<= __r._M_val;
217 constexpr __max_size_type&
218 operator>>=(
const __max_size_type& __r) noexcept
220 __glibcxx_assert(__r <= _S_rep_bits);
223 if (__r._M_val == _S_rep_bits) [[unlikely]]
226 _M_val >>= __r._M_val;
228 if (_M_msb) [[unlikely]]
230 _M_val |= __rep(1) << (_S_rep_bits - __r._M_val);
237 constexpr __max_size_type&
238 operator&=(
const __max_size_type& __r) noexcept
240 _M_val &= __r._M_val;
241 _M_msb &= __r._M_msb;
245 constexpr __max_size_type&
246 operator|=(
const __max_size_type& __r) noexcept
248 _M_val |= __r._M_val;
249 _M_msb |= __r._M_msb;
253 constexpr __max_size_type&
254 operator^=(
const __max_size_type& __r) noexcept
256 _M_val ^= __r._M_val;
257 _M_msb ^= __r._M_msb;
261 template<
typename _Tp> requires integral<_Tp>
262 friend constexpr _Tp&
263 operator+=(_Tp& __a,
const __max_size_type& __b) noexcept
264 {
return (__a =
static_cast<_Tp
>(__a + __b)); }
266 template<
typename _Tp> requires integral<_Tp>
267 friend constexpr _Tp&
268 operator-=(_Tp& __a,
const __max_size_type& __b) noexcept
269 {
return (__a =
static_cast<_Tp
>(__a - __b)); }
271 template<
typename _Tp> requires integral<_Tp>
272 friend constexpr _Tp&
273 operator*=(_Tp& __a,
const __max_size_type& __b) noexcept
274 {
return (__a =
static_cast<_Tp
>(__a * __b)); }
276 template<
typename _Tp> requires integral<_Tp>
277 friend constexpr _Tp&
278 operator/=(_Tp& __a,
const __max_size_type& __b) noexcept
279 {
return (__a =
static_cast<_Tp
>(__a / __b)); }
281 template<
typename _Tp> requires integral<_Tp>
282 friend constexpr _Tp&
283 operator%=(_Tp& __a,
const __max_size_type& __b) noexcept
284 {
return (__a =
static_cast<_Tp
>(__a % __b)); }
286 template<
typename _Tp> requires integral<_Tp>
287 friend constexpr _Tp&
288 operator&=(_Tp& __a,
const __max_size_type& __b) noexcept
289 {
return (__a =
static_cast<_Tp
>(__a & __b)); }
291 template<
typename _Tp> requires integral<_Tp>
292 friend constexpr _Tp&
293 operator|=(_Tp& __a,
const __max_size_type& __b) noexcept
294 {
return (__a =
static_cast<_Tp
>(__a | __b)); }
296 template<
typename _Tp> requires integral<_Tp>
297 friend constexpr _Tp&
298 operator^=(_Tp& __a,
const __max_size_type& __b) noexcept
299 {
return (__a =
static_cast<_Tp
>(__a ^ __b)); }
301 template<
typename _Tp> requires integral<_Tp>
302 friend constexpr _Tp&
303 operator<<=(_Tp& __a,
const __max_size_type& __b) noexcept
304 {
return (__a =
static_cast<_Tp
>(__a << __b)); }
306 template<
typename _Tp> requires integral<_Tp>
307 friend constexpr _Tp&
308 operator>>=(_Tp& __a,
const __max_size_type& __b) noexcept
309 {
return (__a =
static_cast<_Tp
>(__a >> __b)); }
311 friend constexpr __max_size_type
312 operator+(__max_size_type __l,
const __max_size_type& __r) noexcept
318 friend constexpr __max_size_type
319 operator-(__max_size_type __l,
const __max_size_type& __r) noexcept
325 friend constexpr __max_size_type
326 operator*(__max_size_type __l,
const __max_size_type& __r) noexcept
332 friend constexpr __max_size_type
333 operator/(__max_size_type __l,
const __max_size_type& __r) noexcept
339 friend constexpr __max_size_type
340 operator%(__max_size_type __l,
const __max_size_type& __r) noexcept
346 friend constexpr __max_size_type
347 operator<<(__max_size_type __l,
const __max_size_type& __r) noexcept
353 friend constexpr __max_size_type
354 operator>>(__max_size_type __l,
const __max_size_type& __r) noexcept
360 friend constexpr __max_size_type
361 operator&(__max_size_type __l,
const __max_size_type& __r) noexcept
367 friend constexpr __max_size_type
368 operator|(__max_size_type __l,
const __max_size_type& __r) noexcept
374 friend constexpr __max_size_type
375 operator^(__max_size_type __l,
const __max_size_type& __r) noexcept
381 friend constexpr
bool
382 operator==(
const __max_size_type& __l,
const __max_size_type& __r) noexcept
383 {
return __l._M_val == __r._M_val && __l._M_msb == __r._M_msb; }
385 #if __cpp_lib_three_way_comparison
386 friend constexpr strong_ordering
387 operator<=>(
const __max_size_type& __l,
const __max_size_type& __r) noexcept
389 if (__l._M_msb ^ __r._M_msb)
390 return __l._M_msb ? strong_ordering::greater : strong_ordering::less;
392 return __l._M_val <=> __r._M_val;
395 friend constexpr
bool
396 operator!=(
const __max_size_type& __l,
const __max_size_type& __r) noexcept
397 {
return !(__l == __r); }
399 friend constexpr
bool
400 operator<(
const __max_size_type& __l,
const __max_size_type& __r) noexcept
402 if (__l._M_msb == __r._M_msb)
403 return __l._M_val < __r._M_val;
408 friend constexpr
bool
409 operator>(
const __max_size_type& __l,
const __max_size_type& __r) noexcept
410 {
return __r < __l; }
412 friend constexpr
bool
413 operator<=(
const __max_size_type& __l,
const __max_size_type& __r) noexcept
414 {
return !(__l > __r); }
416 friend constexpr
bool
417 operator>=(
const __max_size_type& __l,
const __max_size_type& __r) noexcept
418 {
return __r <= __l; }
421 #if __SIZEOF_INT128__
423 using __rep =
unsigned __int128;
425 using __rep =
unsigned long long;
427 static constexpr
size_t _S_rep_bits =
sizeof(__rep) * __CHAR_BIT__;
430 unsigned _M_msb:1 = 0;
434 __max_size_type(__rep __val,
int __msb) noexcept
435 : _M_val(__val), _M_msb(__msb)
438 friend __max_diff_type;
443 class __max_diff_type
446 __max_diff_type() =
default;
448 template<
typename _Tp> requires integral<_Tp>
450 __max_diff_type(_Tp __i) noexcept
455 __max_diff_type(
const __max_size_type& __d) noexcept
459 template<
typename _Tp> requires integral<_Tp>
461 operator _Tp() const noexcept
462 {
return static_cast<_Tp
>(_M_rep); }
465 operator bool() const noexcept
466 {
return _M_rep != 0; }
468 constexpr __max_diff_type
472 constexpr __max_diff_type
474 {
return __max_diff_type(-_M_rep); }
476 constexpr __max_diff_type
477 operator~() const noexcept
478 {
return __max_diff_type(~_M_rep); }
480 constexpr __max_diff_type&
481 operator++() noexcept
482 {
return *
this += 1; }
484 constexpr __max_diff_type
485 operator++(
int) noexcept
492 constexpr __max_diff_type&
493 operator--() noexcept
494 {
return *
this -= 1; }
496 constexpr __max_diff_type
497 operator--(
int) noexcept
504 constexpr __max_diff_type&
505 operator+=(
const __max_diff_type& __r) noexcept
507 _M_rep += __r._M_rep;
511 constexpr __max_diff_type&
512 operator-=(
const __max_diff_type& __r) noexcept
514 _M_rep -= __r._M_rep;
518 constexpr __max_diff_type&
519 operator*=(
const __max_diff_type& __r) noexcept
521 _M_rep *= __r._M_rep;
525 constexpr __max_diff_type&
526 operator/=(
const __max_diff_type& __r) noexcept
528 __glibcxx_assert (__r != 0);
529 const bool __neg = *
this < 0;
530 const bool __rneg = __r < 0;
531 if (!__neg && !__rneg)
532 _M_rep = _M_rep / __r._M_rep;
533 else if (__neg && __rneg)
534 _M_rep = -_M_rep / -__r._M_rep;
535 else if (__neg && !__rneg)
536 _M_rep = -(-_M_rep / __r._M_rep);
538 _M_rep = -(_M_rep / -__r._M_rep);
542 constexpr __max_diff_type&
543 operator%=(
const __max_diff_type& __r) noexcept
545 __glibcxx_assert (__r != 0);
546 if (*
this >= 0 && __r > 0)
547 _M_rep %= __r._M_rep;
549 *
this -= (*
this / __r) * __r;
553 constexpr __max_diff_type&
554 operator<<=(
const __max_diff_type& __r) noexcept
556 _M_rep.operator<<=(__r._M_rep);
560 constexpr __max_diff_type&
561 operator>>=(
const __max_diff_type& __r) noexcept
564 const auto __msb = _M_rep._M_msb;
565 _M_rep >>= __r._M_rep;
567 _M_rep |= ~(__max_size_type(-1) >> __r._M_rep);
571 constexpr __max_diff_type&
572 operator&=(
const __max_diff_type& __r) noexcept
574 _M_rep &= __r._M_rep;
578 constexpr __max_diff_type&
579 operator|=(
const __max_diff_type& __r) noexcept
581 _M_rep |= __r._M_rep;
585 constexpr __max_diff_type&
586 operator^=(
const __max_diff_type& __r) noexcept
588 _M_rep ^= __r._M_rep;
592 template<
typename _Tp> requires integral<_Tp>
593 friend constexpr _Tp&
594 operator+=(_Tp& __a,
const __max_diff_type& __b) noexcept
595 {
return (__a =
static_cast<_Tp
>(__a + __b)); }
597 template<
typename _Tp> requires integral<_Tp>
598 friend constexpr _Tp&
599 operator-=(_Tp& __a,
const __max_diff_type& __b) noexcept
600 {
return (__a =
static_cast<_Tp
>(__a - __b)); }
602 template<
typename _Tp> requires integral<_Tp>
603 friend constexpr _Tp&
604 operator*=(_Tp& __a,
const __max_diff_type& __b) noexcept
605 {
return (__a =
static_cast<_Tp
>(__a * __b)); }
607 template<
typename _Tp> requires integral<_Tp>
608 friend constexpr _Tp&
609 operator/=(_Tp& __a,
const __max_diff_type& __b) noexcept
610 {
return (__a =
static_cast<_Tp
>(__a / __b)); }
612 template<
typename _Tp> requires integral<_Tp>
613 friend constexpr _Tp&
614 operator%=(_Tp& __a,
const __max_diff_type& __b) noexcept
615 {
return (__a =
static_cast<_Tp
>(__a % __b)); }
617 template<
typename _Tp> requires integral<_Tp>
618 friend constexpr _Tp&
619 operator&=(_Tp& __a,
const __max_diff_type& __b) noexcept
620 {
return (__a =
static_cast<_Tp
>(__a & __b)); }
622 template<
typename _Tp> requires integral<_Tp>
623 friend constexpr _Tp&
624 operator|=(_Tp& __a,
const __max_diff_type& __b) noexcept
625 {
return (__a =
static_cast<_Tp
>(__a | __b)); }
627 template<
typename _Tp> requires integral<_Tp>
628 friend constexpr _Tp&
629 operator^=(_Tp& __a,
const __max_diff_type& __b) noexcept
630 {
return (__a =
static_cast<_Tp
>(__a ^ __b)); }
632 template<
typename _Tp> requires integral<_Tp>
633 friend constexpr _Tp&
634 operator<<=(_Tp& __a,
const __max_diff_type& __b) noexcept
635 {
return (__a =
static_cast<_Tp
>(__a << __b)); }
637 template<
typename _Tp> requires integral<_Tp>
638 friend constexpr _Tp&
639 operator>>=(_Tp& __a,
const __max_diff_type& __b) noexcept
640 {
return (__a =
static_cast<_Tp
>(__a >> __b)); }
642 friend constexpr __max_diff_type
643 operator+(__max_diff_type __l,
const __max_diff_type& __r) noexcept
649 friend constexpr __max_diff_type
650 operator-(__max_diff_type __l,
const __max_diff_type& __r) noexcept
656 friend constexpr __max_diff_type
657 operator*(__max_diff_type __l,
const __max_diff_type& __r) noexcept
663 friend constexpr __max_diff_type
664 operator/(__max_diff_type __l,
const __max_diff_type& __r) noexcept
670 friend constexpr __max_diff_type
671 operator%(__max_diff_type __l,
const __max_diff_type& __r) noexcept
677 friend constexpr __max_diff_type
678 operator<<(__max_diff_type __l,
const __max_diff_type& __r) noexcept
684 friend constexpr __max_diff_type
685 operator>>(__max_diff_type __l,
const __max_diff_type& __r) noexcept
691 friend constexpr __max_diff_type
692 operator&(__max_diff_type __l,
const __max_diff_type& __r) noexcept
698 friend constexpr __max_diff_type
699 operator|(__max_diff_type __l,
const __max_diff_type& __r) noexcept
705 friend constexpr __max_diff_type
706 operator^(__max_diff_type __l,
const __max_diff_type& __r) noexcept
712 friend constexpr
bool
713 operator==(
const __max_diff_type& __l,
const __max_diff_type& __r) noexcept
714 {
return __l._M_rep == __r._M_rep; }
716 #if __cpp_lib_three_way_comparison
717 constexpr strong_ordering
718 operator<=>(
const __max_diff_type& __r)
const noexcept
720 const auto __lsign = _M_rep._M_msb;
721 const auto __rsign = __r._M_rep._M_msb;
722 if (__lsign ^ __rsign)
723 return __lsign ? strong_ordering::less : strong_ordering::greater;
725 return _M_rep <=> __r._M_rep;
728 friend constexpr
bool
729 operator!=(
const __max_diff_type& __l,
const __max_diff_type& __r) noexcept
730 {
return !(__l == __r); }
733 operator<(
const __max_diff_type& __r)
const noexcept
735 const auto __lsign = _M_rep._M_msb;
736 const auto __rsign = __r._M_rep._M_msb;
737 if (__lsign ^ __rsign)
740 return _M_rep < __r._M_rep;
743 friend constexpr
bool
744 operator>(
const __max_diff_type& __l,
const __max_diff_type& __r) noexcept
745 {
return __r < __l; }
747 friend constexpr
bool
748 operator<=(
const __max_diff_type& __l,
const __max_diff_type& __r) noexcept
749 {
return !(__r < __l); }
751 friend constexpr
bool
752 operator>=(
const __max_diff_type& __l,
const __max_diff_type& __r) noexcept
753 {
return !(__l < __r); }
756 __max_size_type _M_rep = 0;
758 friend class __max_size_type;
762 __max_size_type::__max_size_type(
const __max_diff_type& __d) noexcept
763 : __max_size_type(__d._M_rep)
770 struct numeric_limits<ranges::__detail::__max_size_type>
772 using _Sp = ranges::__detail::__max_size_type;
776 static constexpr
bool is_exact =
true;
779 static constexpr
bool traps = __glibcxx_integral_traps;
780 static constexpr
int radix = 2;
781 static constexpr
int digits
784 =
static_cast<int>(
digits * numbers::ln2 / numbers::ln10);
805 {
return _Sp(
static_cast<_Sp::__rep
>(-1), 1); }
837 struct numeric_limits<ranges::__detail::__max_diff_type>
839 using _Dp = ranges::__detail::__max_diff_type;
840 using _Sp = ranges::__detail::__max_size_type;
844 static constexpr
bool is_exact =
true;
847 static constexpr
bool traps = __glibcxx_integral_traps;
848 static constexpr
int radix = 2;
851 =
static_cast<int>(
digits * numbers::ln2 / numbers::ln10);
868 {
return _Dp(_Sp(0, 1)); }
872 {
return _Dp(_Sp(
static_cast<_Sp::__rep
>(-1), 0)); }
905 __bit_width(ranges::__detail::__max_size_type __x) noexcept
910 return std::__bit_width(__x._M_val);
913 _GLIBCXX_END_NAMESPACE_VERSION
916 #endif // C++20 && library concepts
917 #endif // _GLIBCXX_MAX_SIZE_TYPE_H