libstdc++
max_size_type.h
Go to the documentation of this file.
1 // <max_size_type.h> -*- C++ -*-
2 
3 // Copyright (C) 2019-2023 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 
48 namespace std _GLIBCXX_VISIBILITY(default)
49 {
50 _GLIBCXX_BEGIN_NAMESPACE_VERSION
51 
52 template<typename _Tp>
53  struct numeric_limits;
54 
55 namespace 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  if (__msb)
564  _M_rep |= ~(__max_size_type(-1) >> __r._M_rep);
565  return *this;
566  }
567 
568  constexpr __max_diff_type&
569  operator&=(const __max_diff_type& __r) noexcept
570  {
571  _M_rep &= __r._M_rep;
572  return *this;
573  }
574 
575  constexpr __max_diff_type&
576  operator|=(const __max_diff_type& __r) noexcept
577  {
578  _M_rep |= __r._M_rep;
579  return *this;
580  }
581 
582  constexpr __max_diff_type&
583  operator^=(const __max_diff_type& __r) noexcept
584  {
585  _M_rep ^= __r._M_rep;
586  return *this;
587  }
588 
589  template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
590  friend constexpr _Tp&
591  operator+=(_Tp& __a, const __max_diff_type& __b) noexcept
592  { return (__a = static_cast<_Tp>(__a + __b)); }
593 
594  template<typename _Tp> requires integral<_Tp> || __is_int128<_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> || __is_int128<_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> || __is_int128<_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> || __is_int128<_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> || __is_int128<_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> || __is_int128<_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> || __is_int128<_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> || __is_int128<_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> || __is_int128<_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  friend constexpr __max_diff_type
640  operator+(__max_diff_type __l, const __max_diff_type& __r) noexcept
641  {
642  __l += __r;
643  return __l;
644  }
645 
646  friend constexpr __max_diff_type
647  operator-(__max_diff_type __l, const __max_diff_type& __r) noexcept
648  {
649  __l -= __r;
650  return __l;
651  }
652 
653  friend constexpr __max_diff_type
654  operator*(__max_diff_type __l, const __max_diff_type& __r) noexcept
655  {
656  __l *= __r;
657  return __l;
658  }
659 
660  friend constexpr __max_diff_type
661  operator/(__max_diff_type __l, const __max_diff_type& __r) noexcept
662  {
663  __l /= __r;
664  return __l;
665  }
666 
667  friend constexpr __max_diff_type
668  operator%(__max_diff_type __l, const __max_diff_type& __r) noexcept
669  {
670  __l %= __r;
671  return __l;
672  }
673 
674  friend constexpr __max_diff_type
675  operator<<(__max_diff_type __l, const __max_diff_type& __r) noexcept
676  {
677  __l <<= __r;
678  return __l;
679  }
680 
681  friend constexpr __max_diff_type
682  operator>>(__max_diff_type __l, const __max_diff_type& __r) noexcept
683  {
684  __l >>= __r;
685  return __l;
686  }
687 
688  friend constexpr __max_diff_type
689  operator&(__max_diff_type __l, const __max_diff_type& __r) noexcept
690  {
691  __l &= __r;
692  return __l;
693  }
694 
695  friend constexpr __max_diff_type
696  operator|(__max_diff_type __l, const __max_diff_type& __r) noexcept
697  {
698  __l |= __r;
699  return __l;
700  }
701 
702  friend constexpr __max_diff_type
703  operator^(__max_diff_type __l, const __max_diff_type& __r) noexcept
704  {
705  __l ^= __r;
706  return __l;
707  }
708 
709  friend constexpr bool
710  operator==(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
711  { return __l._M_rep == __r._M_rep; }
712 
713 #if __cpp_lib_three_way_comparison
714  constexpr strong_ordering
715  operator<=>(const __max_diff_type& __r) const noexcept
716  {
717  const auto __lsign = _M_rep._M_msb;
718  const auto __rsign = __r._M_rep._M_msb;
719  if (__lsign ^ __rsign)
720  return __lsign ? strong_ordering::less : strong_ordering::greater;
721  else
722  return _M_rep <=> __r._M_rep;
723  }
724 #else
725  friend constexpr bool
726  operator!=(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
727  { return !(__l == __r); }
728 
729  constexpr bool
730  operator<(const __max_diff_type& __r) const noexcept
731  {
732  const auto __lsign = _M_rep._M_msb;
733  const auto __rsign = __r._M_rep._M_msb;
734  if (__lsign ^ __rsign)
735  return __lsign;
736  else
737  return _M_rep < __r._M_rep;
738  }
739 
740  friend constexpr bool
741  operator>(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
742  { return __r < __l; }
743 
744  friend constexpr bool
745  operator<=(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
746  { return !(__r < __l); }
747 
748  friend constexpr bool
749  operator>=(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
750  { return !(__l < __r); }
751 #endif
752 
753  private:
754  __max_size_type _M_rep = 0;
755 
756  friend class __max_size_type;
757  };
758 
759  constexpr
760  __max_size_type::__max_size_type(const __max_diff_type& __d) noexcept
761  : __max_size_type(__d._M_rep)
762  { }
763 
764  } // namespace __detail
765 } // namespace ranges
766 
767  template<>
768  struct numeric_limits<ranges::__detail::__max_size_type>
769  {
770  using _Sp = ranges::__detail::__max_size_type;
771  static constexpr bool is_specialized = true;
772  static constexpr bool is_signed = false;
773  static constexpr bool is_integer = true;
774  static constexpr bool is_exact = true;
775  static constexpr int digits
777  static constexpr int digits10
778  = static_cast<int>(digits * numbers::ln2 / numbers::ln10);
779 
780  static constexpr _Sp
781  min() noexcept
782  { return 0; }
783 
784  static constexpr _Sp
785  max() noexcept
786  { return _Sp(static_cast<_Sp::__rep>(-1), 1); }
787 
788  static constexpr _Sp
789  lowest() noexcept
790  { return min(); }
791  };
792 
793  template<>
794  struct numeric_limits<ranges::__detail::__max_diff_type>
795  {
796  using _Dp = ranges::__detail::__max_diff_type;
797  using _Sp = ranges::__detail::__max_size_type;
798  static constexpr bool is_specialized = true;
799  static constexpr bool is_signed = true;
800  static constexpr bool is_integer = true;
801  static constexpr bool is_exact = true;
802  static constexpr int digits = numeric_limits<_Sp>::digits - 1;
803  static constexpr int digits10
804  = static_cast<int>(digits * numbers::ln2 / numbers::ln10);
805 
806  static constexpr _Dp
807  min() noexcept
808  { return _Dp(_Sp(0, 1)); }
809 
810  static constexpr _Dp
811  max() noexcept
812  { return _Dp(_Sp(static_cast<_Sp::__rep>(-1), 0)); }
813 
814  static constexpr _Dp
815  lowest() noexcept
816  { return min(); }
817  };
818 
819 _GLIBCXX_END_NAMESPACE_VERSION
820 } // namespace
821 
822 #endif // C++20 && library concepts
823 #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:790
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Definition: complex:395
constexpr complex< _Tp > operator/(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x divided by y.
Definition: complex:425
constexpr complex< _Tp > operator-(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x minus y.
Definition: complex:365
constexpr complex< _Tp > operator+(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x plus y.
Definition: complex:335
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:1593
constexpr bitset< _Nb > operator&(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition: bitset:1553
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition: bitset:1683
constexpr bitset< _Nb > operator|(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition: bitset:1563
constexpr bitset< _Nb > operator^(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition: bitset:1573
__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