OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stddef.h> | 5 #include <stddef.h> |
6 #include <stdint.h> | 6 #include <stdint.h> |
7 | 7 |
8 #include <limits> | 8 #include <limits> |
9 #include <type_traits> | 9 #include <type_traits> |
10 | 10 |
11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/numerics/safe_conversions.h" | 13 #include "base/numerics/safe_conversions.h" |
14 #include "base/numerics/safe_math.h" | 14 #include "base/numerics/safe_math.h" |
15 #include "base/test/gtest_util.h" | 15 #include "base/test/gtest_util.h" |
16 #include "build/build_config.h" | 16 #include "build/build_config.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
18 | 18 |
19 #if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS) | 19 #if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS) |
20 #include <mmintrin.h> | 20 #include <mmintrin.h> |
21 #endif | 21 #endif |
22 | 22 |
23 using std::numeric_limits; | 23 using std::numeric_limits; |
24 using base::CheckedNumeric; | 24 using base::CheckedNumeric; |
25 using base::IsValidForType; | 25 using base::IsValidForType; |
26 using base::ValueOrDieForType; | 26 using base::ValueOrDieForType; |
27 using base::ValueOrDefaultForType; | 27 using base::ValueOrDefaultForType; |
28 using base::CheckNum; | 28 using base::CheckNum; |
| 29 using base::CheckMax; |
| 30 using base::CheckMin; |
29 using base::CheckAdd; | 31 using base::CheckAdd; |
30 using base::CheckSub; | 32 using base::CheckSub; |
31 using base::CheckMul; | 33 using base::CheckMul; |
32 using base::CheckDiv; | 34 using base::CheckDiv; |
33 using base::CheckMod; | 35 using base::CheckMod; |
34 using base::CheckLsh; | 36 using base::CheckLsh; |
35 using base::CheckRsh; | 37 using base::CheckRsh; |
36 using base::checked_cast; | 38 using base::checked_cast; |
37 using base::IsValueInRangeForNumericType; | 39 using base::IsValueInRangeForNumericType; |
38 using base::IsValueNegative; | 40 using base::IsValueNegative; |
39 using base::SizeT; | 41 using base::SizeT; |
40 using base::StrictNumeric; | 42 using base::StrictNumeric; |
| 43 using base::MakeStrictNum; |
41 using base::saturated_cast; | 44 using base::saturated_cast; |
42 using base::strict_cast; | 45 using base::strict_cast; |
43 using base::StrictNumeric; | |
44 using base::internal::MaxExponent; | 46 using base::internal::MaxExponent; |
45 using base::internal::RANGE_VALID; | 47 using base::internal::RANGE_VALID; |
46 using base::internal::RANGE_INVALID; | 48 using base::internal::RANGE_INVALID; |
47 using base::internal::RANGE_OVERFLOW; | 49 using base::internal::RANGE_OVERFLOW; |
48 using base::internal::RANGE_UNDERFLOW; | 50 using base::internal::RANGE_UNDERFLOW; |
49 using base::internal::SignedIntegerForSize; | 51 using base::internal::SignedIntegerForSize; |
50 | 52 |
51 // These tests deliberately cause arithmetic boundary errors. If the compiler is | 53 // These tests deliberately cause arithmetic boundary errors. If the compiler is |
52 // aggressive enough, it can const detect these errors, so we disable warnings. | 54 // aggressive enough, it can const detect these errors, so we disable warnings. |
53 #if defined(OS_WIN) | 55 #if defined(OS_WIN) |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 // EXPECT_EQ wrappers providing specific detail on test failures. | 433 // EXPECT_EQ wrappers providing specific detail on test failures. |
432 #define TEST_EXPECTED_RANGE(expected, actual) \ | 434 #define TEST_EXPECTED_RANGE(expected, actual) \ |
433 EXPECT_EQ(expected, base::internal::DstRangeRelationToSrcRange<Dst>(actual)) \ | 435 EXPECT_EQ(expected, base::internal::DstRangeRelationToSrcRange<Dst>(actual)) \ |
434 << "Conversion test: " << src << " value " << actual << " to " << dst \ | 436 << "Conversion test: " << src << " value " << actual << " to " << dst \ |
435 << " on line " << line | 437 << " on line " << line |
436 | 438 |
437 template <typename Dst, typename Src> | 439 template <typename Dst, typename Src> |
438 void TestStrictComparison() { | 440 void TestStrictComparison() { |
439 typedef numeric_limits<Dst> DstLimits; | 441 typedef numeric_limits<Dst> DstLimits; |
440 typedef numeric_limits<Src> SrcLimits; | 442 typedef numeric_limits<Src> SrcLimits; |
441 static_assert(StrictNumeric<Src>(SrcLimits::min()) < DstLimits::max(), ""); | 443 static_assert(StrictNumeric<Src>(SrcLimits::lowest()) < DstLimits::max(), ""); |
442 static_assert(StrictNumeric<Src>(SrcLimits::min()) < SrcLimits::max(), ""); | 444 static_assert(StrictNumeric<Src>(SrcLimits::lowest()) < SrcLimits::max(), ""); |
443 static_assert(!(StrictNumeric<Src>(SrcLimits::min()) >= DstLimits::max()), | 445 static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) >= DstLimits::max()), |
444 ""); | 446 ""); |
445 static_assert(!(StrictNumeric<Src>(SrcLimits::min()) >= SrcLimits::max()), | 447 static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) >= SrcLimits::max()), |
446 ""); | 448 ""); |
447 static_assert(StrictNumeric<Src>(SrcLimits::min()) <= DstLimits::max(), ""); | 449 static_assert(StrictNumeric<Src>(SrcLimits::lowest()) <= DstLimits::max(), |
448 static_assert(StrictNumeric<Src>(SrcLimits::min()) <= SrcLimits::max(), ""); | |
449 static_assert(!(StrictNumeric<Src>(SrcLimits::min()) > DstLimits::max()), ""); | |
450 static_assert(!(StrictNumeric<Src>(SrcLimits::min()) > SrcLimits::max()), ""); | |
451 static_assert(StrictNumeric<Src>(SrcLimits::max()) > DstLimits::min(), ""); | |
452 static_assert(StrictNumeric<Src>(SrcLimits::max()) > SrcLimits::min(), ""); | |
453 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) <= DstLimits::min()), | |
454 ""); | 450 ""); |
455 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) <= SrcLimits::min()), | 451 static_assert(StrictNumeric<Src>(SrcLimits::lowest()) <= SrcLimits::max(), |
456 ""); | 452 ""); |
457 static_assert(StrictNumeric<Src>(SrcLimits::max()) >= DstLimits::min(), ""); | 453 static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) > DstLimits::max()), |
458 static_assert(StrictNumeric<Src>(SrcLimits::max()) >= SrcLimits::min(), ""); | 454 ""); |
459 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) < DstLimits::min()), ""); | 455 static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) > SrcLimits::max()), |
460 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) < SrcLimits::min()), ""); | 456 ""); |
| 457 static_assert(StrictNumeric<Src>(SrcLimits::max()) > DstLimits::lowest(), ""); |
| 458 static_assert(StrictNumeric<Src>(SrcLimits::max()) > SrcLimits::lowest(), ""); |
| 459 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) <= DstLimits::lowest()), |
| 460 ""); |
| 461 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) <= SrcLimits::lowest()), |
| 462 ""); |
| 463 static_assert(StrictNumeric<Src>(SrcLimits::max()) >= DstLimits::lowest(), |
| 464 ""); |
| 465 static_assert(StrictNumeric<Src>(SrcLimits::max()) >= SrcLimits::lowest(), |
| 466 ""); |
| 467 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) < DstLimits::lowest()), |
| 468 ""); |
| 469 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) < SrcLimits::lowest()), |
| 470 ""); |
461 static_assert(StrictNumeric<Src>(static_cast<Src>(1)) == static_cast<Dst>(1), | 471 static_assert(StrictNumeric<Src>(static_cast<Src>(1)) == static_cast<Dst>(1), |
462 ""); | 472 ""); |
463 static_assert(StrictNumeric<Src>(static_cast<Src>(1)) != static_cast<Dst>(0), | 473 static_assert(StrictNumeric<Src>(static_cast<Src>(1)) != static_cast<Dst>(0), |
464 ""); | 474 ""); |
465 static_assert(StrictNumeric<Src>(SrcLimits::max()) != static_cast<Dst>(0), | 475 static_assert(StrictNumeric<Src>(SrcLimits::max()) != static_cast<Dst>(0), |
466 ""); | 476 ""); |
467 static_assert(StrictNumeric<Src>(SrcLimits::max()) != DstLimits::min(), ""); | 477 static_assert(StrictNumeric<Src>(SrcLimits::max()) != DstLimits::lowest(), |
| 478 ""); |
468 static_assert( | 479 static_assert( |
469 !(StrictNumeric<Src>(static_cast<Src>(1)) != static_cast<Dst>(1)), ""); | 480 !(StrictNumeric<Src>(static_cast<Src>(1)) != static_cast<Dst>(1)), ""); |
470 static_assert( | 481 static_assert( |
471 !(StrictNumeric<Src>(static_cast<Src>(1)) == static_cast<Dst>(0)), ""); | 482 !(StrictNumeric<Src>(static_cast<Src>(1)) == static_cast<Dst>(0)), ""); |
| 483 |
| 484 // Due to differences in float handling between compilers, these aren't |
| 485 // compile-time constants everywhere. So, we use run-time tests. |
| 486 EXPECT_EQ(SrcLimits::max(), |
| 487 CheckNum(SrcLimits::max()).Max(DstLimits::lowest()).ValueOrDie()); |
| 488 EXPECT_EQ(DstLimits::max(), |
| 489 CheckNum(SrcLimits::lowest()).Max(DstLimits::max()).ValueOrDie()); |
| 490 EXPECT_EQ(DstLimits::lowest(), |
| 491 CheckNum(SrcLimits::max()).Min(DstLimits::lowest()).ValueOrDie()); |
| 492 EXPECT_EQ(SrcLimits::lowest(), |
| 493 CheckNum(SrcLimits::lowest()).Min(DstLimits::max()).ValueOrDie()); |
| 494 EXPECT_EQ(SrcLimits::lowest(), CheckMin(MakeStrictNum(1), CheckNum(0), |
| 495 DstLimits::max(), SrcLimits::lowest()) |
| 496 .ValueOrDie()); |
| 497 EXPECT_EQ(DstLimits::max(), CheckMax(MakeStrictNum(1), CheckNum(0), |
| 498 DstLimits::max(), SrcLimits::lowest()) |
| 499 .ValueOrDie()); |
472 } | 500 } |
473 | 501 |
474 template <typename Dst, typename Src> | 502 template <typename Dst, typename Src> |
475 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> { | 503 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> { |
476 static void Test(const char *dst, const char *src, int line) { | 504 static void Test(const char *dst, const char *src, int line) { |
477 typedef numeric_limits<Src> SrcLimits; | 505 typedef numeric_limits<Src> SrcLimits; |
478 typedef numeric_limits<Dst> DstLimits; | 506 typedef numeric_limits<Dst> DstLimits; |
479 // Integral to floating. | 507 // Integral to floating. |
480 static_assert((DstLimits::is_iec559 && SrcLimits::is_integer) || | 508 static_assert((DstLimits::is_iec559 && SrcLimits::is_integer) || |
481 // Not floating to integral and... | 509 // Not floating to integral and... |
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d); | 1025 EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d); |
998 auto e = CheckMod(CheckNum(20), 3).ValueOrDie(); | 1026 auto e = CheckMod(CheckNum(20), 3).ValueOrDie(); |
999 EXPECT_EQ(static_cast<decltype(e)::type>(2), e); | 1027 EXPECT_EQ(static_cast<decltype(e)::type>(2), e); |
1000 auto f = CheckLsh(1, CheckNum(2)).ValueOrDie(); | 1028 auto f = CheckLsh(1, CheckNum(2)).ValueOrDie(); |
1001 EXPECT_EQ(static_cast<decltype(f)::type>(4), f); | 1029 EXPECT_EQ(static_cast<decltype(f)::type>(4), f); |
1002 auto g = CheckRsh(4, CheckNum(2)).ValueOrDie(); | 1030 auto g = CheckRsh(4, CheckNum(2)).ValueOrDie(); |
1003 EXPECT_EQ(static_cast<decltype(g)::type>(1), g); | 1031 EXPECT_EQ(static_cast<decltype(g)::type>(1), g); |
1004 auto h = CheckRsh(CheckAdd(1, 1, 1, 1), CheckSub(4, 2)).ValueOrDie(); | 1032 auto h = CheckRsh(CheckAdd(1, 1, 1, 1), CheckSub(4, 2)).ValueOrDie(); |
1005 EXPECT_EQ(static_cast<decltype(h)::type>(1), h); | 1033 EXPECT_EQ(static_cast<decltype(h)::type>(1), h); |
1006 } | 1034 } |
OLD | NEW |