Pull the new r369476 of base library from Chromium

The merge was done against r369476 which corresponds to git commit
0471d0e2e2ef4a544a63481a389e1df33ea7c00a of Jan 14, 2016

Change-Id: Ie6894cf65424cc5ad115110faccd51602b2d1234
Reviewed-on: https://weave-review.googlesource.com/2225
Reviewed-by: Alex Vakulenko <avakulenko@google.com>
diff --git a/third_party/chromium/base/numerics/safe_conversions.h b/third_party/chromium/base/numerics/safe_conversions.h
index 5dd5191..baac188 100644
--- a/third_party/chromium/base/numerics/safe_conversions.h
+++ b/third_party/chromium/base/numerics/safe_conversions.h
@@ -5,7 +5,10 @@
 #ifndef BASE_NUMERICS_SAFE_CONVERSIONS_H_
 #define BASE_NUMERICS_SAFE_CONVERSIONS_H_
 
+#include <stddef.h>
+
 #include <limits>
+#include <type_traits>
 
 #include "base/logging.h"
 #include "base/numerics/safe_conversions_impl.h"
@@ -20,6 +23,24 @@
          internal::RANGE_VALID;
 }
 
+// Convenience function for determining if a numeric value is negative without
+// throwing compiler warnings on: unsigned(value) < 0.
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type
+IsValueNegative(T value) {
+  static_assert(std::numeric_limits<T>::is_specialized,
+                "Argument must be numeric.");
+  return value < 0;
+}
+
+template <typename T>
+typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type
+    IsValueNegative(T) {
+  static_assert(std::numeric_limits<T>::is_specialized,
+                "Argument must be numeric.");
+  return false;
+}
+
 // checked_cast<> is analogous to static_cast<> for numeric types,
 // except that it CHECKs that the specified numeric conversion will not
 // overflow or underflow. NaN source will always trigger a CHECK.
@@ -29,10 +50,30 @@
   return static_cast<Dst>(value);
 }
 
+// HandleNaN will cause this class to CHECK(false).
+struct SaturatedCastNaNBehaviorCheck {
+  template <typename T>
+  static T HandleNaN() {
+    CHECK(false);
+    return T();
+  }
+};
+
+// HandleNaN will return 0 in this case.
+struct SaturatedCastNaNBehaviorReturnZero {
+  template <typename T>
+  static T HandleNaN() {
+    return T();
+  }
+};
+
 // saturated_cast<> is analogous to static_cast<> for numeric types, except
 // that the specified numeric conversion will saturate rather than overflow or
-// underflow. NaN assignment to an integral will trigger a CHECK condition.
-template <typename Dst, typename Src>
+// underflow. NaN assignment to an integral will defer the behavior to a
+// specified class. By default, it will return 0.
+template <typename Dst,
+          class NaNHandler = SaturatedCastNaNBehaviorReturnZero,
+          typename Src>
 inline Dst saturated_cast(Src value) {
   // Optimization for floating point values, which already saturate.
   if (std::numeric_limits<Dst>::is_iec559)
@@ -50,8 +91,7 @@
 
     // Should fail only on attempting to assign NaN to a saturated integer.
     case internal::RANGE_INVALID:
-      CHECK(false);
-      return std::numeric_limits<Dst>::max();
+      return NaNHandler::template HandleNaN<Dst>();
   }
 
   NOTREACHED();
diff --git a/third_party/chromium/base/numerics/safe_conversions_impl.h b/third_party/chromium/base/numerics/safe_conversions_impl.h
index d07221e..e1d376a 100644
--- a/third_party/chromium/base/numerics/safe_conversions_impl.h
+++ b/third_party/chromium/base/numerics/safe_conversions_impl.h
@@ -5,6 +5,9 @@
 #ifndef BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_
 #define BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_
 
+#include <limits.h>
+#include <stdint.h>
+
 #include <limits>
 
 namespace base {
@@ -106,6 +109,55 @@
                             (is_in_lower_bound ? 0 : RANGE_UNDERFLOW));
 }
 
