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 
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  _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 divided by y.
Definition: complex:422
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
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:1472
bitset< _Nb > operator^(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition: bitset:1453
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition: bitset:1540
bitset< _Nb > operator|(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition: bitset:1444
bitset< _Nb > operator&(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition: bitset:1435
__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