1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
10
11 // <numeric>
12
13 // template<class R, class T>
14 // constexpr R saturate_cast(T x) noexcept; // freestanding
15
16 #include <cassert>
17 #include <climits>
18 #include <concepts>
19 #include <limits>
20 #include <numeric>
21
22 #include "test_macros.h"
23 #include <print>
24
25 // Smaller to larger
26 static_assert(noexcept(std::saturate_cast<signed int>(std::numeric_limits<signed char>::max())));
27 static_assert(noexcept(std::saturate_cast<signed int>(std::numeric_limits<unsigned char>::max())));
28
29 static_assert(noexcept(std::saturate_cast<unsigned int>(std::numeric_limits<signed char>::max())));
30 static_assert(noexcept(std::saturate_cast<unsigned int>(std::numeric_limits<unsigned char>::max())));
31
32 // Same type
33 static_assert(noexcept(std::saturate_cast<signed long int>(std::numeric_limits<signed long int>::max())));
34 static_assert(noexcept(std::saturate_cast<unsigned long int>(std::numeric_limits<unsigned long int>::max())));
35
36 // Larger to smaller
37 static_assert(noexcept(std::saturate_cast<signed char>(std::numeric_limits<signed int>::max())));
38 static_assert(noexcept(std::saturate_cast<signed char>(std::numeric_limits<unsigned int>::max())));
39
40 static_assert(noexcept(std::saturate_cast<unsigned char>(std::numeric_limits<signed int>::max())));
41 static_assert(noexcept(std::saturate_cast<unsigned char>(std::numeric_limits<unsigned int>::max())));
42
43 // Tests
44
test()45 constexpr bool test() {
46 // clang-format off
47
48 #ifndef TEST_HAS_NO_INT128
49 using SIntT = __int128_t;
50 using UIntT = __uint128_t;
51 #else
52 using SIntT = long long int;
53 using UIntT = unsigned long long int;
54 #endif
55
56 // Constants the values of which depend on the context (platform)
57
58 constexpr auto sBigMin = std::numeric_limits<SIntT>::min();
59 constexpr auto sZero = SIntT{0};
60 constexpr auto sBigMax = std::numeric_limits<SIntT>::max();
61
62 constexpr auto uZero = UIntT{0};
63 constexpr auto uBigMax = std::numeric_limits<UIntT>::max();
64
65 // Constants to avoid casting in place
66
67 constexpr auto O_C = static_cast<signed char>(0);
68 constexpr auto O_UC = static_cast<unsigned char>(0);
69
70 constexpr auto O_S = static_cast<signed short int>(0);
71 constexpr auto O_US = static_cast<unsigned short int>(0);
72
73 // signed char
74
75 // TODO(LLVM-20) remove [[maybe_unused]] and `{}` scope since all supported compilers support "Placeholder variables with no name",
76 // here and below...
77 { [[maybe_unused]] std::same_as<signed char> decltype(auto) _ = std::saturate_cast<signed char>(SCHAR_MAX); }
78 assert(std::saturate_cast<signed char>(SCHAR_MIN) == SCHAR_MIN);
79 assert(std::saturate_cast<signed char>( O_C) == O_C);
80 assert(std::saturate_cast<signed char>(SCHAR_MAX) == SCHAR_MAX);
81
82 { [[maybe_unused]] std::same_as<signed char> decltype(auto) _ = std::saturate_cast<signed char>(UCHAR_MAX); }
83 assert(std::saturate_cast<signed char>( O_UC) == O_C);
84 assert(std::saturate_cast<signed char>(UCHAR_MAX) == SCHAR_MAX);
85
86 { [[maybe_unused]] std::same_as<signed char> decltype(auto) _ = std::saturate_cast<signed char>(sBigMax); }
87 assert(std::saturate_cast<signed char>(sBigMin) == SCHAR_MIN); // saturated
88 assert(std::saturate_cast<signed char>( sZero) == O_C);
89 assert(std::saturate_cast<signed char>(sBigMax) == SCHAR_MAX); // saturated
90
91 { [[maybe_unused]] std::same_as<signed char> decltype(auto) _ = std::saturate_cast<signed char>(uBigMax); }
92 assert(std::saturate_cast<signed char>( uZero) == O_C);
93 assert(std::saturate_cast<signed char>(uBigMax) == SCHAR_MAX); // saturated
94
95 // short
96
97 { [[maybe_unused]] std::same_as<signed short int> decltype(auto) _ = std::saturate_cast<signed short int>(SCHAR_MAX); }
98 assert(std::saturate_cast<signed short int>(SCHAR_MIN) == static_cast<signed short int>(SCHAR_MIN));
99 assert(std::saturate_cast<signed short int>( O_C) == O_S);
100 assert(std::saturate_cast<signed short int>(SCHAR_MAX) == static_cast<signed short int>(SCHAR_MAX));
101
102 { [[maybe_unused]] std::same_as<signed short int> decltype(auto) _ = std::saturate_cast<signed short int>(UCHAR_MAX); }
103 assert(std::saturate_cast<signed short int>( O_UC) == O_S);
104 assert(std::saturate_cast<signed short int>(UCHAR_MAX) == static_cast<signed short int>(UCHAR_MAX));
105
106 { [[maybe_unused]] std::same_as<signed short int> decltype(auto) _ = std::saturate_cast<signed short int>(SHRT_MAX); }
107 assert(std::saturate_cast<signed short int>( SHRT_MIN) == SHRT_MIN);
108 assert(std::saturate_cast<signed short int>( O_S) == O_S);
109 assert(std::saturate_cast<signed short int>( SHRT_MAX) == SHRT_MAX);
110
111 { [[maybe_unused]] std::same_as<signed short int> decltype(auto) _ = std::saturate_cast<signed short int>(USHRT_MAX); }
112 assert(std::saturate_cast<signed short int>( O_US) == O_S);
113 assert(std::saturate_cast<signed short int>(USHRT_MAX) == SHRT_MAX); // saturated
114
115 { [[maybe_unused]] std::same_as<signed short int> decltype(auto) _ = std::saturate_cast<signed short int>(sBigMax); }
116 assert(std::saturate_cast<signed short int>( sBigMin) == SHRT_MIN); // saturated
117 assert(std::saturate_cast<signed short int>( sZero) == O_S);
118 assert(std::saturate_cast<signed short int>( sBigMax) == SHRT_MAX); // saturated
119
120 { [[maybe_unused]] std::same_as<signed short int> decltype(auto) _ = std::saturate_cast<signed short int>(uBigMax); }
121 assert(std::saturate_cast<signed short int>( uZero) == O_S);
122 assert(std::saturate_cast<signed short int>( uBigMax) == SHRT_MAX); // saturated
123
124 // int
125
126 { [[maybe_unused]] std::same_as<signed int> decltype(auto) _ = std::saturate_cast<signed int>(SCHAR_MAX); }
127 assert(std::saturate_cast<signed int>(SCHAR_MIN) == static_cast<signed int>(SCHAR_MIN));
128 assert(std::saturate_cast<signed int>( O_C) == 0);
129 assert(std::saturate_cast<signed int>(SCHAR_MAX) == static_cast<signed int>(SCHAR_MAX));
130
131 { [[maybe_unused]] std::same_as<signed int> decltype(auto) _ = std::saturate_cast<signed int>(UCHAR_MAX); }
132 assert(std::saturate_cast<signed int>( O_UC) == 0);
133 assert(std::saturate_cast<signed int>(UCHAR_MAX) == static_cast<signed int>(UCHAR_MAX));
134
135 { [[maybe_unused]] std::same_as<signed int> decltype(auto) _ = std::saturate_cast<signed int>(INT_MAX); }
136 assert(std::saturate_cast<signed int>( INT_MIN) == INT_MIN);
137 assert(std::saturate_cast<signed int>( 0) == 0);
138 assert(std::saturate_cast<signed int>( INT_MAX) == INT_MAX);
139
140 { [[maybe_unused]] std::same_as<signed int> decltype(auto) _ = std::saturate_cast<signed int>(UINT_MAX); }
141 assert(std::saturate_cast<signed int>( 0) == 0);
142 assert(std::saturate_cast<signed int>(UINT_MAX) == INT_MAX); // saturated
143
144 { [[maybe_unused]] std::same_as<signed int> decltype(auto) _ = std::saturate_cast<signed int>(sBigMax); }
145 assert(std::saturate_cast<signed int>( sBigMin) == INT_MIN); // saturated
146 assert(std::saturate_cast<signed int>( sZero) == 0);
147 assert(std::saturate_cast<signed int>( sBigMax) == INT_MAX); // saturated
148
149 { [[maybe_unused]] std::same_as<signed int> decltype(auto) _ = std::saturate_cast<signed int>(uBigMax); }
150 assert(std::saturate_cast<signed int>( uZero) == 0);
151 assert(std::saturate_cast<signed int>( uBigMax) == INT_MAX); // saturated
152
153 // long
154
155 { [[maybe_unused]] std::same_as<signed long int> decltype(auto) _ = std::saturate_cast<signed long int>(SCHAR_MAX); }
156 assert(std::saturate_cast<signed long int>(SCHAR_MIN) == static_cast<signed long int>(SCHAR_MIN));
157 assert(std::saturate_cast<signed long int>( O_C) == 0L);
158 assert(std::saturate_cast<signed long int>(SCHAR_MAX) == static_cast<signed long int>(SCHAR_MAX));
159
160 { [[maybe_unused]] std::same_as<signed long int> decltype(auto) _ = std::saturate_cast<signed long int>(UCHAR_MAX); }
161 assert(std::saturate_cast<signed long int>( O_UC) == 0L);
162 assert(std::saturate_cast<signed long int>(UCHAR_MAX) == static_cast<signed long int>(UCHAR_MAX));
163
164 { [[maybe_unused]] std::same_as<signed long int> decltype(auto) _ = std::saturate_cast<signed long int>(LONG_MAX); }
165 assert(std::saturate_cast<signed long int>( LONG_MIN) == LONG_MIN);
166 assert(std::saturate_cast<signed long int>( 0L) == 0L);
167 assert(std::saturate_cast<signed long int>( LONG_MAX) == LONG_MAX);
168
169 { [[maybe_unused]] std::same_as<signed long int> decltype(auto) _ = std::saturate_cast<signed long int>(ULONG_MAX); }
170 assert(std::saturate_cast<signed long int>( 0UL) == 0L);
171 assert(std::saturate_cast<signed long int>(ULONG_MAX) == LONG_MAX); // saturated
172
173 { [[maybe_unused]] std::same_as<signed long int> decltype(auto) _ = std::saturate_cast<signed long int>(sBigMax); }
174 assert(std::saturate_cast<signed long int>( sBigMin) == LONG_MIN); // saturated
175 assert(std::saturate_cast<signed long int>( sZero) == 0L);
176 assert(std::saturate_cast<signed long int>( sBigMax) == LONG_MAX); // saturated
177
178 { [[maybe_unused]] std::same_as<signed long int> decltype(auto) _ = std::saturate_cast<signed long int>(uBigMax); }
179 assert(std::saturate_cast<signed long int>( uZero) == 0L);
180 assert(std::saturate_cast<signed long int>( uBigMax) == LONG_MAX); // saturated
181
182 // long long
183
184 { [[maybe_unused]] std::same_as<signed long long int> decltype(auto) _ = std::saturate_cast<signed long long int>(SCHAR_MAX); }
185 assert(std::saturate_cast<signed long long int>(SCHAR_MIN) == static_cast<signed long long int>(SCHAR_MIN));
186 assert(std::saturate_cast<signed long long int>( 0LL) == 0LL);
187 assert(std::saturate_cast<signed long long int>(SCHAR_MAX) == static_cast<signed long long int>(SCHAR_MAX));
188
189 { [[maybe_unused]] std::same_as<signed long long int> decltype(auto) _ = std::saturate_cast<signed long long int>(UCHAR_MAX); }
190 assert(std::saturate_cast<signed long long int>( O_UC) == 0LL);
191 assert(std::saturate_cast<signed long long int>(UCHAR_MAX) == static_cast<signed long long int>(UCHAR_MAX));
192
193 { [[maybe_unused]] std::same_as<signed long long int> decltype(auto) _ = std::saturate_cast<signed long long int>(LLONG_MIN); }
194 assert(std::saturate_cast<signed long long int>(LLONG_MIN) == LLONG_MIN);
195 assert(std::saturate_cast<signed long long int>( 0LL) == 0LL);
196 assert(std::saturate_cast<signed long long int>(LLONG_MAX) == LLONG_MAX);
197
198 { [[maybe_unused]] std::same_as<signed long long int> decltype(auto) _ = std::saturate_cast<signed long long int>(ULLONG_MAX); }
199 assert(std::saturate_cast<signed long long int>( 0ULL) == 0LL);
200 assert(std::saturate_cast<signed long long int>(ULLONG_MAX) == LLONG_MAX); // saturated
201
202 #ifndef TEST_HAS_NO_INT128
203 { [[maybe_unused]] std::same_as<signed long long int> decltype(auto) _ = std::saturate_cast<signed long long int>(sBigMax); }
204 assert(std::saturate_cast<signed long long int>( sBigMin) == LLONG_MIN); // (128-bit) saturated
205 assert(std::saturate_cast<signed long long int>( sZero) == 0LL);
206 assert(std::saturate_cast<signed long long int>( sBigMax) == LLONG_MAX); // (128-bit) saturated
207
208 { [[maybe_unused]] std::same_as<signed long long int> decltype(auto) _ = std::saturate_cast<signed long long int>(uBigMax); }
209 assert(std::saturate_cast<signed long long int>( uZero) == 0LL);
210 assert(std::saturate_cast<signed long long int>( uBigMax) == LLONG_MAX); // (128-bit) saturated
211
212 { [[maybe_unused]] std::same_as<__int128_t> decltype(auto) _ = std::saturate_cast<__int128_t>(SCHAR_MAX); }
213 assert(std::saturate_cast<__int128_t>(SCHAR_MIN) == static_cast<__int128_t>(SCHAR_MIN));
214 assert(std::saturate_cast<__int128_t>( O_C) == sZero);
215 assert(std::saturate_cast<__int128_t>(SCHAR_MAX) == static_cast<__int128_t>(SCHAR_MAX));
216
217 { [[maybe_unused]] std::same_as<__int128_t> decltype(auto) _ = std::saturate_cast<__int128_t>(UCHAR_MAX); }
218 assert(std::saturate_cast<__int128_t>( O_UC) == sZero);
219 assert(std::saturate_cast<__int128_t>(UCHAR_MAX) == static_cast<__int128_t>(UCHAR_MAX));
220
221 { [[maybe_unused]] std::same_as<__int128_t> decltype(auto) _ = std::saturate_cast<__int128_t>(sBigMax); }
222 assert(std::saturate_cast<__int128_t>( sBigMin) == sBigMin);
223 assert(std::saturate_cast<__int128_t>( sZero) == sZero);
224 assert(std::saturate_cast<__int128_t>( sBigMax) == sBigMax);
225
226 { [[maybe_unused]] std::same_as<__int128_t> decltype(auto) _ = std::saturate_cast<__int128_t>(uBigMax); }
227 assert(std::saturate_cast<__int128_t>( uZero) == sZero);
228 assert(std::saturate_cast<__int128_t>( uBigMax) == sBigMax); // saturated
229 #endif
230
231 // unsigned char
232
233 { [[maybe_unused]] std::same_as<unsigned char> decltype(auto) _ = std::saturate_cast<unsigned char>(SCHAR_MAX); }
234 assert(std::saturate_cast<unsigned char>(SCHAR_MIN) == O_UC);
235 assert(std::saturate_cast<unsigned char>( O_C) == O_UC);
236 assert(std::saturate_cast<unsigned char>(SCHAR_MAX) == static_cast<unsigned char>(SCHAR_MAX));
237
238 { [[maybe_unused]] std::same_as<unsigned char> decltype(auto) _ = std::saturate_cast<unsigned char>(UCHAR_MAX); }
239 assert(std::saturate_cast<unsigned char>( O_UC) == O_UC);
240 assert(std::saturate_cast<unsigned char>(UCHAR_MAX) == UCHAR_MAX);
241
242 { [[maybe_unused]] std::same_as<unsigned char> decltype(auto) _ = std::saturate_cast<unsigned char>(sBigMax); }
243 assert(std::saturate_cast<unsigned char>( sBigMin) == O_UC); // saturated
244 assert(std::saturate_cast<unsigned char>( sZero) == O_UC);
245 assert(std::saturate_cast<unsigned char>( sBigMax) == UCHAR_MAX); // saturated
246
247 { [[maybe_unused]] std::same_as<unsigned char> decltype(auto) _ = std::saturate_cast<unsigned char>(uBigMax); }
248 assert(std::saturate_cast<unsigned char>( uZero) == O_UC);
249 assert(std::saturate_cast<unsigned char>( uBigMax) == UCHAR_MAX); // saturated
250
251 // unsigned short
252
253 { [[maybe_unused]] std::same_as<unsigned short int> decltype(auto) _ = std::saturate_cast<unsigned short int>(SCHAR_MAX); }
254 assert(std::saturate_cast<unsigned short int>(SCHAR_MIN) == O_US);
255 assert(std::saturate_cast<unsigned short int>( O_C) == O_US);
256 assert(std::saturate_cast<unsigned short int>(SCHAR_MAX) == static_cast<unsigned short int>(SCHAR_MAX));
257
258 { [[maybe_unused]] std::same_as<unsigned short int> decltype(auto) _ = std::saturate_cast<unsigned short int>(UCHAR_MAX); }
259 assert(std::saturate_cast<unsigned short int>( O_UC) == O_US);
260 assert(std::saturate_cast<unsigned short int>(UCHAR_MAX) == static_cast<unsigned short int>(UCHAR_MAX));
261
262 { [[maybe_unused]] std::same_as<unsigned short int> decltype(auto) _ = std::saturate_cast<unsigned short int>(SCHAR_MIN); }
263 assert(std::saturate_cast<unsigned short int>( SHRT_MIN) == O_US);
264 assert(std::saturate_cast<unsigned short int>( O_S) == O_US);
265 assert(std::saturate_cast<unsigned short int>( SHRT_MAX) == static_cast<unsigned short int>(SHRT_MAX));
266
267 { [[maybe_unused]] std::same_as<unsigned short int> decltype(auto) _ = std::saturate_cast<unsigned short int>(UCHAR_MAX); }
268 assert(std::saturate_cast<unsigned short int>( O_US) == O_US);
269 assert(std::saturate_cast<unsigned short int>(USHRT_MAX) == USHRT_MAX);
270
271 { [[maybe_unused]] std::same_as<unsigned short int> decltype(auto) _ = std::saturate_cast<unsigned short int>(sBigMax); }
272 assert(std::saturate_cast<unsigned short int>( sBigMin) == O_US); // saturated
273 assert(std::saturate_cast<unsigned short int>( sZero) == O_US);
274 assert(std::saturate_cast<unsigned short int>( sBigMax) == USHRT_MAX); // saturated
275
276 { [[maybe_unused]] std::same_as<unsigned short int> decltype(auto) _ = std::saturate_cast<unsigned short int>(uBigMax); }
277 assert(std::saturate_cast<unsigned short int>( uZero) == O_US);
278 assert(std::saturate_cast<unsigned short int>( uBigMax) == USHRT_MAX); // saturated
279
280 // unsigned int
281
282 { [[maybe_unused]] std::same_as<unsigned int> decltype(auto) _ = std::saturate_cast<unsigned int>(SCHAR_MAX); }
283 assert(std::saturate_cast<unsigned int>(SCHAR_MIN) == O_US);
284 assert(std::saturate_cast<unsigned int>( O_UC) == 0U);
285 assert(std::saturate_cast<unsigned int>(SCHAR_MAX) == static_cast<unsigned int>(SCHAR_MAX));
286
287 { [[maybe_unused]] std::same_as<unsigned int> decltype(auto) _ = std::saturate_cast<unsigned int>(UCHAR_MAX); }
288 assert(std::saturate_cast<unsigned int>( O_UC) == 0U);
289 assert(std::saturate_cast<unsigned int>(UCHAR_MAX) == static_cast<unsigned int>(UCHAR_MAX));
290
291 { [[maybe_unused]] std::same_as<unsigned int> decltype(auto) _ = std::saturate_cast<unsigned int>(INT_MAX); }
292 assert(std::saturate_cast<unsigned int>( INT_MIN) == 0U);
293 assert(std::saturate_cast<unsigned int>( 0) == 0U);
294 assert(std::saturate_cast<unsigned int>( INT_MAX) == static_cast<unsigned int>(INT_MAX));
295
296 { [[maybe_unused]] std::same_as<unsigned int> decltype(auto) _ = std::saturate_cast<unsigned int>(UINT_MAX); }
297 assert(std::saturate_cast<unsigned int>( 0U) == 0U);
298 assert(std::saturate_cast<unsigned int>( UINT_MAX) == UINT_MAX);
299
300 { [[maybe_unused]] std::same_as<unsigned int> decltype(auto) _ = std::saturate_cast<unsigned int>(sBigMax); }
301 assert(std::saturate_cast<unsigned int>( sBigMin) == 0U); // saturated
302 assert(std::saturate_cast<unsigned int>( sZero) == 0U);
303 assert(std::saturate_cast<unsigned int>( sBigMax) == UINT_MAX); // saturated
304
305 { [[maybe_unused]] std::same_as<unsigned int> decltype(auto) _ = std::saturate_cast<unsigned int>(uBigMax); }
306 assert(std::saturate_cast<unsigned int>( uZero) == 0U);
307 assert(std::saturate_cast<unsigned int>( uBigMax) == UINT_MAX); // saturated
308
309 // unsigned long
310
311 { [[maybe_unused]] std::same_as<unsigned long int> decltype(auto) _ = std::saturate_cast<unsigned long int>(SCHAR_MAX); }
312 assert(std::saturate_cast<unsigned long int>(SCHAR_MIN) == 0UL);
313 assert(std::saturate_cast<unsigned long int>( O_C) == 0UL);
314 assert(std::saturate_cast<unsigned long int>(SCHAR_MAX) == static_cast<unsigned long int>(SCHAR_MAX));
315
316 { [[maybe_unused]] std::same_as<unsigned long int> decltype(auto) _ = std::saturate_cast<unsigned long int>(UCHAR_MAX); }
317 assert(std::saturate_cast<unsigned long int>( O_UC) == 0UL);
318 assert(std::saturate_cast<unsigned long int>(UCHAR_MAX) == static_cast<unsigned long int>(UCHAR_MAX));
319
320 { [[maybe_unused]] std::same_as<unsigned long int> decltype(auto) _ = std::saturate_cast<unsigned long int>(LONG_MAX); }
321 assert(std::saturate_cast<unsigned long int>( LONG_MIN) == 0UL);
322 assert(std::saturate_cast<unsigned long int>( 0L) == 0UL);
323 assert(std::saturate_cast<unsigned long int>( LONG_MAX) == static_cast<unsigned long int>(LONG_MAX));
324
325 { [[maybe_unused]] std::same_as<unsigned long int> decltype(auto) _ = std::saturate_cast<unsigned long int>(ULONG_MAX); }
326 assert(std::saturate_cast<unsigned long int>( 0UL) == 0UL);
327 assert(std::saturate_cast<unsigned long int>(ULONG_MAX) == ULONG_MAX);
328
329 { [[maybe_unused]] std::same_as<unsigned long int> decltype(auto) _ = std::saturate_cast<unsigned long int>(sBigMax); }
330 assert(std::saturate_cast<unsigned long int>( sBigMin) == 0UL); // saturated
331 assert(std::saturate_cast<unsigned long int>( sZero) == 0UL);
332 assert(std::saturate_cast<unsigned long int>( sBigMax) == (sizeof(UIntT) > sizeof(unsigned long int) ? ULONG_MAX : LONG_MAX)); // saturated depending on underlying types
333
334 { [[maybe_unused]] std::same_as<unsigned long int> decltype(auto) _ = std::saturate_cast<unsigned long int>(uBigMax); }
335 assert(std::saturate_cast<unsigned long int>( uZero) == 0UL);
336 assert(std::saturate_cast<unsigned long int>( uBigMax) == ULONG_MAX); // saturated
337
338 // unsigned long long
339
340 { [[maybe_unused]] std::same_as<unsigned long long int> decltype(auto) _ = std::saturate_cast<unsigned long long int>(SCHAR_MAX); }
341 assert(std::saturate_cast<unsigned long long int>( SCHAR_MIN) == 0ULL);
342 assert(std::saturate_cast<unsigned long long int>( O_C) == 0ULL);
343 assert(std::saturate_cast<unsigned long long int>( SCHAR_MAX) == static_cast<unsigned long long int>(SCHAR_MAX));
344
345 { [[maybe_unused]] std::same_as<unsigned long long int> decltype(auto) _ = std::saturate_cast<unsigned long long int>(UCHAR_MAX); }
346 assert(std::saturate_cast<unsigned long long int>( O_UC) == 0ULL);
347 assert(std::saturate_cast<unsigned long long int>( UCHAR_MAX) == static_cast<unsigned long long int>(UCHAR_MAX));
348
349 { [[maybe_unused]] std::same_as<unsigned long long int> decltype(auto) _ = std::saturate_cast<unsigned long long int>(LLONG_MAX); }
350 assert(std::saturate_cast<unsigned long long int>( LLONG_MIN) == 0ULL);
351 assert(std::saturate_cast<unsigned long long int>( 0LL) == 0ULL);
352 assert(std::saturate_cast<unsigned long long int>( LLONG_MAX) == static_cast<unsigned long long int>(LLONG_MAX));
353
354 { [[maybe_unused]] std::same_as<unsigned long long int> decltype(auto) _ = std::saturate_cast<unsigned long long int>(ULLONG_MAX); }
355 assert(std::saturate_cast<unsigned long long int>( 0ULL) == 0ULL);
356 assert(std::saturate_cast<unsigned long long int>(ULLONG_MAX) == ULLONG_MAX);
357
358 #ifndef TEST_HAS_NO_INT128
359 { [[maybe_unused]] std::same_as<unsigned long long int> decltype(auto) _ = std::saturate_cast<unsigned long long int>(sBigMax); }
360 assert(std::saturate_cast<unsigned long long int>( sBigMin) == 0ULL); // (128-bit) saturated
361 assert(std::saturate_cast<unsigned long long int>( sZero) == 0ULL);
362 assert(std::saturate_cast<unsigned long long int>( sBigMax) == ULLONG_MAX); // (128-bit) saturated
363
364 { [[maybe_unused]] std::same_as<unsigned long long int> decltype(auto) _ = std::saturate_cast<unsigned long long int>(uBigMax); }
365 assert(std::saturate_cast<unsigned long long int>( uZero) == 0ULL);
366 assert(std::saturate_cast<unsigned long long int>( uBigMax) == ULLONG_MAX); // (128-bit) saturated
367
368 { [[maybe_unused]] std::same_as<__uint128_t> decltype(auto) _ = std::saturate_cast<__uint128_t>(SCHAR_MIN); }
369 assert(std::saturate_cast<__uint128_t>(SCHAR_MIN) == uZero);
370 assert(std::saturate_cast<__uint128_t>( O_C) == uZero);
371 assert(std::saturate_cast<__uint128_t>(SCHAR_MAX) == static_cast<__uint128_t>(SCHAR_MAX));
372
373 { [[maybe_unused]] std::same_as<__uint128_t> decltype(auto) _ = std::saturate_cast<__uint128_t>(UCHAR_MAX); }
374 assert(std::saturate_cast<__uint128_t>( O_UC) == uZero);
375 assert(std::saturate_cast<__uint128_t>(UCHAR_MAX) == static_cast<__uint128_t>(UCHAR_MAX));
376
377 { [[maybe_unused]] std::same_as<__uint128_t> decltype(auto) _ = std::saturate_cast<__uint128_t>(sBigMax); }
378 assert(std::saturate_cast<__uint128_t>( sBigMin) == uZero); // saturated
379 assert(std::saturate_cast<__uint128_t>( sZero) == uZero);
380 assert(std::saturate_cast<__uint128_t>( sBigMax) == static_cast<__uint128_t>(sBigMax));
381
382 { [[maybe_unused]] std::same_as<__uint128_t> decltype(auto) _ = std::saturate_cast<__uint128_t>(uBigMax); }
383 assert(std::saturate_cast<__uint128_t>( uZero) == uZero);
384 assert(std::saturate_cast<__uint128_t>( uBigMax) == uBigMax);
385 #endif
386
387 // clang-format on
388
389 return true;
390 }
391
main(int,char **)392 int main(int, char**) {
393 test();
394 static_assert(test());
395
396 return 0;
397 }
398