+// The following helper template addresses a corner case in range checks for
+// conversion from a floating-point type to an integral type of smaller range
+// but larger precision (e.g. float -> unsigned). The problem is as follows:
+//   1. Integral maximum is always one less than a power of two, so it must be
+//      truncated to fit the mantissa of the floating point. The direction of
+//      rounding is implementation defined, but by default it's always IEEE
+//      floats, which round to nearest and thus result in a value of larger
+//      magnitude than the integral value.
+//      Example: float f = UINT_MAX; // f is 4294967296f but UINT_MAX
+//                                   // is 4294967295u.
+//   2. If the floating point value is equal to the promoted integral maximum
+//      value, a range check will erroneously pass.
+//      Example: (4294967296f <= 4294967295u) // This is true due to a precision
+//                                            // loss in rounding up to float.
+//   3. When the floating point value is then converted to an integral, the
+//      resulting value is out of range for the target integral type and
+//      thus is implementation defined.
+//      Example: unsigned u = (float)INT_MAX; // u will typically overflow to 0.
+// To fix this bug we manually truncate the maximum value when the destination
+// type is an integral of larger precision than the source floating-point type,
+// such that the resulting maximum is represented exactly as a floating point.
+template <typename Dst, typename Src>
+struct NarrowingRange {
+  typedef typename std::numeric_limits<Src> SrcLimits;
+  typedef typename std::numeric_limits<Dst> DstLimits;
+
+  static Dst max() {
+    // The following logic avoids warnings where the max function is
+    // instantiated with invalid values for a bit shift (even though
+    // such a function can never be called).
+    static const int shift =
+        (MaxExponent<Src>::value > MaxExponent<Dst>::value &&
+         SrcLimits::digits < DstLimits::digits && SrcLimits::is_iec559 &&
+         DstLimits::is_integer)
+            ? (DstLimits::digits - SrcLimits::digits)
+            : 0;
+
+    // We use UINTMAX_C below to avoid compiler warnings about shifting floating
+    // points. Since it's a compile time calculation, it shouldn't have any
+    // performance impact.
+    return DstLimits::max() - static_cast<Dst>((UINTMAX_C(1) << shift) - 1);
+  }
+
+  static Dst min() {
+    return std::numeric_limits<Dst>::is_iec559 ? -DstLimits::max()
+                                               : DstLimits::min();
+  }
+};
+
 template <
     typename Dst,
     typename Src,
@@ -133,7 +185,7 @@
                                       DstSign,
                                       SrcSign,
                                       NUMERIC_RANGE_CONTAINED> {
-  static RangeConstraint Check(Src value) { return RANGE_VALID; }
+  static RangeConstraint Check(Src /* value */) { return RANGE_VALID; }
 };
 
 // Signed to signed narrowing: Both the upper and lower boundaries may be
@@ -145,11 +197,8 @@
                                       INTEGER_REPRESENTATION_SIGNED,
                                       NUMERIC_RANGE_NOT_CONTAINED> {
   static RangeConstraint Check(Src value) {
-    return std::numeric_limits<Dst>::is_iec559
-               ? GetRangeConstraint((value < std::numeric_limits<Dst>::max()),
-                                    (value > -std::numeric_limits<Dst>::max()))
-               : GetRangeConstraint((value < std::numeric_limits<Dst>::max()),
-                                    (value > std::numeric_limits<Dst>::min()));
+    return GetRangeConstraint((value <= NarrowingRange<Dst, Src>::max()),
+                              (value >= NarrowingRange<Dst, Src>::min()));
   }
 };
 
@@ -161,7 +210,7 @@
                                       INTEGER_REPRESENTATION_UNSIGNED,
                                       NUMERIC_RANGE_NOT_CONTAINED> {
   static RangeConstraint Check(Src value) {
-    return GetRangeConstraint(value < std::numeric_limits<Dst>::max(), true);
+    return GetRangeConstraint(value <= NarrowingRange<Dst, Src>::max(), true);
   }
 };
 
@@ -176,7 +225,7 @@
     return sizeof(Dst) > sizeof(Src)
                ? RANGE_VALID
                : GetRangeConstraint(
-                     value < static_cast<Src>(std::numeric_limits<Dst>::max()),
+                     value <= static_cast<Src>(NarrowingRange<Dst, Src>::max()),
                      true);
   }
 };
@@ -193,7 +242,7 @@
     return (MaxExponent<Dst>::value >= MaxExponent<Src>::value)
                ? GetRangeConstraint(true, value >= static_cast<Src>(0))
                : GetRangeConstraint(
-                     value < static_cast<Src>(std::numeric_limits<Dst>::max()),
+                     value <= static_cast<Src>(NarrowingRange<Dst, Src>::max()),
                      value >= static_cast<Src>(0));
   }
 };
