Performance optimizations for base/numerics absolute value and multiply

Removes a number of branches from the calculations. Also now exporting
SafeUnsignedAbs as a public API.

NOTRY=true

Review-Url: https://codereview.chromium.org/2566733002
Cr-Commit-Position: refs/heads/master@{#437769}
diff --git a/base/numerics/safe_numerics_unittest.cc b/base/numerics/safe_numerics_unittest.cc
index 985a308..c0cc514 100644
--- a/base/numerics/safe_numerics_unittest.cc
+++ b/base/numerics/safe_numerics_unittest.cc
@@ -106,12 +106,15 @@
 #define TEST_EXPECTED_SUCCESS(actual) TEST_EXPECTED_VALIDITY(true, actual)
 #define TEST_EXPECTED_FAILURE(actual) TEST_EXPECTED_VALIDITY(false, actual)
 
-#define TEST_EXPECTED_VALUE(expected, actual)                              \
-  EXPECT_EQ(static_cast<Dst>(expected),                                    \
-            ((actual)                                                      \
-                 .template Cast<Dst>()                                     \
-                 .template ValueOrDie<Dst, LogOnFailure>()))               \
-      << "Result test: Value " << GetNumericValueForTest(actual) << " as " \
+// We have to handle promotions, so infer the underlying type below from actual.
+#define TEST_EXPECTED_VALUE(expected, actual)                               \
+  EXPECT_EQ(static_cast<typename std::decay<decltype(actual)>::type::type>( \
+                expected),                                                  \
+            ((actual)                                                       \
+                 .template ValueOrDie<                                      \
+                     typename std::decay<decltype(actual)>::type::type,     \
+                     LogOnFailure>()))                                      \
+      << "Result test: Value " << GetNumericValueForTest(actual) << " as "  \
       << dst << " on line " << line
 
 // Test the simple pointer arithmetic overrides.
@@ -143,6 +146,8 @@
   TEST_EXPECTED_FAILURE(-CheckedNumeric<Dst>(DstLimits::lowest()));
   TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()).Abs());
   TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
+  TEST_EXPECTED_VALUE(DstLimits::max(),
+                      MakeCheckedNum(-DstLimits::max()).Abs());
 
   TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + -1);
   TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) + -1);
@@ -161,6 +166,13 @@
   TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) / -1);
   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) / 2);
   TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * -1);
+  TEST_EXPECTED_VALUE(DstLimits::lowest(),
+                      MakeCheckedNum(DstLimits::lowest()).UnsignedAbs());
+  TEST_EXPECTED_VALUE(DstLimits::max(),
+                      MakeCheckedNum(DstLimits::max()).UnsignedAbs());
+  TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0).UnsignedAbs());
+  TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).UnsignedAbs());
+  TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).UnsignedAbs());
 
   // Modulus is legal only for integers.
   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);
@@ -221,6 +233,12 @@
       CheckedNumeric<typename std::make_signed<Dst>::type>(
           std::numeric_limits<typename std::make_signed<Dst>::type>::lowest())
           .UnsignedAbs());
+  TEST_EXPECTED_VALUE(DstLimits::lowest(),
+                      MakeCheckedNum(DstLimits::lowest()).UnsignedAbs());
+  TEST_EXPECTED_VALUE(DstLimits::max(),
+                      MakeCheckedNum(DstLimits::max()).UnsignedAbs());
+  TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0).UnsignedAbs());
+  TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).UnsignedAbs());
 
   // Modulus is legal only for integers.
   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);