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 
50 namespace std _GLIBCXX_VISIBILITY(default)
51 {
52 _GLIBCXX_BEGIN_NAMESPACE_VERSION
53 
54 template<typename _Tp>
55  struct numeric_limits;
56 
57 namespace 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;
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
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 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:859
constexpr bool operator>=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:873
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 divided by y.
Definition: complex:464
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
ISO C++ entities toplevel namespace is std.
std::basic_istream< _CharT, _Traits > & operator>>(std::basic_istream< _CharT, _Traits > &__is, bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition: bitset:1602
constexpr bitset< _Nb > operator&(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition: bitset:1562
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:1582
__numeric_traits_integer< _Tp > __int_traits
Convenience alias for __numeric_traits<integer-type>.
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