1// -*- C++ -*- 
2 
3// Copyright (C) 2007-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 terms 
7// of the GNU General Public License as published by the Free Software 
8// Foundation; either version 3, or (at your option) any later 
9// version. 
10 
11// This library is distributed in the hope that it will be useful, but 
12// WITHOUT ANY WARRANTY; without even the implied warranty of 
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
14// 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 ext/numeric_traits.h 
26 * This file is a GNU extension to the Standard C++ Library. 
27 */ 
28 
29#ifndef _EXT_NUMERIC_TRAITS 
30#define _EXT_NUMERIC_TRAITS 1 
31 
32#pragma GCC system_header 
33 
34#include <bits/cpp_type_traits.h> 
35#include <ext/type_traits.h> 
36 
37namespace __gnu_cxx _GLIBCXX_VISIBILITY(default
38
39_GLIBCXX_BEGIN_NAMESPACE_VERSION 
40 
41 // Compile time constants for builtin types. 
42 // In C++98 std::numeric_limits member functions are not constant expressions 
43 // (that changed in C++11 with the addition of 'constexpr'). 
44 // Even for C++11, this header is smaller than <limits> and can be used 
45 // when only is_signed, digits, min, or max values are needed for integers, 
46 // or is_signed, digits10, max_digits10, or max_exponent10 for floats. 
47 
48 // Unlike __is_integer (and std::is_integral) this trait is true for 
49 // non-standard built-in integer types such as __int128 and __int20. 
50 template<typename _Tp> 
51 struct __is_integer_nonstrict 
52 : public std::__is_integer<_Tp> 
53
54 using std::__is_integer<_Tp>::__value; 
55 
56 // The number of bits in the value representation. 
57 enum { __width = __value ? sizeof(_Tp) * __CHAR_BIT__ : 0 }; 
58 }; 
59 
60 template<typename _Value> 
61 struct __numeric_traits_integer 
62
63#if __cplusplus >= 201103L 
64 static_assert(__is_integer_nonstrict<_Value>::__value, 
65 "invalid specialization"); 
66#endif 
67 
68 // NB: these two are also available in std::numeric_limits as compile 
69 // time constants, but <limits> is big and we can avoid including it. 
70 static const bool __is_signed = (_Value)(-1) < 0
71 static const int __digits 
72 = __is_integer_nonstrict<_Value>::__width - __is_signed
73 
74 // The initializers must be constants so that __max and __min are too. 
75 static const _Value __max = __is_signed 
76 ? (((((_Value)1 << (__digits - 1)) - 1) << 1) + 1
77 : ~(_Value)0
78 static const _Value __min = __is_signed ? -__max - 1 : (_Value)0
79 }; 
80 
81 template<typename _Value> 
82 const _Value __numeric_traits_integer<_Value>::__min
83 
84 template<typename _Value> 
85 const _Value __numeric_traits_integer<_Value>::__max
86 
87 template<typename _Value> 
88 const bool __numeric_traits_integer<_Value>::__is_signed
89 
90 template<typename _Value> 
91 const int __numeric_traits_integer<_Value>::__digits
92 
93 // Enable __numeric_traits_integer for types where the __is_integer_nonstrict 
94 // primary template doesn't give the right answer. 
95#define _GLIBCXX_INT_N_TRAITS(T, WIDTH) \ 
96 template<> struct __is_integer_nonstrict<T> \ 
97 { \ 
98 enum { __value = 1 }; \ 
99 typedef std::__true_type __type; \ 
100 enum { __width = WIDTH }; \ 
101 }; \ 
102 template<> struct __is_integer_nonstrict<unsigned T> \ 
103 { \ 
104 enum { __value = 1 }; \ 
105 typedef std::__true_type __type; \ 
106 enum { __width = WIDTH }; \ 
107 }; 
108 
109 // We need to specify the width for some __intNN types because they 
110 // have padding bits, e.g. the object representation of __int20 has 32 bits, 
111 // but its width (number of bits in the value representation) is only 20. 
112#if defined __GLIBCXX_TYPE_INT_N_0 && __GLIBCXX_BITSIZE_INT_N_0 % __CHAR_BIT__ 
113 _GLIBCXX_INT_N_TRAITS(__GLIBCXX_TYPE_INT_N_0, __GLIBCXX_BITSIZE_INT_N_0) 
114#endif 
115#if defined __GLIBCXX_TYPE_INT_N_1 && __GLIBCXX_BITSIZE_INT_N_1 % __CHAR_BIT__ 
116 _GLIBCXX_INT_N_TRAITS(__GLIBCXX_TYPE_INT_N_1, __GLIBCXX_BITSIZE_INT_N_1) 
117#endif 
118#if defined __GLIBCXX_TYPE_INT_N_2 && __GLIBCXX_BITSIZE_INT_N_2 % __CHAR_BIT__ 
119 _GLIBCXX_INT_N_TRAITS(__GLIBCXX_TYPE_INT_N_2, __GLIBCXX_BITSIZE_INT_N_2) 
120#endif 
121#if defined __GLIBCXX_TYPE_INT_N_3 && __GLIBCXX_BITSIZE_INT_N_3 % __CHAR_BIT__ 
122 _GLIBCXX_INT_N_TRAITS(__GLIBCXX_TYPE_INT_N_3, __GLIBCXX_BITSIZE_INT_N_3) 
123#endif 
124 
125#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__ 
126 // In strict modes __is_integer<__int128> is false, 
127 // but we still want to define __numeric_traits_integer<__int128>. 
128 _GLIBCXX_INT_N_TRAITS(__int128, 128
129#endif 
130 
131#undef _GLIBCXX_INT_N_TRAITS 
132 
133#if __cplusplus >= 201103L 
134 /// Convenience alias for __numeric_traits<integer-type>. 
135 template<typename _Tp> 
136 using __int_traits = __numeric_traits_integer<_Tp>; 
137#endif 
138 
139#define __glibcxx_floating(_Tp, _Fval, _Dval, _LDval) \ 
140 (std::__are_same<_Tp, float>::__value ? _Fval \ 
141 : std::__are_same<_Tp, double>::__value ? _Dval : _LDval) 
142 
143#define __glibcxx_max_digits10(_Tp) \ 
144 (2 + __glibcxx_floating(_Tp, __FLT_MANT_DIG__, __DBL_MANT_DIG__, \ 
145 __LDBL_MANT_DIG__) * 643L / 2136) 
146 
147#define __glibcxx_digits10(_Tp) \ 
148 __glibcxx_floating(_Tp, __FLT_DIG__, __DBL_DIG__, __LDBL_DIG__) 
149 
150#define __glibcxx_max_exponent10(_Tp) \ 
151 __glibcxx_floating(_Tp, __FLT_MAX_10_EXP__, __DBL_MAX_10_EXP__, \ 
152 __LDBL_MAX_10_EXP__) 
153 
154 // N.B. this only supports float, double and long double (no __float128 etc.) 
155 template<typename _Value> 
156 struct __numeric_traits_floating 
157
158 // Only floating point types. See N1822. 
159 static const int __max_digits10 = __glibcxx_max_digits10(_Value); 
160 
161 // See above comment... 
162 static const bool __is_signed = true
163 static const int __digits10 = __glibcxx_digits10(_Value); 
164 static const int __max_exponent10 = __glibcxx_max_exponent10(_Value); 
165 }; 
166 
167 template<typename _Value> 
168 const int __numeric_traits_floating<_Value>::__max_digits10
169 
170 template<typename _Value> 
171 const bool __numeric_traits_floating<_Value>::__is_signed
172 
173 template<typename _Value> 
174 const int __numeric_traits_floating<_Value>::__digits10
175 
176 template<typename _Value> 
177 const int __numeric_traits_floating<_Value>::__max_exponent10
178 
179#undef __glibcxx_floating 
180#undef __glibcxx_max_digits10 
181#undef __glibcxx_digits10 
182#undef __glibcxx_max_exponent10 
183 
184 template<typename _Value> 
185 struct __numeric_traits 
186 : public __numeric_traits_integer<_Value> 
187 { }; 
188 
189 template<> 
190 struct __numeric_traits<float
191 : public __numeric_traits_floating<float
192 { }; 
193 
194 template<> 
195 struct __numeric_traits<double
196 : public __numeric_traits_floating<double
197 { }; 
198 
199 template<> 
200 struct __numeric_traits<long double
201 : public __numeric_traits_floating<long double
202 { }; 
203 
204#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT 
205# if defined __LONG_DOUBLE_IEEE128__ 
206 // long double is __ieee128, define traits for __ibm128 
207 template<> 
208 struct __numeric_traits_floating<__ibm128
209
210 static const int __max_digits10 = 33
211 static const bool __is_signed = true
212 static const int __digits10 = 31
213 static const int __max_exponent10 = 308
214 }; 
215 template<> 
216 struct __numeric_traits<__ibm128
217 : public __numeric_traits_floating<__ibm128
218 { }; 
219# elif defined __LONG_DOUBLE_IBM128__ 
220 // long double is __ibm128, define traits for __ieee128 
221 template<> 
222 struct __numeric_traits_floating<__ieee128> 
223
224 static const int __max_digits10 = 36
225 static const bool __is_signed = true
226 static const int __digits10 = 33
227 static const int __max_exponent10 = 4932
228 }; 
229 template<> 
230 struct __numeric_traits<__ieee128> 
231 : public __numeric_traits_floating<__ieee128> 
232 { }; 
233# endif 
234#endif 
235 
236_GLIBCXX_END_NAMESPACE_VERSION 
237} // namespace 
238 
239#endif 
240