libstdc++
max_size_type.h
Go to the documentation of this file.
1// <max_size_type.h> -*- C++ -*-
2
3// Copyright (C) 2019-2025 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/max_size_type.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{iterator}
28 */
29
30#ifndef _GLIBCXX_MAX_SIZE_TYPE_H
31#define _GLIBCXX_MAX_SIZE_TYPE_H 1
32
33#ifdef _GLIBCXX_SYSHDR
34#pragma GCC system_header
35#endif
36
37#if __cplusplus > 201703L && __cpp_lib_concepts
38#include <ext/numeric_traits.h>
39#include <bit> // __bit_width
40#include <numbers>
41#include <limits> // __glibcxx_integral_traps
42
43// This header implements unsigned and signed integer-class types (as per
44// [iterator.concept.winc]) that are one bit wider than the widest supported
45// integer type.
46//
47// The set of integer types we consider includes __int128 and unsigned __int128
48// (when they exist), even though they are really integer types only in GNU
49// mode. This is to obtain a consistent ABI for these integer-class types
50// across strict mode and GNU mode.
51
52namespace std _GLIBCXX_VISIBILITY(default)
53{
54_GLIBCXX_BEGIN_NAMESPACE_VERSION
55
56template<typename _Tp>
57 struct numeric_limits;
58
59namespace ranges
60{
61 namespace __detail
62 {
63 class __max_size_type
64 {
65 public:
66 __max_size_type() = default;
67
68 template<typename _Tp> requires integral<_Tp>
69 constexpr
70 __max_size_type(_Tp __i) noexcept
71 : _M_val(__i), _M_msb(__i < 0)
72 { }
73
74 constexpr explicit
75 __max_size_type(const __max_diff_type& __d) noexcept;
76
77 template<typename _Tp> requires integral<_Tp>
78 constexpr explicit
79 operator _Tp() const noexcept
80 { return _M_val; }
81
82 constexpr explicit
83 operator bool() const noexcept
84 { return _M_val != 0 || _M_msb != 0; }
85
86 constexpr __max_size_type
87 operator+() const noexcept
88 { return *this; }
89
90 constexpr __max_size_type
91 operator~() const noexcept
92 { return __max_size_type{~_M_val, !_M_msb}; }
93
94 constexpr __max_size_type
95 operator-() const noexcept
96 { return operator~() + 1; }
97
98 constexpr __max_size_type&
99 operator++() noexcept
100 { return *this += 1; }
101
102 constexpr __max_size_type
103 operator++(int) noexcept
104 {
105 auto __tmp = *this;
106 ++*this;
107 return __tmp;
108 }
109
110 constexpr __max_size_type&
111 operator--() noexcept
112 { return *this -= 1; }
113
114 constexpr __max_size_type
115 operator--(int) noexcept
116 {
117 auto __tmp = *this;
118 --*this;
119 return __tmp;
120 }
121
122 constexpr __max_size_type&
123 operator+=(const __max_size_type& __r) noexcept
124 {
125 const auto __sum = _M_val + __r._M_val;
126 const bool __overflow = (__sum < _M_val);
127 _M_msb = _M_msb ^ __r._M_msb ^ __overflow;
128 _M_val = __sum;
129 return *this;
130 }
131
132 constexpr __max_size_type&
133 operator-=(const __max_size_type& __r) noexcept
134 { return *this += -__r; }
135
136 constexpr __max_size_type&
137 operator*=(__max_size_type __r) noexcept
138 {
139 constexpr __max_size_type __threshold
140 = __rep(1) << (_S_rep_bits / 2 - 1);
141 if (_M_val < __threshold && __r < __threshold)
142 // When both operands are below this threshold then the
143 // multiplication can be safely computed in the base precision.
144 _M_val = _M_val * __r._M_val;
145 else
146 {
147 // Otherwise, perform the multiplication in four steps, by
148 // decomposing the LHS and the RHS into 2*x+a and 2*y+b,
149 // respectively, and computing 4*x*y + 2*x*b + 2*y*a + a*b.
150 const bool __lsb = _M_val & 1;
151 const bool __rlsb = __r._M_val & 1;
152 *this >>= 1;
153 __r >>= 1;
154 _M_val = (2 * _M_val * __r._M_val
155 + _M_val * __rlsb + __r._M_val * __lsb);
156 *this <<= 1;
157 *this += __rlsb * __lsb;
158 }
159
160 return *this;
161 }
162
163 constexpr __max_size_type&
164 operator/=(const __max_size_type& __r) noexcept
165 {
166 __glibcxx_assert(__r != 0);
167
168 if (!_M_msb && !__r._M_msb) [[likely]]
169 _M_val /= __r._M_val;
170 else if (_M_msb && __r._M_msb)
171 {
172 _M_val = (_M_val >= __r._M_val);
173 _M_msb = 0;
174 }
175 else if (!_M_msb && __r._M_msb)
176 _M_val = 0;
177 else if (_M_msb && !__r._M_msb)
178 {
179 // The non-trivial case: the dividend has its MSB set and the
180 // divisor doesn't. In this case we compute ((LHS/2)/RHS)*2
181 // in the base precision. This quantity is either the true
182 // quotient or one less than the true quotient.
183 const auto __orig = *this;
184 *this >>= 1;
185 _M_val /= __r._M_val;
186 *this <<= 1;
187 if (__orig - *this * __r >= __r)
188 ++_M_val;
189 }
190 return *this;
191 }
192
193 constexpr __max_size_type&
194 operator%=(const __max_size_type& __r) noexcept
195 {
196 if (!_M_msb && !__r._M_msb) [[likely]]
197 _M_val %= __r._M_val;
198 else
199 *this -= (*this / __r) * __r;
200 return *this;
201 }
202
203 constexpr __max_size_type&
204 operator<<=(const __max_size_type& __r) noexcept
205 {
206 __glibcxx_assert(__r <= _S_rep_bits);
207 if (__r != 0)
208 {
209 _M_msb = (_M_val >> (_S_rep_bits - __r._M_val)) & 1;
210
211 if (__r._M_val == _S_rep_bits) [[unlikely]]
212 _M_val = 0;
213 else
214 _M_val <<= __r._M_val;
215 }
216 return *this;
217 }
218
219 constexpr __max_size_type&
220 operator>>=(const __max_size_type& __r) noexcept
221 {
222 __glibcxx_assert(__r <= _S_rep_bits);
223 if (__r != 0)
224 {
225 if (__r._M_val == _S_rep_bits) [[unlikely]]
226 _M_val = 0;
227 else
228 _M_val >>= __r._M_val;
229
230 if (_M_msb) [[unlikely]]
231 {
232 _M_val |= __rep(1) << (_S_rep_bits - __r._M_val);
233 _M_msb = 0;
234 }
235 }
236 return *this;
237 }
238
239 constexpr __max_size_type&
240 operator&=(const __max_size_type& __r) noexcept
241 {
242 _M_val &= __r._M_val;
243 _M_msb &= __r._M_msb;
244 return *this;
245 }
246
247 constexpr __max_size_type&
248 operator|=(const __max_size_type& __r) noexcept
249 {
250 _M_val |= __r._M_val;
251 _M_msb |= __r._M_msb;
252 return *this;
253 }
254
255 constexpr __max_size_type&
256 operator^=(const __max_size_type& __r) noexcept
257 {
258 _M_val ^= __r._M_val;
259 _M_msb ^= __r._M_msb;
260 return *this;
261 }
262
263 template<typename _Tp> requires integral<_Tp>
264 friend constexpr _Tp&
265 operator+=(_Tp& __a, const __max_size_type& __b) noexcept
266 { return (__a = static_cast<_Tp>(__a + __b)); }
267
268 template<typename _Tp> requires integral<_Tp>
269 friend constexpr _Tp&
270 operator-=(_Tp& __a, const __max_size_type& __b) noexcept
271 { return (__a = static_cast<_Tp>(__a - __b)); }
272
273 template<typename _Tp> requires integral<_Tp>
274 friend constexpr _Tp&
275 operator*=(_Tp& __a, const __max_size_type& __b) noexcept
276 { return (__a = static_cast<_Tp>(__a * __b)); }
277
278 template<typename _Tp> requires integral<_Tp>
279 friend constexpr _Tp&
280 operator/=(_Tp& __a, const __max_size_type& __b) noexcept
281 { return (__a = static_cast<_Tp>(__a / __b)); }
282
283 template<typename _Tp> requires integral<_Tp>
284 friend constexpr _Tp&
285 operator%=(_Tp& __a, const __max_size_type& __b) noexcept
286 { return (__a = static_cast<_Tp>(__a % __b)); }
287
288 template<typename _Tp> requires integral<_Tp>
289 friend constexpr _Tp&
290 operator&=(_Tp& __a, const __max_size_type& __b) noexcept
291 { return (__a = static_cast<_Tp>(__a & __b)); }
292
293 template<typename _Tp> requires integral<_Tp>
294 friend constexpr _Tp&
295 operator|=(_Tp& __a, const __max_size_type& __b) noexcept
296 { return (__a = static_cast<_Tp>(__a | __b)); }
297
298 template<typename _Tp> requires integral<_Tp>
299 friend constexpr _Tp&
300 operator^=(_Tp& __a, const __max_size_type& __b) noexcept
301 { return (__a = static_cast<_Tp>(__a ^ __b)); }
302
303 template<typename _Tp> requires integral<_Tp>
304 friend constexpr _Tp&
305 operator<<=(_Tp& __a, const __max_size_type& __b) noexcept
306 { return (__a = static_cast<_Tp>(__a << __b)); }
307
308 template<typename _Tp> requires integral<_Tp>
309 friend constexpr _Tp&
310 operator>>=(_Tp& __a, const __max_size_type& __b) noexcept
311 { return (__a = static_cast<_Tp>(__a >> __b)); }
312
313 friend constexpr __max_size_type
314 operator+(__max_size_type __l, const __max_size_type& __r) noexcept
315 {
316 __l += __r;
317 return __l;
318 }
319
320 friend constexpr __max_size_type
321 operator-(__max_size_type __l, const __max_size_type& __r) noexcept
322 {
323 __l -= __r;
324 return __l;
325 }
326
327 friend constexpr __max_size_type
328 operator*(__max_size_type __l, const __max_size_type& __r) noexcept
329 {
330 __l *= __r;
331 return __l;
332 }
333
334 friend constexpr __max_size_type
335 operator/(__max_size_type __l, const __max_size_type& __r) noexcept
336 {
337 __l /= __r;
338 return __l;
339 }
340
341 friend constexpr __max_size_type
342 operator%(__max_size_type __l, const __max_size_type& __r) noexcept
343 {
344 __l %= __r;
345 return __l;
346 }
347
348 friend constexpr __max_size_type
349 operator<<(__max_size_type __l, const __max_size_type& __r) noexcept
350 {
351 __l <<= __r;
352 return __l;
353 }
354
355 friend constexpr __max_size_type
356 operator>>(__max_size_type __l, const __max_size_type& __r) noexcept
357 {
358 __l >>= __r;
359 return __l;
360 }
361
362 friend constexpr __max_size_type
363 operator&(__max_size_type __l, const __max_size_type& __r) noexcept
364 {
365 __l &= __r;
366 return __l;
367 }
368
369 friend constexpr __max_size_type
370 operator|(__max_size_type __l, const __max_size_type& __r) noexcept
371 {
372 __l |= __r;
373 return __l;
374 }
375
376 friend constexpr __max_size_type
377 operator^(__max_size_type __l, const __max_size_type& __r) noexcept
378 {
379 __l ^= __r;
380 return __l;
381 }
382
383 friend constexpr bool
384 operator==(const __max_size_type& __l, const __max_size_type& __r) noexcept
385 { return __l._M_val == __r._M_val && __l._M_msb == __r._M_msb; }
386
387#if __cpp_lib_three_way_comparison
388 friend constexpr strong_ordering
389 operator<=>(const __max_size_type& __l, const __max_size_type& __r) noexcept
390 {
391 if (__l._M_msb ^ __r._M_msb)
392 return __l._M_msb ? strong_ordering::greater : strong_ordering::less;
393 else
394 return __l._M_val <=> __r._M_val;
395 }
396#else
397 friend constexpr bool
398 operator!=(const __max_size_type& __l, const __max_size_type& __r) noexcept
399 { return !(__l == __r); }
400
401 friend constexpr bool
402 operator<(const __max_size_type& __l, const __max_size_type& __r) noexcept
403 {
404 if (__l._M_msb == __r._M_msb)
405 return __l._M_val < __r._M_val;
406 else
407 return __r._M_msb;
408 }
409
410 friend constexpr bool
411 operator>(const __max_size_type& __l, const __max_size_type& __r) noexcept
412 { return __r < __l; }
413
414 friend constexpr bool
415 operator<=(const __max_size_type& __l, const __max_size_type& __r) noexcept
416 { return !(__l > __r); }
417
418 friend constexpr bool
419 operator>=(const __max_size_type& __l, const __max_size_type& __r) noexcept
420 { return __r <= __l; }
421#endif
422
423#if __SIZEOF_INT128__
424 __extension__
425 using __rep = unsigned __int128;
426#else
427 using __rep = unsigned long long;
428#endif
429 static constexpr size_t _S_rep_bits = sizeof(__rep) * __CHAR_BIT__;
430
431 __rep _M_val = 0;
432 unsigned _M_msb:1 = 0;
433
434 private:
435 constexpr explicit
436 __max_size_type(__rep __val, int __msb) noexcept
437 : _M_val(__val), _M_msb(__msb)
438 { }
439
440 friend __max_diff_type;
441 friend std::numeric_limits<__max_size_type>;
442 friend std::numeric_limits<__max_diff_type>;
443 };
444
445 class __max_diff_type
446 {
447 public:
448 __max_diff_type() = default;
449
450 template<typename _Tp> requires integral<_Tp>
451 constexpr
452 __max_diff_type(_Tp __i) noexcept
453 : _M_rep(__i)
454 { }
455
456 constexpr explicit
457 __max_diff_type(const __max_size_type& __d) noexcept
458 : _M_rep(__d)
459 { }
460
461 template<typename _Tp> requires integral<_Tp>
462 constexpr explicit
463 operator _Tp() const noexcept
464 { return static_cast<_Tp>(_M_rep); }
465
466 constexpr explicit
467 operator bool() const noexcept
468 { return _M_rep != 0; }
469
470 constexpr __max_diff_type
471 operator+() const noexcept
472 { return *this; }
473
474 constexpr __max_diff_type
475 operator-() const noexcept
476 { return __max_diff_type(-_M_rep); }
477
478 constexpr __max_diff_type
479 operator~() const noexcept
480 { return __max_diff_type(~_M_rep); }
481
482 constexpr __max_diff_type&
483 operator++() noexcept
484 { return *this += 1; }
485
486 constexpr __max_diff_type
487 operator++(int) noexcept
488 {
489 auto __tmp = *this;
490 ++*this;
491 return __tmp;
492 }
493
494 constexpr __max_diff_type&
495 operator--() noexcept
496 { return *this -= 1; }
497
498 constexpr __max_diff_type
499 operator--(int) noexcept
500 {
501 auto __tmp = *this;
502 --*this;
503 return __tmp;
504 }
505
506 constexpr __max_diff_type&
507 operator+=(const __max_diff_type& __r) noexcept
508 {
509 _M_rep += __r._M_rep;
510 return *this;
511 }
512
513 constexpr __max_diff_type&
514 operator-=(const __max_diff_type& __r) noexcept
515 {
516 _M_rep -= __r._M_rep;
517 return *this;
518 }
519
520 constexpr __max_diff_type&
521 operator*=(const __max_diff_type& __r) noexcept
522 {
523 _M_rep *= __r._M_rep;
524 return *this;
525 }
526
527 constexpr __max_diff_type&
528 operator/=(const __max_diff_type& __r) noexcept
529 {
530 __glibcxx_assert (__r != 0);
531 const bool __neg = *this < 0;
532 const bool __rneg = __r < 0;
533 if (!__neg && !__rneg)
534 _M_rep = _M_rep / __r._M_rep;
535 else if (__neg && __rneg)
536 _M_rep = -_M_rep / -__r._M_rep;
537 else if (__neg && !__rneg)
538 _M_rep = -(-_M_rep / __r._M_rep);
539 else
540 _M_rep = -(_M_rep / -__r._M_rep);
541 return *this ;
542 }
543
544 constexpr __max_diff_type&
545 operator%=(const __max_diff_type& __r) noexcept
546 {
547 __glibcxx_assert (__r != 0);
548 if (*this >= 0 && __r > 0)
549 _M_rep %= __r._M_rep;
550 else
551 *this -= (*this / __r) * __r;
552 return *this;
553 }
554
555 constexpr __max_diff_type&
556 operator<<=(const __max_diff_type& __r) noexcept
557 {
558 _M_rep.operator<<=(__r._M_rep);
559 return *this;
560 }
561
562 constexpr __max_diff_type&
563 operator>>=(const __max_diff_type& __r) noexcept
564 {
565 // Arithmetic right shift.
566 const auto __msb = _M_rep._M_msb;
567 _M_rep >>= __r._M_rep;
568 if (__msb)
569 _M_rep |= ~(__max_size_type(-1) >> __r._M_rep);
570 return *this;
571 }
572
573 constexpr __max_diff_type&
574 operator&=(const __max_diff_type& __r) noexcept
575 {
576 _M_rep &= __r._M_rep;
577 return *this;
578 }
579
580 constexpr __max_diff_type&
581 operator|=(const __max_diff_type& __r) noexcept
582 {
583 _M_rep |= __r._M_rep;
584 return *this;
585 }
586
587 constexpr __max_diff_type&
588 operator^=(const __max_diff_type& __r) noexcept
589 {
590 _M_rep ^= __r._M_rep;
591 return *this;
592 }
593
594 template<typename _Tp> requires integral<_Tp>
595 friend constexpr _Tp&
596 operator+=(_Tp& __a, const __max_diff_type& __b) noexcept
597 { return (__a = static_cast<_Tp>(__a + __b)); }
598
599 template<typename _Tp> requires integral<_Tp>
600 friend constexpr _Tp&
601 operator-=(_Tp& __a, const __max_diff_type& __b) noexcept
602 { return (__a = static_cast<_Tp>(__a - __b)); }
603
604 template<typename _Tp> requires integral<_Tp>
605 friend constexpr _Tp&
606 operator*=(_Tp& __a, const __max_diff_type& __b) noexcept
607 { return (__a = static_cast<_Tp>(__a * __b)); }
608
609 template<typename _Tp> requires integral<_Tp>
610 friend constexpr _Tp&
611 operator/=(_Tp& __a, const __max_diff_type& __b) noexcept
612 { return (__a = static_cast<_Tp>(__a / __b)); }
613
614 template<typename _Tp> requires integral<_Tp>
615 friend constexpr _Tp&
616 operator%=(_Tp& __a, const __max_diff_type& __b) noexcept
617 { return (__a = static_cast<_Tp>(__a % __b)); }
618
619 template<typename _Tp> requires integral<_Tp>
620 friend constexpr _Tp&
621 operator&=(_Tp& __a, const __max_diff_type& __b) noexcept
622 { return (__a = static_cast<_Tp>(__a & __b)); }
623
624 template<typename _Tp> requires integral<_Tp>
625 friend constexpr _Tp&
626 operator|=(_Tp& __a, const __max_diff_type& __b) noexcept
627 { return (__a = static_cast<_Tp>(__a | __b)); }
628
629 template<typename _Tp> requires integral<_Tp>
630 friend constexpr _Tp&
631 operator^=(_Tp& __a, const __max_diff_type& __b) noexcept
632 { return (__a = static_cast<_Tp>(__a ^ __b)); }
633
634 template<typename _Tp> requires integral<_Tp>
635 friend constexpr _Tp&
636 operator<<=(_Tp& __a, const __max_diff_type& __b) noexcept
637 { return (__a = static_cast<_Tp>(__a << __b)); }
638
639 template<typename _Tp> requires integral<_Tp>
640 friend constexpr _Tp&
641 operator>>=(_Tp& __a, const __max_diff_type& __b) noexcept
642 { return (__a = static_cast<_Tp>(__a >> __b)); }
643
644 friend constexpr __max_diff_type
645 operator+(__max_diff_type __l, const __max_diff_type& __r) noexcept
646 {
647 __l += __r;
648 return __l;
649 }
650
651 friend constexpr __max_diff_type
652 operator-(__max_diff_type __l, const __max_diff_type& __r) noexcept
653 {
654 __l -= __r;
655 return __l;
656 }
657
658 friend constexpr __max_diff_type
659 operator*(__max_diff_type __l, const __max_diff_type& __r) noexcept
660 {
661 __l *= __r;
662 return __l;
663 }
664
665 friend constexpr __max_diff_type
666 operator/(__max_diff_type __l, const __max_diff_type& __r) noexcept
667 {
668 __l /= __r;
669 return __l;
670 }
671
672 friend constexpr __max_diff_type
673 operator%(__max_diff_type __l, const __max_diff_type& __r) noexcept
674 {
675 __l %= __r;
676 return __l;
677 }
678
679 friend constexpr __max_diff_type
680 operator<<(__max_diff_type __l, const __max_diff_type& __r) noexcept
681 {
682 __l <<= __r;
683 return __l;
684 }
685
686 friend constexpr __max_diff_type
687 operator>>(__max_diff_type __l, const __max_diff_type& __r) noexcept
688 {
689 __l >>= __r;
690 return __l;
691 }
692
693 friend constexpr __max_diff_type
694 operator&(__max_diff_type __l, const __max_diff_type& __r) noexcept
695 {
696 __l &= __r;
697 return __l;
698 }
699
700 friend constexpr __max_diff_type
701 operator|(__max_diff_type __l, const __max_diff_type& __r) noexcept
702 {
703 __l |= __r;
704 return __l;
705 }
706
707 friend constexpr __max_diff_type
708 operator^(__max_diff_type __l, const __max_diff_type& __r) noexcept
709 {
710 __l ^= __r;
711 return __l;
712 }
713
714 friend constexpr bool
715 operator==(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
716 { return __l._M_rep == __r._M_rep; }
717
718#if __cpp_lib_three_way_comparison
719 constexpr strong_ordering
720 operator<=>(const __max_diff_type& __r) const noexcept
721 {
722 const auto __lsign = _M_rep._M_msb;
723 const auto __rsign = __r._M_rep._M_msb;
724 if (__lsign ^ __rsign)
725 return __lsign ? strong_ordering::less : strong_ordering::greater;
726 else
727 return _M_rep <=> __r._M_rep;
728 }
729#else
730 friend constexpr bool
731 operator!=(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
732 { return !(__l == __r); }
733
734 constexpr bool
735 operator<(const __max_diff_type& __r) const noexcept
736 {
737 const auto __lsign = _M_rep._M_msb;
738 const auto __rsign = __r._M_rep._M_msb;
739 if (__lsign ^ __rsign)
740 return __lsign;
741 else
742 return _M_rep < __r._M_rep;
743 }
744
745 friend constexpr bool
746 operator>(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
747 { return __r < __l; }
748
749 friend constexpr bool
750 operator<=(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
751 { return !(__r < __l); }
752
753 friend constexpr bool
754 operator>=(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
755 { return !(__l < __r); }
756#endif
757
758 __max_size_type _M_rep = 0;
759
760 friend class __max_size_type;
761 };
762
763 constexpr
764 __max_size_type::__max_size_type(const __max_diff_type& __d) noexcept
765 : __max_size_type(__d._M_rep)
766 { }
767
768 } // namespace __detail
769} // namespace ranges
770
771 template<>
772 struct numeric_limits<ranges::__detail::__max_size_type>
773 {
774 using _Sp = ranges::__detail::__max_size_type;
775 static constexpr bool is_specialized = true;
776 static constexpr bool is_signed = false;
777 static constexpr bool is_integer = true;
778 static constexpr bool is_exact = true;
779 static constexpr bool is_bounded = true;
780 static constexpr bool is_modulo = true;
781 static constexpr bool traps = __glibcxx_integral_traps;
782 static constexpr int radix = 2;
783 static constexpr int digits
784 = __gnu_cxx::__int_traits<_Sp::__rep>::__digits + 1;
785 static constexpr int digits10
786 = static_cast<int>(digits * numbers::ln2 / numbers::ln10);
787 static constexpr int max_digits10 = 0;
788 static constexpr int min_exponent = 0;
789 static constexpr int min_exponent10 = 0;
790 static constexpr int max_exponent = 0;
791 static constexpr int max_exponent10 = 0;
792 static constexpr bool is_iec559 = false;
793 static constexpr bool has_infinity = false;
794 static constexpr bool has_quiet_NaN = false;
795 static constexpr bool has_signaling_NaN = false;
796 static constexpr bool has_denorm_loss = false;
797 static constexpr bool tinyness_before = false;
800
801 static constexpr _Sp
802 min() noexcept
803 { return 0; }
804
805 static constexpr _Sp
806 max() noexcept
807 { return _Sp(static_cast<_Sp::__rep>(-1), 1); }
808
809 static constexpr _Sp
810 lowest() noexcept
811 { return min(); }
812
813 static constexpr _Sp
814 denorm_min() noexcept
815 { return 0; }
816
817 static constexpr _Sp
818 epsilon() noexcept
819 { return 0; }
820
821 static constexpr _Sp
822 round_error() noexcept
823 { return 0; }
824
825 static constexpr _Sp
826 infinity() noexcept
827 { return 0; }
828
829 static constexpr _Sp
830 quiet_NaN() noexcept
831 { return 0; }
832
833 static constexpr _Sp
834 signaling_NaN() noexcept
835 { return 0; }
836 };
837
838 template<>
839 struct numeric_limits<ranges::__detail::__max_diff_type>
840 {
841 using _Dp = ranges::__detail::__max_diff_type;
842 using _Sp = ranges::__detail::__max_size_type;
843 static constexpr bool is_specialized = true;
844 static constexpr bool is_signed = true;
845 static constexpr bool is_integer = true;
846 static constexpr bool is_exact = true;
847 static constexpr bool is_bounded = true;
848 static constexpr bool is_modulo = false;
849 static constexpr bool traps = __glibcxx_integral_traps;
850 static constexpr int radix = 2;
851 static constexpr int digits = numeric_limits<_Sp>::digits - 1;
852 static constexpr int digits10
853 = static_cast<int>(digits * numbers::ln2 / numbers::ln10);
854 static constexpr int max_digits10 = 0;
855 static constexpr int min_exponent = 0;
856 static constexpr int min_exponent10 = 0;
857 static constexpr int max_exponent = 0;
858 static constexpr int max_exponent10 = 0;
859 static constexpr bool is_iec559 = false;
860 static constexpr bool has_infinity = false;
861 static constexpr bool has_quiet_NaN = false;
862 static constexpr bool has_signaling_NaN = false;
863 static constexpr bool has_denorm_loss = false;
864 static constexpr bool tinyness_before = false;
867
868 static constexpr _Dp
869 min() noexcept
870 { return _Dp(_Sp(0, 1)); }
871
872 static constexpr _Dp
873 max() noexcept
874 { return _Dp(_Sp(static_cast<_Sp::__rep>(-1), 0)); }
875
876 static constexpr _Dp
877 lowest() noexcept
878 { return min(); }
879
880 static constexpr _Dp
881 denorm_min() noexcept
882 { return 0; }
883
884 static constexpr _Dp
885 epsilon() noexcept
886 { return 0; }
887
888 static constexpr _Dp
889 round_error() noexcept
890 { return 0; }
891
892 static constexpr _Dp
893 infinity() noexcept
894 { return 0; }
895
896 static constexpr _Dp
897 quiet_NaN() noexcept
898 { return 0; }
899
900 static constexpr _Dp
901 signaling_NaN() noexcept
902 { return 0; }
903 };
904
905 template<>
906 inline constexpr int
907 __bit_width(ranges::__detail::__max_size_type __x) noexcept
908 {
909 if (__x._M_msb)
911 else
912 return std::__bit_width(__x._M_val);
913 }
914
915_GLIBCXX_END_NAMESPACE_VERSION
916} // namespace
917
918#endif // C++20 && library concepts
919#endif // _GLIBCXX_MAX_SIZE_TYPE_H
constexpr bool operator<=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition chrono.h:859
constexpr bool operator>=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition chrono.h:873
constexpr duration< __common_rep_t< _Rep1, __disable_if_is_duration< _Rep2 > >, _Period > operator%(const duration< _Rep1, _Period > &__d, const _Rep2 &__s)
Definition chrono.h:783
constexpr bool operator<(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition chrono.h:826
constexpr bool operator>(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition chrono.h:866
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Definition complex:434
constexpr complex< _Tp > operator-(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x minus y.
Definition complex:404
constexpr complex< _Tp > operator+(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x plus y.
Definition complex:374
constexpr complex< _Tp > operator/(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x divided by y.
Definition complex:464
ISO C++ entities toplevel namespace is std.
float_round_style
Describes the rounding style for floating-point types.
Definition limits:175
@ round_toward_zero
To zero.
Definition limits:177
float_denorm_style
Describes the denormalization for floating-point types.
Definition limits:190
@ denorm_absent
The type does not allow denormalized values.
Definition limits:194
constexpr bitset< _Nb > operator^(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition bitset:1617
std::basic_istream< _CharT, _Traits > & operator>>(std::basic_istream< _CharT, _Traits > &__is, bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition bitset:1637
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition bitset:1733
constexpr bitset< _Nb > operator|(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition bitset:1607
constexpr bitset< _Nb > operator&(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition bitset:1597
static constexpr bool is_modulo
Definition limits:295
static constexpr bool has_quiet_NaN
Definition limits:266
static constexpr bool is_integer
Definition limits:233
static constexpr int max_digits10
Definition limits:226
static constexpr int min_exponent
Definition limits:246
static constexpr int digits
Definition limits:218
static constexpr bool is_bounded
Definition limits:286
static constexpr bool has_denorm_loss
Definition limits:277
static constexpr bool is_iec559
Definition limits:281
static constexpr bool is_exact
Definition limits:238
static constexpr bool traps
Definition limits:298
static constexpr bool has_signaling_NaN
Definition limits:270
static constexpr bool is_specialized
Definition limits:213
static constexpr int max_exponent
Definition limits:255
static constexpr bool is_signed
Definition limits:230
static constexpr int digits10
Definition limits:221
static constexpr int min_exponent10
Definition limits:250
static constexpr bool tinyness_before
Definition limits:301
static constexpr float_round_style round_style
Definition limits:306
static constexpr bool has_infinity
Definition limits:262
static constexpr int radix
Definition limits:242
static constexpr int max_exponent10
Definition limits:259
static constexpr float_denorm_style has_denorm
Definition limits:273
Properties of fundamental types.
Definition limits:320
static constexpr _Tp max() noexcept
Definition limits:328
static constexpr _Tp epsilon() noexcept
Definition limits:340
static constexpr _Tp quiet_NaN() noexcept
Definition limits:353
static constexpr _Tp lowest() noexcept
Definition limits:334
static constexpr _Tp min() noexcept
Definition limits:324
static constexpr _Tp denorm_min() noexcept
Definition limits:364
static constexpr _Tp infinity() noexcept
Definition limits:348
static constexpr _Tp round_error() noexcept
Definition limits:344
static constexpr _Tp signaling_NaN() noexcept
Definition limits:358