| 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 while (max != static_cast<Src>(static_cast<Dst>(max))) { | 59 while (max != static_cast<Src>(static_cast<Dst>(max))) { |
| 60 max /= 2; | 60 max /= 2; |
| 61 } | 61 } |
| 62 return static_cast<Dst>(max); | 62 return static_cast<Dst>(max); |
| 63 } | 63 } |
| 64 | 64 |
| 65 // Helper macros to wrap displaying the conversion types and line numbers. | 65 // Helper macros to wrap displaying the conversion types and line numbers. |
| 66 #define TEST_EXPECTED_VALIDITY(expected, actual) \ | 66 #define TEST_EXPECTED_VALIDITY(expected, actual) \ |
| 67 EXPECT_EQ(expected, CheckedNumeric<Dst>(actual).IsValid()) \ | 67 EXPECT_EQ(expected, CheckedNumeric<Dst>(actual).IsValid()) \ |
| 68 << "Result test: Value " << +(actual).ValueUnsafe() << " as " << dst \ | 68 << "Result test: Value " << +(actual).ValueUnsafe() << " as " << dst \ |
| 69 << " on line " << line; | 69 << " on line " << line |
| 70 | 70 |
| 71 #define TEST_EXPECTED_SUCCESS(actual) TEST_EXPECTED_VALIDITY(true, actual) | 71 #define TEST_EXPECTED_SUCCESS(actual) TEST_EXPECTED_VALIDITY(true, actual) |
| 72 #define TEST_EXPECTED_FAILURE(actual) TEST_EXPECTED_VALIDITY(false, actual) | 72 #define TEST_EXPECTED_FAILURE(actual) TEST_EXPECTED_VALIDITY(false, actual) |
| 73 | 73 |
| 74 #define TEST_EXPECTED_VALUE(expected, actual) \ | 74 #define TEST_EXPECTED_VALUE(expected, actual) \ |
| 75 EXPECT_EQ(static_cast<Dst>(expected), \ | 75 EXPECT_EQ(static_cast<Dst>(expected), \ |
| 76 CheckedNumeric<Dst>(actual).ValueOrDie()) \ | 76 CheckedNumeric<Dst>(actual).ValueOrDie()) \ |
| 77 << "Result test: Value " << +((actual).ValueUnsafe()) << " as " << dst \ | 77 << "Result test: Value " << +((actual).ValueUnsafe()) << " as " << dst \ |
| 78 << " on line " << line; | 78 << " on line " << line |
| 79 | 79 |
| 80 // Signed integer arithmetic. | 80 // Signed integer arithmetic. |
| 81 template <typename Dst> | 81 template <typename Dst> |
| 82 static void TestSpecializedArithmetic( | 82 static void TestSpecializedArithmetic( |
| 83 const char* dst, | 83 const char* dst, |
| 84 int line, | 84 int line, |
| 85 typename std::enable_if<numeric_limits<Dst>::is_integer && | 85 typename std::enable_if<numeric_limits<Dst>::is_integer && |
| 86 numeric_limits<Dst>::is_signed, | 86 numeric_limits<Dst>::is_signed, |
| 87 int>::type = 0) { | 87 int>::type = 0) { |
| 88 typedef numeric_limits<Dst> DstLimits; | 88 typedef numeric_limits<Dst> DstLimits; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 99 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) - -1); | 99 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) - -1); |
| 100 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - | 100 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - |
| 101 -DstLimits::max()); | 101 -DstLimits::max()); |
| 102 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) - | 102 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) - |
| 103 DstLimits::max()); | 103 DstLimits::max()); |
| 104 | 104 |
| 105 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) * 2); | 105 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) * 2); |
| 106 | 106 |
| 107 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) / -1); | 107 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) / -1); |
| 108 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) / 2); | 108 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) / 2); |
| 109 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) * -1); |
| 109 | 110 |
| 110 // Modulus is legal only for integers. | 111 // Modulus is legal only for integers. |
| 111 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1); | 112 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1); |
| 112 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); | 113 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); |
| 113 TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % 2); | 114 TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % 2); |
| 114 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-1) % -2); | 115 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-1) % -2); |
| 115 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2); | 116 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2); |
| 116 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2); | 117 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2); |
| 117 // Test all the different modulus combinations. | 118 // Test all the different modulus combinations. |
| 118 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1)); | 119 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1)); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) + 1); | 250 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) + 1); |
| 250 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) + | 251 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) + |
| 251 DstLimits::max()); | 252 DstLimits::max()); |
| 252 | 253 |
| 253 // Generic subtraction. | 254 // Generic subtraction. |
| 254 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(1) - 1)); | 255 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(1) - 1)); |
| 255 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) - 1); | 256 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) - 1); |
| 256 if (numeric_limits<Dst>::is_signed) { | 257 if (numeric_limits<Dst>::is_signed) { |
| 257 TEST_EXPECTED_VALUE(-1, (CheckedNumeric<Dst>() - 1)); | 258 TEST_EXPECTED_VALUE(-1, (CheckedNumeric<Dst>() - 1)); |
| 258 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) - 1)); | 259 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) - 1)); |
| 260 } else { |
| 261 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - -1); |
| 259 } | 262 } |
| 260 | 263 |
| 261 // Generic multiplication. | 264 // Generic multiplication. |
| 262 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>() * 1)); | 265 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>() * 1)); |
| 263 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>(1) * 1)); | 266 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>(1) * 1)); |
| 264 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * 0)); | 267 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * 0)); |
| 265 if (numeric_limits<Dst>::is_signed) { | 268 if (numeric_limits<Dst>::is_signed) { |
| 266 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) * 0)); | 269 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) * 0)); |
| 267 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * -1)); | 270 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * -1)); |
| 268 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) * 2)); | 271 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) * 2)); |
| 272 } else { |
| 273 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * -2); |
| 274 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * |
| 275 CheckedNumeric<uintmax_t>(-2)); |
| 269 } | 276 } |
| 270 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * | 277 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * |
| 271 DstLimits::max()); | 278 DstLimits::max()); |
| 272 | 279 |
| 273 // Generic division. | 280 // Generic division. |
| 274 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() / 1); | 281 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() / 1); |
| 275 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1); | 282 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1); |
| 276 TEST_EXPECTED_VALUE(DstLimits::min() / 2, | 283 TEST_EXPECTED_VALUE(DstLimits::min() / 2, |
| 277 CheckedNumeric<Dst>(DstLimits::min()) / 2); | 284 CheckedNumeric<Dst>(DstLimits::min()) / 2); |
| 278 TEST_EXPECTED_VALUE(DstLimits::max() / 2, | 285 TEST_EXPECTED_VALUE(DstLimits::max() / 2, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 }; | 320 }; |
| 314 | 321 |
| 315 // Template covering the different conversion tests. | 322 // Template covering the different conversion tests. |
| 316 template <typename Dst, typename Src, NumericConversionType conversion> | 323 template <typename Dst, typename Src, NumericConversionType conversion> |
| 317 struct TestNumericConversion {}; | 324 struct TestNumericConversion {}; |
| 318 | 325 |
| 319 // EXPECT_EQ wrappers providing specific detail on test failures. | 326 // EXPECT_EQ wrappers providing specific detail on test failures. |
| 320 #define TEST_EXPECTED_RANGE(expected, actual) \ | 327 #define TEST_EXPECTED_RANGE(expected, actual) \ |
| 321 EXPECT_EQ(expected, base::internal::DstRangeRelationToSrcRange<Dst>(actual)) \ | 328 EXPECT_EQ(expected, base::internal::DstRangeRelationToSrcRange<Dst>(actual)) \ |
| 322 << "Conversion test: " << src << " value " << actual << " to " << dst \ | 329 << "Conversion test: " << src << " value " << actual << " to " << dst \ |
| 323 << " on line " << line; | 330 << " on line " << line |
| 324 | 331 |
| 325 template <typename Dst, typename Src> | 332 template <typename Dst, typename Src> |
| 326 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> { | 333 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> { |
| 327 static void Test(const char *dst, const char *src, int line) { | 334 static void Test(const char *dst, const char *src, int line) { |
| 328 typedef numeric_limits<Src> SrcLimits; | 335 typedef numeric_limits<Src> SrcLimits; |
| 329 typedef numeric_limits<Dst> DstLimits; | 336 typedef numeric_limits<Dst> DstLimits; |
| 330 // Integral to floating. | 337 // Integral to floating. |
| 331 static_assert((DstLimits::is_iec559 && SrcLimits::is_integer) || | 338 static_assert((DstLimits::is_iec559 && SrcLimits::is_integer) || |
| 332 // Not floating to integral and... | 339 // Not floating to integral and... |
| 333 (!(DstLimits::is_integer && SrcLimits::is_iec559) && | 340 (!(DstLimits::is_integer && SrcLimits::is_iec559) && |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 | 769 |
| 763 CheckedNumeric<int> too_large = std::numeric_limits<int>::max(); | 770 CheckedNumeric<int> too_large = std::numeric_limits<int>::max(); |
| 764 EXPECT_TRUE(too_large.IsValid()); | 771 EXPECT_TRUE(too_large.IsValid()); |
| 765 too_large += d; | 772 too_large += d; |
| 766 EXPECT_FALSE(too_large.IsValid()); | 773 EXPECT_FALSE(too_large.IsValid()); |
| 767 too_large -= d; | 774 too_large -= d; |
| 768 EXPECT_FALSE(too_large.IsValid()); | 775 EXPECT_FALSE(too_large.IsValid()); |
| 769 too_large /= d; | 776 too_large /= d; |
| 770 EXPECT_FALSE(too_large.IsValid()); | 777 EXPECT_FALSE(too_large.IsValid()); |
| 771 } | 778 } |
| OLD | NEW |