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