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

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

Issue 2545253002: Add support for CheckedNumeric Max and Min constexpr functions (Closed)
Patch Set: MakeStrictNum Created 4 years 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
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
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
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 }
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