1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
11 #include "base/compiler_specific.h"
12 #include "build/build_config.h"
14 // WARNING: This block must come before the base/numerics headers are included.
15 // These tests deliberately cause arithmetic boundary errors. If the compiler is
16 // aggressive enough, it can const detect these errors, so we disable warnings.
18 #pragma warning(disable : 4756) // Arithmetic overflow.
19 #pragma warning(disable : 4293) // Invalid shift.
22 // This may not need to come before the base/numerics headers, but let's keep
23 // it close to the MSVC equivalent.
24 #if defined(__clang__)
25 #pragma clang diagnostic push
26 #pragma clang diagnostic ignored "-Winteger-overflow"
29 #include "base/logging.h"
30 #include "base/numerics/safe_conversions.h"
31 #include "base/numerics/safe_math.h"
32 #include "base/test/gtest_util.h"
33 #include "testing/gtest/include/gtest/gtest.h"
35 #if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS)
42 using std::numeric_limits;
44 // This is a helper function for finding the maximum value in Src that can be
45 // wholy represented as the destination floating-point type.
46 template <typename Dst, typename Src>
47 Dst GetMaxConvertibleToFloat() {
48 using DstLimits = numeric_limits<Dst>;
49 using SrcLimits = numeric_limits<Src>;
50 static_assert(SrcLimits::is_specialized, "Source must be numeric.");
51 static_assert(DstLimits::is_specialized, "Destination must be numeric.");
52 CHECK(DstLimits::is_iec559);
54 if (SrcLimits::digits <= DstLimits::digits &&
55 MaxExponent<Src>::value <= MaxExponent<Dst>::value)
56 return SrcLimits::max();
57 Src max = SrcLimits::max() / 2 + (SrcLimits::is_integer ? 1 : 0);
58 while (max != static_cast<Src>(static_cast<Dst>(max))) {
61 return static_cast<Dst>(max);
64 // Test corner case promotions used
65 static_assert(IsIntegerArithmeticSafe<int32_t, int8_t, int8_t>::value, "");
66 static_assert(IsIntegerArithmeticSafe<int32_t, int16_t, int8_t>::value, "");
67 static_assert(IsIntegerArithmeticSafe<int32_t, int8_t, int16_t>::value, "");
68 static_assert(!IsIntegerArithmeticSafe<int32_t, int32_t, int8_t>::value, "");
69 static_assert(BigEnoughPromotion<int16_t, int8_t>::is_contained, "");
70 static_assert(BigEnoughPromotion<int32_t, uint32_t>::is_contained, "");
71 static_assert(BigEnoughPromotion<intmax_t, int8_t>::is_contained, "");
72 static_assert(!BigEnoughPromotion<uintmax_t, int8_t>::is_contained, "");
74 std::is_same<BigEnoughPromotion<int16_t, int8_t>::type, int16_t>::value,
77 std::is_same<BigEnoughPromotion<int32_t, uint32_t>::type, int64_t>::value,
80 std::is_same<BigEnoughPromotion<intmax_t, int8_t>::type, intmax_t>::value,
83 std::is_same<BigEnoughPromotion<uintmax_t, int8_t>::type, uintmax_t>::value,
85 static_assert(BigEnoughPromotion<int16_t, int8_t>::is_contained, "");
86 static_assert(BigEnoughPromotion<int32_t, uint32_t>::is_contained, "");
87 static_assert(BigEnoughPromotion<intmax_t, int8_t>::is_contained, "");
88 static_assert(!BigEnoughPromotion<uintmax_t, int8_t>::is_contained, "");
90 std::is_same<FastIntegerArithmeticPromotion<int16_t, int8_t>::type,
94 std::is_same<FastIntegerArithmeticPromotion<int32_t, uint32_t>::type,
98 std::is_same<FastIntegerArithmeticPromotion<intmax_t, int8_t>::type,
102 std::is_same<FastIntegerArithmeticPromotion<uintmax_t, int8_t>::type,
105 static_assert(FastIntegerArithmeticPromotion<int16_t, int8_t>::is_contained,
107 static_assert(FastIntegerArithmeticPromotion<int32_t, uint32_t>::is_contained,
109 static_assert(!FastIntegerArithmeticPromotion<intmax_t, int8_t>::is_contained,
111 static_assert(!FastIntegerArithmeticPromotion<uintmax_t, int8_t>::is_contained,
114 // Test compile-time (constexpr) evaluation of checking and saturation.
115 constexpr int32_t kIntOne = 1;
116 static_assert(1 == checked_cast<uint8_t>(kIntOne), "");
117 static_assert(1 == saturated_cast<uint8_t>(kIntOne), "");
118 static_assert(2U == MakeClampedNum(kIntOne) + 1, "");
119 static_assert(2U == (MakeCheckedNum(kIntOne) + 1).ValueOrDie(), "");
120 static_assert(0U == MakeClampedNum(kIntOne) - 1, "");
121 static_assert(0U == (MakeCheckedNum(kIntOne) - 1).ValueOrDie(), "");
122 static_assert(-1 == -MakeClampedNum(kIntOne), "");
123 static_assert(-1 == (-MakeCheckedNum(kIntOne)).ValueOrDie(), "");
124 static_assert(1U == MakeClampedNum(kIntOne) * 1, "");
125 static_assert(1U == (MakeCheckedNum(kIntOne) * 1).ValueOrDie(), "");
126 static_assert(1U == MakeClampedNum(kIntOne) / 1, "");
127 static_assert(1U == (MakeCheckedNum(kIntOne) / 1).ValueOrDie(), "");
128 static_assert(1 == MakeClampedNum(-kIntOne).Abs(), "");
129 static_assert(1 == MakeCheckedNum(-kIntOne).Abs().ValueOrDie(), "");
130 static_assert(1U == MakeClampedNum(kIntOne) % 2, "");
131 static_assert(1U == (MakeCheckedNum(kIntOne) % 2).ValueOrDie(), "");
132 static_assert(0U == MakeClampedNum(kIntOne) >> 1U, "");
133 static_assert(0U == (MakeCheckedNum(kIntOne) >> 1U).ValueOrDie(), "");
134 static_assert(2U == MakeClampedNum(kIntOne) << 1U, "");
135 static_assert(2U == (MakeCheckedNum(kIntOne) << 1U).ValueOrDie(), "");
136 static_assert(1 == MakeClampedNum(kIntOne) & 1U, "");
137 static_assert(1 == (MakeCheckedNum(kIntOne) & 1U).ValueOrDie(), "");
138 static_assert(1 == MakeClampedNum(kIntOne) | 1U, "");
139 static_assert(1 == (MakeCheckedNum(kIntOne) | 1U).ValueOrDie(), "");
140 static_assert(0 == MakeClampedNum(kIntOne) ^ 1U, "");
141 static_assert(0 == (MakeCheckedNum(kIntOne) ^ 1U).ValueOrDie(), "");
142 constexpr float kFloatOne = 1.0;
143 static_assert(1 == int{checked_cast<int8_t>(kFloatOne)}, "");
144 static_assert(1 == int{saturated_cast<int8_t>(kFloatOne)}, "");
145 static_assert(2U == unsigned{MakeClampedNum(kFloatOne) + 1}, "");
147 (MakeCheckedNum(kFloatOne) + 1).Cast<unsigned>().ValueOrDie(),
149 static_assert(0U == unsigned{MakeClampedNum(kFloatOne) - 1}, "");
151 (MakeCheckedNum(kFloatOne) - 1).Cast<unsigned>().ValueOrDie(),
153 static_assert(-1 == int{-MakeClampedNum(kFloatOne)}, "");
154 static_assert(-1 == (-MakeCheckedNum(kFloatOne)).Cast<int>().ValueOrDie(), "");
155 static_assert(1U == unsigned{MakeClampedNum(kFloatOne) * 1}, "");
157 (MakeCheckedNum(kFloatOne) * 1).Cast<unsigned>().ValueOrDie(),
159 static_assert(1U == unsigned{MakeClampedNum(kFloatOne) / 1}, "");
161 (MakeCheckedNum(kFloatOne) / 1).Cast<unsigned>().ValueOrDie(),
163 static_assert(1 == int{MakeClampedNum(-kFloatOne).Abs()}, "");
164 static_assert(1 == MakeCheckedNum(-kFloatOne).Abs().Cast<int>().ValueOrDie(),
167 template <typename U>
168 U GetNumericValueForTest(const CheckedNumeric<U>& src) {
169 return src.state_.value();
172 template <typename U>
173 U GetNumericValueForTest(const ClampedNumeric<U>& src) {
174 return static_cast<U>(src);
177 template <typename U>
178 U GetNumericValueForTest(const U& src) {
182 // Logs the ValueOrDie() failure instead of crashing.
183 struct LogOnFailure {
184 template <typename T>
185 static T HandleFailure() {
186 LOG(WARNING) << "ValueOrDie() failed unexpectedly.";
191 template <typename T>
192 constexpr T GetValue(const T& src) {
196 template <typename T, typename U>
197 constexpr T GetValueAsDest(const U& src) {
198 return static_cast<T>(src);
201 template <typename T>
202 constexpr T GetValue(const CheckedNumeric<T>& src) {
203 return src.template ValueOrDie<T, LogOnFailure>();
206 template <typename T, typename U>
207 constexpr T GetValueAsDest(const CheckedNumeric<U>& src) {
208 return src.template ValueOrDie<T, LogOnFailure>();
211 template <typename T>
212 constexpr T GetValue(const ClampedNumeric<T>& src) {
213 return static_cast<T>(src);
216 template <typename T, typename U>
217 constexpr T GetValueAsDest(const ClampedNumeric<U>& src) {
218 return static_cast<T>(src);
221 // Helper macros to wrap displaying the conversion types and line numbers.
222 #define TEST_EXPECTED_VALIDITY(expected, actual) \
223 EXPECT_EQ(expected, (actual).template Cast<Dst>().IsValid()) \
224 << "Result test: Value " << GetNumericValueForTest(actual) << " as " \
225 << dst << " on line " << line
227 #define TEST_EXPECTED_SUCCESS(actual) TEST_EXPECTED_VALIDITY(true, actual)
228 #define TEST_EXPECTED_FAILURE(actual) TEST_EXPECTED_VALIDITY(false, actual)
230 // We have to handle promotions, so infer the underlying type below from actual.
231 #define TEST_EXPECTED_VALUE(expected, actual) \
232 EXPECT_EQ(GetValue(expected), GetValueAsDest<decltype(expected)>(actual)) \
233 << "Result test: Value " << GetNumericValueForTest(actual) << " as " \
234 << dst << " on line " << line
236 // Test the simple pointer arithmetic overrides.
237 template <typename Dst>
238 void TestStrictPointerMath() {
240 Dst* dummy_ptr = &dummy_value;
241 static const Dst kDummyOffset = 2; // Don't want to go too far.
242 EXPECT_EQ(dummy_ptr + kDummyOffset,
243 dummy_ptr + StrictNumeric<Dst>(kDummyOffset));
244 EXPECT_EQ(dummy_ptr - kDummyOffset,
245 dummy_ptr - StrictNumeric<Dst>(kDummyOffset));
246 EXPECT_NE(dummy_ptr, dummy_ptr + StrictNumeric<Dst>(kDummyOffset));
247 EXPECT_NE(dummy_ptr, dummy_ptr - StrictNumeric<Dst>(kDummyOffset));
248 EXPECT_DEATH_IF_SUPPORTED(
249 dummy_ptr + StrictNumeric<size_t>(std::numeric_limits<size_t>::max()),
253 // Signed integer arithmetic.
254 template <typename Dst>
255 static void TestSpecializedArithmetic(
258 typename std::enable_if<numeric_limits<Dst>::is_integer &&
259 numeric_limits<Dst>::is_signed,
261 using DstLimits = SaturationDefaultLimits<Dst>;
262 TEST_EXPECTED_FAILURE(-CheckedNumeric<Dst>(DstLimits::lowest()));
263 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()).Abs());
264 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
265 TEST_EXPECTED_VALUE(DstLimits::max(),
266 MakeCheckedNum(-DstLimits::max()).Abs());
268 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
269 -ClampedNumeric<Dst>(DstLimits::lowest()));
270 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
271 ClampedNumeric<Dst>(DstLimits::lowest()).Abs());
272 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(-1).Abs());
273 TEST_EXPECTED_VALUE(DstLimits::max(),
274 MakeClampedNum(-DstLimits::max()).Abs());
276 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + -1);
277 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) + -1);
278 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) +
279 DstLimits::lowest());
281 TEST_EXPECTED_VALUE(DstLimits::max() - 1,
282 ClampedNumeric<Dst>(DstLimits::max()) + -1);
283 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
284 ClampedNumeric<Dst>(DstLimits::lowest()) + -1);
286 DstLimits::Underflow(),
287 ClampedNumeric<Dst>(DstLimits::lowest()) + DstLimits::lowest());
289 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) - 1);
290 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) - -1);
291 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) -
292 DstLimits::lowest());
293 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) -
296 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
297 ClampedNumeric<Dst>(DstLimits::lowest()) - 1);
298 TEST_EXPECTED_VALUE(DstLimits::lowest() + 1,
299 ClampedNumeric<Dst>(DstLimits::lowest()) - -1);
301 DstLimits::Overflow(),
302 ClampedNumeric<Dst>(DstLimits::max()) - DstLimits::lowest());
304 DstLimits::Underflow(),
305 ClampedNumeric<Dst>(DstLimits::lowest()) - DstLimits::max());
307 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * 2);
308 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
309 ClampedNumeric<Dst>(DstLimits::lowest()) * 2);
311 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) / -1);
312 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) / 2);
313 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * -1);
314 TEST_EXPECTED_VALUE(DstLimits::max(),
315 CheckedNumeric<Dst>(DstLimits::lowest() + 1) * Dst(-1));
316 TEST_EXPECTED_VALUE(DstLimits::max(),
317 CheckedNumeric<Dst>(-1) * Dst(DstLimits::lowest() + 1));
318 TEST_EXPECTED_VALUE(DstLimits::lowest(),
319 CheckedNumeric<Dst>(DstLimits::lowest()) * Dst(1));
320 TEST_EXPECTED_VALUE(DstLimits::lowest(),
321 CheckedNumeric<Dst>(1) * Dst(DstLimits::lowest()));
323 typename std::make_unsigned<Dst>::type(0) - DstLimits::lowest(),
324 MakeCheckedNum(DstLimits::lowest()).UnsignedAbs());
325 TEST_EXPECTED_VALUE(DstLimits::max(),
326 MakeCheckedNum(DstLimits::max()).UnsignedAbs());
327 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0).UnsignedAbs());
328 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).UnsignedAbs());
329 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).UnsignedAbs());
331 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
332 ClampedNumeric<Dst>(DstLimits::lowest()) / -1);
333 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(-1) / 2);
334 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
335 ClampedNumeric<Dst>(DstLimits::lowest()) * -1);
336 TEST_EXPECTED_VALUE(DstLimits::max(),
337 ClampedNumeric<Dst>(DstLimits::lowest() + 1) * Dst(-1));
338 TEST_EXPECTED_VALUE(DstLimits::max(),
339 ClampedNumeric<Dst>(-1) * Dst(DstLimits::lowest() + 1));
340 TEST_EXPECTED_VALUE(DstLimits::lowest(),
341 ClampedNumeric<Dst>(DstLimits::lowest()) * Dst(1));
342 TEST_EXPECTED_VALUE(DstLimits::lowest(),
343 ClampedNumeric<Dst>(1) * Dst(DstLimits::lowest()));
345 typename std::make_unsigned<Dst>::type(0) - DstLimits::lowest(),
346 MakeClampedNum(DstLimits::lowest()).UnsignedAbs());
347 TEST_EXPECTED_VALUE(DstLimits::max(),
348 MakeClampedNum(DstLimits::max()).UnsignedAbs());
349 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0).UnsignedAbs());
350 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1).UnsignedAbs());
351 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(-1).UnsignedAbs());
353 // Modulus is legal only for integers.
354 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) % 2);
355 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) % 1);
356 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) % -1);
357 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) % -2);
358 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2);
359 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
360 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % -1);
361 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % -2);
362 TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % 2);
363 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) % 1);
364 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) % -1);
365 TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % -2);
366 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % 2);
367 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % 1);
368 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % -1);
369 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % -2);
370 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2);
371 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::max()) % 1);
372 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::max()) % -1);
373 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % -2);
374 // Test all the different modulus combinations.
375 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1));
376 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1));
377 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
378 CheckedNumeric<Dst> checked_dst = 1;
379 TEST_EXPECTED_VALUE(0, checked_dst %= 1);
380 // Test that div by 0 is avoided but returns invalid result.
381 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) % 0);
383 volatile Dst negative_one = -1;
384 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) << negative_one);
385 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1)
386 << (IntegerBitsPlusSign<Dst>::value - 1));
387 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(0)
388 << IntegerBitsPlusSign<Dst>::value);
389 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) << 1);
391 static_cast<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 2),
392 CheckedNumeric<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 2));
393 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0)
394 << (IntegerBitsPlusSign<Dst>::value - 1));
395 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) << 0);
396 TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) << 1);
397 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >>
398 IntegerBitsPlusSign<Dst>::value);
400 0, CheckedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value - 1));
401 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >> negative_one);
403 // Modulus is legal only for integers.
404 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) % 2);
405 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) % 1);
406 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) % -1);
407 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) % -2);
408 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) % 2);
409 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
410 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % -1);
411 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) % -2);
412 TEST_EXPECTED_VALUE(-1, ClampedNumeric<Dst>(-1) % 2);
413 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(-1) % 1);
414 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(-1) % -1);
415 TEST_EXPECTED_VALUE(-1, ClampedNumeric<Dst>(-1) % -2);
416 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % 2);
417 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % 1);
418 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % -1);
419 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % -2);
420 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(DstLimits::max()) % 2);
421 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::max()) % 1);
422 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::max()) % -1);
423 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(DstLimits::max()) % -2);
424 // Test all the different modulus combinations.
425 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % ClampedNumeric<Dst>(1));
426 TEST_EXPECTED_VALUE(0, 1 % ClampedNumeric<Dst>(1));
427 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
428 ClampedNumeric<Dst> clamped_dst = 1;
429 TEST_EXPECTED_VALUE(0, clamped_dst %= 1);
430 TEST_EXPECTED_VALUE(Dst(1), ClampedNumeric<Dst>(1) % 0);
432 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
433 ClampedNumeric<Dst>(1)
434 << (IntegerBitsPlusSign<Dst>::value - 1U));
435 TEST_EXPECTED_VALUE(Dst(0), ClampedNumeric<Dst>(0)
436 << (IntegerBitsPlusSign<Dst>::value + 0U));
437 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
438 ClampedNumeric<Dst>(DstLimits::max()) << 1U);
440 static_cast<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 2U),
441 ClampedNumeric<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 2U));
442 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0)
443 << (IntegerBitsPlusSign<Dst>::value - 1U));
444 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) << 0U);
445 TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) << 1U);
447 0, ClampedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value + 0U));
449 0, ClampedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value - 1U));
451 -1, ClampedNumeric<Dst>(-1) >> (IntegerBitsPlusSign<Dst>::value - 1U));
452 TEST_EXPECTED_VALUE(-1, ClampedNumeric<Dst>(DstLimits::lowest()) >>
453 (IntegerBitsPlusSign<Dst>::value - 0U));
455 TestStrictPointerMath<Dst>();
458 // Unsigned integer arithmetic.
459 template <typename Dst>
460 static void TestSpecializedArithmetic(
463 typename std::enable_if<numeric_limits<Dst>::is_integer &&
464 !numeric_limits<Dst>::is_signed,
466 using DstLimits = SaturationDefaultLimits<Dst>;
467 TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::lowest()));
468 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).Abs());
469 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) + -1);
470 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) - 1);
471 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) * 2);
472 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) / 2);
473 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).UnsignedAbs());
474 TEST_EXPECTED_SUCCESS(
475 CheckedNumeric<typename std::make_signed<Dst>::type>(
476 std::numeric_limits<typename std::make_signed<Dst>::type>::lowest())
478 TEST_EXPECTED_VALUE(DstLimits::lowest(),
479 MakeCheckedNum(DstLimits::lowest()).UnsignedAbs());
480 TEST_EXPECTED_VALUE(DstLimits::max(),
481 MakeCheckedNum(DstLimits::max()).UnsignedAbs());
482 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0).UnsignedAbs());
483 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).UnsignedAbs());
485 TEST_EXPECTED_VALUE(0, -ClampedNumeric<Dst>(DstLimits::lowest()));
486 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()).Abs());
487 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
488 ClampedNumeric<Dst>(DstLimits::lowest()) + -1);
489 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
490 ClampedNumeric<Dst>(DstLimits::lowest()) - 1);
491 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) * 2);
492 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) / 2);
493 TEST_EXPECTED_VALUE(0,
494 ClampedNumeric<Dst>(DstLimits::lowest()).UnsignedAbs());
497 std::numeric_limits<typename std::make_signed<Dst>::type>::lowest()),
498 ClampedNumeric<typename std::make_signed<Dst>::type>(
499 std::numeric_limits<typename std::make_signed<Dst>::type>::lowest())
501 TEST_EXPECTED_VALUE(DstLimits::lowest(),
502 MakeClampedNum(DstLimits::lowest()).UnsignedAbs());
503 TEST_EXPECTED_VALUE(DstLimits::max(),
504 MakeClampedNum(DstLimits::max()).UnsignedAbs());
505 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0).UnsignedAbs());
506 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1).UnsignedAbs());
508 // Modulus is legal only for integers.
509 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);
510 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
511 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2);
512 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % 2);
513 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2);
514 // Test all the different modulus combinations.
515 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1));
516 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1));
517 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
518 CheckedNumeric<Dst> checked_dst = 1;
519 TEST_EXPECTED_VALUE(0, checked_dst %= 1);
520 // Test that div by 0 is avoided but returns invalid result.
521 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) % 0);
522 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1)
523 << IntegerBitsPlusSign<Dst>::value);
525 volatile int negative_one = -1;
526 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) << negative_one);
527 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1)
528 << IntegerBitsPlusSign<Dst>::value);
529 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(0)
530 << IntegerBitsPlusSign<Dst>::value);
531 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) << 1);
533 static_cast<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 1),
534 CheckedNumeric<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 1));
535 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) << 0);
536 TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) << 1);
537 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >>
538 IntegerBitsPlusSign<Dst>::value);
540 0, CheckedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value - 1));
541 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >> negative_one);
542 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) & 1);
543 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) & 0);
544 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) & 1);
545 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) & 0);
546 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
547 MakeCheckedNum(DstLimits::max()) & -1);
548 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) | 1);
549 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) | 0);
550 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(0) | 1);
551 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) | 0);
552 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
553 CheckedNumeric<Dst>(0) | static_cast<Dst>(-1));
554 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) ^ 1);
555 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) ^ 0);
556 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(0) ^ 1);
557 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) ^ 0);
558 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
559 CheckedNumeric<Dst>(0) ^ static_cast<Dst>(-1));
560 TEST_EXPECTED_VALUE(DstLimits::max(), ~CheckedNumeric<Dst>(0));
562 // Modulus is legal only for integers.
563 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>() % 1);
564 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
565 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) % 2);
566 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % 2);
567 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(DstLimits::max()) % 2);
568 // Test all the different modulus combinations.
569 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % ClampedNumeric<Dst>(1));
570 TEST_EXPECTED_VALUE(0, 1 % ClampedNumeric<Dst>(1));
571 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
572 ClampedNumeric<Dst> clamped_dst = 1;
573 TEST_EXPECTED_VALUE(0, clamped_dst %= 1);
574 // Test that div by 0 is avoided but returns invalid result.
575 TEST_EXPECTED_VALUE(Dst(1), ClampedNumeric<Dst>(1) % 0);
577 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
578 ClampedNumeric<Dst>(1)
579 << as_unsigned(IntegerBitsPlusSign<Dst>::value));
580 TEST_EXPECTED_VALUE(Dst(0), ClampedNumeric<Dst>(0) << as_unsigned(
581 IntegerBitsPlusSign<Dst>::value));
582 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
583 ClampedNumeric<Dst>(DstLimits::max()) << 1U);
585 static_cast<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 1U),
586 ClampedNumeric<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 1U));
587 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) << 0U);
588 TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) << 1U);
589 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) >>
590 as_unsigned(IntegerBitsPlusSign<Dst>::value));
592 0, ClampedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value - 1U));
593 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) & 1);
594 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) & 0);
595 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) & 1);
596 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) & 0);
597 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
598 MakeClampedNum(DstLimits::max()) & -1);
599 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) | 1);
600 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) | 0);
601 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(0) | 1);
602 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) | 0);
603 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
604 ClampedNumeric<Dst>(0) | static_cast<Dst>(-1));
605 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) ^ 1);
606 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) ^ 0);
607 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(0) ^ 1);
608 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) ^ 0);
609 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
610 ClampedNumeric<Dst>(0) ^ static_cast<Dst>(-1));
611 TEST_EXPECTED_VALUE(DstLimits::max(), ~ClampedNumeric<Dst>(0));
613 TestStrictPointerMath<Dst>();
616 // Floating point arithmetic.
617 template <typename Dst>
618 void TestSpecializedArithmetic(
621 typename std::enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) {
622 using DstLimits = SaturationDefaultLimits<Dst>;
623 TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::lowest()));
625 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).Abs());
626 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
628 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) + -1);
629 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + 1);
630 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) +
631 DstLimits::lowest());
633 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) -
634 DstLimits::lowest());
635 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) -
638 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * 2);
640 TEST_EXPECTED_VALUE(-0.5, CheckedNumeric<Dst>(-1.0) / 2);
642 TEST_EXPECTED_VALUE(DstLimits::max(),
643 -ClampedNumeric<Dst>(DstLimits::lowest()));
645 TEST_EXPECTED_VALUE(DstLimits::max(),
646 ClampedNumeric<Dst>(DstLimits::lowest()).Abs());
647 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(-1).Abs());
649 TEST_EXPECTED_VALUE(DstLimits::lowest() - 1,
650 ClampedNumeric<Dst>(DstLimits::lowest()) + -1);
651 TEST_EXPECTED_VALUE(DstLimits::max() + 1,
652 ClampedNumeric<Dst>(DstLimits::max()) + 1);
654 DstLimits::Underflow(),
655 ClampedNumeric<Dst>(DstLimits::lowest()) + DstLimits::lowest());
658 DstLimits::Overflow(),
659 ClampedNumeric<Dst>(DstLimits::max()) - DstLimits::lowest());
661 DstLimits::Underflow(),
662 ClampedNumeric<Dst>(DstLimits::lowest()) - DstLimits::max());
664 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
665 ClampedNumeric<Dst>(DstLimits::lowest()) * 2);
667 TEST_EXPECTED_VALUE(-0.5, ClampedNumeric<Dst>(-1.0) / 2);
670 // Generic arithmetic tests.
671 template <typename Dst>
672 static void TestArithmetic(const char* dst, int line) {
673 using DstLimits = SaturationDefaultLimits<Dst>;
675 // Test C++17 class template argument deduction
677 std::is_same_v<Dst, typename decltype(CheckedNumeric(Dst{0}))::type>);
679 std::is_same_v<Dst, typename decltype(ClampedNumeric(Dst{0}))::type>);
681 std::is_same_v<Dst, typename decltype(StrictNumeric(Dst{0}))::type>);
683 EXPECT_EQ(true, CheckedNumeric<Dst>().IsValid());
684 EXPECT_EQ(false, CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) *
687 EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDie());
688 EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDefault(1));
689 EXPECT_EQ(static_cast<Dst>(1),
690 CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) *
694 // Test the operator combinations.
695 TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + CheckedNumeric<Dst>(1));
696 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - CheckedNumeric<Dst>(1));
697 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * CheckedNumeric<Dst>(1));
698 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / CheckedNumeric<Dst>(1));
699 TEST_EXPECTED_VALUE(2, 1 + CheckedNumeric<Dst>(1));
700 TEST_EXPECTED_VALUE(0, 1 - CheckedNumeric<Dst>(1));
701 TEST_EXPECTED_VALUE(1, 1 * CheckedNumeric<Dst>(1));
702 TEST_EXPECTED_VALUE(1, 1 / CheckedNumeric<Dst>(1));
703 TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + 1);
704 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - 1);
705 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * 1);
706 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
707 CheckedNumeric<Dst> checked_dst = 1;
708 TEST_EXPECTED_VALUE(2, checked_dst += 1);
710 TEST_EXPECTED_VALUE(0, checked_dst -= 1);
712 TEST_EXPECTED_VALUE(1, checked_dst *= 1);
714 TEST_EXPECTED_VALUE(1, checked_dst /= 1);
716 TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) + ClampedNumeric<Dst>(1));
717 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) - ClampedNumeric<Dst>(1));
718 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) * ClampedNumeric<Dst>(1));
719 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) / ClampedNumeric<Dst>(1));
720 TEST_EXPECTED_VALUE(2, 1 + ClampedNumeric<Dst>(1));
721 TEST_EXPECTED_VALUE(0, 1 - ClampedNumeric<Dst>(1));
722 TEST_EXPECTED_VALUE(1, 1 * ClampedNumeric<Dst>(1));
723 TEST_EXPECTED_VALUE(1, 1 / ClampedNumeric<Dst>(1));
724 TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) + 1);
725 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) - 1);
726 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) * 1);
727 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) / 1);
728 ClampedNumeric<Dst> clamped_dst = 1;
729 TEST_EXPECTED_VALUE(2, clamped_dst += 1);
731 TEST_EXPECTED_VALUE(0, clamped_dst -= 1);
733 TEST_EXPECTED_VALUE(1, clamped_dst *= 1);
735 TEST_EXPECTED_VALUE(1, clamped_dst /= 1);
738 if (DstLimits::is_signed) {
739 TEST_EXPECTED_VALUE(0, -CheckedNumeric<Dst>());
740 TEST_EXPECTED_VALUE(-1, -CheckedNumeric<Dst>(1));
741 TEST_EXPECTED_VALUE(1, -CheckedNumeric<Dst>(-1));
742 TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1),
743 -CheckedNumeric<Dst>(DstLimits::max()));
745 TEST_EXPECTED_VALUE(0, -ClampedNumeric<Dst>());
746 TEST_EXPECTED_VALUE(-1, -ClampedNumeric<Dst>(1));
747 TEST_EXPECTED_VALUE(1, -ClampedNumeric<Dst>(-1));
748 TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1),
749 -ClampedNumeric<Dst>(DstLimits::max()));
751 // The runtime paths for saturated negation differ significantly from what
752 // gets evaluated at compile-time. Making this test volatile forces the
753 // compiler to generate code rather than fold constant expressions.
754 volatile Dst value = Dst(0);
755 TEST_EXPECTED_VALUE(0, -MakeClampedNum(value));
757 TEST_EXPECTED_VALUE(-1, -MakeClampedNum(value));
759 TEST_EXPECTED_VALUE(-2, -MakeClampedNum(value));
761 TEST_EXPECTED_VALUE(1, -MakeClampedNum(value));
763 TEST_EXPECTED_VALUE(2, -MakeClampedNum(value));
764 value = DstLimits::max();
765 TEST_EXPECTED_VALUE(Dst(DstLimits::max() * -1), -MakeClampedNum(value));
766 value = Dst(-1 * DstLimits::max());
767 TEST_EXPECTED_VALUE(DstLimits::max(), -MakeClampedNum(value));
768 value = DstLimits::lowest();
769 TEST_EXPECTED_VALUE(DstLimits::max(), -MakeClampedNum(value));
772 // Generic absolute value.
773 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>().Abs());
774 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).Abs());
775 TEST_EXPECTED_VALUE(DstLimits::max(),
776 CheckedNumeric<Dst>(DstLimits::max()).Abs());
778 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>().Abs());
779 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1).Abs());
780 TEST_EXPECTED_VALUE(DstLimits::max(),
781 ClampedNumeric<Dst>(DstLimits::max()).Abs());
784 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>() + 1));
785 TEST_EXPECTED_VALUE(2, (CheckedNumeric<Dst>(1) + 1));
786 if (numeric_limits<Dst>::is_signed)
787 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) + 1));
788 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) + 1);
789 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) +
792 TEST_EXPECTED_VALUE(1, (ClampedNumeric<Dst>() + 1));
793 TEST_EXPECTED_VALUE(2, (ClampedNumeric<Dst>(1) + 1));
794 if (numeric_limits<Dst>::is_signed)
795 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(-1) + 1));
796 TEST_EXPECTED_VALUE(DstLimits::lowest() + 1,
797 ClampedNumeric<Dst>(DstLimits::lowest()) + 1);
798 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
799 ClampedNumeric<Dst>(DstLimits::max()) + DstLimits::max());
801 // Generic subtraction.
802 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(1) - 1));
803 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) - 1);
804 if (numeric_limits<Dst>::is_signed) {
805 TEST_EXPECTED_VALUE(-1, (CheckedNumeric<Dst>() - 1));
806 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) - 1));
808 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - -1);
811 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(1) - 1));
812 TEST_EXPECTED_VALUE(DstLimits::max() - 1,
813 ClampedNumeric<Dst>(DstLimits::max()) - 1);
814 if (numeric_limits<Dst>::is_signed) {
815 TEST_EXPECTED_VALUE(-1, (ClampedNumeric<Dst>() - 1));
816 TEST_EXPECTED_VALUE(-2, (ClampedNumeric<Dst>(-1) - 1));
818 TEST_EXPECTED_VALUE(DstLimits::max(),
819 ClampedNumeric<Dst>(DstLimits::max()) - -1);
822 // Generic multiplication.
823 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>() * 1));
824 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>(1) * 1));
825 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * 0));
826 if (numeric_limits<Dst>::is_signed) {
827 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) * 0));
828 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * -1));
829 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) * 2));
831 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * -2);
832 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) *
833 CheckedNumeric<uintmax_t>(-2));
835 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) *
838 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>() * 1));
839 TEST_EXPECTED_VALUE(1, (ClampedNumeric<Dst>(1) * 1));
840 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(0) * 0));
841 if (numeric_limits<Dst>::is_signed) {
842 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(-1) * 0));
843 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(0) * -1));
844 TEST_EXPECTED_VALUE(-2, (ClampedNumeric<Dst>(-1) * 2));
846 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
847 ClampedNumeric<Dst>(DstLimits::max()) * -2);
848 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::max()) *
849 ClampedNumeric<uintmax_t>(-2));
851 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
852 ClampedNumeric<Dst>(DstLimits::max()) * DstLimits::max());
855 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() / 1);
856 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
857 TEST_EXPECTED_VALUE(DstLimits::lowest() / 2,
858 CheckedNumeric<Dst>(DstLimits::lowest()) / 2);
859 TEST_EXPECTED_VALUE(DstLimits::max() / 2,
860 CheckedNumeric<Dst>(DstLimits::max()) / 2);
861 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) / 0);
863 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>() / 1);
864 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) / 1);
865 TEST_EXPECTED_VALUE(DstLimits::lowest() / 2,
866 ClampedNumeric<Dst>(DstLimits::lowest()) / 2);
867 TEST_EXPECTED_VALUE(DstLimits::max() / 2,
868 ClampedNumeric<Dst>(DstLimits::max()) / 2);
869 TEST_EXPECTED_VALUE(DstLimits::Overflow(), ClampedNumeric<Dst>(1) / 0);
870 TEST_EXPECTED_VALUE(DstLimits::Underflow(), ClampedNumeric<Dst>(-1) / 0);
871 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) / 0);
873 TestSpecializedArithmetic<Dst>(dst, line);
876 // Helper macro to wrap displaying the conversion types and line numbers.
877 #define TEST_ARITHMETIC(Dst) TestArithmetic<Dst>(#Dst, __LINE__)
879 TEST(SafeNumerics, SignedIntegerMath) {
880 TEST_ARITHMETIC(int8_t);
881 TEST_ARITHMETIC(int16_t);
882 TEST_ARITHMETIC(int);
883 TEST_ARITHMETIC(intptr_t);
884 TEST_ARITHMETIC(intmax_t);
887 TEST(SafeNumerics, UnsignedIntegerMath) {
888 TEST_ARITHMETIC(uint8_t);
889 TEST_ARITHMETIC(uint16_t);
890 TEST_ARITHMETIC(unsigned int);
891 TEST_ARITHMETIC(uintptr_t);
892 TEST_ARITHMETIC(uintmax_t);
895 TEST(SafeNumerics, FloatingPointMath) {
896 TEST_ARITHMETIC(float);
897 TEST_ARITHMETIC(double);
900 // Enumerates the five different conversions types we need to test.
901 enum NumericConversionType {
902 SIGN_PRESERVING_VALUE_PRESERVING,
903 SIGN_PRESERVING_NARROW,
904 SIGN_TO_UNSIGN_WIDEN_OR_EQUAL,
905 SIGN_TO_UNSIGN_NARROW,
906 UNSIGN_TO_SIGN_NARROW_OR_EQUAL,
909 // Template covering the different conversion tests.
910 template <typename Dst, typename Src, NumericConversionType conversion>
911 struct TestNumericConversion {};
913 enum RangeConstraint {
914 RANGE_VALID = 0x0, // Value can be represented by the destination type.
915 RANGE_UNDERFLOW = 0x1, // Value would underflow.
916 RANGE_OVERFLOW = 0x2, // Value would overflow.
917 RANGE_INVALID = RANGE_UNDERFLOW | RANGE_OVERFLOW // Invalid (i.e. NaN).
920 // These are some wrappers to make the tests a bit cleaner.
921 constexpr RangeConstraint RangeCheckToEnum(const RangeCheck constraint) {
922 return static_cast<RangeConstraint>(
923 static_cast<int>(constraint.IsOverflowFlagSet()) << 1 |
924 static_cast<int>(constraint.IsUnderflowFlagSet()));
927 // EXPECT_EQ wrappers providing specific detail on test failures.
928 #define TEST_EXPECTED_RANGE(expected, actual) \
929 EXPECT_EQ(expected, \
930 RangeCheckToEnum(DstRangeRelationToSrcRange<Dst>(actual))) \
931 << "Conversion test: " << src << " value " << actual << " to " << dst \
932 << " on line " << line
934 template <typename Dst, typename Src>
935 void TestStrictComparison(const char* dst, const char* src, int line) {
936 using DstLimits = numeric_limits<Dst>;
937 using SrcLimits = numeric_limits<Src>;
938 static_assert(StrictNumeric<Src>(SrcLimits::lowest()) < DstLimits::max(), "");
939 static_assert(StrictNumeric<Src>(SrcLimits::lowest()) < SrcLimits::max(), "");
940 static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) >= DstLimits::max()),
942 static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) >= SrcLimits::max()),
944 static_assert(StrictNumeric<Src>(SrcLimits::lowest()) <= DstLimits::max(),
946 static_assert(StrictNumeric<Src>(SrcLimits::lowest()) <= SrcLimits::max(),
948 static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) > DstLimits::max()),
950 static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) > SrcLimits::max()),
952 static_assert(StrictNumeric<Src>(SrcLimits::max()) > DstLimits::lowest(), "");
953 static_assert(StrictNumeric<Src>(SrcLimits::max()) > SrcLimits::lowest(), "");
954 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) <= DstLimits::lowest()),
956 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) <= SrcLimits::lowest()),
958 static_assert(StrictNumeric<Src>(SrcLimits::max()) >= DstLimits::lowest(),
960 static_assert(StrictNumeric<Src>(SrcLimits::max()) >= SrcLimits::lowest(),
962 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) < DstLimits::lowest()),
964 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) < SrcLimits::lowest()),
966 static_assert(StrictNumeric<Src>(static_cast<Src>(1)) == static_cast<Dst>(1),
968 static_assert(StrictNumeric<Src>(static_cast<Src>(1)) != static_cast<Dst>(0),
970 static_assert(StrictNumeric<Src>(SrcLimits::max()) != static_cast<Dst>(0),
972 static_assert(StrictNumeric<Src>(SrcLimits::max()) != DstLimits::lowest(),
975 !(StrictNumeric<Src>(static_cast<Src>(1)) != static_cast<Dst>(1)), "");
977 !(StrictNumeric<Src>(static_cast<Src>(1)) == static_cast<Dst>(0)), "");
979 // Due to differences in float handling between compilers, these aren't
980 // compile-time constants everywhere. So, we use run-time tests.
983 MakeCheckedNum(SrcLimits::max()).Max(DstLimits::lowest()).ValueOrDie());
986 MakeCheckedNum(SrcLimits::lowest()).Max(DstLimits::max()).ValueOrDie());
989 MakeCheckedNum(SrcLimits::max()).Min(DstLimits::lowest()).ValueOrDie());
992 MakeCheckedNum(SrcLimits::lowest()).Min(DstLimits::max()).ValueOrDie());
993 EXPECT_EQ(SrcLimits::lowest(), CheckMin(MakeStrictNum(1), MakeCheckedNum(0),
994 DstLimits::max(), SrcLimits::lowest())
996 EXPECT_EQ(DstLimits::max(), CheckMax(MakeStrictNum(1), MakeCheckedNum(0),
997 DstLimits::max(), SrcLimits::lowest())
1000 EXPECT_EQ(SrcLimits::max(),
1001 MakeClampedNum(SrcLimits::max()).Max(DstLimits::lowest()));
1002 EXPECT_EQ(DstLimits::max(),
1003 MakeClampedNum(SrcLimits::lowest()).Max(DstLimits::max()));
1004 EXPECT_EQ(DstLimits::lowest(),
1005 MakeClampedNum(SrcLimits::max()).Min(DstLimits::lowest()));
1006 EXPECT_EQ(SrcLimits::lowest(),
1007 MakeClampedNum(SrcLimits::lowest()).Min(DstLimits::max()));
1008 EXPECT_EQ(SrcLimits::lowest(),
1009 ClampMin(MakeStrictNum(1), MakeClampedNum(0), DstLimits::max(),
1010 SrcLimits::lowest()));
1011 EXPECT_EQ(DstLimits::max(), ClampMax(MakeStrictNum(1), MakeClampedNum(0),
1012 DstLimits::max(), SrcLimits::lowest()));
1014 if (IsValueInRangeForNumericType<Dst>(SrcLimits::max())) {
1015 TEST_EXPECTED_VALUE(Dst(SrcLimits::max()), (CommonMax<Dst, Src>()));
1016 TEST_EXPECTED_VALUE(Dst(SrcLimits::max()),
1017 (CommonMaxOrMin<Dst, Src>(false)));
1019 TEST_EXPECTED_VALUE(DstLimits::max(), (CommonMax<Dst, Src>()));
1020 TEST_EXPECTED_VALUE(DstLimits::max(), (CommonMaxOrMin<Dst, Src>(false)));
1023 if (IsValueInRangeForNumericType<Dst>(SrcLimits::lowest())) {
1024 TEST_EXPECTED_VALUE(Dst(SrcLimits::lowest()), (CommonMin<Dst, Src>()));
1025 TEST_EXPECTED_VALUE(Dst(SrcLimits::lowest()),
1026 (CommonMaxOrMin<Dst, Src>(true)));
1028 TEST_EXPECTED_VALUE(DstLimits::lowest(), (CommonMin<Dst, Src>()));
1029 TEST_EXPECTED_VALUE(DstLimits::lowest(), (CommonMaxOrMin<Dst, Src>(true)));
1033 template <typename Dst, typename Src>
1034 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> {
1035 static void Test(const char* dst, const char* src, int line) {
1036 using SrcLimits = SaturationDefaultLimits<Src>;
1037 using DstLimits = SaturationDefaultLimits<Dst>;
1038 // Integral to floating.
1039 static_assert((DstLimits::is_iec559 && SrcLimits::is_integer) ||
1040 // Not floating to integral and...
1041 (!(DstLimits::is_integer && SrcLimits::is_iec559) &&
1042 // Same sign, same numeric, source is narrower or same.
1043 ((SrcLimits::is_signed == DstLimits::is_signed &&
1044 MaxExponent<Dst>::value >= MaxExponent<Src>::value) ||
1045 // Or signed destination and source is smaller
1046 (DstLimits::is_signed &&
1047 MaxExponent<Dst>::value >= MaxExponent<Src>::value))),
1048 "Comparison must be sign preserving and value preserving");
1050 TestStrictComparison<Dst, Src>(dst, src, line);
1052 const CheckedNumeric<Dst> checked_dst = SrcLimits::max();
1053 const ClampedNumeric<Dst> clamped_dst = SrcLimits::max();
1054 TEST_EXPECTED_SUCCESS(checked_dst);
1055 TEST_EXPECTED_VALUE(Dst(SrcLimits::max()), clamped_dst);
1056 if (MaxExponent<Dst>::value > MaxExponent<Src>::value) {
1057 if (MaxExponent<Dst>::value >= MaxExponent<Src>::value * 2 - 1) {
1058 // At least twice larger type.
1059 TEST_EXPECTED_SUCCESS(SrcLimits::max() * checked_dst);
1060 TEST_EXPECTED_VALUE(SrcLimits::max() * clamped_dst,
1061 Dst(SrcLimits::max()) * Dst(SrcLimits::max()));
1062 } else { // Larger, but not at least twice as large.
1063 TEST_EXPECTED_FAILURE(SrcLimits::max() * checked_dst);
1064 TEST_EXPECTED_SUCCESS(checked_dst + 1);
1065 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
1066 SrcLimits::max() * clamped_dst);
1067 TEST_EXPECTED_VALUE(Dst(SrcLimits::max()) + Dst(1),
1068 clamped_dst + Dst(1));
1070 } else { // Same width type.
1071 TEST_EXPECTED_FAILURE(checked_dst + 1);
1072 TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + Dst(1));
1075 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
1076 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
1077 if (SrcLimits::is_iec559) {
1078 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast<Src>(-1));
1079 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
1080 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
1081 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
1082 } else if (numeric_limits<Src>::is_signed) {
1083 // This block reverses the Src to Dst relationship so we don't have to
1084 // complicate the test macros.
1085 if (!std::is_same<Src, Dst>::value) {
1086 TEST_EXPECTED_SUCCESS(CheckDiv(SrcLimits::lowest(), Dst(-1)));
1088 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
1089 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest());
1094 template <typename Dst, typename Src>
1095 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW> {
1096 static void Test(const char* dst, const char* src, int line) {
1097 using SrcLimits = SaturationDefaultLimits<Src>;
1098 using DstLimits = SaturationDefaultLimits<Dst>;
1099 static_assert(SrcLimits::is_signed == DstLimits::is_signed,
1100 "Destination and source sign must be the same");
1101 static_assert(MaxExponent<Dst>::value <= MaxExponent<Src>::value,
1102 "Destination must be narrower than source");
1104 TestStrictComparison<Dst, Src>(dst, src, line);
1106 const CheckedNumeric<Dst> checked_dst;
1107 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
1108 TEST_EXPECTED_VALUE(1, checked_dst + Src(1));
1109 TEST_EXPECTED_FAILURE(checked_dst - SrcLimits::max());
1111 ClampedNumeric<Dst> clamped_dst;
1112 TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + SrcLimits::max());
1113 TEST_EXPECTED_VALUE(1, clamped_dst + Src(1));
1114 TEST_EXPECTED_VALUE(DstLimits::Underflow(), clamped_dst - SrcLimits::max());
1115 clamped_dst += SrcLimits::max();
1116 TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst);
1117 clamped_dst = DstLimits::max();
1118 clamped_dst += SrcLimits::max();
1119 TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst);
1120 clamped_dst = DstLimits::max();
1121 clamped_dst -= SrcLimits::max();
1122 TEST_EXPECTED_VALUE(DstLimits::Underflow(), clamped_dst);
1125 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
1126 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
1127 if (SrcLimits::is_iec559) {
1128 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
1129 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
1130 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
1131 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
1132 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
1133 if (DstLimits::is_integer) {
1134 if (SrcLimits::digits < DstLimits::digits) {
1135 TEST_EXPECTED_RANGE(RANGE_OVERFLOW,
1136 static_cast<Src>(DstLimits::max()));
1138 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
1140 TEST_EXPECTED_RANGE(
1142 static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
1143 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::lowest()));
1145 } else if (SrcLimits::is_signed) {
1146 TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1));
1147 TEST_EXPECTED_VALUE(-1, clamped_dst - static_cast<Src>(1));
1148 TEST_EXPECTED_VALUE(Src(Src(0) - DstLimits::lowest()),
1149 ClampDiv(DstLimits::lowest(), Src(-1)));
1150 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest());
1151 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
1153 TEST_EXPECTED_FAILURE(checked_dst - static_cast<Src>(1));
1154 TEST_EXPECTED_VALUE(Dst(0), clamped_dst - static_cast<Src>(1));
1155 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest());
1160 template <typename Dst, typename Src>
1161 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL> {
1162 static void Test(const char* dst, const char* src, int line) {
1163 using SrcLimits = SaturationDefaultLimits<Src>;
1164 using DstLimits = SaturationDefaultLimits<Dst>;
1165 static_assert(MaxExponent<Dst>::value >= MaxExponent<Src>::value,
1166 "Destination must be equal or wider than source.");
1167 static_assert(SrcLimits::is_signed, "Source must be signed");
1168 static_assert(!DstLimits::is_signed, "Destination must be unsigned");
1170 TestStrictComparison<Dst, Src>(dst, src, line);
1172 const CheckedNumeric<Dst> checked_dst;
1173 TEST_EXPECTED_VALUE(SrcLimits::max(), checked_dst + SrcLimits::max());
1174 TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1));
1175 TEST_EXPECTED_SUCCESS(checked_dst * static_cast<Src>(-1));
1176 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::lowest());
1177 TEST_EXPECTED_VALUE(Dst(0), CheckDiv(Dst(0), Src(-1)));
1179 const ClampedNumeric<Dst> clamped_dst;
1180 TEST_EXPECTED_VALUE(SrcLimits::max(), clamped_dst + SrcLimits::max());
1181 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
1182 clamped_dst + static_cast<Src>(-1));
1183 TEST_EXPECTED_VALUE(0, clamped_dst * static_cast<Src>(-1));
1184 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
1185 clamped_dst + SrcLimits::lowest());
1187 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest());
1188 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
1189 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
1190 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
1194 template <typename Dst, typename Src>
1195 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_NARROW> {
1196 static void Test(const char* dst, const char* src, int line) {
1197 using SrcLimits = SaturationDefaultLimits<Src>;
1198 using DstLimits = SaturationDefaultLimits<Dst>;
1199 static_assert(MaxExponent<Dst>::value < MaxExponent<Src>::value,
1200 "Destination must be narrower than source.");
1201 static_assert(SrcLimits::is_signed, "Source must be signed.");
1202 static_assert(!DstLimits::is_signed, "Destination must be unsigned.");
1204 TestStrictComparison<Dst, Src>(dst, src, line);
1206 const CheckedNumeric<Dst> checked_dst;
1207 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
1208 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
1209 TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1));
1210 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::lowest());
1212 ClampedNumeric<Dst> clamped_dst;
1213 TEST_EXPECTED_VALUE(1, clamped_dst + static_cast<Src>(1));
1214 TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + SrcLimits::max());
1215 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
1216 clamped_dst + static_cast<Src>(-1));
1217 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
1218 clamped_dst + SrcLimits::lowest());
1219 clamped_dst += SrcLimits::max();
1220 TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst);
1221 clamped_dst = DstLimits::max();
1222 clamped_dst += SrcLimits::max();
1223 TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst);
1224 clamped_dst = DstLimits::max();
1225 clamped_dst -= SrcLimits::max();
1226 TEST_EXPECTED_VALUE(DstLimits::Underflow(), clamped_dst);
1229 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
1230 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
1231 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
1233 // Additional saturation tests.
1234 EXPECT_EQ(DstLimits::max(), saturated_cast<Dst>(SrcLimits::max()));
1235 EXPECT_EQ(DstLimits::lowest(), saturated_cast<Dst>(SrcLimits::lowest()));
1237 if (SrcLimits::is_iec559) {
1238 EXPECT_EQ(Dst(0), saturated_cast<Dst>(SrcLimits::quiet_NaN()));
1240 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
1241 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
1242 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
1243 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
1244 if (DstLimits::is_integer) {
1245 if (SrcLimits::digits < DstLimits::digits) {
1246 TEST_EXPECTED_RANGE(RANGE_OVERFLOW,
1247 static_cast<Src>(DstLimits::max()));
1249 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
1251 TEST_EXPECTED_RANGE(
1253 static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
1254 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::lowest()));
1257 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest());
1262 template <typename Dst, typename Src>
1263 struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL> {
1264 static void Test(const char* dst, const char* src, int line) {
1265 using SrcLimits = SaturationDefaultLimits<Src>;
1266 using DstLimits = SaturationDefaultLimits<Dst>;
1267 static_assert(MaxExponent<Dst>::value <= MaxExponent<Src>::value,
1268 "Destination must be narrower or equal to source.");
1269 static_assert(!SrcLimits::is_signed, "Source must be unsigned.");
1270 static_assert(DstLimits::is_signed, "Destination must be signed.");
1272 TestStrictComparison<Dst, Src>(dst, src, line);
1274 const CheckedNumeric<Dst> checked_dst;
1275 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
1276 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
1277 TEST_EXPECTED_VALUE(SrcLimits::lowest(), checked_dst + SrcLimits::lowest());
1279 const ClampedNumeric<Dst> clamped_dst;
1280 TEST_EXPECTED_VALUE(1, clamped_dst + static_cast<Src>(1));
1281 TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + SrcLimits::max());
1282 TEST_EXPECTED_VALUE(SrcLimits::lowest(), clamped_dst + SrcLimits::lowest());
1284 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest());
1285 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
1286 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
1288 // Additional saturation tests.
1289 EXPECT_EQ(DstLimits::max(), saturated_cast<Dst>(SrcLimits::max()));
1290 EXPECT_EQ(Dst(0), saturated_cast<Dst>(SrcLimits::lowest()));
1294 // Helper macro to wrap displaying the conversion types and line numbers
1295 #define TEST_NUMERIC_CONVERSION(d, s, t) \
1296 TestNumericConversion<d, s, t>::Test(#d, #s, __LINE__)
1298 TEST(SafeNumerics, IntMinOperations) {
1299 TEST_NUMERIC_CONVERSION(int8_t, int8_t, SIGN_PRESERVING_VALUE_PRESERVING);
1300 TEST_NUMERIC_CONVERSION(uint8_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
1302 TEST_NUMERIC_CONVERSION(int8_t, int16_t, SIGN_PRESERVING_NARROW);
1303 TEST_NUMERIC_CONVERSION(int8_t, int, SIGN_PRESERVING_NARROW);
1304 TEST_NUMERIC_CONVERSION(uint8_t, uint16_t, SIGN_PRESERVING_NARROW);
1305 TEST_NUMERIC_CONVERSION(uint8_t, unsigned int, SIGN_PRESERVING_NARROW);
1306 TEST_NUMERIC_CONVERSION(int8_t, float, SIGN_PRESERVING_NARROW);
1308 TEST_NUMERIC_CONVERSION(uint8_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
1310 TEST_NUMERIC_CONVERSION(uint8_t, int16_t, SIGN_TO_UNSIGN_NARROW);
1311 TEST_NUMERIC_CONVERSION(uint8_t, int, SIGN_TO_UNSIGN_NARROW);
1312 TEST_NUMERIC_CONVERSION(uint8_t, intmax_t, SIGN_TO_UNSIGN_NARROW);
1313 TEST_NUMERIC_CONVERSION(uint8_t, float, SIGN_TO_UNSIGN_NARROW);
1315 TEST_NUMERIC_CONVERSION(int8_t, uint16_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1316 TEST_NUMERIC_CONVERSION(int8_t, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1317 TEST_NUMERIC_CONVERSION(int8_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1320 TEST(SafeNumerics, Int16Operations) {
1321 TEST_NUMERIC_CONVERSION(int16_t, int16_t, SIGN_PRESERVING_VALUE_PRESERVING);
1322 TEST_NUMERIC_CONVERSION(uint16_t, uint16_t, SIGN_PRESERVING_VALUE_PRESERVING);
1324 TEST_NUMERIC_CONVERSION(int16_t, int, SIGN_PRESERVING_NARROW);
1325 TEST_NUMERIC_CONVERSION(uint16_t, unsigned int, SIGN_PRESERVING_NARROW);
1326 TEST_NUMERIC_CONVERSION(int16_t, float, SIGN_PRESERVING_NARROW);
1328 TEST_NUMERIC_CONVERSION(uint16_t, int16_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
1330 TEST_NUMERIC_CONVERSION(uint16_t, int, SIGN_TO_UNSIGN_NARROW);
1331 TEST_NUMERIC_CONVERSION(uint16_t, intmax_t, SIGN_TO_UNSIGN_NARROW);
1332 TEST_NUMERIC_CONVERSION(uint16_t, float, SIGN_TO_UNSIGN_NARROW);
1334 TEST_NUMERIC_CONVERSION(int16_t, unsigned int,
1335 UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1336 TEST_NUMERIC_CONVERSION(int16_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1339 TEST(SafeNumerics, IntOperations) {
1340 TEST_NUMERIC_CONVERSION(int, int, SIGN_PRESERVING_VALUE_PRESERVING);
1341 TEST_NUMERIC_CONVERSION(unsigned int, unsigned int,
1342 SIGN_PRESERVING_VALUE_PRESERVING);
1343 TEST_NUMERIC_CONVERSION(int, int8_t, SIGN_PRESERVING_VALUE_PRESERVING);
1344 TEST_NUMERIC_CONVERSION(unsigned int, uint8_t,
1345 SIGN_PRESERVING_VALUE_PRESERVING);
1346 TEST_NUMERIC_CONVERSION(int, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
1348 TEST_NUMERIC_CONVERSION(int, intmax_t, SIGN_PRESERVING_NARROW);
1349 TEST_NUMERIC_CONVERSION(unsigned int, uintmax_t, SIGN_PRESERVING_NARROW);
1350 TEST_NUMERIC_CONVERSION(int, float, SIGN_PRESERVING_NARROW);
1351 TEST_NUMERIC_CONVERSION(int, double, SIGN_PRESERVING_NARROW);
1353 TEST_NUMERIC_CONVERSION(unsigned int, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
1354 TEST_NUMERIC_CONVERSION(unsigned int, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
1356 TEST_NUMERIC_CONVERSION(unsigned int, intmax_t, SIGN_TO_UNSIGN_NARROW);
1357 TEST_NUMERIC_CONVERSION(unsigned int, float, SIGN_TO_UNSIGN_NARROW);
1358 TEST_NUMERIC_CONVERSION(unsigned int, double, SIGN_TO_UNSIGN_NARROW);
1360 TEST_NUMERIC_CONVERSION(int, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1361 TEST_NUMERIC_CONVERSION(int, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1364 TEST(SafeNumerics, IntMaxOperations) {
1365 TEST_NUMERIC_CONVERSION(intmax_t, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
1366 TEST_NUMERIC_CONVERSION(uintmax_t, uintmax_t,
1367 SIGN_PRESERVING_VALUE_PRESERVING);
1368 TEST_NUMERIC_CONVERSION(intmax_t, int, SIGN_PRESERVING_VALUE_PRESERVING);
1369 TEST_NUMERIC_CONVERSION(uintmax_t, unsigned int,
1370 SIGN_PRESERVING_VALUE_PRESERVING);
1371 TEST_NUMERIC_CONVERSION(intmax_t, unsigned int,
1372 SIGN_PRESERVING_VALUE_PRESERVING);
1373 TEST_NUMERIC_CONVERSION(intmax_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
1375 TEST_NUMERIC_CONVERSION(intmax_t, float, SIGN_PRESERVING_NARROW);
1376 TEST_NUMERIC_CONVERSION(intmax_t, double, SIGN_PRESERVING_NARROW);
1378 TEST_NUMERIC_CONVERSION(uintmax_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
1379 TEST_NUMERIC_CONVERSION(uintmax_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
1381 TEST_NUMERIC_CONVERSION(uintmax_t, float, SIGN_TO_UNSIGN_NARROW);
1382 TEST_NUMERIC_CONVERSION(uintmax_t, double, SIGN_TO_UNSIGN_NARROW);
1384 TEST_NUMERIC_CONVERSION(intmax_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1387 TEST(SafeNumerics, FloatOperations) {
1388 TEST_NUMERIC_CONVERSION(float, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
1389 TEST_NUMERIC_CONVERSION(float, uintmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
1390 TEST_NUMERIC_CONVERSION(float, int, SIGN_PRESERVING_VALUE_PRESERVING);
1391 TEST_NUMERIC_CONVERSION(float, unsigned int,
1392 SIGN_PRESERVING_VALUE_PRESERVING);
1394 TEST_NUMERIC_CONVERSION(float, double, SIGN_PRESERVING_NARROW);
1397 TEST(SafeNumerics, DoubleOperations) {
1398 TEST_NUMERIC_CONVERSION(double, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
1399 TEST_NUMERIC_CONVERSION(double, uintmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
1400 TEST_NUMERIC_CONVERSION(double, int, SIGN_PRESERVING_VALUE_PRESERVING);
1401 TEST_NUMERIC_CONVERSION(double, unsigned int,
1402 SIGN_PRESERVING_VALUE_PRESERVING);
1405 TEST(SafeNumerics, SizeTOperations) {
1406 TEST_NUMERIC_CONVERSION(size_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
1407 TEST_NUMERIC_CONVERSION(int, size_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1410 // A one-off test to ensure StrictNumeric won't resolve to an incorrect type.
1411 // If this fails we'll just get a compiler error on an ambiguous overload.
1412 int TestOverload(int) { // Overload fails.
1415 uint8_t TestOverload(uint8_t) { // Overload fails.
1418 size_t TestOverload(size_t) { // Overload succeeds.
1423 std::is_same<decltype(TestOverload(StrictNumeric<int>())), int>::value,
1425 static_assert(std::is_same<decltype(TestOverload(StrictNumeric<size_t>())),
1429 template <typename T>
1431 static constexpr T NaN() { return -1; }
1432 static constexpr T max() { return numeric_limits<T>::max() - 1; }
1433 static constexpr T Overflow() { return max(); }
1434 static constexpr T lowest() { return numeric_limits<T>::lowest() + 1; }
1435 static constexpr T Underflow() { return lowest(); }
1438 template <typename T>
1440 static constexpr T NaN() { return 11; }
1441 static constexpr T max() { return 10; }
1442 static constexpr T Overflow() { return max(); }
1443 static constexpr T lowest() { return 1; }
1444 static constexpr T Underflow() { return lowest(); }
1447 TEST(SafeNumerics, CastTests) {
1448 // MSVC catches and warns that we're forcing saturation in these tests.
1449 // Since that's intentional, we need to shut this warning off.
1450 #if defined(COMPILER_MSVC)
1451 #pragma warning(disable : 4756)
1454 int small_positive = 1;
1455 int small_negative = -1;
1456 double double_small = 1.0;
1457 double double_large = numeric_limits<double>::max();
1458 double double_infinity = numeric_limits<float>::infinity();
1459 double double_large_int = numeric_limits<int>::max();
1460 double double_small_int = numeric_limits<int>::lowest();
1462 // Just test that the casts compile, since the other tests cover logic.
1463 EXPECT_EQ(0, checked_cast<int>(static_cast<size_t>(0)));
1464 EXPECT_EQ(0, strict_cast<int>(static_cast<char>(0)));
1465 EXPECT_EQ(0, strict_cast<int>(static_cast<unsigned char>(0)));
1466 EXPECT_EQ(0U, strict_cast<unsigned>(static_cast<unsigned char>(0)));
1467 EXPECT_EQ(1ULL, static_cast<uint64_t>(StrictNumeric<size_t>(1U)));
1468 EXPECT_EQ(1ULL, static_cast<uint64_t>(SizeT(1U)));
1469 EXPECT_EQ(1U, static_cast<size_t>(StrictNumeric<unsigned>(1U)));
1471 EXPECT_TRUE(CheckedNumeric<uint64_t>(StrictNumeric<unsigned>(1U)).IsValid());
1472 EXPECT_TRUE(CheckedNumeric<int>(StrictNumeric<unsigned>(1U)).IsValid());
1473 EXPECT_FALSE(CheckedNumeric<unsigned>(StrictNumeric<int>(-1)).IsValid());
1475 EXPECT_TRUE(IsValueNegative(-1));
1476 EXPECT_TRUE(IsValueNegative(numeric_limits<int>::lowest()));
1477 EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::lowest()));
1478 EXPECT_TRUE(IsValueNegative(numeric_limits<double>::lowest()));
1479 EXPECT_FALSE(IsValueNegative(0));
1480 EXPECT_FALSE(IsValueNegative(1));
1481 EXPECT_FALSE(IsValueNegative(0u));
1482 EXPECT_FALSE(IsValueNegative(1u));
1483 EXPECT_FALSE(IsValueNegative(numeric_limits<int>::max()));
1484 EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::max()));
1485 EXPECT_FALSE(IsValueNegative(numeric_limits<double>::max()));
1487 // These casts and coercions will fail to compile:
1488 // EXPECT_EQ(0, strict_cast<int>(static_cast<size_t>(0)));
1489 // EXPECT_EQ(0, strict_cast<size_t>(static_cast<int>(0)));
1490 // EXPECT_EQ(1ULL, StrictNumeric<size_t>(1));
1491 // EXPECT_EQ(1, StrictNumeric<size_t>(1U));
1493 // Test various saturation corner cases.
1494 EXPECT_EQ(saturated_cast<int>(small_negative),
1495 static_cast<int>(small_negative));
1496 EXPECT_EQ(saturated_cast<int>(small_positive),
1497 static_cast<int>(small_positive));
1498 EXPECT_EQ(saturated_cast<unsigned>(small_negative), static_cast<unsigned>(0));
1499 EXPECT_EQ(saturated_cast<int>(double_small), static_cast<int>(double_small));
1500 EXPECT_EQ(saturated_cast<int>(double_large), numeric_limits<int>::max());
1501 EXPECT_EQ(saturated_cast<float>(double_large), double_infinity);
1502 EXPECT_EQ(saturated_cast<float>(-double_large), -double_infinity);
1503 EXPECT_EQ(numeric_limits<int>::lowest(),
1504 saturated_cast<int>(double_small_int));
1505 EXPECT_EQ(numeric_limits<int>::max(), saturated_cast<int>(double_large_int));
1507 // Test the saturated cast overrides.
1508 using FloatLimits = numeric_limits<float>;
1509 using IntLimits = numeric_limits<int>;
1510 EXPECT_EQ(-1, (saturated_cast<int, CastTest1>(FloatLimits::quiet_NaN())));
1511 EXPECT_EQ(CastTest1<int>::max(),
1512 (saturated_cast<int, CastTest1>(FloatLimits::infinity())));
1513 EXPECT_EQ(CastTest1<int>::max(),
1514 (saturated_cast<int, CastTest1>(FloatLimits::max())));
1515 EXPECT_EQ(CastTest1<int>::max(),
1516 (saturated_cast<int, CastTest1>(float(IntLimits::max()))));
1517 EXPECT_EQ(CastTest1<int>::lowest(),
1518 (saturated_cast<int, CastTest1>(-FloatLimits::infinity())));
1519 EXPECT_EQ(CastTest1<int>::lowest(),
1520 (saturated_cast<int, CastTest1>(FloatLimits::lowest())));
1521 EXPECT_EQ(0, (saturated_cast<int, CastTest1>(0.0)));
1522 EXPECT_EQ(1, (saturated_cast<int, CastTest1>(1.0)));
1523 EXPECT_EQ(-1, (saturated_cast<int, CastTest1>(-1.0)));
1524 EXPECT_EQ(0, (saturated_cast<int, CastTest1>(0)));
1525 EXPECT_EQ(1, (saturated_cast<int, CastTest1>(1)));
1526 EXPECT_EQ(-1, (saturated_cast<int, CastTest1>(-1)));
1527 EXPECT_EQ(CastTest1<int>::lowest(),
1528 (saturated_cast<int, CastTest1>(float(IntLimits::lowest()))));
1529 EXPECT_EQ(11, (saturated_cast<int, CastTest2>(FloatLimits::quiet_NaN())));
1530 EXPECT_EQ(10, (saturated_cast<int, CastTest2>(FloatLimits::infinity())));
1531 EXPECT_EQ(10, (saturated_cast<int, CastTest2>(FloatLimits::max())));
1532 EXPECT_EQ(1, (saturated_cast<int, CastTest2>(-FloatLimits::infinity())));
1533 EXPECT_EQ(1, (saturated_cast<int, CastTest2>(FloatLimits::lowest())));
1534 EXPECT_EQ(1, (saturated_cast<int, CastTest2>(0U)));
1536 float not_a_number = std::numeric_limits<float>::infinity() -
1537 std::numeric_limits<float>::infinity();
1538 EXPECT_TRUE(std::isnan(not_a_number));
1539 EXPECT_EQ(0, saturated_cast<int>(not_a_number));
1541 // Test the CheckedNumeric value extractions functions.
1542 auto int8_min = MakeCheckedNum(numeric_limits<int8_t>::lowest());
1543 auto int8_max = MakeCheckedNum(numeric_limits<int8_t>::max());
1544 auto double_max = MakeCheckedNum(numeric_limits<double>::max());
1546 std::is_same<int16_t,
1547 decltype(int8_min.ValueOrDie<int16_t>())::type>::value,
1548 "ValueOrDie returning incorrect type.");
1550 std::is_same<int16_t,
1551 decltype(int8_min.ValueOrDefault<int16_t>(0))::type>::value,
1552 "ValueOrDefault returning incorrect type.");
1553 EXPECT_FALSE(IsValidForType<uint8_t>(int8_min));
1554 EXPECT_TRUE(IsValidForType<uint8_t>(int8_max));
1555 EXPECT_EQ(static_cast<int>(numeric_limits<int8_t>::lowest()),
1556 ValueOrDieForType<int>(int8_min));
1557 EXPECT_TRUE(IsValidForType<uint32_t>(int8_max));
1558 EXPECT_EQ(static_cast<int>(numeric_limits<int8_t>::max()),
1559 ValueOrDieForType<int>(int8_max));
1560 EXPECT_EQ(0, ValueOrDefaultForType<int>(double_max, 0));
1561 uint8_t uint8_dest = 0;
1562 int16_t int16_dest = 0;
1563 double double_dest = 0;
1564 EXPECT_TRUE(int8_max.AssignIfValid(&uint8_dest));
1565 EXPECT_EQ(static_cast<uint8_t>(numeric_limits<int8_t>::max()), uint8_dest);
1566 EXPECT_FALSE(int8_min.AssignIfValid(&uint8_dest));
1567 EXPECT_TRUE(int8_max.AssignIfValid(&int16_dest));
1568 EXPECT_EQ(static_cast<int16_t>(numeric_limits<int8_t>::max()), int16_dest);
1569 EXPECT_TRUE(int8_min.AssignIfValid(&int16_dest));
1570 EXPECT_EQ(static_cast<int16_t>(numeric_limits<int8_t>::lowest()), int16_dest);
1571 EXPECT_FALSE(double_max.AssignIfValid(&uint8_dest));
1572 EXPECT_FALSE(double_max.AssignIfValid(&int16_dest));
1573 EXPECT_TRUE(double_max.AssignIfValid(&double_dest));
1574 EXPECT_EQ(numeric_limits<double>::max(), double_dest);
1575 EXPECT_EQ(1, checked_cast<int>(StrictNumeric<int>(1)));
1576 EXPECT_EQ(1, saturated_cast<int>(StrictNumeric<int>(1)));
1577 EXPECT_EQ(1, strict_cast<int>(StrictNumeric<int>(1)));
1579 enum class EnumTest { kOne = 1 };
1580 EXPECT_EQ(1, checked_cast<int>(EnumTest::kOne));
1581 EXPECT_EQ(1, saturated_cast<int>(EnumTest::kOne));
1582 EXPECT_EQ(1, strict_cast<int>(EnumTest::kOne));
1585 TEST(SafeNumerics, IsValueInRangeForNumericType) {
1586 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0));
1587 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(1));
1588 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(2));
1589 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(-1));
1590 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0xffffffffu));
1591 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0xffffffff)));
1592 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000000)));
1593 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000001)));
1594 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(
1595 std::numeric_limits<int32_t>::lowest()));
1596 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(
1597 std::numeric_limits<int64_t>::lowest()));
1599 // Converting to integer types will discard the fractional part first, so -0.9
1600 // will be truncated to -0.0.
1601 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(-0.9));
1602 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(-1.0));
1604 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0));
1605 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(1));
1606 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(2));
1607 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(-1));
1608 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffff));
1609 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffffu));
1610 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0x80000000u));
1611 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0xffffffffu));
1612 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x80000000)));
1613 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0xffffffff)));
1614 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x100000000)));
1615 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(
1616 std::numeric_limits<int32_t>::lowest()));
1617 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(
1618 static_cast<int64_t>(std::numeric_limits<int32_t>::lowest())));
1619 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(
1620 static_cast<int64_t>(std::numeric_limits<int32_t>::lowest()) - 1));
1621 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(
1622 std::numeric_limits<int64_t>::lowest()));
1624 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0));
1625 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(1));
1626 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(2));
1627 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(-1));
1628 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0xffffffffu));
1629 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0xffffffff)));
1630 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000000)));
1631 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000001)));
1632 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(
1633 std::numeric_limits<int32_t>::lowest()));
1634 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(INT64_C(-1)));
1635 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(
1636 std::numeric_limits<int64_t>::lowest()));
1638 // Converting to integer types will discard the fractional part first, so -0.9
1639 // will be truncated to -0.0.
1640 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(-0.9));
1641 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(-1.0));
1643 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0));
1644 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(1));
1645 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(2));
1646 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(-1));
1647 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffff));
1648 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffffu));
1649 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x80000000u));
1650 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0xffffffffu));
1651 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x80000000)));
1652 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0xffffffff)));
1653 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x100000000)));
1655 IsValueInRangeForNumericType<int64_t>(INT64_C(0x7fffffffffffffff)));
1657 IsValueInRangeForNumericType<int64_t>(UINT64_C(0x7fffffffffffffff)));
1659 IsValueInRangeForNumericType<int64_t>(UINT64_C(0x8000000000000000)));
1661 IsValueInRangeForNumericType<int64_t>(UINT64_C(0xffffffffffffffff)));
1662 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
1663 std::numeric_limits<int32_t>::lowest()));
1664 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
1665 static_cast<int64_t>(std::numeric_limits<int32_t>::lowest())));
1666 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
1667 std::numeric_limits<int64_t>::lowest()));
1670 TEST(SafeNumerics, CompoundNumericOperations) {
1671 CheckedNumeric<int> a = 1;
1672 CheckedNumeric<int> b = 2;
1673 CheckedNumeric<int> c = 3;
1674 CheckedNumeric<int> d = 4;
1676 EXPECT_EQ(3, a.ValueOrDie());
1678 EXPECT_EQ(0, a.ValueOrDie());
1680 EXPECT_EQ(2, d.ValueOrDie());
1682 EXPECT_EQ(4, d.ValueOrDie());
1684 EXPECT_EQ(2, d.ValueOrDie());
1686 CheckedNumeric<int> too_large = std::numeric_limits<int>::max();
1687 EXPECT_TRUE(too_large.IsValid());
1689 EXPECT_FALSE(too_large.IsValid());
1691 EXPECT_FALSE(too_large.IsValid());
1693 EXPECT_FALSE(too_large.IsValid());
1696 TEST(SafeNumerics, VariadicNumericOperations) {
1697 { // Synthetic scope to avoid variable naming collisions.
1698 auto a = CheckAdd(1, 2UL, MakeCheckedNum(3LL), 4).ValueOrDie();
1699 EXPECT_EQ(static_cast<decltype(a)::type>(10), a);
1700 auto b = CheckSub(MakeCheckedNum(20.0), 2UL, 4).ValueOrDie();
1701 EXPECT_EQ(static_cast<decltype(b)::type>(14.0), b);
1702 auto c = CheckMul(20.0, MakeCheckedNum(1), 5, 3UL).ValueOrDie();
1703 EXPECT_EQ(static_cast<decltype(c)::type>(300.0), c);
1704 auto d = CheckDiv(20.0, 2.0, MakeCheckedNum(5LL), -4).ValueOrDie();
1705 EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d);
1706 auto e = CheckMod(MakeCheckedNum(20), 3).ValueOrDie();
1707 EXPECT_EQ(static_cast<decltype(e)::type>(2), e);
1708 auto f = CheckLsh(1, MakeCheckedNum(2)).ValueOrDie();
1709 EXPECT_EQ(static_cast<decltype(f)::type>(4), f);
1710 auto g = CheckRsh(4, MakeCheckedNum(2)).ValueOrDie();
1711 EXPECT_EQ(static_cast<decltype(g)::type>(1), g);
1712 auto h = CheckRsh(CheckAdd(1, 1, 1, 1), CheckSub(4, 2)).ValueOrDie();
1713 EXPECT_EQ(static_cast<decltype(h)::type>(1), h);
1717 auto a = ClampAdd(1, 2UL, MakeClampedNum(3LL), 4);
1718 EXPECT_EQ(static_cast<decltype(a)::type>(10), a);
1719 auto b = ClampSub(MakeClampedNum(20.0), 2UL, 4);
1720 EXPECT_EQ(static_cast<decltype(b)::type>(14.0), b);
1721 auto c = ClampMul(20.0, MakeClampedNum(1), 5, 3UL);
1722 EXPECT_EQ(static_cast<decltype(c)::type>(300.0), c);
1723 auto d = ClampDiv(20.0, 2.0, MakeClampedNum(5LL), -4);
1724 EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d);
1725 auto e = ClampMod(MakeClampedNum(20), 3);
1726 EXPECT_EQ(static_cast<decltype(e)::type>(2), e);
1727 auto f = ClampLsh(1, MakeClampedNum(2U));
1728 EXPECT_EQ(static_cast<decltype(f)::type>(4), f);
1729 auto g = ClampRsh(4, MakeClampedNum(2U));
1730 EXPECT_EQ(static_cast<decltype(g)::type>(1), g);
1731 auto h = ClampRsh(ClampAdd(1, 1, 1, 1), ClampSub(4U, 2));
1732 EXPECT_EQ(static_cast<decltype(h)::type>(1), h);
1736 TEST(SafeNumerics, CeilInt) {
1737 constexpr float kMax = static_cast<float>(std::numeric_limits<int>::max());
1738 constexpr float kMin = std::numeric_limits<int>::min();
1739 constexpr float kInfinity = std::numeric_limits<float>::infinity();
1740 constexpr float kNaN = std::numeric_limits<float>::quiet_NaN();
1742 constexpr int kIntMax = std::numeric_limits<int>::max();
1743 constexpr int kIntMin = std::numeric_limits<int>::min();
1745 EXPECT_EQ(kIntMax, ClampCeil(kInfinity));
1746 EXPECT_EQ(kIntMax, ClampCeil(kMax));
1747 EXPECT_EQ(kIntMax, ClampCeil(kMax + 100.0f));
1748 EXPECT_EQ(0, ClampCeil(kNaN));
1750 EXPECT_EQ(-100, ClampCeil(-100.5f));
1751 EXPECT_EQ(0, ClampCeil(0.0f));
1752 EXPECT_EQ(101, ClampCeil(100.5f));
1754 EXPECT_EQ(kIntMin, ClampCeil(-kInfinity));
1755 EXPECT_EQ(kIntMin, ClampCeil(kMin));
1756 EXPECT_EQ(kIntMin, ClampCeil(kMin - 100.0f));
1757 EXPECT_EQ(0, ClampCeil(-kNaN));
1760 TEST(SafeNumerics, FloorInt) {
1761 constexpr float kMax = static_cast<float>(std::numeric_limits<int>::max());
1762 constexpr float kMin = std::numeric_limits<int>::min();
1763 constexpr float kInfinity = std::numeric_limits<float>::infinity();
1764 constexpr float kNaN = std::numeric_limits<float>::quiet_NaN();
1766 constexpr int kIntMax = std::numeric_limits<int>::max();
1767 constexpr int kIntMin = std::numeric_limits<int>::min();
1769 EXPECT_EQ(kIntMax, ClampFloor(kInfinity));
1770 EXPECT_EQ(kIntMax, ClampFloor(kMax));
1771 EXPECT_EQ(kIntMax, ClampFloor(kMax + 100.0f));
1772 EXPECT_EQ(0, ClampFloor(kNaN));
1774 EXPECT_EQ(-101, ClampFloor(-100.5f));
1775 EXPECT_EQ(0, ClampFloor(0.0f));
1776 EXPECT_EQ(100, ClampFloor(100.5f));
1778 EXPECT_EQ(kIntMin, ClampFloor(-kInfinity));
1779 EXPECT_EQ(kIntMin, ClampFloor(kMin));
1780 EXPECT_EQ(kIntMin, ClampFloor(kMin - 100.0f));
1781 EXPECT_EQ(0, ClampFloor(-kNaN));
1784 TEST(SafeNumerics, RoundInt) {
1785 constexpr float kMax = static_cast<float>(std::numeric_limits<int>::max());
1786 constexpr float kMin = std::numeric_limits<int>::min();
1787 constexpr float kInfinity = std::numeric_limits<float>::infinity();
1788 constexpr float kNaN = std::numeric_limits<float>::quiet_NaN();
1790 constexpr int kIntMax = std::numeric_limits<int>::max();
1791 constexpr int kIntMin = std::numeric_limits<int>::min();
1793 EXPECT_EQ(kIntMax, ClampRound(kInfinity));
1794 EXPECT_EQ(kIntMax, ClampRound(kMax));
1795 EXPECT_EQ(kIntMax, ClampRound(kMax + 100.0f));
1796 EXPECT_EQ(0, ClampRound(kNaN));
1798 EXPECT_EQ(-100, ClampRound(-100.1f));
1799 EXPECT_EQ(-101, ClampRound(-100.5f));
1800 EXPECT_EQ(-101, ClampRound(-100.9f));
1801 EXPECT_EQ(0, ClampRound(0.0f));
1802 EXPECT_EQ(100, ClampRound(100.1f));
1803 EXPECT_EQ(101, ClampRound(100.5f));
1804 EXPECT_EQ(101, ClampRound(100.9f));
1806 EXPECT_EQ(kIntMin, ClampRound(-kInfinity));
1807 EXPECT_EQ(kIntMin, ClampRound(kMin));
1808 EXPECT_EQ(kIntMin, ClampRound(kMin - 100.0f));
1809 EXPECT_EQ(0, ClampRound(-kNaN));
1812 TEST(SafeNumerics, Int64) {
1813 constexpr double kMax =
1814 static_cast<double>(std::numeric_limits<int64_t>::max());
1815 constexpr double kMin = std::numeric_limits<int64_t>::min();
1816 constexpr double kInfinity = std::numeric_limits<double>::infinity();
1817 constexpr double kNaN = std::numeric_limits<double>::quiet_NaN();
1819 constexpr int64_t kInt64Max = std::numeric_limits<int64_t>::max();
1820 constexpr int64_t kInt64Min = std::numeric_limits<int64_t>::min();
1822 EXPECT_EQ(kInt64Max, ClampFloor<int64_t>(kInfinity));
1823 EXPECT_EQ(kInt64Max, ClampCeil<int64_t>(kInfinity));
1824 EXPECT_EQ(kInt64Max, ClampRound<int64_t>(kInfinity));
1825 EXPECT_EQ(kInt64Max, ClampFloor<int64_t>(kMax));
1826 EXPECT_EQ(kInt64Max, ClampCeil<int64_t>(kMax));
1827 EXPECT_EQ(kInt64Max, ClampRound<int64_t>(kMax));
1828 EXPECT_EQ(kInt64Max, ClampFloor<int64_t>(kMax + 100.0));
1829 EXPECT_EQ(kInt64Max, ClampCeil<int64_t>(kMax + 100.0));
1830 EXPECT_EQ(kInt64Max, ClampRound<int64_t>(kMax + 100.0));
1831 EXPECT_EQ(0, ClampFloor<int64_t>(kNaN));
1832 EXPECT_EQ(0, ClampCeil<int64_t>(kNaN));
1833 EXPECT_EQ(0, ClampRound<int64_t>(kNaN));
1835 EXPECT_EQ(kInt64Min, ClampFloor<int64_t>(-kInfinity));
1836 EXPECT_EQ(kInt64Min, ClampCeil<int64_t>(-kInfinity));
1837 EXPECT_EQ(kInt64Min, ClampRound<int64_t>(-kInfinity));
1838 EXPECT_EQ(kInt64Min, ClampFloor<int64_t>(kMin));
1839 EXPECT_EQ(kInt64Min, ClampCeil<int64_t>(kMin));
1840 EXPECT_EQ(kInt64Min, ClampRound<int64_t>(kMin));
1841 EXPECT_EQ(kInt64Min, ClampFloor<int64_t>(kMin - 100.0));
1842 EXPECT_EQ(kInt64Min, ClampCeil<int64_t>(kMin - 100.0));
1843 EXPECT_EQ(kInt64Min, ClampRound<int64_t>(kMin - 100.0));
1844 EXPECT_EQ(0, ClampFloor<int64_t>(-kNaN));
1845 EXPECT_EQ(0, ClampCeil<int64_t>(-kNaN));
1846 EXPECT_EQ(0, ClampRound<int64_t>(-kNaN));
1849 #if defined(__clang__)
1850 #pragma clang diagnostic pop // -Winteger-overflow
1853 } // namespace internal