]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / std / ranges / iota / max_size_type.cc
1 // Copyright (C) 2020-2024 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-do run { target c++20 } }
19 // { dg-timeout-factor 4 }
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 #if __SIZEOF_INT128__
29 using signed_rep_t = __int128;
30 #else
31 using signed_rep_t = long long;
32 #endif
33
34 static_assert(sizeof(max_size_t) == sizeof(max_diff_t));
35 static_assert(sizeof(rep_t) == sizeof(signed_rep_t));
36
37 static_assert(std::regular<max_size_t>);
38 static_assert(std::totally_ordered<max_size_t>);
39
40 static_assert(std::regular<max_diff_t>);
41 static_assert(std::totally_ordered<max_diff_t>);
42
43 // We can't use numeric_limits<rep_t>::max() here because __int128 is an
44 // integral type only in GNU mode.
45 constexpr max_size_t mu = max_size_t(~rep_t(0));
46 constexpr max_size_t ou = 1;
47 constexpr max_diff_t ns = -1;
48
49 void
50 test01()
51 {
52 static_assert(max_size_t(7) % 3 == 1);
53 static_assert(max_size_t(7) % 4 == 3);
54
55 static_assert(-max_diff_t(1) == max_diff_t(-1));
56 static_assert(max_diff_t(3) % 2 == 1);
57 static_assert(max_diff_t(-3) / 2 == -1);
58 static_assert(max_diff_t(-3) % 2 == -1);
59 static_assert(max_diff_t(3) % -2 == 1);
60 static_assert(max_diff_t(-3) << 1 == -6);
61 static_assert(max_diff_t(-3) >> 1 == -2);
62 static_assert(max_diff_t(-3) >> 2 == -1);
63 static_assert(max_diff_t(-3) >> 10 == -1);
64 static_assert(max_diff_t(3) >> 1 == 1);
65 static_assert(max_diff_t(3) >> 2 == 0);
66
67 static_assert(max_diff_t(-5) / 3 == -1);
68 static_assert(max_diff_t(5) / -3 == -1);
69 static_assert(max_diff_t(-5) / -3 == 1);
70 static_assert(max_diff_t(5) / 3 == 1);
71
72 static_assert(max_diff_t(-6) / 3 == -2);
73 static_assert(max_diff_t(6) / -3 == -2);
74 static_assert(max_diff_t(-6) / -3 == 2);
75 static_assert(max_diff_t(6) / 3 == 2);
76
77 static_assert(~max_size_t(-3) == 2);
78 static_assert(~max_diff_t(-3) == 2);
79
80 static_assert(max_diff_t(1) < max_diff_t(3));
81 static_assert(max_diff_t(-1) < max_diff_t(3));
82 static_assert(max_diff_t(1) > max_diff_t(-3));
83 static_assert(max_diff_t(-1) > max_diff_t(-3));
84
85 static_assert(max_diff_t(mu)/-1 == -max_diff_t(mu));
86 static_assert(-max_diff_t(mu)/1 == -max_diff_t(mu));
87 static_assert(max_diff_t(mu)>>1 == max_diff_t(mu)/2);
88 static_assert(-max_diff_t(mu+1) == max_diff_t(mu+1));
89 static_assert(-(mu+1) == mu+1);
90 static_assert((mu+1)<<1 == 0);
91 static_assert(max_diff_t(mu+1)<<1 == 0);
92 static_assert(max_diff_t(mu+1)>>1 < 0);
93
94 static_assert(int(max_diff_t(mu+1)) == 0);
95 static_assert(rep_t(max_diff_t(mu+1)) == 0);
96 static_assert(int(max_diff_t(mu)) == -1);
97 static_assert(rep_t(max_diff_t(mu)) == rep_t(-1));
98
99 static_assert(2*mu+1 > 2*mu);
100 static_assert(~(2*mu+1) == 0);
101 static_assert(mu/mu == 1);
102 static_assert(2*mu > mu);
103 static_assert(2*mu-mu == mu);
104 static_assert((2*mu)/mu == 2);
105 static_assert((2*mu+1)/mu == 2);
106 static_assert((2*mu-1)/(mu-1) == 2);
107 static_assert((2*mu-1)/mu == 1);
108 static_assert((2*mu+-1)/mu == 1);
109 static_assert(2*mu-1 < 2*mu);
110 static_assert(2*mu-1 <= 2*mu);
111 static_assert(2*mu+1 > 2*mu);
112 static_assert(2*mu+1 >= 2*mu);
113 static_assert((2*mu)/1 == 2*mu);
114 static_assert(mu/mu-1 == 0);
115 static_assert(mu*0 == 0);
116 static_assert((2*mu-1)*0 == 0);
117 static_assert((2*mu-1)>>1 == mu-1);
118 static_assert(mu+-1+1 == mu);
119 static_assert(mu+1+-1 == mu);
120 static_assert(mu+1);
121 static_assert((2*mu)/2 == mu);
122 static_assert((2*mu)>>1 == mu);
123 static_assert((mu<<1)>>1 == mu);
124 static_assert(1/mu == 0);
125 static_assert(mu/1 == mu);
126 static_assert(((mu+1)|mu) == -1);
127 static_assert((mu+1)+(mu+1) < mu+1);
128
129 static_assert(max_size_t(ns) == -1);
130 static_assert(-max_diff_t(ou) == -1);
131 static_assert(-max_diff_t(-ou) == 1);
132 static_assert(max_size_t(-max_diff_t(-ou)) == 1);
133 static_assert(ns*ns == max_diff_t(ou));
134 static_assert(max_size_t(ns)*max_size_t(ns) == ou);
135 static_assert(-max_diff_t(0) == max_diff_t(0));
136 static_assert(-ou-ou == -2*ou);
137
138 static_assert(int(ns) == -1);
139 static_assert(rep_t(ns) == rep_t(-1));
140
141 static_assert(max_size_t() == 0);
142 static_assert(max_diff_t() == 0);
143
144 auto f = [] (auto a) { a /= a; return a; };
145 static_assert(f(max_size_t(5)) == 1);
146 static_assert(f(max_size_t(-5)) == 1);
147 static_assert(f(max_diff_t(5)) == 1);
148
149 auto g = [] (auto a) { a >>= a; return a; };
150 static_assert(g(max_size_t(5)) == 0);
151 static_assert(g(max_diff_t(5)) == 0);
152
153 auto h = [] (auto a) { a <<= a; return a; };
154 static_assert(h(max_size_t(3)) == 24);
155 static_assert(h(max_diff_t(3)) == 24);
156
157 auto w = [] (auto a) {
158 const auto b = a;
159 VERIFY( a++ == b && a == b+1 );
160 VERIFY( a-- == b+1 && a == b );
161
162 VERIFY( ++(++a) == b+2 );
163 VERIFY( --(--a) == b );
164 return true;
165 };
166 static_assert(w(max_size_t(10)));
167 static_assert(w(-max_diff_t(10)));
168
169 #if __cpp_lib_three_way_comparison
170 static_assert(max_size_t{1} <=> max_size_t{9} == std::strong_ordering::less);
171 static_assert(max_size_t{3} <=> max_size_t{2} == std::strong_ordering::greater);
172 static_assert(max_size_t{5} <=> max_size_t{5} == std::strong_ordering::equal);
173 static_assert(~max_size_t{1} <=> ~max_size_t{9} == std::strong_ordering::greater);
174 static_assert(~max_size_t{3} <=> ~max_size_t{2} == std::strong_ordering::less);
175 static_assert(~max_size_t{5} <=> ~max_size_t{5} == std::strong_ordering::equal);
176 static_assert(~max_size_t{5} <=> max_size_t{9} == std::strong_ordering::greater);
177 static_assert(~max_size_t{9} <=> max_size_t{5} == std::strong_ordering::greater);
178 static_assert(max_size_t{5} <=> ~max_size_t{9} == std::strong_ordering::less);
179 static_assert(max_size_t{9} <=> ~max_size_t{5} == std::strong_ordering::less);
180
181 static_assert(max_diff_t{1} <=> max_diff_t{9} == std::strong_ordering::less);
182 static_assert(max_diff_t{3} <=> max_diff_t{2} == std::strong_ordering::greater);
183 static_assert(max_diff_t{5} <=> max_diff_t{5} == std::strong_ordering::equal);
184 static_assert(max_diff_t{-1} <=> max_diff_t{-9} == std::strong_ordering::greater);
185 static_assert(max_diff_t{-3} <=> max_diff_t{-2} == std::strong_ordering::less);
186 static_assert(max_diff_t{-5} <=> max_diff_t{-5} == std::strong_ordering::equal);
187 static_assert(max_diff_t{-5} <=> max_diff_t{9} == std::strong_ordering::less);
188 static_assert(max_diff_t{-9} <=> max_diff_t{5} == std::strong_ordering::less);
189 static_assert(max_diff_t{5} <=> max_diff_t{-9} == std::strong_ordering::greater);
190 static_assert(max_diff_t{9} <=> max_diff_t{-5} == std::strong_ordering::greater);
191 #endif
192 }
193
194 template<bool signed_p, bool shorten_p>
195 void
196 test02()
197 {
198 using hw_type = std::conditional_t<signed_p, signed_rep_t, rep_t>;
199 using max_type = std::conditional_t<signed_p, max_diff_t, max_size_t>;
200 using shorten_type = std::conditional_t<shorten_p, hw_type, max_type>;
201 const int hw_type_bit_size = sizeof(hw_type) * __CHAR_BIT__;
202 const unsigned limit = 100;
203 const int log2_limit = 7;
204 static_assert((1 << log2_limit) >= limit);
205 const int min = (signed_p ? -limit : 0);
206 const int max = limit;
207 for (hw_type i = min; i <= max; i++)
208 {
209 bool ok = true;
210 if (signed_p || shorten_p)
211 {
212 ok &= (~i == shorten_type(~max_type(i)));
213 ok &= (-i == shorten_type(-max_type(i)));
214 }
215 for (hw_type j = min; j <= max; j++)
216 {
217 ok &= (i*j == shorten_type(max_type(i)*j));
218 ok &= (i+j == shorten_type(max_type(i)+j));
219 if (j != 0)
220 {
221 ok &= (i/j == shorten_type(max_type(i)/j));
222 ok &= (i%j == shorten_type(max_type(i)%j));
223 }
224 if (signed_p || shorten_p)
225 ok &= (i-j == shorten_type(max_type(i)-j));
226 ok &= ((i&j) == shorten_type(max_type(i)&j));
227 ok &= ((i|j) == shorten_type(max_type(i)|j));
228 ok &= ((i^j) == shorten_type(max_type(i)^j));
229 if (j >= 0 && j < hw_type(hw_type_bit_size)
230 && (shorten_p || j < hw_type(hw_type_bit_size) - log2_limit))
231 {
232 ok &= ((i>>j) == shorten_type(max_type(i)>>j));
233 ok &= ((i<<j) == shorten_type(max_type(i)<<j));
234 }
235 ok &= (i>j) == (max_type(i) > j);
236 ok &= (i<j) == (max_type(i) < j);
237 ok &= (i>=j) == (max_type(i) >= j);
238 ok &= (i<=j) == (max_type(i) <= j);
239 ok &= (i==j) == (max_type(i) == j);
240 ok &= (i!=j) == (max_type(i) != j);
241 if (!ok)
242 {
243 fprintf(stderr,
244 "Inconsistency found: %d %d %lld %lld\n",
245 signed_p, shorten_p, (long long)i, (long long)j) ;
246 VERIFY(0);
247 }
248 }
249 }
250 }
251
252 template<bool signed_p, bool toggle_base_p>
253 void
254 test03()
255 {
256 using hw_type = std::conditional_t<signed_p, signed_rep_t, rep_t>;
257 using max_type = std::conditional_t<signed_p, max_diff_t, max_size_t>;
258 using base_type = std::conditional_t<toggle_base_p, hw_type, max_type>;
259 constexpr int hw_type_bit_size = sizeof(hw_type) * __CHAR_BIT__;
260 constexpr unsigned limit = 100;
261 constexpr int log2_limit = 7;
262 static_assert((1 << log2_limit) >= limit);
263 const int min = (signed_p ? -limit : 0);
264 const int max = limit;
265 for (hw_type i = min; i <= max; i++)
266 {
267 bool ok = true;
268 base_type k;
269 for (hw_type j = min; j <= max; j++)
270 {
271 k = i; k *= j;
272 ok &= (k == (max_type(i)*j));
273 k = i; k += j;
274 ok &= (k == (max_type(i)+j));
275 if (j != 0)
276 {
277 k = i; k /= j;
278 ok &= (k == (max_type(i)/j));
279 k = i; k %= j;
280 ok &= (k == (max_type(i)%j));
281 }
282 if (signed_p)
283 {
284 k = i; k -= j;
285 ok &= (k == (max_type(i)-j));
286 }
287 k = i; k &= j;
288 ok &= (k == (max_type(i)&j));
289 k = i; k |= j;
290 ok &= (k == (max_type(i)|j));
291 k = i; k ^= j;
292 ok &= (k == (max_type(i)^j));
293 if (j >= 0 && j < hw_type(hw_type_bit_size)
294 && (!toggle_base_p || j < hw_type(hw_type_bit_size) - log2_limit))
295 {
296 k = i; k >>= j;
297 ok &= (k == (max_type(i)>>j));
298 k = i; k <<= j;
299 ok &= (k == (max_type(i)<<j));
300 }
301 if (!ok)
302 {
303 fprintf(stderr,
304 "Inconsistency found: %d %d %lld %lld\n",
305 signed_p, toggle_base_p, (long long)i, (long long)j) ;
306 VERIFY(0);
307 }
308 }
309 }
310 }
311
312 void
313 test04()
314 {
315 constexpr int limit = 1000;
316 for (int i = -limit; i <= limit; i++)
317 {
318 VERIFY( -max_size_t(-i) == i );
319 for (int j = i; j <= limit; j++)
320 {
321 VERIFY( max_size_t(-i) * max_size_t(-j) == i*j );
322 VERIFY( max_size_t(-j) * max_size_t(-i) == j*i );
323 VERIFY( rep_t(((mu+1)+i)*((mu+1)+j)) == rep_t(i*j) );
324 VERIFY( rep_t(((mu+1)+j)*((mu+1)+i)) == rep_t(j*i) );
325 if (i >= 0 && j > 0)
326 {
327 auto r = (mu+i)-((mu+i)/j)*j;
328 VERIFY( r >= 0 && r < j );
329 VERIFY( r == (mu+i)%j );
330 }
331 }
332 }
333 }
334
335 void
336 test05()
337 {
338 #if __SIZEOF_INT128__
339 max_size_t x = 0;
340 x = static_cast<__int128>(0);
341 x = static_cast<unsigned __int128>(0);
342
343 max_diff_t y = 0;
344 y = static_cast<__int128>(0);;
345 y = static_cast<unsigned __int128>(0);
346 #endif
347 }
348
349 using std::numeric_limits;
350
351 static_assert(numeric_limits<max_size_t>::is_specialized);
352 static_assert(!numeric_limits<max_size_t>::is_signed);
353 static_assert(numeric_limits<max_size_t>::is_integer);
354 static_assert(numeric_limits<max_size_t>::is_exact);
355 // We can't unconditionally use numeric_limits here because __int128 is an
356 // integral type only in GNU mode.
357 #if __SIZEOF_INT128__
358 static_assert(numeric_limits<max_size_t>::digits == 129);
359 static_assert(numeric_limits<max_size_t>::digits10 == 38);
360 static_assert(numeric_limits<max_size_t>::max()
361 == 2*max_size_t(~rep_t(0)) + 1);
362 #else
363 static_assert(numeric_limits<max_size_t>::digits
364 == numeric_limits<rep_t>::digits + 1);
365 static_assert(numeric_limits<max_size_t>::digits10
366 == numeric_limits<rep_t>::digits10);
367 static_assert(numeric_limits<max_size_t>::max()
368 == 2*max_size_t(numeric_limits<rep_t>::max())+1);
369 #endif
370 static_assert(numeric_limits<max_size_t>::min() == 0);
371 static_assert(numeric_limits<max_size_t>::max()
372 == max_size_t(-1));
373 static_assert((numeric_limits<max_size_t>::max()
374 >> (numeric_limits<max_size_t>::digits-1)) == 1);
375 static_assert(numeric_limits<max_size_t>::lowest()
376 == numeric_limits<max_size_t>::min());
377
378 static_assert(numeric_limits<max_diff_t>::is_specialized);
379 static_assert(numeric_limits<max_diff_t>::is_signed);
380 static_assert(numeric_limits<max_diff_t>::is_integer);
381 static_assert(numeric_limits<max_diff_t>::is_exact);
382 static_assert(numeric_limits<max_diff_t>::digits
383 == numeric_limits<max_size_t>::digits - 1);
384 static_assert(numeric_limits<max_diff_t>::digits10
385 == numeric_limits<max_size_t>::digits10);
386 // We can't unconditionally use numeric_limits here because __int128 is an
387 // integral type only in GNU mode.
388 #if __SIZEOF_INT128__
389 static_assert(numeric_limits<max_diff_t>::min() == -max_diff_t(~rep_t(0))-1);
390 static_assert(numeric_limits<max_diff_t>::max() == ~rep_t(0));
391 #else
392 static_assert(numeric_limits<max_diff_t>::min()
393 == -max_diff_t(numeric_limits<rep_t>::max())-1);
394 static_assert(numeric_limits<max_diff_t>::max()
395 == numeric_limits<rep_t>::max());
396 #endif
397 static_assert(numeric_limits<max_diff_t>::lowest()
398 == numeric_limits<max_diff_t>::min());
399 static_assert(max_diff_t(max_size_t(1)
400 << (numeric_limits<max_size_t>::digits-1))
401 == numeric_limits<max_diff_t>::min());
402
403 int
404 main()
405 {
406 test01();
407
408 test02<false,false>();
409 test02<false,true>();
410 test02<true,false>();
411 test02<true,true>();
412
413 test03<false,false>();
414 test03<false,true>();
415 test03<true,false>();
416 test03<true,true>();
417
418 test04();
419 test05();
420 }