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