Line data Source code
1 : // Copyright (c) 2022 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/snapdev
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program 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 : // You should have received a copy of the GNU General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 : #pragma once
20 :
21 : /** \file
22 : * \brief Implements the limits of int128 and unsigned int128.
23 : *
24 : * The default std library on Ubuntu 18.04 does not yet define the int128
25 : * limits so I have this code here which is expected to add that
26 : * functionality.
27 : *
28 : * The __INT_N() definition is from the Ubuntu 18.04 standard library. The
29 : * __INT_N() implementation is from Ubuntu 22.04.
30 : *
31 : * We can get rid of this once we move away from Ubuntu 18.04 (which should
32 : * be soon, but I'm still somewhat tighted up to it at the moment).
33 : */
34 :
35 : // C++
36 : //
37 : #include <limits>
38 :
39 : // this test is probably wrong, Ubuntu 18.04 is 7.5 and it's not there yet
40 : // I also tested with 20.04, it's 9.3 and it's not there yet
41 : // I checked on Debian 11 which has g++ 10.2.1 and it has it
42 : // I know that 22.04 has it, it's g++ 11.x
43 : // so for now I use version 10 here
44 : //
45 : #if (__GNUC__ < 10)
46 :
47 :
48 : namespace std _GLIBCXX_VISIBILITY(default)
49 : {
50 :
51 : #define __INT_N(TYPE, BITSIZE, EXT, UEXT) \
52 : template<> \
53 : struct numeric_limits<TYPE> \
54 : { \
55 : static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true; \
56 : \
57 : static _GLIBCXX_CONSTEXPR TYPE \
58 : min() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_min_b (TYPE, BITSIZE); } \
59 : \
60 : static _GLIBCXX_CONSTEXPR TYPE \
61 : max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max_b (TYPE, BITSIZE); } \
62 : \
63 : static _GLIBCXX_USE_CONSTEXPR int digits \
64 : = BITSIZE - 1; \
65 : static _GLIBCXX_USE_CONSTEXPR int digits10 \
66 : = (BITSIZE - 1) * 643L / 2136; \
67 : \
68 : static _GLIBCXX_USE_CONSTEXPR bool is_signed = true; \
69 : static _GLIBCXX_USE_CONSTEXPR bool is_integer = true; \
70 : static _GLIBCXX_USE_CONSTEXPR bool is_exact = true; \
71 : static _GLIBCXX_USE_CONSTEXPR int radix = 2; \
72 : \
73 : static _GLIBCXX_CONSTEXPR TYPE \
74 : epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; } \
75 : \
76 : static _GLIBCXX_CONSTEXPR TYPE \
77 : round_error() _GLIBCXX_USE_NOEXCEPT { return 0; } \
78 : \
79 : EXT \
80 : \
81 : static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0; \
82 : static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0; \
83 : static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0; \
84 : static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0; \
85 : \
86 : static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false; \
87 : static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false; \
88 : static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false; \
89 : static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm \
90 : = denorm_absent; \
91 : static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false; \
92 : \
93 : static _GLIBCXX_CONSTEXPR TYPE \
94 : infinity() _GLIBCXX_USE_NOEXCEPT \
95 : { return static_cast<TYPE>(0); } \
96 : \
97 : static _GLIBCXX_CONSTEXPR TYPE \
98 : quiet_NaN() _GLIBCXX_USE_NOEXCEPT \
99 : { return static_cast<TYPE>(0); } \
100 : \
101 : static _GLIBCXX_CONSTEXPR TYPE \
102 : signaling_NaN() _GLIBCXX_USE_NOEXCEPT \
103 : { return static_cast<TYPE>(0); } \
104 : \
105 : static _GLIBCXX_CONSTEXPR TYPE \
106 : denorm_min() _GLIBCXX_USE_NOEXCEPT \
107 : { return static_cast<TYPE>(0); } \
108 : \
109 : static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false; \
110 : static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; \
111 : static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false; \
112 : \
113 : static _GLIBCXX_USE_CONSTEXPR bool traps \
114 : = __glibcxx_integral_traps; \
115 : static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; \
116 : static _GLIBCXX_USE_CONSTEXPR float_round_style round_style \
117 : = round_toward_zero; \
118 : }; \
119 : \
120 : template<> \
121 : struct numeric_limits<unsigned TYPE> \
122 : { \
123 : static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true; \
124 : \
125 : static _GLIBCXX_CONSTEXPR unsigned TYPE \
126 : min() _GLIBCXX_USE_NOEXCEPT { return 0; } \
127 : \
128 : static _GLIBCXX_CONSTEXPR unsigned TYPE \
129 : max() _GLIBCXX_USE_NOEXCEPT \
130 : { return __glibcxx_max_b (unsigned TYPE, BITSIZE); } \
131 : \
132 : UEXT \
133 : \
134 : static _GLIBCXX_USE_CONSTEXPR int digits \
135 : = BITSIZE; \
136 : static _GLIBCXX_USE_CONSTEXPR int digits10 \
137 : = BITSIZE * 643L / 2136; \
138 : static _GLIBCXX_USE_CONSTEXPR bool is_signed = false; \
139 : static _GLIBCXX_USE_CONSTEXPR bool is_integer = true; \
140 : static _GLIBCXX_USE_CONSTEXPR bool is_exact = true; \
141 : static _GLIBCXX_USE_CONSTEXPR int radix = 2; \
142 : \
143 : static _GLIBCXX_CONSTEXPR unsigned TYPE \
144 : epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; } \
145 : \
146 : static _GLIBCXX_CONSTEXPR unsigned TYPE \
147 : round_error() _GLIBCXX_USE_NOEXCEPT { return 0; } \
148 : \
149 : static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0; \
150 : static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0; \
151 : static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0; \
152 : static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0; \
153 : \
154 : static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false; \
155 : static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false; \
156 : static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false; \
157 : static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm \
158 : = denorm_absent; \
159 : static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false; \
160 : \
161 : static _GLIBCXX_CONSTEXPR unsigned TYPE \
162 : infinity() _GLIBCXX_USE_NOEXCEPT \
163 : { return static_cast<unsigned TYPE>(0); } \
164 : \
165 : static _GLIBCXX_CONSTEXPR unsigned TYPE \
166 : quiet_NaN() _GLIBCXX_USE_NOEXCEPT \
167 : { return static_cast<unsigned TYPE>(0); } \
168 : \
169 : static _GLIBCXX_CONSTEXPR unsigned TYPE \
170 : signaling_NaN() _GLIBCXX_USE_NOEXCEPT \
171 : { return static_cast<unsigned TYPE>(0); } \
172 : \
173 : static _GLIBCXX_CONSTEXPR unsigned TYPE \
174 : denorm_min() _GLIBCXX_USE_NOEXCEPT \
175 : { return static_cast<unsigned TYPE>(0); } \
176 : \
177 : static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false; \
178 : static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; \
179 : static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true; \
180 : \
181 : static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps; \
182 : static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; \
183 : static _GLIBCXX_USE_CONSTEXPR float_round_style round_style \
184 : = round_toward_zero; \
185 : };
186 :
187 : #define __INT_N_201103(TYPE) \
188 : static constexpr TYPE \
189 : lowest() noexcept { return min(); } \
190 : static constexpr int max_digits10 = 0;
191 :
192 : #define __INT_N_U201103(TYPE) \
193 : static constexpr unsigned TYPE \
194 : lowest() noexcept { return min(); } \
195 : static constexpr int max_digits10 = 0;
196 :
197 : #pragma GCC diagnostic push
198 : #pragma GCC diagnostic ignored "-Wpedantic"
199 36 : __INT_N(__int128, 128,
200 : __INT_N_201103 (__int128),
201 : __INT_N_U201103 (__int128))
202 : #pragma GCC diagnostic pop
203 : #endif
204 :
205 : } // std namespace
206 : // vim: ts=4 sw=4 et
|