libstdc++
max_size_type.h
Go to the documentation of this file.
1 // <max_size_type.h> -*- C++ -*-
2 
3 // Copyright (C) 2019-2021 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  using __rep = unsigned __int128;
421 #else
422  using __rep = unsigned long long;
423 #endif
424  static constexpr size_t _S_rep_bits = sizeof(__rep) * __CHAR_BIT__;
425  private:
426  __rep _M_val = 0;
427  unsigned _M_msb:1 = 0;
428 
429  constexpr explicit
430  __max_size_type(__rep __val, int __msb) noexcept
431  : _M_val(__val), _M_msb(__msb)
432  { }
433 
434  friend __max_diff_type;
437  };
438 
439  class __max_diff_type
440  {
441  public:
442  __max_diff_type() = default;
443 
444  template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
445  constexpr
446  __max_diff_type(_Tp __i) noexcept
447  : _M_rep(__i)
448  { }
449 
450  constexpr explicit
451  __max_diff_type(const __max_size_type& __d) noexcept
452  : _M_rep(__d)
453  { }
454 
455  template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
456  constexpr explicit
457  operator _Tp() const noexcept
458  { return static_cast<_Tp>(_M_rep); }
459 
460  constexpr explicit
461  operator bool() const noexcept
462  { return _M_rep != 0; }
463 
464  constexpr __max_diff_type
465  operator+() const noexcept
466  { return *this; }
467 
468  constexpr __max_diff_type
469  operator-() const noexcept
470  { return __max_diff_type(-_M_rep); }
471 
472  constexpr __max_diff_type
473  operator~() const noexcept
474  { return __max_diff_type(~_M_rep); }
475 
476  constexpr __max_diff_type&
477  operator++() noexcept
478  { return *this += 1; }
479 
480  constexpr __max_diff_type
481  operator++(int) noexcept
482  {
483  auto __tmp = *this;
484  ++*this;
485  return __tmp;
486  }
487 
488  constexpr __max_diff_type&
489  operator--() noexcept
490  { return *this -= 1; }
491 
492  constexpr __max_diff_type
493  operator--(int) noexcept
494  {
495  auto __tmp = *this;
496  --*this;
497  return __tmp;
498  }
499 
500  constexpr __max_diff_type&
501  operator+=(const __max_diff_type& __r) noexcept
502  {
503  _M_rep += __r._M_rep;
504  return *this;
505  }
506 
507  constexpr __max_diff_type&
508  operator-=(const __max_diff_type& __r) noexcept
509  {
510  _M_rep -= __r._M_rep;
511  return *this;
512  }
513 
514  constexpr __max_diff_type&
515  operator*=(const __max_diff_type& __r) noexcept
516  {
517  _M_rep *= __r._M_rep;
518  return *this;
519  }
520 
521  constexpr __max_diff_type&
522  operator/=(const __max_diff_type& __r) noexcept
523  {
524  __glibcxx_assert (__r != 0);
525  const bool __neg = *this < 0;
526  const bool __rneg = __r < 0;
527  if (!__neg && !__rneg)
528  _M_rep = _M_rep / __r._M_rep;
529  else if (__neg && __rneg)
530  _M_rep = -_M_rep / -__r._M_rep;
531  else if (__neg && !__rneg)
532  _M_rep = -(-_M_rep / __r._M_rep);
533  else
534  _M_rep = -(_M_rep / -__r._M_rep);
535  return *this ;
536  }
537 
538  constexpr __max_diff_type&
539  operator%=(const __max_diff_type& __r) noexcept
540  {
541  __glibcxx_assert (__r != 0);
542  if (*this >= 0 && __r > 0)
543  _M_rep %= __r._M_rep;
544  else
545  *this -= (*this / __r) * __r;
546  return *this;
547  }
548 
549  constexpr __max_diff_type&
550  operator<<=(const __max_diff_type& __r) noexcept
551  {
552  _M_rep.operator<<=(__r._M_rep);
553  return *this;
554  }
555 
556  constexpr __max_diff_type&
557  operator>>=(const __max_diff_type& __r) noexcept
558  {
559  // Arithmetic right shift.
560  const auto __msb = _M_rep._M_msb;
561  _M_rep >>= __r._M_rep;
562  _M_rep._M_msb |= __msb;
563  return *this;
564  }
565 
566  constexpr __max_diff_type&
567  operator&=(const __max_diff_type& __r) noexcept
568  {
569  _M_rep &= __r._M_rep;
570  return *this;
571  }
572 
573  constexpr __max_diff_type&
574  operator|=(const __max_diff_type& __r) noexcept
575  {
576  _M_rep |= __r._M_rep;
577  return *this;
578  }
579 
580  constexpr __max_diff_type&
581  operator^=(const __max_diff_type& __r) noexcept
582  {
583  _M_rep ^= __r._M_rep;
584  return *this;
585  }
586 
587  template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
588  friend constexpr _Tp&
589  operator+=(_Tp& __a, const __max_diff_type& __b) noexcept
590  { return (__a = static_cast<_Tp>(__a + __b)); }
591 
592  template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
593  friend constexpr _Tp&
594  operator-=(_Tp& __a, const __max_diff_type& __b) noexcept
595  { return (__a = static_cast<_Tp>(__a - __b)); }
596 
597  template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
598  friend constexpr _Tp&
599  operator*=(_Tp& __a, const __max_diff_type& __b) noexcept
600  { return (__a = static_cast<_Tp>(__a * __b)); }
601 
602  template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
603  friend constexpr _Tp&
604  operator/=(_Tp& __a, const __max_diff_type& __b) noexcept
605  { return (__a = static_cast<_Tp>(__a / __b)); }
606 
607  template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
608  friend constexpr _Tp&
609  operator%=(_Tp& __a, const __max_diff_type& __b) noexcept
610  { return (__a = static_cast<_Tp>(__a % __b)); }
611 
612  template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
613  friend constexpr _Tp&
614  operator&=(_Tp& __a, const __max_diff_type& __b) noexcept
615  { return (__a = static_cast<_Tp>(__a & __b)); }
616 
617  template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
618  friend constexpr _Tp&
619  operator|=(_Tp& __a, const __max_diff_type& __b) noexcept
620  { return (__a = static_cast<_Tp>(__a | __b)); }
621 
622  template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
623  friend constexpr _Tp&
624  operator^=(_Tp& __a, const __max_diff_type& __b) noexcept
625  { return (__a = static_cast<_Tp>(__a ^ __b)); }
626 
627  template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
628  friend constexpr _Tp&
629  operator<<=(_Tp& __a, const __max_diff_type& __b) noexcept
630  { return (__a = static_cast<_Tp>(__a << __b)); }
631 
632  template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
633  friend constexpr _Tp&
634  operator>>=(_Tp& __a, const __max_diff_type& __b) noexcept
635  { return (__a = static_cast<_Tp>(__a >> __b)); }
636 
637  friend constexpr __max_diff_type
638  operator+(__max_diff_type __l, const __max_diff_type& __r) noexcept
639  {
640  __l += __r;
641  return __l;
642  }
643 
644  friend constexpr __max_diff_type
645  operator-(__max_diff_type __l, const __max_diff_type& __r) noexcept
646  {
647  __l -= __r;
648  return __l;
649  }
650 
651  friend constexpr __max_diff_type
652  operator*(__max_diff_type __l, const __max_diff_type& __r) noexcept
653  {
654  __l *= __r;
655  return __l;
656  }
657 
658  friend constexpr __max_diff_type
659  operator/(__max_diff_type __l, const __max_diff_type& __r) noexcept
660  {
661  __l /= __r;
662  return __l;
663  }
664 
665  friend constexpr __max_diff_type
666  operator%(__max_diff_type __l, const __max_diff_type& __r) noexcept
667  {
668  __l %= __r;
669  return __l;
670  }
671 
672  friend constexpr __max_diff_type
673  operator<<(__max_diff_type __l, const __max_diff_type& __r) noexcept
674  {
675  __l <<= __r;
676  return __l;
677  }
678 
679  friend constexpr __max_diff_type
680  operator>>(__max_diff_type __l, const __max_diff_type& __r) noexcept
681  {
682  __l >>= __r;
683  return __l;
684  }
685 
686  friend constexpr __max_diff_type
687  operator&(__max_diff_type __l, const __max_diff_type& __r) noexcept
688  {
689  __l &= __r;
690  return __l;
691  }
692 
693  friend constexpr __max_diff_type
694  operator|(__max_diff_type __l, const __max_diff_type& __r) noexcept
695  {
696  __l |= __r;
697  return __l;
698  }
699 
700  friend constexpr __max_diff_type
701  operator^(__max_diff_type __l, const __max_diff_type& __r) noexcept
702  {
703  __l ^= __r;
704  return __l;
705  }
706 
707  friend constexpr bool
708  operator==(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
709  { return __l._M_rep == __r._M_rep; }
710 
711 #if __cpp_lib_three_way_comparison
712  constexpr strong_ordering
713  operator<=>(const __max_diff_type& __r) const noexcept
714  {
715  const auto __lsign = _M_rep._M_msb;
716  const auto __rsign = __r._M_rep._M_msb;
717  if (__lsign ^ __rsign)
718  return __lsign ? strong_ordering::less : strong_ordering::greater;
719  else
720  return _M_rep <=> __r._M_rep;
721  }
722 #else
723  friend constexpr bool
724  operator!=(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
725  { return !(__l == __r); }
726 
727  constexpr bool
728  operator<(const __max_diff_type& __r) const noexcept
729  {
730  const auto __lsign = _M_rep._M_msb;
731  const auto __rsign = __r._M_rep._M_msb;
732  if (__lsign ^ __rsign)
733  return __lsign;
734  else
735  return _M_rep < __r._M_rep;
736  }
737 
738  friend constexpr bool
739  operator>(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
740  { return __r < __l; }
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 !(__l < __r); }
749 #endif
750 
751  private:
752  __max_size_type _M_rep = 0;
753 
754  friend class __max_size_type;
755  };
756 
757  constexpr
758  __max_size_type::__max_size_type(const __max_diff_type& __d) noexcept
759  : __max_size_type(__d._M_rep)
760  { }
761 
762  } // namespace __detail
763 } // namespace ranges
764 
765  template<>
766  struct numeric_limits<ranges::__detail::__max_size_type>
767  {
768  using _Sp = ranges::__detail::__max_size_type;
769  static constexpr bool is_specialized = true;
770  static constexpr bool is_signed = false;
771  static constexpr bool is_integer = true;
772  static constexpr bool is_exact = true;
773 #if __SIZEOF_INT128__
774  static_assert(same_as<_Sp::__rep, unsigned __int128>);
775  static constexpr int digits = 129;
776 #else
777  static_assert(same_as<_Sp::__rep, unsigned long long>);
778  static constexpr int digits
780 #endif
781  static constexpr int digits10
782  = static_cast<int>(digits * numbers::ln2 / numbers::ln10);
783 
784  static constexpr _Sp
785  min() noexcept
786  { return 0; }
787 
788  static constexpr _Sp
789  max() noexcept
790  { return _Sp(static_cast<_Sp::__rep>(-1), 1); }
791 
792  static constexpr _Sp
793  lowest() noexcept
794  { return min(); }
795  };
796 
797  template<>
798  struct numeric_limits<ranges::__detail::__max_diff_type>
799  {
800  using _Dp = ranges::__detail::__max_diff_type;
801  using _Sp = ranges::__detail::__max_size_type;
802  static constexpr bool is_specialized = true;
803  static constexpr bool is_signed = true;
804  static constexpr bool is_integer = true;
805  static constexpr bool is_exact = true;
806  static constexpr int digits = numeric_limits<_Sp>::digits - 1;
807  static constexpr int digits10
808  = static_cast<int>(digits * numbers::ln2 / numbers::ln10);
809 
810  static constexpr _Dp
811  min() noexcept
812  { return _Dp(_Sp(0, 1)); }
813 
814  static constexpr _Dp
815  max() noexcept
816  { return _Dp(_Sp(static_cast<_Sp::__rep>(-1), 0)); }
817 
818  static constexpr _Dp
819  lowest() noexcept
820  { return min(); }
821  };
822 
823 _GLIBCXX_END_NAMESPACE_VERSION
824 } // namespace
825 
826 #endif // C++20 && library concepts
827 #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