diff --git a/third_party/chromium/base/numerics/safe_math.h b/third_party/chromium/base/numerics/safe_math.h
index a596d4b..ddffb6e 100644
--- a/third_party/chromium/base/numerics/safe_math.h
+++ b/third_party/chromium/base/numerics/safe_math.h
@@ -5,6 +5,8 @@
 #ifndef BASE_NUMERICS_SAFE_MATH_H_
 #define BASE_NUMERICS_SAFE_MATH_H_
 
+#include <stddef.h>
+
 #include "base/numerics/safe_math_impl.h"
 
 namespace base {
@@ -36,9 +38,8 @@
 //     CheckedNumeric<int> checked_int = untrusted_input_value;
 //     int x = checked_int.ValueOrDefault(0) | kFlagValues;
 // Comparison:
-//   CheckedNumeric<size_t> checked_size;
-//   CheckedNumeric<int> checked_size = untrusted_input_value;
-//   checked_size = checked_size + HEADER LENGTH;
+//   CheckedNumeric<size_t> checked_size = untrusted_input_value;
+//   checked_size += HEADER LENGTH;
 //   if (checked_size.IsValid() && checked_size.ValueOrDie() < buffer_size)
 //     Do stuff...
 template <typename T>
@@ -145,6 +146,14 @@
     return CheckedNumeric<T>(value, validity);
   }
 
+  // This function is available only for integral types. It returns an unsigned
+  // integer of the same width as the source type, containing the absolute value
+  // of the source, and properly handling signed min.
+  CheckedNumeric<typename UnsignedOrFloatForSize<T>::type> UnsignedAbs() const {
+    return CheckedNumeric<typename UnsignedOrFloatForSize<T>::type>(
+        CheckedUnsignedAbs(state_.value()), state_.validity());
+  }
+
   CheckedNumeric& operator++() {
     *this += 1;
     return *this;
@@ -188,6 +197,16 @@
   static const CheckedNumeric<T>& cast(const CheckedNumeric<T>& u) { return u; }
 
  private:
+  template <typename NumericType>
+  struct UnderlyingType {
+    using type = NumericType;
+  };
+
+  template <typename NumericType>
+  struct UnderlyingType<CheckedNumeric<NumericType>> {
+    using type = NumericType;
+  };
+
   CheckedNumericState<T> state_;
 };
 
@@ -224,7 +243,8 @@
   template <typename T>                                                       \
   template <typename Src>                                                     \
   CheckedNumeric<T>& CheckedNumeric<T>::operator COMPOUND_OP(Src rhs) {       \
-    *this = CheckedNumeric<T>::cast(*this) OP CheckedNumeric<Src>::cast(rhs); \
+    *this = CheckedNumeric<T>::cast(*this)                                    \
+        OP CheckedNumeric<typename UnderlyingType<Src>::type>::cast(rhs);     \
     return *this;                                                             \
   }                                                                           \
   /* Binary arithmetic operator for CheckedNumeric of different type. */      \
diff --git a/third_party/chromium/base/numerics/safe_math_impl.h b/third_party/chromium/base/numerics/safe_math_impl.h
index 0ae1dfe..487b3bc 100644
--- a/third_party/chromium/base/numerics/safe_math_impl.h
+++ b/third_party/chromium/base/numerics/safe_math_impl.h
@@ -5,11 +5,13 @@
 #ifndef BASE_NUMERICS_SAFE_MATH_IMPL_H_
 #define BASE_NUMERICS_SAFE_MATH_IMPL_H_
 
+#include <stddef.h>
 #include <stdint.h>
 
 #include <cmath>
 #include <cstdlib>
 #include <limits>
+#include <type_traits>
 
 #include "base/numerics/safe_conversions.h"
 
@@ -86,7 +88,27 @@
 template <typename Integer>
 struct PositionOfSignBit {
   static const typename std::enable_if<std::numeric_limits<Integer>::is_integer,
-                                  size_t>::type value = 8 * sizeof(Integer) - 1;
+                                       size_t>::type value =
+      8 * sizeof(Integer) - 1;
+};
+
+// This is used for UnsignedAbs, where we need to support floating-point
+// template instantiations even though we don't actually support the operations.
+// However, there is no corresponding implementation of e.g. CheckedUnsignedAbs,
+// so the float versions will not compile.
+template <typename Numeric,
+          bool IsInteger = std::numeric_limits<Numeric>::is_integer,
+          bool IsFloat = std::numeric_limits<Numeric>::is_iec559>
+struct UnsignedOrFloatForSize;
+
+template <typename Numeric>
+struct UnsignedOrFloatForSize<Numeric, true, false> {
+  typedef typename UnsignedIntegerForSize<Numeric>::type type;
+};
+
+template <typename Numeric>
+struct UnsignedOrFloatForSize<Numeric, false, true> {
+  typedef Numeric type;
 };
 
 // Helper templates for integer manipulations.
