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