]> 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-2021 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 }