@@ -159,9 +181,9 @@
 // slow case we need to manually check that the result won't be truncated by
 // checking with division against the appropriate bound.
 template <typename T>
-typename std::enable_if<
-    std::numeric_limits<T>::is_integer && sizeof(T) * 2 <= sizeof(uintmax_t),
-    T>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+                            sizeof(T) * 2 <= sizeof(uintmax_t),
+                        T>::type
 CheckedMul(T x, T y, RangeConstraint* validity) {
   typedef typename TwiceWiderInteger<T>::type IntermediateType;
   IntermediateType tmp =
@@ -202,9 +224,9 @@
 
 template <typename T>
 typename std::enable_if<std::numeric_limits<T>::is_integer &&
-                       !std::numeric_limits<T>::is_signed &&
-                       (sizeof(T) * 2 > sizeof(uintmax_t)),
-                   T>::type
+                            !std::numeric_limits<T>::is_signed &&
+                            (sizeof(T) * 2 > sizeof(uintmax_t)),
+                        T>::type
 CheckedMul(T x, T y, RangeConstraint* validity) {
   *validity = (y == 0 || x <= std::numeric_limits<T>::max() / y)
                   ? RANGE_VALID
@@ -230,27 +252,27 @@
 }
 
 template <typename T>
-typename std::enable_if<
-    std::numeric_limits<T>::is_integer&& std::numeric_limits<T>::is_signed,
-    T>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+                            std::numeric_limits<T>::is_signed,
+                        T>::type
 CheckedMod(T x, T y, RangeConstraint* validity) {
   *validity = y > 0 ? RANGE_VALID : RANGE_INVALID;
   return x % y;
 }
 
 template <typename T>
-typename std::enable_if<
-    std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed,
-    T>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+                            !std::numeric_limits<T>::is_signed,
+                        T>::type
 CheckedMod(T x, T y, RangeConstraint* validity) {
   *validity = RANGE_VALID;
   return x % y;
 }
 
 template <typename T>
-typename std::enable_if<
-    std::numeric_limits<T>::is_integer&& std::numeric_limits<T>::is_signed,
-    T>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+                            std::numeric_limits<T>::is_signed,
+                        T>::type
 CheckedNeg(T value, RangeConstraint* validity) {
   *validity =
       value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW;
@@ -259,9 +281,9 @@
 }
 
 template <typename T>
-typename std::enable_if<
-    std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed,
-    T>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+                            !std::numeric_limits<T>::is_signed,
+                        T>::type
 CheckedNeg(T value, RangeConstraint* validity) {
   // The only legal unsigned negation is zero.
   *validity = value ? RANGE_UNDERFLOW : RANGE_VALID;
@@ -270,9 +292,9 @@
 }
 
 template <typename T>
-typename std::enable_if<
-    std::numeric_limits<T>::is_integer&& std::numeric_limits<T>::is_signed,
-    T>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+                            std::numeric_limits<T>::is_signed,
+                        T>::type
 CheckedAbs(T value, RangeConstraint* validity) {
   *validity =
       value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW;
@@ -280,23 +302,43 @@
 }
 
 template <typename T>
-typename std::enable_if<
-    std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed,
-    T>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+                            !std::numeric_limits<T>::is_signed,
+                        T>::type
 CheckedAbs(T value, RangeConstraint* validity) {
-  // Absolute value of a positive is just its identiy.
+  // T is unsigned, so |value| must already be positive.
   *validity = RANGE_VALID;
   return value;
 }
 
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+                            std::numeric_limits<T>::is_signed,
+                        typename UnsignedIntegerForSize<T>::type>::type
+CheckedUnsignedAbs(T value) {
+  typedef typename UnsignedIntegerForSize<T>::type UnsignedT;
+  return value == std::numeric_limits<T>::min()
+             ? static_cast<UnsignedT>(std::numeric_limits<T>::max()) + 1
+             : static_cast<UnsignedT>(std::abs(value));
+}
+
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+                            !std::numeric_limits<T>::is_signed,
+                        T>::type
+CheckedUnsignedAbs(T value) {
+  // T is unsigned, so |value| must already be positive.
+  return value;
+}
+
 // These are the floating point stubs that the compiler needs to see. Only the
 // negation operation is ever called.
-#define BASE_FLOAT_ARITHMETIC_STUBS(NAME)                        \
-  template <typename T>                                          \
+#define BASE_FLOAT_ARITHMETIC_STUBS(NAME)                             \
+  template <typename T>                                               \
   typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type \
-  Checked##NAME(T, T, RangeConstraint*) {                        \
-    NOTREACHED();                                                \
-    return 0;                                                    \
+      Checked##NAME(T, T, RangeConstraint*) {                         \
+    NOTREACHED();                                                     \
+    return 0;                                                         \
   }
 
 BASE_FLOAT_ARITHMETIC_STUBS(Add)
