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 |