]>
Commit | Line | Data |
---|---|---|
e6c76f0d PP |
1 | // Copyright (C) 2020 Free Software Foundation, Inc. |
2 | // | |
3 | // This file is part of the GNU ISO C++ Library. This library is free | |
4 | // software; you can redistribute it and/or modify it under the | |
5 | // terms of the GNU General Public License as published by the | |
6 | // Free Software Foundation; either version 3, or (at your option) | |
7 | // any later version. | |
8 | ||
9 | // This library is distributed in the hope that it will be useful, | |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | // GNU General Public License for more details. | |
13 | ||
14 | // You should have received a copy of the GNU General Public License along | |
15 | // with this library; see the file COPYING3. If not see | |
16 | // <http://www.gnu.org/licenses/>. | |
17 | ||
18 | // { dg-options "-std=gnu++2a" } | |
19 | // { dg-do run { target c++2a } } | |
20 | ||
21 | #include <limits> | |
22 | #include <ranges> | |
23 | #include <testsuite_hooks.h> | |
24 | ||
25 | using max_size_t = std::ranges::__detail::__max_size_type; | |
26 | using max_diff_t = std::ranges::__detail::__max_diff_type; | |
27 | using rep_t = max_size_t::__rep; | |
28 | ||
29 | static_assert(sizeof(max_size_t) == sizeof(max_diff_t)); | |
30 | ||
31 | static_assert(std::regular<max_size_t>); | |
32 | static_assert(std::totally_ordered<max_size_t>); | |
33 | ||
34 | static_assert(std::regular<max_diff_t>); | |
35 | static_assert(std::totally_ordered<max_diff_t>); | |
36 | ||
37 | // We can't use numeric_limits<rep_t>::max() here because __int128 is an | |
38 | // integral type only in GNU mode. | |
39 | constexpr max_size_t mu = max_size_t(~rep_t(0)); | |
40 | constexpr max_size_t ou = 1; | |
41 | constexpr max_diff_t ns = -1; | |
42 | ||
43 | void | |
44 | test01() | |
45 | { | |
46 | static_assert(max_size_t(7) % 3 == 1); | |
47 | static_assert(max_size_t(7) % 4 == 3); | |
48 | ||
49 | static_assert(-max_diff_t(1) == max_diff_t(-1)); | |
50 | static_assert(max_diff_t(3) % 2 == 1); | |
51 | static_assert(max_diff_t(-3) / 2 == -1); | |
52 | static_assert(max_diff_t(-3) % 2 == -1); | |
53 | static_assert(max_diff_t(3) % -2 == 1); | |
54 | static_assert(max_diff_t(-3) << 1 == -6); | |
55 | static_assert(max_diff_t(-3) >> 1 == -2); | |
56 | static_assert(max_diff_t(3) >> 1 == 1); | |
57 | static_assert(max_diff_t(3) >> 2 == 0); | |
58 | ||
59 | static_assert(max_diff_t(-5) / 3 == -1); | |
60 | static_assert(max_diff_t(5) / -3 == -1); | |
61 | static_assert(max_diff_t(-5) / -3 == 1); | |
62 | static_assert(max_diff_t(5) / 3 == 1); | |
63 | ||
64 | static_assert(max_diff_t(-6) / 3 == -2); | |
65 | static_assert(max_diff_t(6) / -3 == -2); | |
66 | static_assert(max_diff_t(-6) / -3 == 2); | |
67 | static_assert(max_diff_t(6) / 3 == 2); | |
68 | ||
69 | static_assert(~max_size_t(-3) == 2); | |
70 | static_assert(~max_diff_t(-3) == 2); | |
71 | ||
72 | static_assert(max_diff_t(1) < max_diff_t(3)); | |
73 | static_assert(max_diff_t(-1) < max_diff_t(3)); | |
74 | static_assert(max_diff_t(1) > max_diff_t(-3)); | |
75 | static_assert(max_diff_t(-1) > max_diff_t(-3)); | |
76 | ||
77 | static_assert(max_diff_t(mu)/-1 == -max_diff_t(mu)); | |
78 | static_assert(-max_diff_t(mu)/1 == -max_diff_t(mu)); | |
79 | static_assert(max_diff_t(mu)>>1 == max_diff_t(mu)/2); | |
80 | static_assert(-max_diff_t(mu+1) == max_diff_t(mu+1)); | |
81 | static_assert(-(mu+1) == mu+1); | |
82 | static_assert((mu+1)<<1 == 0); | |
83 | static_assert(max_diff_t(mu+1)<<1 == 0); | |
84 | static_assert(max_diff_t(mu+1)>>1 < 0); | |
85 | ||
86 | static_assert(int(max_diff_t(mu+1)) == 0); | |
87 | static_assert(rep_t(max_diff_t(mu+1)) == 0); | |
88 | static_assert(int(max_diff_t(mu)) == -1); | |
89 | static_assert(rep_t(max_diff_t(mu)) == rep_t(-1)); | |
90 | ||
91 | static_assert(2*mu+1 > 2*mu); | |
92 | static_assert(~(2*mu+1) == 0); | |
93 | static_assert(mu/mu == 1); | |
94 | static_assert(2*mu > mu); | |
95 | static_assert(2*mu-mu == mu); | |
96 | static_assert((2*mu)/mu == 2); | |
97 | static_assert((2*mu+1)/mu == 2); | |
98 | static_assert((2*mu-1)/(mu-1) == 2); | |
99 | static_assert((2*mu-1)/mu == 1); | |
100 | static_assert((2*mu+-1)/mu == 1); | |
101 | static_assert(2*mu-1 < 2*mu); | |
102 | static_assert(2*mu-1 <= 2*mu); | |
103 | static_assert(2*mu+1 > 2*mu); | |
104 | static_assert(2*mu+1 >= 2*mu); | |
105 | static_assert((2*mu)/1 == 2*mu); | |
106 | static_assert(mu/mu-1 == 0); | |
107 | static_assert(mu*0 == 0); | |
108 | static_assert((2*mu-1)*0 == 0); | |
109 | static_assert((2*mu-1)>>1 == mu-1); | |
110 | static_assert(mu+-1+1 == mu); | |
111 | static_assert(mu+1+-1 == mu); | |
112 | static_assert(mu+1); | |
113 | static_assert((2*mu)/2 == mu); | |
114 | static_assert((2*mu)>>1 == mu); | |
115 | static_assert((mu<<1)>>1 == mu); | |
116 | static_assert(1/mu == 0); | |
117 | static_assert(mu/1 == mu); | |
118 | static_assert(((mu+1)|mu) == -1); | |
119 | static_assert((mu+1)+(mu+1) < mu+1); | |
120 | ||
121 | static_assert(max_size_t(ns) == -1); | |
122 | static_assert(-max_diff_t(ou) == -1); | |
123 | static_assert(-max_diff_t(-ou) == 1); | |
124 | static_assert(max_size_t(-max_diff_t(-ou)) == 1); | |
125 | static_assert(ns*ns == max_diff_t(ou)); | |
126 | static_assert(max_size_t(ns)*max_size_t(ns) == ou); | |
127 | static_assert(-max_diff_t(0) == max_diff_t(0)); | |
128 | static_assert(-ou-ou == -2*ou); | |
129 | ||
130 | static_assert(int(ns) == -1); | |
131 | static_assert(rep_t(ns) == rep_t(-1)); | |
132 | ||
133 | static_assert(max_size_t() == 0); | |
134 | static_assert(max_diff_t() == 0); | |
135 | ||
136 | auto f = [] (auto a) { a /= a; return a; }; | |
137 | static_assert(f(max_size_t(5)) == 1); | |
138 | static_assert(f(max_size_t(-5)) == 1); | |
139 | static_assert(f(max_diff_t(5)) == 1); | |
140 | ||
141 | auto g = [] (auto a) { a >>= a; return a; }; | |
142 | static_assert(g(max_size_t(5)) == 0); | |
143 | static_assert(g(max_diff_t(5)) == 0); | |
144 | ||
145 | auto h = [] (auto a) { a <<= a; return a; }; | |
146 | static_assert(h(max_size_t(3)) == 24); | |
147 | static_assert(h(max_diff_t(3)) == 24); | |
148 | } | |
149 | ||
150 | template<bool signed_p, bool shorten_p> | |
151 | void | |
152 | test02() | |
153 | { | |
154 | using hw_type = std::conditional_t<signed_p, signed rep_t, rep_t>; | |
155 | using max_type = std::conditional_t<signed_p, max_diff_t, max_size_t>; | |
156 | using shorten_type = std::conditional_t<shorten_p, hw_type, max_type>; | |
157 | const int hw_type_bit_size = sizeof(hw_type) * __CHAR_BIT__; | |
158 | const int limit = 1000; | |
159 | const int log2_limit = 10; | |
160 | static_assert((1 << log2_limit) >= limit); | |
161 | const int min = (signed_p ? -limit : 0); | |
162 | const int max = limit; | |
163 | for (hw_type i = min; i <= max; i++) | |
164 | { | |
165 | bool ok = true; | |
166 | if (signed_p || shorten_p) | |
167 | { | |
168 | ok &= (~i == shorten_type(~max_type(i))); | |
169 | ok &= (-i == shorten_type(-max_type(i))); | |
170 | } | |
171 | for (hw_type j = min; j <= max; j++) | |
172 | { | |
173 | ok &= (i*j == shorten_type(max_type(i)*j)); | |
174 | ok &= (i+j == shorten_type(max_type(i)+j)); | |
175 | if (j != 0) | |
176 | { | |
177 | ok &= (i/j == shorten_type(max_type(i)/j)); | |
178 | ok &= (i%j == shorten_type(max_type(i)%j)); | |
179 | } | |
180 | if (signed_p || shorten_p) | |
181 | ok &= (i-j == shorten_type(max_type(i)-j)); | |
182 | ok &= ((i&j) == shorten_type(max_type(i)&j)); | |
183 | ok &= ((i|j) == shorten_type(max_type(i)|j)); | |
184 | ok &= ((i^j) == shorten_type(max_type(i)^j)); | |
185 | if (j >= 0 && j < hw_type(hw_type_bit_size) | |
186 | && (shorten_p || j < hw_type(hw_type_bit_size) - log2_limit)) | |
187 | { | |
188 | ok &= ((i>>j) == shorten_type(max_type(i)>>j)); | |
189 | ok &= ((i<<j) == shorten_type(max_type(i)<<j)); | |
190 | } | |
191 | ok &= (i>j) == (max_type(i) > j); | |
192 | ok &= (i<j) == (max_type(i) < j); | |
193 | ok &= (i>=j) == (max_type(i) >= j); | |
194 | ok &= (i<=j) == (max_type(i) <= j); | |
195 | ok &= (i==j) == (max_type(i) == j); | |
196 | ok &= (i!=j) == (max_type(i) != j); | |
197 | if (!ok) | |
198 | { | |
199 | fprintf(stderr, | |
200 | "Inconsistency found: %d %d %lld %lld\n", | |
201 | signed_p, shorten_p, (long long)i, (long long)j) ; | |
202 | VERIFY(0); | |
203 | } | |
204 | } | |
205 | } | |
206 | } | |
207 | ||
208 | template<bool signed_p, bool toggle_base_p> | |
209 | void | |
210 | test03() | |
211 | { | |
212 | using hw_type = std::conditional_t<signed_p, signed rep_t, rep_t>; | |
213 | using max_type = std::conditional_t<signed_p, max_diff_t, max_size_t>; | |
214 | using base_type = std::conditional_t<toggle_base_p, hw_type, max_type>; | |
215 | constexpr int hw_type_bit_size = sizeof(hw_type) * __CHAR_BIT__; | |
216 | constexpr int limit = 1000; | |
217 | constexpr int log2_limit = 10; | |
218 | static_assert((1 << log2_limit) >= limit); | |
219 | const int min = (signed_p ? -limit : 0); | |
220 | const int max = limit; | |
221 | for (hw_type i = min; i <= max; i++) | |
222 | { | |
223 | bool ok = true; | |
224 | base_type k; | |
225 | for (hw_type j = min; j <= max; j++) | |
226 | { | |
227 | k = i; k *= j; | |
228 | ok &= (k == (max_type(i)*j)); | |
229 | k = i; k += j; | |
230 | ok &= (k == (max_type(i)+j)); | |
231 | if (j != 0) | |
232 | { | |
233 | k = i; k /= j; | |
234 | ok &= (k == (max_type(i)/j)); | |
235 | k = i; k %= j; | |
236 | ok &= (k == (max_type(i)%j)); | |
237 | } | |
238 | if (signed_p) | |
239 | { | |
240 | k = i; k -= j; | |
241 | ok &= (k == (max_type(i)-j)); | |
242 | } | |
243 | k = i; k &= j; | |
244 | ok &= (k == (max_type(i)&j)); | |
245 | k = i; k |= j; | |
246 | ok &= (k == (max_type(i)|j)); | |
247 | k = i; k ^= j; | |
248 | ok &= (k == (max_type(i)^j)); | |
249 | if (j >= 0 && j < hw_type(hw_type_bit_size) | |
250 | && (!toggle_base_p || j < hw_type(hw_type_bit_size) - log2_limit)) | |
251 | { | |
252 | k = i; k >>= j; | |
253 | ok &= (k == (max_type(i)>>j)); | |
254 | k = i; k <<= j; | |
255 | ok &= (k == (max_type(i)<<j)); | |
256 | } | |
257 | if (!ok) | |
258 | { | |
259 | fprintf(stderr, | |
260 | "Inconsistency found: %d %d %lld %lld\n", | |
261 | signed_p, toggle_base_p, (long long)i, (long long)j) ; | |
262 | VERIFY(0); | |
263 | } | |
264 | } | |
265 | } | |
266 | } | |
267 | ||
268 | void | |
269 | test04() | |
270 | { | |
271 | constexpr int limit = 1000; | |
272 | for (int i = -limit; i <= limit; i++) | |
273 | { | |
274 | VERIFY( -max_size_t(-i) == i ); | |
275 | for (int j = i; j <= limit; j++) | |
276 | { | |
277 | VERIFY( max_size_t(-i) * max_size_t(-j) == i*j ); | |
278 | VERIFY( max_size_t(-j) * max_size_t(-i) == j*i ); | |
279 | VERIFY( rep_t(((mu+1)+i)*((mu+1)+j)) == rep_t(i*j) ); | |
280 | VERIFY( rep_t(((mu+1)+j)*((mu+1)+i)) == rep_t(j*i) ); | |
281 | if (i >= 0 && j > 0) | |
282 | { | |
283 | auto r = (mu+i)-((mu+i)/j)*j; | |
284 | VERIFY( r >= 0 && r < j ); | |
285 | VERIFY( r == (mu+i)%j ); | |
286 | } | |
287 | } | |
288 | } | |
289 | } | |
290 | ||
291 | void | |
292 | test05() | |
293 | { | |
294 | #if __SIZEOF_INT128__ | |
295 | max_size_t x = 0; | |
296 | x = static_cast<__int128>(0); | |
297 | x = static_cast<unsigned __int128>(0); | |
298 | ||
299 | max_diff_t y = 0; | |
300 | y = static_cast<__int128>(0);; | |
301 | y = static_cast<unsigned __int128>(0); | |
302 | #endif | |
303 | } | |
304 | ||
305 | using std::numeric_limits; | |
306 | ||
307 | static_assert(numeric_limits<max_size_t>::is_specialized); | |
308 | static_assert(!numeric_limits<max_size_t>::is_signed); | |
309 | static_assert(numeric_limits<max_size_t>::is_integer); | |
310 | static_assert(numeric_limits<max_size_t>::is_exact); | |
311 | // We can't unconditionally use numeric_limits here because __int128 is an | |
312 | // integral type only in GNU mode. | |
313 | #if __SIZEOF_INT128__ | |
314 | static_assert(numeric_limits<max_size_t>::digits == 129); | |
315 | static_assert(numeric_limits<max_size_t>::digits10 == 38); | |
316 | static_assert(numeric_limits<max_size_t>::max() | |
317 | == 2*max_size_t(~rep_t(0)) + 1); | |
318 | #else | |
319 | static_assert(numeric_limits<max_size_t>::digits | |
320 | == numeric_limits<rep_t>::digits + 1); | |
321 | static_assert(numeric_limits<max_size_t>::digits10 | |
322 | == numeric_limits<rep_t>::digits10); | |
323 | static_assert(numeric_limits<max_size_t>::max() | |
324 | == 2*max_size_t(numeric_limits<rep_t>::max())+1); | |
325 | #endif | |
326 | static_assert(numeric_limits<max_size_t>::min() == 0); | |
327 | static_assert(numeric_limits<max_size_t>::max() | |
328 | == max_size_t(-1)); | |
329 | static_assert((numeric_limits<max_size_t>::max() | |
330 | >> (numeric_limits<max_size_t>::digits-1)) == 1); | |
331 | static_assert(numeric_limits<max_size_t>::lowest() | |
332 | == numeric_limits<max_size_t>::min()); | |
333 | ||
334 | static_assert(numeric_limits<max_diff_t>::is_specialized); | |
335 | static_assert(numeric_limits<max_diff_t>::is_signed); | |
336 | static_assert(numeric_limits<max_diff_t>::is_integer); | |
337 | static_assert(numeric_limits<max_diff_t>::is_exact); | |
338 | static_assert(numeric_limits<max_diff_t>::digits | |
339 | == numeric_limits<max_size_t>::digits - 1); | |
340 | static_assert(numeric_limits<max_diff_t>::digits10 | |
341 | == numeric_limits<max_size_t>::digits10); | |
342 | // We can't unconditionally use numeric_limits here because __int128 is an | |
343 | // integral type only in GNU mode. | |
344 | #if __SIZEOF_INT128__ | |
345 | static_assert(numeric_limits<max_diff_t>::min() == -max_diff_t(~rep_t(0))-1); | |
346 | static_assert(numeric_limits<max_diff_t>::max() == ~rep_t(0)); | |
347 | #else | |
348 | static_assert(numeric_limits<max_diff_t>::min() | |
349 | == -max_diff_t(numeric_limits<rep_t>::max())-1); | |
350 | static_assert(numeric_limits<max_diff_t>::max() | |
351 | == numeric_limits<rep_t>::max()); | |
352 | #endif | |
353 | static_assert(numeric_limits<max_diff_t>::lowest() | |
354 | == numeric_limits<max_diff_t>::min()); | |
355 | static_assert(max_diff_t(max_size_t(1) | |
356 | << (numeric_limits<max_size_t>::digits-1)) | |
357 | == numeric_limits<max_diff_t>::min()); | |
358 | ||
359 | int | |
360 | main() | |
361 | { | |
362 | test01(); | |
363 | ||
364 | test02<false,false>(); | |
365 | test02<false,true>(); | |
366 | test02<true,false>(); | |
367 | test02<true,true>(); | |
368 | ||
369 | test03<false,false>(); | |
370 | test03<false,true>(); | |
371 | test03<true,false>(); | |
372 | test03<true,true>(); | |
373 | ||
374 | test04(); | |
375 | test05(); | |
376 | } |