@@ -399,7 +441,7 @@
   template <typename Src>
   CheckedNumericState(
       Src value,
-      RangeConstraint validity,
+      RangeConstraint /* validity */,
       typename std::enable_if<std::numeric_limits<Src>::is_integer, int>::type =
           0) {
     switch (DstRangeRelationToSrcRange<T>(value)) {
diff --git a/third_party/chromium/base/numerics/safe_numerics_unittest.cc b/third_party/chromium/base/numerics/safe_numerics_unittest.cc
index 96b579a..8ac7b0c 100644
--- a/third_party/chromium/base/numerics/safe_numerics_unittest.cc
+++ b/third_party/chromium/base/numerics/safe_numerics_unittest.cc
@@ -2,12 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS)
-#include <mmintrin.h>
-#endif
+#include <stddef.h>
 #include <stdint.h>
 
 #include <limits>
+#include <type_traits>
 
 #include <gtest/gtest.h>
 
@@ -19,6 +18,8 @@
 using std::numeric_limits;
 using base::CheckedNumeric;
 using base::checked_cast;
+using base::IsValueInRangeForNumericType;
+using base::IsValueNegative;
 using base::SizeT;
 using base::StrictNumeric;
 using base::saturated_cast;
@@ -28,7 +29,7 @@
 using base::internal::RANGE_INVALID;
 using base::internal::RANGE_OVERFLOW;
 using base::internal::RANGE_UNDERFLOW;
-using std::enable_if;
+using base::internal::SignedIntegerForSize;
 
 // These tests deliberately cause arithmetic overflows. If the compiler is
 // aggressive enough, it can const fold these overflows. Disable warnings about
@@ -37,6 +38,26 @@
 #pragma warning(disable:4756)
 #endif
 
+// This is a helper function for finding the maximum value in Src that can be
+// wholy represented as the destination floating-point type.
+template <typename Dst, typename Src>
+Dst GetMaxConvertibleToFloat() {
+  typedef numeric_limits<Dst> DstLimits;
+  typedef numeric_limits<Src> SrcLimits;
+  static_assert(SrcLimits::is_specialized, "Source must be numeric.");
+  static_assert(DstLimits::is_specialized, "Destination must be numeric.");
+  CHECK(DstLimits::is_iec559);
+
+  if (SrcLimits::digits <= DstLimits::digits &&
+      MaxExponent<Src>::value <= MaxExponent<Dst>::value)
+    return SrcLimits::max();
+  Src max = SrcLimits::max() / 2 + (SrcLimits::is_integer ? 1 : 0);
+  while (max != static_cast<Src>(static_cast<Dst>(max))) {
+    max /= 2;
+  }
+  return static_cast<Dst>(max);
+}
+
 // Helper macros to wrap displaying the conversion types and line numbers.
 #define TEST_EXPECTED_VALIDITY(expected, actual)                           \
   EXPECT_EQ(expected, CheckedNumeric<Dst>(actual).validity())              \
@@ -54,9 +75,9 @@
 static void TestSpecializedArithmetic(
     const char* dst,
     int line,
-    typename enable_if<
-        numeric_limits<Dst>::is_integer&& numeric_limits<Dst>::is_signed,
-        int>::type = 0) {
+    typename std::enable_if<numeric_limits<Dst>::is_integer &&
+                                numeric_limits<Dst>::is_signed,
+                            int>::type = 0) {
   typedef numeric_limits<Dst> DstLimits;
   TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW,
                          -CheckedNumeric<Dst>(DstLimits::min()));
@@ -110,9 +131,9 @@
 static void TestSpecializedArithmetic(
     const char* dst,
     int line,
-    typename enable_if<
-        numeric_limits<Dst>::is_integer && !numeric_limits<Dst>::is_signed,
-        int>::type = 0) {
+    typename std::enable_if<numeric_limits<Dst>::is_integer &&
+                                !numeric_limits<Dst>::is_signed,
+                            int>::type = 0) {
   typedef numeric_limits<Dst> DstLimits;
   TEST_EXPECTED_VALIDITY(RANGE_VALID, -CheckedNumeric<Dst>(DstLimits::min()));
   TEST_EXPECTED_VALIDITY(RANGE_VALID,
@@ -123,6 +144,13 @@
                          CheckedNumeric<Dst>(DstLimits::min()) - 1);
   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) * 2);
   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) / 2);
