Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(178)

Side by Side Diff: base/numerics/safe_numerics_unittest.cc

Issue 2496143003: Simplify CheckedNumeric macros (Closed)
Patch Set: nits Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/numerics/safe_math_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « base/numerics/safe_math_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698