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 |
(...skipping 27 matching lines...) Expand all Loading... |
38 using base::checked_cast; | 38 using base::checked_cast; |
39 using base::IsValueInRangeForNumericType; | 39 using base::IsValueInRangeForNumericType; |
40 using base::IsValueNegative; | 40 using base::IsValueNegative; |
41 using base::SizeT; | 41 using base::SizeT; |
42 using base::StrictNumeric; | 42 using base::StrictNumeric; |
43 using base::MakeStrictNum; | 43 using base::MakeStrictNum; |
44 using base::saturated_cast; | 44 using base::saturated_cast; |
45 using base::strict_cast; | 45 using base::strict_cast; |
46 using base::internal::MaxExponent; | 46 using base::internal::MaxExponent; |
47 using base::internal::IntegerBitsPlusSign; | 47 using base::internal::IntegerBitsPlusSign; |
48 using base::internal::RANGE_VALID; | 48 using base::internal::RangeCheck; |
49 using base::internal::RANGE_INVALID; | |
50 using base::internal::RANGE_OVERFLOW; | |
51 using base::internal::RANGE_UNDERFLOW; | |
52 | 49 |
53 // These tests deliberately cause arithmetic boundary errors. If the compiler is | 50 // These tests deliberately cause arithmetic boundary errors. If the compiler is |
54 // aggressive enough, it can const detect these errors, so we disable warnings. | 51 // aggressive enough, it can const detect these errors, so we disable warnings. |
55 #if defined(OS_WIN) | 52 #if defined(OS_WIN) |
56 #pragma warning(disable : 4756) // Arithmetic overflow. | 53 #pragma warning(disable : 4756) // Arithmetic overflow. |
57 #pragma warning(disable : 4293) // Invalid shift. | 54 #pragma warning(disable : 4293) // Invalid shift. |
58 #endif | 55 #endif |
59 | 56 |
60 // This is a helper function for finding the maximum value in Src that can be | 57 // This is a helper function for finding the maximum value in Src that can be |
61 // wholy represented as the destination floating-point type. | 58 // wholy represented as the destination floating-point type. |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 SIGN_PRESERVING_NARROW, | 506 SIGN_PRESERVING_NARROW, |
510 SIGN_TO_UNSIGN_WIDEN_OR_EQUAL, | 507 SIGN_TO_UNSIGN_WIDEN_OR_EQUAL, |
511 SIGN_TO_UNSIGN_NARROW, | 508 SIGN_TO_UNSIGN_NARROW, |
512 UNSIGN_TO_SIGN_NARROW_OR_EQUAL, | 509 UNSIGN_TO_SIGN_NARROW_OR_EQUAL, |
513 }; | 510 }; |
514 | 511 |
515 // Template covering the different conversion tests. | 512 // Template covering the different conversion tests. |
516 template <typename Dst, typename Src, NumericConversionType conversion> | 513 template <typename Dst, typename Src, NumericConversionType conversion> |
517 struct TestNumericConversion {}; | 514 struct TestNumericConversion {}; |
518 | 515 |
| 516 enum RangeConstraint { |
| 517 RANGE_VALID = 0x0, // Value can be represented by the destination type. |
| 518 RANGE_UNDERFLOW = 0x1, // Value would underflow. |
| 519 RANGE_OVERFLOW = 0x2, // Value would overflow. |
| 520 RANGE_INVALID = RANGE_UNDERFLOW | RANGE_OVERFLOW // Invalid (i.e. NaN). |
| 521 }; |
| 522 |
| 523 // These are some wrappers to make the tests a bit cleaner. |
| 524 constexpr RangeConstraint RangeCheckToEnum(const RangeCheck constraint) { |
| 525 return static_cast<RangeConstraint>( |
| 526 static_cast<int>(constraint.IsOverflowFlagSet()) << 1 | |
| 527 static_cast<int>(constraint.IsUnderflowFlagSet())); |
| 528 } |
| 529 |
519 // EXPECT_EQ wrappers providing specific detail on test failures. | 530 // EXPECT_EQ wrappers providing specific detail on test failures. |
520 #define TEST_EXPECTED_RANGE(expected, actual) \ | 531 #define TEST_EXPECTED_RANGE(expected, actual) \ |
521 EXPECT_EQ(expected, base::internal::DstRangeRelationToSrcRange<Dst>(actual)) \ | 532 EXPECT_EQ(expected, \ |
522 << "Conversion test: " << src << " value " << actual << " to " << dst \ | 533 RangeCheckToEnum( \ |
| 534 base::internal::DstRangeRelationToSrcRange<Dst>(actual))) \ |
| 535 << "Conversion test: " << src << " value " << actual << " to " << dst \ |
523 << " on line " << line | 536 << " on line " << line |
524 | 537 |
525 template <typename Dst, typename Src> | 538 template <typename Dst, typename Src> |
526 void TestStrictComparison() { | 539 void TestStrictComparison() { |
527 using DstLimits = numeric_limits<Dst>; | 540 using DstLimits = numeric_limits<Dst>; |
528 using SrcLimits = numeric_limits<Src>; | 541 using SrcLimits = numeric_limits<Src>; |
529 static_assert(StrictNumeric<Src>(SrcLimits::lowest()) < DstLimits::max(), ""); | 542 static_assert(StrictNumeric<Src>(SrcLimits::lowest()) < DstLimits::max(), ""); |
530 static_assert(StrictNumeric<Src>(SrcLimits::lowest()) < SrcLimits::max(), ""); | 543 static_assert(StrictNumeric<Src>(SrcLimits::lowest()) < SrcLimits::max(), ""); |
531 static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) >= DstLimits::max()), | 544 static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) >= DstLimits::max()), |
532 ""); | 545 ""); |
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1164 EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d); | 1177 EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d); |
1165 auto e = CheckMod(MakeCheckedNum(20), 3).ValueOrDie(); | 1178 auto e = CheckMod(MakeCheckedNum(20), 3).ValueOrDie(); |
1166 EXPECT_EQ(static_cast<decltype(e)::type>(2), e); | 1179 EXPECT_EQ(static_cast<decltype(e)::type>(2), e); |
1167 auto f = CheckLsh(1, MakeCheckedNum(2)).ValueOrDie(); | 1180 auto f = CheckLsh(1, MakeCheckedNum(2)).ValueOrDie(); |
1168 EXPECT_EQ(static_cast<decltype(f)::type>(4), f); | 1181 EXPECT_EQ(static_cast<decltype(f)::type>(4), f); |
1169 auto g = CheckRsh(4, MakeCheckedNum(2)).ValueOrDie(); | 1182 auto g = CheckRsh(4, MakeCheckedNum(2)).ValueOrDie(); |
1170 EXPECT_EQ(static_cast<decltype(g)::type>(1), g); | 1183 EXPECT_EQ(static_cast<decltype(g)::type>(1), g); |
1171 auto h = CheckRsh(CheckAdd(1, 1, 1, 1), CheckSub(4, 2)).ValueOrDie(); | 1184 auto h = CheckRsh(CheckAdd(1, 1, 1, 1), CheckSub(4, 2)).ValueOrDie(); |
1172 EXPECT_EQ(static_cast<decltype(h)::type>(1), h); | 1185 EXPECT_EQ(static_cast<decltype(h)::type>(1), h); |
1173 } | 1186 } |
OLD | NEW |