+  TEST_EXPECTED_VALIDITY(RANGE_VALID,
+                         CheckedNumeric<Dst>(DstLimits::min()).UnsignedAbs());
+  TEST_EXPECTED_VALIDITY(
+      RANGE_VALID,
+      CheckedNumeric<typename SignedIntegerForSize<Dst>::type>(
+          std::numeric_limits<typename SignedIntegerForSize<Dst>::type>::min())
+          .UnsignedAbs());
 
   // Modulus is legal only for integers.
   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);
@@ -143,7 +171,7 @@
 void TestSpecializedArithmetic(
     const char* dst,
     int line,
-    typename enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) {
+    typename std::enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) {
   typedef numeric_limits<Dst> DstLimits;
   TEST_EXPECTED_VALIDITY(RANGE_VALID, -CheckedNumeric<Dst>(DstLimits::min()));
 
@@ -318,7 +346,6 @@
                   "Comparison must be sign preserving and value preserving");
 
     const CheckedNumeric<Dst> checked_dst = SrcLimits::max();
-    ;
     TEST_EXPECTED_VALIDITY(RANGE_VALID, checked_dst);
     if (MaxExponent<Dst>::value > MaxExponent<Src>::value) {
       if (MaxExponent<Dst>::value >= MaxExponent<Src>::value * 2 - 1) {
@@ -371,6 +398,18 @@
       TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
       TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
       TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
+      if (DstLimits::is_integer) {
+        if (SrcLimits::digits < DstLimits::digits) {
+          TEST_EXPECTED_RANGE(RANGE_OVERFLOW,
+                              static_cast<Src>(DstLimits::max()));
+        } else {
+          TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
+        }
+        TEST_EXPECTED_RANGE(
+            RANGE_VALID,
+            static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
+        TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min()));
+      }
     } else if (SrcLimits::is_signed) {
       TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1));
       TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min());
@@ -429,6 +468,18 @@
       TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
       TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
       TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
+      if (DstLimits::is_integer) {
+        if (SrcLimits::digits < DstLimits::digits) {
+          TEST_EXPECTED_RANGE(RANGE_OVERFLOW,
+                              static_cast<Src>(DstLimits::max()));
+        } else {
+          TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
+        }
+        TEST_EXPECTED_RANGE(
+            RANGE_VALID,
+            static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
+        TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min()));
+      }
     } else {
       TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min());
     }
@@ -579,6 +630,18 @@
   EXPECT_TRUE(CheckedNumeric<int>(StrictNumeric<unsigned>(1U)).IsValid());
   EXPECT_FALSE(CheckedNumeric<unsigned>(StrictNumeric<int>(-1)).IsValid());
 
+  EXPECT_TRUE(IsValueNegative(-1));
+  EXPECT_TRUE(IsValueNegative(numeric_limits<int>::min()));
+  EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::min()));
+  EXPECT_TRUE(IsValueNegative(-numeric_limits<double>::max()));
+  EXPECT_FALSE(IsValueNegative(0));
+  EXPECT_FALSE(IsValueNegative(1));
+  EXPECT_FALSE(IsValueNegative(0u));
+  EXPECT_FALSE(IsValueNegative(1u));
+  EXPECT_FALSE(IsValueNegative(numeric_limits<int>::max()));
+  EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::max()));
+  EXPECT_FALSE(IsValueNegative(numeric_limits<double>::max()));
+
   // These casts and coercions will fail to compile:
   // EXPECT_EQ(0, strict_cast<int>(static_cast<size_t>(0)));
   // EXPECT_EQ(0, strict_cast<size_t>(static_cast<int>(0)));
