30 #ifndef _GLIBCXX_MAX_SIZE_TYPE_H
31 #define _GLIBCXX_MAX_SIZE_TYPE_H 1
33 #pragma GCC system_header
35 #if __cplusplus > 201703L && __cpp_lib_concepts
48 namespace std _GLIBCXX_VISIBILITY(default)
50 _GLIBCXX_BEGIN_NAMESPACE_VERSION
52 template<
typename _Tp>
53 struct numeric_limits;
62 __max_size_type() =
default;
64 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
66 __max_size_type(_Tp __i) noexcept
67 : _M_val(__i), _M_msb(__i < 0)
71 __max_size_type(
const __max_diff_type& __d) noexcept;
73 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
74 constexpr
explicit operator _Tp() const noexcept
78 operator bool() const noexcept
79 {
return _M_val != 0 || _M_msb != 0; }
81 constexpr __max_size_type
85 constexpr __max_size_type
86 operator~() const noexcept
87 {
return __max_size_type{~_M_val, !_M_msb}; }
89 constexpr __max_size_type
91 {
return operator~() + 1; }
93 constexpr __max_size_type&
94 operator+=(
const __max_size_type& __r) noexcept
96 const auto __sum = _M_val + __r._M_val;
97 const bool __overflow = (__sum < _M_val);
98 _M_msb = _M_msb ^ __r._M_msb ^ __overflow;
103 constexpr __max_size_type&
104 operator-=(
const __max_size_type& __r) noexcept
105 {
return *
this += -__r; }
107 constexpr __max_size_type&
108 operator*=(__max_size_type __r) noexcept
110 constexpr __max_size_type __threshold
111 = __rep(1) << (_S_rep_bits / 2 - 1);
112 if (_M_val < __threshold && __r < __threshold)
115 _M_val = _M_val * __r._M_val;
121 const bool __lsb = _M_val & 1;
122 const bool __rlsb = __r._M_val & 1;
125 _M_val = (2 * _M_val * __r._M_val
126 + _M_val * __rlsb + __r._M_val * __lsb);
128 *
this += __rlsb * __lsb;
134 constexpr __max_size_type&
135 operator/=(
const __max_size_type& __r) noexcept
137 __glibcxx_assert(__r != 0);
139 if (!_M_msb && !__r._M_msb) [[likely]]
140 _M_val /= __r._M_val;
141 else if (_M_msb && __r._M_msb)
143 _M_val = (_M_val >= __r._M_val);
146 else if (!_M_msb && __r._M_msb)
148 else if (_M_msb && !__r._M_msb)
154 const auto __orig = *
this;
156 _M_val /= __r._M_val;
158 if (__orig - *
this * __r >= __r)
164 constexpr __max_size_type&
165 operator%=(
const __max_size_type& __r) noexcept
167 if (!_M_msb && !__r._M_msb) [[likely]]
168 _M_val %= __r._M_val;
170 *
this -= (*
this / __r) * __r;
174 constexpr __max_size_type&
175 operator<<=(
const __max_size_type& __r) noexcept
177 __glibcxx_assert(__r <= _S_rep_bits);
180 _M_msb = (_M_val >> (_S_rep_bits - __r._M_val)) & 1;
182 if (__r._M_val == _S_rep_bits) [[unlikely]]
185 _M_val <<= __r._M_val;
190 constexpr __max_size_type&
191 operator>>=(
const __max_size_type& __r) noexcept
193 __glibcxx_assert(__r <= _S_rep_bits);
196 if (__r._M_val == _S_rep_bits) [[unlikely]]
199 _M_val >>= __r._M_val;
201 if (_M_msb) [[unlikely]]
203 _M_val |= __rep(1) << (_S_rep_bits - __r._M_val);
210 constexpr __max_size_type&
211 operator&=(
const __max_size_type& __r) noexcept
213 _M_val &= __r._M_val;
214 _M_msb &= __r._M_msb;
218 constexpr __max_size_type&
219 operator|=(
const __max_size_type& __r) noexcept
221 _M_val |= __r._M_val;
222 _M_msb |= __r._M_msb;
226 constexpr __max_size_type&
227 operator^=(
const __max_size_type& __r) noexcept
229 _M_val ^= __r._M_val;
230 _M_msb ^= __r._M_msb;
234 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
235 friend constexpr _Tp&
236 operator+=(_Tp& __a,
const __max_size_type& __b) noexcept
237 {
return (__a =
static_cast<_Tp
>(__a + __b)); }
239 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
240 friend constexpr _Tp&
241 operator-=(_Tp& __a,
const __max_size_type& __b) noexcept
242 {
return (__a =
static_cast<_Tp
>(__a - __b)); }
244 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
245 friend constexpr _Tp&
246 operator*=(_Tp& __a,
const __max_size_type& __b) noexcept
247 {
return (__a =
static_cast<_Tp
>(__a * __b)); }
249 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
250 friend constexpr _Tp&
251 operator/=(_Tp& __a,
const __max_size_type& __b) noexcept
252 {
return (__a =
static_cast<_Tp
>(__a / __b)); }
254 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
255 friend constexpr _Tp&
256 operator%=(_Tp& __a,
const __max_size_type& __b) noexcept
257 {
return (__a =
static_cast<_Tp
>(__a % __b)); }
259 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
260 friend constexpr _Tp&
261 operator&=(_Tp& __a,
const __max_size_type& __b) noexcept
262 {
return (__a =
static_cast<_Tp
>(__a & __b)); }
264 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
265 friend constexpr _Tp&
266 operator|=(_Tp& __a,
const __max_size_type& __b) noexcept
267 {
return (__a =
static_cast<_Tp
>(__a | __b)); }
269 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
270 friend constexpr _Tp&
271 operator^=(_Tp& __a,
const __max_size_type& __b) noexcept
272 {
return (__a =
static_cast<_Tp
>(__a ^ __b)); }
274 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
275 friend constexpr _Tp&
276 operator<<=(_Tp& __a,
const __max_size_type& __b) noexcept
277 {
return (__a =
static_cast<_Tp
>(__a << __b)); }
279 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
280 friend constexpr _Tp&
281 operator>>=(_Tp& __a,
const __max_size_type& __b) noexcept
282 {
return (__a =
static_cast<_Tp
>(__a >> __b)); }
284 friend constexpr __max_size_type
285 operator+(__max_size_type __l,
const __max_size_type& __r) noexcept
291 friend constexpr __max_size_type
292 operator-(__max_size_type __l,
const __max_size_type& __r) noexcept
298 friend constexpr __max_size_type
299 operator*(__max_size_type __l,
const __max_size_type& __r) noexcept
305 friend constexpr __max_size_type
306 operator/(__max_size_type __l,
const __max_size_type& __r) noexcept
312 friend constexpr __max_size_type
313 operator%(__max_size_type __l,
const __max_size_type& __r) noexcept
319 friend constexpr __max_size_type
320 operator<<(__max_size_type __l,
const __max_size_type& __r) noexcept
326 friend constexpr __max_size_type
327 operator>>(__max_size_type __l,
const __max_size_type& __r) noexcept
333 friend constexpr __max_size_type
334 operator&(__max_size_type __l,
const __max_size_type& __r) noexcept
340 friend constexpr __max_size_type
341 operator|(__max_size_type __l,
const __max_size_type& __r) noexcept
347 friend constexpr __max_size_type
348 operator^(__max_size_type __l,
const __max_size_type& __r) noexcept
354 friend constexpr
bool
355 operator==(
const __max_size_type& __l,
const __max_size_type& __r) noexcept
356 {
return __l._M_val == __r._M_val && __l._M_msb == __r._M_msb; }
358 friend constexpr
bool
359 operator!=(
const __max_size_type& __l,
const __max_size_type& __r) noexcept
360 {
return !(__l == __r); }
362 friend constexpr
bool
363 operator<(
const __max_size_type& __l,
const __max_size_type& __r) noexcept
365 if (__l._M_msb == __r._M_msb)
366 return __l._M_val < __r._M_val;
371 friend constexpr
bool
372 operator>(
const __max_size_type& __l,
const __max_size_type& __r) noexcept
373 {
return __r < __l; }
375 friend constexpr
bool
376 operator<=(
const __max_size_type& __l,
const __max_size_type& __r) noexcept
377 {
return !(__l > __r); }
379 friend constexpr
bool
380 operator>=(
const __max_size_type& __l,
const __max_size_type& __r) noexcept
381 {
return __r <= __l; }
383 #if __SIZEOF_INT128__
384 using __rep =
unsigned __int128;
386 using __rep =
unsigned long long;
388 static constexpr
size_t _S_rep_bits =
sizeof(__rep) * __CHAR_BIT__;
391 unsigned _M_msb:1 = 0;
394 __max_size_type(__rep __val,
int __msb) noexcept
395 : _M_val(__val), _M_msb(__msb)
398 friend __max_diff_type;
403 class __max_diff_type
406 __max_diff_type() =
default;
408 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
410 __max_diff_type(_Tp __i) noexcept
415 __max_diff_type(
const __max_size_type& __d) noexcept
419 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
420 constexpr
explicit operator _Tp() const noexcept
421 {
return static_cast<_Tp
>(_M_rep); }
424 operator bool() const noexcept
425 {
return _M_rep != 0; }
427 constexpr __max_diff_type
431 constexpr __max_diff_type
433 {
return __max_diff_type(-_M_rep); }
435 constexpr __max_diff_type
436 operator~() const noexcept
437 {
return __max_diff_type(~_M_rep); }
439 constexpr __max_diff_type&
440 operator+=(
const __max_diff_type& __r) noexcept
442 _M_rep += __r._M_rep;
446 constexpr __max_diff_type&
447 operator-=(
const __max_diff_type& __r) noexcept
449 _M_rep -= __r._M_rep;
453 constexpr __max_diff_type&
454 operator*=(
const __max_diff_type& __r) noexcept
456 _M_rep *= __r._M_rep;
460 constexpr __max_diff_type&
461 operator/=(
const __max_diff_type& __r) noexcept
463 __glibcxx_assert (__r != 0);
464 const bool __neg = *
this < 0;
465 const bool __rneg = __r < 0;
466 if (!__neg && !__rneg)
467 _M_rep = _M_rep / __r._M_rep;
468 else if (__neg && __rneg)
469 _M_rep = -_M_rep / -__r._M_rep;
470 else if (__neg && !__rneg)
471 _M_rep = -(-_M_rep / __r._M_rep);
473 _M_rep = -(_M_rep / -__r._M_rep);
477 constexpr __max_diff_type&
478 operator%=(
const __max_diff_type& __r) noexcept
480 __glibcxx_assert (__r != 0);
481 if (*
this >= 0 && __r > 0)
482 _M_rep %= __r._M_rep;
484 *
this -= (*
this / __r) * __r;
488 constexpr __max_diff_type&
489 operator<<=(
const __max_diff_type& __r) noexcept
491 _M_rep.operator<<=(__r._M_rep);
495 constexpr __max_diff_type&
496 operator>>=(
const __max_diff_type& __r) noexcept
499 const auto __msb = _M_rep._M_msb;
500 _M_rep >>= __r._M_rep;
501 _M_rep._M_msb |= __msb;
505 constexpr __max_diff_type&
506 operator&=(
const __max_diff_type& __r) noexcept
508 _M_rep &= __r._M_rep;
512 constexpr __max_diff_type&
513 operator|=(
const __max_diff_type& __r) noexcept
515 _M_rep |= __r._M_rep;
519 constexpr __max_diff_type&
520 operator^=(
const __max_diff_type& __r) noexcept
522 _M_rep ^= __r._M_rep;
526 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
527 friend constexpr _Tp&
528 operator+=(_Tp& __a,
const __max_diff_type& __b) noexcept
529 {
return (__a =
static_cast<_Tp
>(__a + __b)); }
531 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
532 friend constexpr _Tp&
533 operator-=(_Tp& __a,
const __max_diff_type& __b) noexcept
534 {
return (__a =
static_cast<_Tp
>(__a - __b)); }
536 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
537 friend constexpr _Tp&
538 operator*=(_Tp& __a,
const __max_diff_type& __b) noexcept
539 {
return (__a =
static_cast<_Tp
>(__a * __b)); }
541 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
542 friend constexpr _Tp&
543 operator/=(_Tp& __a,
const __max_diff_type& __b) noexcept
544 {
return (__a =
static_cast<_Tp
>(__a / __b)); }
546 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
547 friend constexpr _Tp&
548 operator%=(_Tp& __a,
const __max_diff_type& __b) noexcept
549 {
return (__a =
static_cast<_Tp
>(__a % __b)); }
551 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
552 friend constexpr _Tp&
553 operator&=(_Tp& __a,
const __max_diff_type& __b) noexcept
554 {
return (__a =
static_cast<_Tp
>(__a & __b)); }
556 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
557 friend constexpr _Tp&
558 operator|=(_Tp& __a,
const __max_diff_type& __b) noexcept
559 {
return (__a =
static_cast<_Tp
>(__a | __b)); }
561 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
562 friend constexpr _Tp&
563 operator^=(_Tp& __a,
const __max_diff_type& __b) noexcept
564 {
return (__a =
static_cast<_Tp
>(__a ^ __b)); }
566 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
567 friend constexpr _Tp&
568 operator<<=(_Tp& __a,
const __max_diff_type& __b) noexcept
569 {
return (__a =
static_cast<_Tp
>(__a << __b)); }
571 template<
typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
572 friend constexpr _Tp&
573 operator>>=(_Tp& __a,
const __max_diff_type& __b) noexcept
574 {
return (__a =
static_cast<_Tp
>(__a >> __b)); }
576 friend constexpr __max_diff_type
577 operator+(__max_diff_type __l,
const __max_diff_type& __r) noexcept
583 friend constexpr __max_diff_type
584 operator-(__max_diff_type __l,
const __max_diff_type& __r) noexcept
590 friend constexpr __max_diff_type
591 operator*(__max_diff_type __l,
const __max_diff_type& __r) noexcept
597 friend constexpr __max_diff_type
598 operator/(__max_diff_type __l,
const __max_diff_type& __r) noexcept
604 friend constexpr __max_diff_type
605 operator%(__max_diff_type __l,
const __max_diff_type& __r) noexcept
611 friend constexpr __max_diff_type
612 operator<<(__max_diff_type __l,
const __max_diff_type& __r) noexcept
618 friend constexpr __max_diff_type
619 operator>>(__max_diff_type __l,
const __max_diff_type& __r) noexcept
625 friend constexpr __max_diff_type
626 operator&(__max_diff_type __l,
const __max_diff_type& __r) noexcept
632 friend constexpr __max_diff_type
633 operator|(__max_diff_type __l,
const __max_diff_type& __r) noexcept
639 friend constexpr __max_diff_type
640 operator^(__max_diff_type __l,
const __max_diff_type& __r) noexcept
646 friend constexpr
bool
647 operator==(
const __max_diff_type& __l,
const __max_diff_type& __r) noexcept
648 {
return __l._M_rep == __r._M_rep; }
650 friend constexpr
bool
651 operator!=(
const __max_diff_type& __l,
const __max_diff_type& __r) noexcept
652 {
return !(__l == __r); }
655 operator<(
const __max_diff_type& __r)
const noexcept
657 const auto __lsign = _M_rep._M_msb;
658 const auto __rsign = __r._M_rep._M_msb;
659 if (__lsign ^ __rsign)
662 return _M_rep < __r._M_rep;
665 friend constexpr
bool
666 operator>(
const __max_diff_type& __l,
const __max_diff_type& __r) noexcept
667 {
return __r < __l; }
669 friend constexpr
bool
670 operator<=(
const __max_diff_type& __l,
const __max_diff_type& __r) noexcept
671 {
return !(__r < __l); }
673 friend constexpr
bool
674 operator>=(
const __max_diff_type& __l,
const __max_diff_type& __r) noexcept
675 {
return !(__l < __r); }
678 __max_size_type _M_rep = 0;
680 friend class __max_size_type;
684 __max_size_type::__max_size_type(
const __max_diff_type& __d) noexcept
685 : __max_size_type(__d._M_rep)
692 struct numeric_limits<ranges::__detail::__max_size_type>
694 using _Sp = ranges::__detail::__max_size_type;
698 static constexpr
bool is_exact =
true;
699 #if __SIZEOF_INT128__
700 static_assert(same_as<_Sp::__rep, unsigned __int128>);
701 static constexpr
int digits = 129;
703 static_assert(same_as<_Sp::__rep, unsigned long long>);
704 static constexpr
int digits
708 =
static_cast<int>(
digits * numbers::ln2 / numbers::ln10);
716 {
return _Sp(
static_cast<_Sp::__rep
>(-1), 1); }
724 struct numeric_limits<ranges::__detail::__max_diff_type>
726 using _Dp = ranges::__detail::__max_diff_type;
727 using _Sp = ranges::__detail::__max_size_type;
731 static constexpr
bool is_exact =
true;
734 =
static_cast<int>(
digits * numbers::ln2 / numbers::ln10);
738 {
return _Dp(_Sp(0, 1)); }
742 {
return _Dp(_Sp(
static_cast<_Sp::__rep
>(-1), 0)); }
749 _GLIBCXX_END_NAMESPACE_VERSION
752 #endif // C++20 && library concepts
753 #endif // _GLIBCXX_MAX_SIZE_TYPE_H