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 <numbers>
40
41// This header implements unsigned and signed integer-class types (as per
42// [iterator.concept.winc]) that are one bit wider than the widest supported
43// integer type.
44//
45// The set of integer types we consider includes __int128 and unsigned __int128
46// (when they exist), even though they are really integer types only in GNU
47// mode. This is to obtain a consistent ABI for these integer-class types
48// across strict mode and GNU mode.
49
50namespace std _GLIBCXX_VISIBILITY(default)
51{
52_GLIBCXX_BEGIN_NAMESPACE_VERSION
53
54template<typename _Tp>
55 struct numeric_limits;
56
57namespace ranges
58{
59 namespace __detail
60 {
61 class __max_size_type
62 {
63 public:
64 __max_size_type() = default;
65
66 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
67 constexpr
68 __max_size_type(_Tp __i) noexcept
69 : _M_val(__i), _M_msb(__i < 0)
70 { }
71
72 constexpr explicit
73 __max_size_type(const __max_diff_type& __d) noexcept;
74
75 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
76 constexpr explicit
77 operator _Tp() const noexcept
78 { return _M_val; }
79
80 constexpr explicit
81 operator bool() const noexcept
82 { return _M_val != 0 || _M_msb != 0; }
83
84 constexpr __max_size_type
85 operator+() const noexcept
86 { return *this; }
87
88 constexpr __max_size_type
89 operator~() const noexcept
90 { return __max_size_type{~_M_val, !_M_msb}; }
91
92 constexpr __max_size_type
93 operator-() const noexcept
94 { return operator~() + 1; }
95
96 constexpr __max_size_type&
97 operator++() noexcept
98 { return *this += 1; }
99
100 constexpr __max_size_type
101 operator++(int) noexcept
102 {
103 auto __tmp = *this;
104 ++*this;
105 return __tmp;
106 }
107
108 constexpr __max_size_type&
109 operator--() noexcept
110 { return *this -= 1; }
111
112 constexpr __max_size_type
113 operator--(int) noexcept
114 {
115 auto __tmp = *this;
116 --*this;
117 return __tmp;
118 }
119
120 constexpr __max_size_type&
121 operator+=(const __max_size_type& __r) noexcept
122 {
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;
126 _M_val = __sum;
127 return *this;
128 }
129
130 constexpr __max_size_type&
131 operator-=(const __max_size_type& __r) noexcept
132 { return *this += -__r; }
133
134 constexpr __max_size_type&
135 operator*=(__max_size_type __r) noexcept
136 {
137 constexpr __max_size_type __threshold
138 = __rep(1) << (_S_rep_bits / 2 - 1);
139 if (_M_val < __threshold && __r < __threshold)
140 // When both operands are below this threshold then the
141 // multiplication can be safely computed in the base precision.
142 _M_val = _M_val * __r._M_val;
143 else
144 {
145 // Otherwise, perform the multiplication in four steps, by
146 // decomposing the LHS and the RHS into 2*x+a and 2*y+b,
147 // respectively, and computing 4*x*y + 2*x*b + 2*y*a + a*b.
148 const bool __lsb = _M_val & 1;
149 const bool __rlsb = __r._M_val & 1;
150 *this >>= 1;
151 __r >>= 1;
152 _M_val = (2 * _M_val * __r._M_val
153 + _M_val * __rlsb + __r._M_val * __lsb);
154 *this <<= 1;
155 *this += __rlsb * __lsb;
156 }
157
158 return *this;
159 }
160
161 constexpr __max_size_type&
162 operator/=(const __max_size_type& __r) noexcept
163 {
164 __glibcxx_assert(__r != 0);
165
166 if (!_M_msb && !__r._M_msb) [[likely]]
167 _M_val /= __r._M_val;
168 else if (_M_msb && __r._M_msb)
169 {
170 _M_val = (_M_val >= __r._M_val);
171 _M_msb = 0;
172 }
173 else if (!_M_msb && __r._M_msb)
174 _M_val = 0;
175 else if (_M_msb && !__r._M_msb)
176 {
177 // The non-trivial case: the dividend has its MSB set and the
178 // divisor doesn't. In this case we compute ((LHS/2)/RHS)*2
179 // in the base precision. This quantity is either the true
180 // quotient or one less than the true quotient.
181 const auto __orig = *this;
182 *this >>= 1;
183 _M_val /= __r._M_val;
184 *this <<= 1;
185 if (__orig - *this * __r >= __r)
186 ++_M_val;
187 }
188 return *this;
189 }
190
191 constexpr __max_size_type&
192 operator%=(const __max_size_type& __r) noexcept
193 {
194 if (!_M_msb && !__r._M_msb) [[likely]]
195 _M_val %= __r._M_val;
196 else
197 *this -= (*this / __r) * __r;
198 return *this;
199 }
200
201 constexpr __max_size_type&
202 operator<<=(const __max_size_type& __r) noexcept
203 {
204 __glibcxx_assert(__r <= _S_rep_bits);
205 if (__r != 0)
206 {
207 _M_msb = (_M_val >> (_S_rep_bits - __r._M_val)) & 1;
208
209 if (__r._M_val == _S_rep_bits) [[unlikely]]
210 _M_val = 0;
211 else
212 _M_val <<= __r._M_val;
213 }
214 return *this;
215 }
216
217 constexpr __max_size_type&
218 operator>>=(const __max_size_type& __r) noexcept
219 {
220 __glibcxx_assert(__r <= _S_rep_bits);
221 if (__r != 0)
222 {
223 if (__r._M_val == _S_rep_bits) [[unlikely]]
224 _M_val = 0;
225 else
226 _M_val >>= __r._M_val;
227
228 if (_M_msb) [[unlikely]]
229 {
230 _M_val |= __rep(1) << (_S_rep_bits - __r._M_val);
231 _M_msb = 0;
232 }
233 }
234 return *this;
235 }
236
237 constexpr __max_size_type&
238 operator&=(const __max_size_type& __r) noexcept
239 {
240 _M_val &= __r._M_val;
241 _M_msb &= __r._M_msb;
242 return *this;
243 }
244
245 constexpr __max_size_type&
246 operator|=(const __max_size_type& __r) noexcept
247 {
248 _M_val |= __r._M_val;
249 _M_msb |= __r._M_msb;
250 return *this;
251 }
252
253 constexpr __max_size_type&
254 operator^=(const __max_size_type& __r) noexcept
255 {
256 _M_val ^= __r._M_val;
257 _M_msb ^= __r._M_msb;
258 return *this;
259 }
260
261 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
262 friend constexpr _Tp&
263 operator+=(_Tp& __a, const __max_size_type& __b) noexcept
264 { return (__a = static_cast<_Tp>(__a + __b)); }
265
266 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
267 friend constexpr _Tp&
268 operator-=(_Tp& __a, const __max_size_type& __b) noexcept
269 { return (__a = static_cast<_Tp>(__a - __b)); }
270
271 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
272 friend constexpr _Tp&
273 operator*=(_Tp& __a, const __max_size_type& __b) noexcept
274 { return (__a = static_cast<_Tp>(__a * __b)); }
275
276 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
277 friend constexpr _Tp&
278 operator/=(_Tp& __a, const __max_size_type& __b) noexcept
279 { return (__a = static_cast<_Tp>(__a / __b)); }
280
281 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
282 friend constexpr _Tp&
283 operator%=(_Tp& __a, const __max_size_type& __b) noexcept
284 { return (__a = static_cast<_Tp>(__a % __b)); }
285
286 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
287 friend constexpr _Tp&
288 operator&=(_Tp& __a, const __max_size_type& __b) noexcept
289 { return (__a = static_cast<_Tp>(__a & __b)); }
290
291 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
292 friend constexpr _Tp&
293 operator|=(_Tp& __a, const __max_size_type& __b) noexcept
294 { return (__a = static_cast<_Tp>(__a | __b)); }
295
296 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
297 friend constexpr _Tp&
298 operator^=(_Tp& __a, const __max_size_type& __b) noexcept
299 { return (__a = static_cast<_Tp>(__a ^ __b)); }
300
301 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
302 friend constexpr _Tp&
303 operator<<=(_Tp& __a, const __max_size_type& __b) noexcept
304 { return (__a = static_cast<_Tp>(__a << __b)); }
305
306 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
307 friend constexpr _Tp&
308 operator>>=(_Tp& __a, const __max_size_type& __b) noexcept
309 { return (__a = static_cast<_Tp>(__a >> __b)); }
310
311 friend constexpr __max_size_type
312 operator+(__max_size_type __l, const __max_size_type& __r) noexcept
313 {
314 __l += __r;
315 return __l;
316 }
317
318 friend constexpr __max_size_type
319 operator-(__max_size_type __l, const __max_size_type& __r) noexcept
320 {
321 __l -= __r;
322 return __l;
323 }
324
325 friend constexpr __max_size_type
326 operator*(__max_size_type __l, const __max_size_type& __r) noexcept
327 {
328 __l *= __r;
329 return __l;
330 }
331
332 friend constexpr __max_size_type
333 operator/(__max_size_type __l, const __max_size_type& __r) noexcept
334 {
335 __l /= __r;
336 return __l;
337 }
338
339 friend constexpr __max_size_type
340 operator%(__max_size_type __l, const __max_size_type& __r) noexcept
341 {
342 __l %= __r;
343 return __l;
344 }
345
346 friend constexpr __max_size_type
347 operator<<(__max_size_type __l, const __max_size_type& __r) noexcept
348 {
349 __l <<= __r;
350 return __l;
351 }
352
353 friend constexpr __max_size_type
354 operator>>(__max_size_type __l, const __max_size_type& __r) noexcept
355 {
356 __l >>= __r;
357 return __l;
358 }
359
360 friend constexpr __max_size_type
361 operator&(__max_size_type __l, const __max_size_type& __r) noexcept
362 {
363 __l &= __r;
364 return __l;
365 }
366
367 friend constexpr __max_size_type
368 operator|(__max_size_type __l, const __max_size_type& __r) noexcept
369 {
370 __l |= __r;
371 return __l;
372 }
373
374 friend constexpr __max_size_type
375 operator^(__max_size_type __l, const __max_size_type& __r) noexcept
376 {
377 __l ^= __r;
378 return __l;
379 }
380
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; }
384
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
388 {
389 if (__l._M_msb ^ __r._M_msb)
390 return __l._M_msb ? strong_ordering::greater : strong_ordering::less;
391 else
392 return __l._M_val <=> __r._M_val;
393 }
394#else
395 friend constexpr bool
396 operator!=(const __max_size_type& __l, const __max_size_type& __r) noexcept
397 { return !(__l == __r); }
398
399 friend constexpr bool
400 operator<(const __max_size_type& __l, const __max_size_type& __r) noexcept
401 {
402 if (__l._M_msb == __r._M_msb)
403 return __l._M_val < __r._M_val;
404 else
405 return __r._M_msb;
406 }
407
408 friend constexpr bool
409 operator>(const __max_size_type& __l, const __max_size_type& __r) noexcept
410 { return __r < __l; }
411
412 friend constexpr bool
413 operator<=(const __max_size_type& __l, const __max_size_type& __r) noexcept
414 { return !(__l > __r); }
415
416 friend constexpr bool
417 operator>=(const __max_size_type& __l, const __max_size_type& __r) noexcept
418 { return __r <= __l; }
419#endif
420
421#if __SIZEOF_INT128__
422 __extension__
423 using __rep = unsigned __int128;
424#else
425 using __rep = unsigned long long;
426#endif
427 static constexpr size_t _S_rep_bits = sizeof(__rep) * __CHAR_BIT__;
428 private:
429 __rep _M_val = 0;
430 unsigned _M_msb:1 = 0;
431
432 constexpr explicit
433 __max_size_type(__rep __val, int __msb) noexcept
434 : _M_val(__val), _M_msb(__msb)
435 { }
436
437 friend __max_diff_type;
438 friend std::numeric_limits<__max_size_type>;
439 friend std::numeric_limits<__max_diff_type>;
440 };
441
442 class __max_diff_type
443 {
444 public:
445 __max_diff_type() = default;
446
447 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
448 constexpr
449 __max_diff_type(_Tp __i) noexcept
450 : _M_rep(__i)
451 { }
452
453 constexpr explicit
454 __max_diff_type(const __max_size_type& __d) noexcept
455 : _M_rep(__d)
456 { }
457
458 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
459 constexpr explicit
460 operator _Tp() const noexcept
461 { return static_cast<_Tp>(_M_rep); }
462
463 constexpr explicit
464 operator bool() const noexcept
465 { return _M_rep != 0; }
466
467 constexpr __max_diff_type
468 operator+() const noexcept
469 { return *this; }
470
471 constexpr __max_diff_type
472 operator-() const noexcept
473 { return __max_diff_type(-_M_rep); }
474
475 constexpr __max_diff_type
476 operator~() const noexcept
477 { return __max_diff_type(~_M_rep); }
478
479 constexpr __max_diff_type&
480 operator++() noexcept
481 { return *this += 1; }
482
483 constexpr __max_diff_type
484 operator++(int) noexcept
485 {
486 auto __tmp = *this;
487 ++*this;
488 return __tmp;
489 }
490
491 constexpr __max_diff_type&
492 operator--() noexcept
493 { return *this -= 1; }
494
495 constexpr __max_diff_type
496 operator--(int) noexcept
497 {
498 auto __tmp = *this;
499 --*this;
500 return __tmp;
501 }
502
503 constexpr __max_diff_type&
504 operator+=(const __max_diff_type& __r) noexcept
505 {
506 _M_rep += __r._M_rep;
507 return *this;
508 }
509
510 constexpr __max_diff_type&
511 operator-=(const __max_diff_type& __r) noexcept
512 {
513 _M_rep -= __r._M_rep;
514 return *this;
515 }
516
517 constexpr __max_diff_type&
518 operator*=(const __max_diff_type& __r) noexcept
519 {
520 _M_rep *= __r._M_rep;
521 return *this;
522 }
523
524 constexpr __max_diff_type&
525 operator/=(const __max_diff_type& __r) noexcept
526 {
527 __glibcxx_assert (__r != 0);
528 const bool __neg = *this < 0;
529 const bool __rneg = __r < 0;
530 if (!__neg && !__rneg)
531 _M_rep = _M_rep / __r._M_rep;
532 else if (__neg && __rneg)
533 _M_rep = -_M_rep / -__r._M_rep;
534 else if (__neg && !__rneg)
535 _M_rep = -(-_M_rep / __r._M_rep);
536 else
537 _M_rep = -(_M_rep / -__r._M_rep);
538 return *this ;
539 }
540
541 constexpr __max_diff_type&
542 operator%=(const __max_diff_type& __r) noexcept
543 {
544 __glibcxx_assert (__r != 0);
545 if (*this >= 0 && __r > 0)
546 _M_rep %= __r._M_rep;
547 else
548 *this -= (*this / __r) * __r;
549 return *this;
550 }
551
552 constexpr __max_diff_type&
553 operator<<=(const __max_diff_type& __r) noexcept
554 {
555 _M_rep.operator<<=(__r._M_rep);
556 return *this;
557 }
558
559 constexpr __max_diff_type&
560 operator>>=(const __max_diff_type& __r) noexcept
561 {
562 // Arithmetic right shift.
563 const auto __msb = _M_rep._M_msb;
564 _M_rep >>= __r._M_rep;
565 if (__msb)
566 _M_rep |= ~(__max_size_type(-1) >> __r._M_rep);
567 return *this;
568 }
569
570 constexpr __max_diff_type&
571 operator&=(const __max_diff_type& __r) noexcept
572 {
573 _M_rep &= __r._M_rep;
574 return *this;
575 }
576
577 constexpr __max_diff_type&
578 operator|=(const __max_diff_type& __r) noexcept
579 {
580 _M_rep |= __r._M_rep;
581 return *this;
582 }
583
584 constexpr __max_diff_type&
585 operator^=(const __max_diff_type& __r) noexcept
586 {
587 _M_rep ^= __r._M_rep;
588 return *this;
589 }
590
591 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
592 friend constexpr _Tp&
593 operator+=(_Tp& __a, const __max_diff_type& __b) noexcept
594 { return (__a = static_cast<_Tp>(__a + __b)); }
595
596 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
597 friend constexpr _Tp&
598 operator-=(_Tp& __a, const __max_diff_type& __b) noexcept
599 { return (__a = static_cast<_Tp>(__a - __b)); }
600
601 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
602 friend constexpr _Tp&
603 operator*=(_Tp& __a, const __max_diff_type& __b) noexcept
604 { return (__a = static_cast<_Tp>(__a * __b)); }
605
606 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
607 friend constexpr _Tp&
608 operator/=(_Tp& __a, const __max_diff_type& __b) noexcept
609 { return (__a = static_cast<_Tp>(__a / __b)); }
610
611 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
612 friend constexpr _Tp&
613 operator%=(_Tp& __a, const __max_diff_type& __b) noexcept
614 { return (__a = static_cast<_Tp>(__a % __b)); }
615
616 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
617 friend constexpr _Tp&
618 operator&=(_Tp& __a, const __max_diff_type& __b) noexcept
619 { return (__a = static_cast<_Tp>(__a & __b)); }
620
621 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
622 friend constexpr _Tp&
623 operator|=(_Tp& __a, const __max_diff_type& __b) noexcept
624 { return (__a = static_cast<_Tp>(__a | __b)); }
625
626 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
627 friend constexpr _Tp&
628 operator^=(_Tp& __a, const __max_diff_type& __b) noexcept
629 { return (__a = static_cast<_Tp>(__a ^ __b)); }
630
631 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
632 friend constexpr _Tp&
633 operator<<=(_Tp& __a, const __max_diff_type& __b) noexcept
634 { return (__a = static_cast<_Tp>(__a << __b)); }
635
636 template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
637 friend constexpr _Tp&
638 operator>>=(_Tp& __a, const __max_diff_type& __b) noexcept
639 { return (__a = static_cast<_Tp>(__a >> __b)); }
640
641 friend constexpr __max_diff_type
642 operator+(__max_diff_type __l, const __max_diff_type& __r) noexcept
643 {
644 __l += __r;
645 return __l;
646 }
647
648 friend constexpr __max_diff_type
649 operator-(__max_diff_type __l, const __max_diff_type& __r) noexcept
650 {
651 __l -= __r;
652 return __l;
653 }
654
655 friend constexpr __max_diff_type
656 operator*(__max_diff_type __l, const __max_diff_type& __r) noexcept
657 {
658 __l *= __r;
659 return __l;
660 }
661
662 friend constexpr __max_diff_type
663 operator/(__max_diff_type __l, const __max_diff_type& __r) noexcept
664 {
665 __l /= __r;
666 return __l;
667 }
668
669 friend constexpr __max_diff_type
670 operator%(__max_diff_type __l, const __max_diff_type& __r) noexcept
671 {
672 __l %= __r;
673 return __l;
674 }
675
676 friend constexpr __max_diff_type
677 operator<<(__max_diff_type __l, const __max_diff_type& __r) noexcept
678 {
679 __l <<= __r;
680 return __l;
681 }
682
683 friend constexpr __max_diff_type
684 operator>>(__max_diff_type __l, const __max_diff_type& __r) noexcept
685 {
686 __l >>= __r;
687 return __l;
688 }
689
690 friend constexpr __max_diff_type
691 operator&(__max_diff_type __l, const __max_diff_type& __r) noexcept
692 {
693 __l &= __r;
694 return __l;
695 }
696
697 friend constexpr __max_diff_type
698 operator|(__max_diff_type __l, const __max_diff_type& __r) noexcept
699 {
700 __l |= __r;
701 return __l;
702 }
703
704 friend constexpr __max_diff_type
705 operator^(__max_diff_type __l, const __max_diff_type& __r) noexcept
706 {
707 __l ^= __r;
708 return __l;
709 }
710
711 friend constexpr bool
712 operator==(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
713 { return __l._M_rep == __r._M_rep; }
714
715#if __cpp_lib_three_way_comparison
716 constexpr strong_ordering
717 operator<=>(const __max_diff_type& __r) const noexcept
718 {
719 const auto __lsign = _M_rep._M_msb;
720 const auto __rsign = __r._M_rep._M_msb;
721 if (__lsign ^ __rsign)
722 return __lsign ? strong_ordering::less : strong_ordering::greater;
723 else
724 return _M_rep <=> __r._M_rep;
725 }
726#else
727 friend constexpr bool
728 operator!=(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
729 { return !(__l == __r); }
730
731 constexpr bool
732 operator<(const __max_diff_type& __r) const noexcept
733 {
734 const auto __lsign = _M_rep._M_msb;
735 const auto __rsign = __r._M_rep._M_msb;
736 if (__lsign ^ __rsign)
737 return __lsign;
738 else
739 return _M_rep < __r._M_rep;
740 }
741
742 friend constexpr bool
743 operator>(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
744 { return __r < __l; }
745
746 friend constexpr bool
747 operator<=(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
748 { return !(__r < __l); }
749
750 friend constexpr bool
751 operator>=(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
752 { return !(__l < __r); }
753#endif
754
755 private:
756 __max_size_type _M_rep = 0;
757
758 friend class __max_size_type;
759 };
760
761 constexpr
762 __max_size_type::__max_size_type(const __max_diff_type& __d) noexcept
763 : __max_size_type(__d._M_rep)
764 { }
765
766 } // namespace __detail
767} // namespace ranges
768
769 template<>
770 struct numeric_limits<ranges::__detail::__max_size_type>
771 {
772 using _Sp = ranges::__detail::__max_size_type;
773 static constexpr bool is_specialized = true;
774 static constexpr bool is_signed = false;
775 static constexpr bool is_integer = true;
776 static constexpr bool is_exact = true;
777 static constexpr int digits
778 = __gnu_cxx::__int_traits<_Sp::__rep>::__digits + 1;
779 static constexpr int digits10
780 = static_cast<int>(digits * numbers::ln2 / numbers::ln10);
781
782 static constexpr _Sp
783 min() noexcept
784 { return 0; }
785
786 static constexpr _Sp
787 max() noexcept
788 { return _Sp(static_cast<_Sp::__rep>(-1), 1); }
789
790 static constexpr _Sp
791 lowest() noexcept
792 { return min(); }
793 };
794
795 template<>
796 struct numeric_limits<ranges::__detail::__max_diff_type>
797 {
798 using _Dp = ranges::__detail::__max_diff_type;
799 using _Sp = ranges::__detail::__max_size_type;
800 static constexpr bool is_specialized = true;
801 static constexpr bool is_signed = true;
802 static constexpr bool is_integer = true;
803 static constexpr bool is_exact = true;
804 static constexpr int digits = numeric_limits<_Sp>::digits - 1;
805 static constexpr int digits10
806 = static_cast<int>(digits * numbers::ln2 / numbers::ln10);
807
808 static constexpr _Dp
809 min() noexcept
810 { return _Dp(_Sp(0, 1)); }
811
812 static constexpr _Dp
813 max() noexcept
814 { return _Dp(_Sp(static_cast<_Sp::__rep>(-1), 0)); }
815
816 static constexpr _Dp
817 lowest() noexcept
818 { return min(); }
819 };
820
821_GLIBCXX_END_NAMESPACE_VERSION
822} // namespace
823
824#endif // C++20 && library concepts
825#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:405
constexpr complex< _Tp > operator-(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x minus y.
Definition complex:375
constexpr complex< _Tp > operator+(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x plus y.
Definition complex:345
constexpr complex< _Tp > operator/(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x divided by y.
Definition complex:435
ISO C++ entities toplevel namespace is std.
constexpr bitset< _Nb > operator^(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition bitset:1582
std::basic_istream< _CharT, _Traits > & operator>>(std::basic_istream< _CharT, _Traits > &__is, bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition bitset:1602
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition bitset:1692
constexpr bitset< _Nb > operator|(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition bitset:1572
constexpr bitset< _Nb > operator&(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition bitset:1562
static constexpr bool is_integer
Definition limits:233
static constexpr int digits
Definition limits:218
static constexpr bool is_exact
Definition limits:238
static constexpr bool is_specialized
Definition limits:213
static constexpr bool is_signed
Definition limits:230
static constexpr int digits10
Definition limits:221
Properties of fundamental types.
Definition limits:320
static constexpr _Tp max() noexcept
Definition limits:328
static constexpr _Tp lowest() noexcept
Definition limits:334
static constexpr _Tp min() noexcept
Definition limits:324