@@ -599,5 +662,120 @@
   EXPECT_EQ(saturated_cast<float>(-double_large), -double_infinity);
   EXPECT_EQ(numeric_limits<int>::min(), saturated_cast<int>(double_small_int));
   EXPECT_EQ(numeric_limits<int>::max(), saturated_cast<int>(double_large_int));
+
+  float not_a_number = std::numeric_limits<float>::infinity() -
+                       std::numeric_limits<float>::infinity();
+  EXPECT_TRUE(std::isnan(not_a_number));
+  EXPECT_EQ(0, saturated_cast<int>(not_a_number));
 }
 
+#if GTEST_HAS_DEATH_TEST
+
+TEST(SafeNumerics, SaturatedCastChecks) {
+  float not_a_number = std::numeric_limits<float>::infinity() -
+                       std::numeric_limits<float>::infinity();
+  EXPECT_TRUE(std::isnan(not_a_number));
+  EXPECT_DEATH((saturated_cast<int, base::SaturatedCastNaNBehaviorCheck>(
+      not_a_number)), "");
+}
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+TEST(SafeNumerics, IsValueInRangeForNumericType) {
+  EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0));
+  EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(1));
+  EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(2));
+  EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(-1));
+  EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0xffffffffu));
+  EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0xffffffff)));
+  EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000000)));
+  EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000001)));
+  EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(
+      std::numeric_limits<int32_t>::min()));
+  EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(
+      std::numeric_limits<int64_t>::min()));
+
+  EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(1));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(2));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(-1));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffff));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffffu));
+  EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0x80000000u));
+  EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0xffffffffu));
+  EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x80000000)));
+  EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0xffffffff)));
+  EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x100000000)));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(
+      std::numeric_limits<int32_t>::min()));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(
+      static_cast<int64_t>(std::numeric_limits<int32_t>::min())));
+  EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(
+      static_cast<int64_t>(std::numeric_limits<int32_t>::min()) - 1));
+  EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(
+      std::numeric_limits<int64_t>::min()));
+
+  EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0));
+  EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(1));
+  EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(2));
+  EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(-1));
+  EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0xffffffffu));
+  EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0xffffffff)));
+  EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000000)));
+  EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000001)));
+  EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(
+      std::numeric_limits<int32_t>::min()));
+  EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(INT64_C(-1)));
+  EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(
+      std::numeric_limits<int64_t>::min()));
+
+  EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(1));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(2));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(-1));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffff));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffffu));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x80000000u));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0xffffffffu));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x80000000)));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0xffffffff)));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x100000000)));
+  EXPECT_TRUE(
+      IsValueInRangeForNumericType<int64_t>(INT64_C(0x7fffffffffffffff)));
+  EXPECT_TRUE(
+      IsValueInRangeForNumericType<int64_t>(UINT64_C(0x7fffffffffffffff)));
+  EXPECT_FALSE(
+      IsValueInRangeForNumericType<int64_t>(UINT64_C(0x8000000000000000)));
+  EXPECT_FALSE(
+      IsValueInRangeForNumericType<int64_t>(UINT64_C(0xffffffffffffffff)));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
+      std::numeric_limits<int32_t>::min()));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
+      static_cast<int64_t>(std::numeric_limits<int32_t>::min())));
+  EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
+      std::numeric_limits<int64_t>::min()));
+}
+
+TEST(SafeNumerics, CompoundNumericOperations) {
+  CheckedNumeric<int> a = 1;
+  CheckedNumeric<int> b = 2;
+  CheckedNumeric<int> c = 3;
+  CheckedNumeric<int> d = 4;
+  a += b;
+  EXPECT_EQ(3, a.ValueOrDie());
+  a -= c;
+  EXPECT_EQ(0, a.ValueOrDie());
+  d /= b;
+  EXPECT_EQ(2, d.ValueOrDie());
+  d *= d;
+  EXPECT_EQ(4, d.ValueOrDie());
+
+  CheckedNumeric<int> too_large = std::numeric_limits<int>::max();
+  EXPECT_TRUE(too_large.IsValid());
+  too_large += d;
+  EXPECT_FALSE(too_large.IsValid());
+  too_large -= d;
+  EXPECT_FALSE(too_large.IsValid());
+  too_large /= d;
+  EXPECT_FALSE(too_large.IsValid());
+}