]>
git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc
1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
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)
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.
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/>.
18 // { dg-do run { target c++20 } }
19 // { dg-timeout-factor 4 }
23 #include <testsuite_hooks.h>
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
;
29 using signed_rep_t
= __int128
;
31 using signed_rep_t
= long long;
34 static_assert(sizeof(max_size_t
) == sizeof(max_diff_t
));
35 static_assert(sizeof(rep_t
) == sizeof(signed_rep_t
));
37 static_assert(std::regular
<max_size_t
>);
38 static_assert(std::totally_ordered
<max_size_t
>);
40 static_assert(std::regular
<max_diff_t
>);
41 static_assert(std::totally_ordered
<max_diff_t
>);
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;
52 static_assert(max_size_t(7) % 3 == 1);
53 static_assert(max_size_t(7) % 4 == 3);
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);
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);
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);
77 static_assert(~max_size_t(-3) == 2);
78 static_assert(~max_diff_t(-3) == 2);
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));
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);
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));
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
);
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);
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
);
138 static_assert(int(ns
) == -1);
139 static_assert(rep_t(ns
) == rep_t(-1));
141 static_assert(max_size_t() == 0);
142 static_assert(max_diff_t() == 0);
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);
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);
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);
157 auto w
= [] (auto a
) {
159 VERIFY( a
++ == b
&& a
== b
+1 );
160 VERIFY( a
-- == b
+1 && a
== b
);
162 VERIFY( ++(++a
) == b
+2 );
163 VERIFY( --(--a
) == b
);
166 static_assert(w(max_size_t(10)));
167 static_assert(w(-max_diff_t(10)));
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
);
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
);
194 template<bool signed_p
, bool shorten_p
>
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
++)
210 if (signed_p
|| shorten_p
)
212 ok
&= (~i
== shorten_type(~max_type(i
)));
213 ok
&= (-i
== shorten_type(-max_type(i
)));
215 for (hw_type j
= min
; j
<= max
; j
++)
217 ok
&= (i
*j
== shorten_type(max_type(i
)*j
));
218 ok
&= (i
+j
== shorten_type(max_type(i
)+j
));
221 ok
&= (i
/j
== shorten_type(max_type(i
)/j
));
222 ok
&= (i
%j
== shorten_type(max_type(i
)%j
));
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
))
232 ok
&= ((i
>>j
) == shorten_type(max_type(i
)>>j
));
233 ok
&= ((i
<<j
) == shorten_type(max_type(i
)<<j
));
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
);
244 "Inconsistency found: %d %d %lld %lld\n",
245 signed_p
, shorten_p
, (long long)i
, (long long)j
) ;
252 template<bool signed_p
, bool toggle_base_p
>
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
++)
269 for (hw_type j
= min
; j
<= max
; j
++)
272 ok
&= (k
== (max_type(i
)*j
));
274 ok
&= (k
== (max_type(i
)+j
));
278 ok
&= (k
== (max_type(i
)/j
));
280 ok
&= (k
== (max_type(i
)%j
));
285 ok
&= (k
== (max_type(i
)-j
));
288 ok
&= (k
== (max_type(i
)&j
));
290 ok
&= (k
== (max_type(i
)|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
))
297 ok
&= (k
== (max_type(i
)>>j
));
299 ok
&= (k
== (max_type(i
)<<j
));
304 "Inconsistency found: %d %d %lld %lld\n",
305 signed_p
, toggle_base_p
, (long long)i
, (long long)j
) ;
315 constexpr int limit
= 1000;
316 for (int i
= -limit
; i
<= limit
; i
++)
318 VERIFY( -max_size_t(-i
) == i
);
319 for (int j
= i
; j
<= limit
; j
++)
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
) );
327 auto r
= (mu
+i
)-((mu
+i
)/j
)*j
;
328 VERIFY( r
>= 0 && r
< j
);
329 VERIFY( r
== (mu
+i
)%j
);
338 #if __SIZEOF_INT128__
340 x
= static_cast<__int128
>(0);
341 x
= static_cast<unsigned __int128
>(0);
344 y
= static_cast<__int128
>(0);;
345 y
= static_cast<unsigned __int128
>(0);
349 using std::numeric_limits
;
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);
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);
370 static_assert(numeric_limits
<max_size_t
>::min() == 0);
371 static_assert(numeric_limits
<max_size_t
>::max()
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());
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));
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());
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());
408 test02
<false,false>();
409 test02
<false,true>();
410 test02
<true,false>();
413 test03
<false,false>();
414 test03
<false,true>();
415 test03
<true,false>();