Update third_party/base/numerics

Update to the latest numerics code from Chromium. Pick up
https://crrev.com/1008363, https://crrev.com/1040096, and
https://crrev.com/1092231.

Change-Id: I41d4160afd7a209a802b68e0e244eeddd5fe92b7
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/105450
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/third_party/base/numerics/README.pdfium b/third_party/base/numerics/README.pdfium
index 636f2df..8d73ef3 100644
--- a/third_party/base/numerics/README.pdfium
+++ b/third_party/base/numerics/README.pdfium
@@ -4,4 +4,3 @@
 Local Modifications:
 
 Namespaced from base:: to pdfium::base:: in all files.
-Remove ostream operators in safe_conversions.h and clamped_math.h
diff --git a/third_party/base/numerics/checked_math.h b/third_party/base/numerics/checked_math.h
index eb0d9a5..9eb5b07 100644
--- a/third_party/base/numerics/checked_math.h
+++ b/third_party/base/numerics/checked_math.h
@@ -34,19 +34,24 @@
   constexpr CheckedNumeric(const CheckedNumeric<Src>& rhs)
       : state_(rhs.state_.value(), rhs.IsValid()) {}
 
+  // Strictly speaking, this is not necessary, but declaring this allows class
+  // template argument deduction to be used so that it is possible to simply
+  // write `CheckedNumeric(777)` instead of `CheckedNumeric<int>(777)`.
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  constexpr CheckedNumeric(T value) : state_(value) {}
+
   // This is not an explicit constructor because we implicitly upgrade regular
   // numerics to CheckedNumerics to make them easier to use.
-  template <typename Src>
-  constexpr CheckedNumeric(Src value)  // NOLINT(runtime/explicit)
-      : state_(value) {
-    static_assert(UnderlyingType<Src>::is_numeric, "Argument must be numeric.");
-  }
+  template <typename Src,
+            typename = std::enable_if_t<std::is_arithmetic<Src>::value>>
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  constexpr CheckedNumeric(Src value) : state_(value) {}
 
   // This is not an explicit constructor because we want a seamless conversion
   // from StrictNumeric types.
   template <typename Src>
-  constexpr CheckedNumeric(
-      StrictNumeric<Src> value)  // NOLINT(runtime/explicit)
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  constexpr CheckedNumeric(StrictNumeric<Src> value)
       : state_(static_cast<Src>(value)) {}
 
   // IsValid() - The public API to test if a CheckedNumeric is currently valid.
diff --git a/third_party/base/numerics/checked_math_impl.h b/third_party/base/numerics/checked_math_impl.h
index e61053d..47c73d5 100644
--- a/third_party/base/numerics/checked_math_impl.h
+++ b/third_party/base/numerics/checked_math_impl.h
@@ -165,7 +165,7 @@
   if (uy > UnsignedDst(!std::is_signed<T>::value || is_negative) &&
       ux > (std::numeric_limits<T>::max() + UnsignedDst(is_negative)) / uy)
     return false;
-  *result = is_negative ? 0 - uresult : uresult;
+  *result = static_cast<T>(is_negative ? 0 - uresult : uresult);
   return true;
 }
 
@@ -195,7 +195,10 @@
     bool is_valid = true;
     if (CheckedMulFastOp<Promotion, Promotion>::is_supported) {
       // The fast op may be available with the promoted type.
-      is_valid = CheckedMulFastOp<Promotion, Promotion>::Do(x, y, &presult);
+      // The casts here are safe because of the "value in range" conditional
+      // above.
+      is_valid = CheckedMulFastOp<Promotion, Promotion>::Do(
+          static_cast<Promotion>(x), static_cast<Promotion>(y), &presult);
     } else if (IsIntegerArithmeticSafe<Promotion, T, U>::value) {
       presult = static_cast<Promotion>(x) * static_cast<Promotion>(y);
     } else {
diff --git a/third_party/base/numerics/clamped_math.h b/third_party/base/numerics/clamped_math.h
index ffa48f0..019bc31 100644
--- a/third_party/base/numerics/clamped_math.h
+++ b/third_party/base/numerics/clamped_math.h
@@ -34,19 +34,25 @@
   template <typename Src>
   friend class ClampedNumeric;
 
+  // Strictly speaking, this is not necessary, but declaring this allows class
+  // template argument deduction to be used so that it is possible to simply
+  // write `ClampedNumeric(777)` instead of `ClampedNumeric<int>(777)`.
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  constexpr ClampedNumeric(T value) : value_(value) {}
+
   // This is not an explicit constructor because we implicitly upgrade regular
   // numerics to ClampedNumerics to make them easier to use.
   template <typename Src>
-  constexpr ClampedNumeric(Src value)  // NOLINT(runtime/explicit)
-      : value_(saturated_cast<T>(value)) {
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  constexpr ClampedNumeric(Src value) : value_(saturated_cast<T>(value)) {
     static_assert(UnderlyingType<Src>::is_numeric, "Argument must be numeric.");
   }
 
   // This is not an explicit constructor because we want a seamless conversion
   // from StrictNumeric types.
   template <typename Src>
-  constexpr ClampedNumeric(
-      StrictNumeric<Src> value)  // NOLINT(runtime/explicit)
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  constexpr ClampedNumeric(StrictNumeric<Src> value)
       : value_(saturated_cast<T>(static_cast<Src>(value))) {}
 
   // Returns a ClampedNumeric of the specified type, cast from the current
diff --git a/third_party/base/numerics/clamped_math_impl.h b/third_party/base/numerics/clamped_math_impl.h
index 10b097f..a49309e 100644
--- a/third_party/base/numerics/clamped_math_impl.h
+++ b/third_party/base/numerics/clamped_math_impl.h
@@ -58,8 +58,9 @@
   // special case of numeric_limits<T>::min(), by evaluating the bit pattern as
   // a signed integer value. If it is the overflow case, we end up subtracting
   // one from the unsigned result, thus saturating to numeric_limits<T>::max().
-  return static_cast<T>(SafeUnsignedAbs(value) -
-                        IsValueNegative<T>(SafeUnsignedAbs(value)));
+  return static_cast<T>(
+      SafeUnsignedAbs(value) -
+      IsValueNegative<T>(static_cast<T>(SafeUnsignedAbs(value))));
 }
 
 template <
diff --git a/third_party/base/numerics/safe_conversions.h b/third_party/base/numerics/safe_conversions.h
index bcc7ba8..77ec8ce 100644
--- a/third_party/base/numerics/safe_conversions.h
+++ b/third_party/base/numerics/safe_conversions.h
@@ -20,10 +20,6 @@
 #define BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS (0)
 #endif
 
-#if !BASE_NUMERICS_DISABLE_OSTREAM_OPERATORS
-#include <ostream>
-#endif
-
 namespace pdfium {
 namespace base {
 namespace internal {
@@ -121,21 +117,27 @@
 template <typename T>
 struct SaturationDefaultLimits : public std::numeric_limits<T> {
   static constexpr T NaN() {
-    return std::numeric_limits<T>::has_quiet_NaN
-               ? std::numeric_limits<T>::quiet_NaN()
-               : T();
+    if constexpr (std::numeric_limits<T>::has_quiet_NaN) {
+      return std::numeric_limits<T>::quiet_NaN();
+    } else {
+      return T();
+    }
   }
   using std::numeric_limits<T>::max;
   static constexpr T Overflow() {
-    return std::numeric_limits<T>::has_infinity
-               ? std::numeric_limits<T>::infinity()
-               : std::numeric_limits<T>::max();
+    if constexpr (std::numeric_limits<T>::has_infinity) {
+      return std::numeric_limits<T>::infinity();
+    } else {
+      return std::numeric_limits<T>::max();
+    }
   }
   using std::numeric_limits<T>::lowest;
   static constexpr T Underflow() {
-    return std::numeric_limits<T>::has_infinity
-               ? std::numeric_limits<T>::infinity() * -1
-               : std::numeric_limits<T>::lowest();
+    if constexpr (std::numeric_limits<T>::has_infinity) {
+      return std::numeric_limits<T>::infinity() * -1;
+    } else {
+      return std::numeric_limits<T>::lowest();
+    }
   }
 };
 
@@ -279,11 +281,17 @@
   constexpr StrictNumeric(const StrictNumeric<Src>& rhs)
       : value_(strict_cast<T>(rhs.value_)) {}
 
+  // Strictly speaking, this is not necessary, but declaring this allows class
+  // template argument deduction to be used so that it is possible to simply
+  // write `StrictNumeric(777)` instead of `StrictNumeric<int>(777)`.
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  constexpr StrictNumeric(T value) : value_(value) {}
+
   // This is not an explicit constructor because we implicitly upgrade regular
   // numerics to StrictNumerics to make them easier to use.
   template <typename Src>
-  constexpr StrictNumeric(Src value)  // NOLINT(runtime/explicit)
-      : value_(strict_cast<T>(value)) {}
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  constexpr StrictNumeric(Src value) : value_(strict_cast<T>(value)) {}
 
   // If you got here from a compiler error, it's because you tried to assign
   // from a source type to a destination type that has insufficient range.
diff --git a/third_party/base/numerics/safe_conversions_impl.h b/third_party/base/numerics/safe_conversions_impl.h
index 4d8a7b7..44c921a 100644
--- a/third_party/base/numerics/safe_conversions_impl.h
+++ b/third_party/base/numerics/safe_conversions_impl.h
@@ -72,8 +72,9 @@
   static_assert(std::is_integral<T>::value, "Type must be integral");
   using SignedT = typename std::make_signed<T>::type;
   using UnsignedT = typename std::make_unsigned<T>::type;
-  return static_cast<SignedT>(
-      (static_cast<UnsignedT>(x) ^ -SignedT(is_negative)) + is_negative);
+  return static_cast<SignedT>((static_cast<UnsignedT>(x) ^
+                               static_cast<UnsignedT>(-SignedT(is_negative))) +
+                              is_negative);
 }
 
 // This performs a safe, absolute value via unsigned overflow.
@@ -245,9 +246,10 @@
   static constexpr T Adjust(T value) {
     static_assert(std::is_same<T, Dst>::value, "");
     static_assert(kShift < DstLimits::digits, "");
-    return static_cast<T>(
-        ConditionalNegate(SafeUnsignedAbs(value) & ~((T(1) << kShift) - T(1)),
-                          IsValueNegative(value)));
+    using UnsignedDst = typename std::make_unsigned_t<T>;
+    return static_cast<T>(ConditionalNegate(
+        SafeUnsignedAbs(value) & ~((UnsignedDst{1} << kShift) - UnsignedDst{1}),
+        IsValueNegative(value)));
   }
 
   template <typename T,
diff --git a/third_party/base/numerics/safe_math_arm_impl.h b/third_party/base/numerics/safe_math_arm_impl.h
index cea9632..ff97333 100644
--- a/third_party/base/numerics/safe_math_arm_impl.h
+++ b/third_party/base/numerics/safe_math_arm_impl.h
@@ -57,7 +57,7 @@
     // This will get promoted to an int, so let the compiler do whatever is
     // clever and rely on the saturated cast to bounds check.
     if (IsIntegerArithmeticSafe<int, T, U>::value)
-      return saturated_cast<V>(x + y);
+      return saturated_cast<V>(static_cast<int>(x) + static_cast<int>(y));
 
     int32_t result;
     int32_t x_i32 = checked_cast<int32_t>(x);
@@ -83,7 +83,7 @@
     // This will get promoted to an int, so let the compiler do whatever is
     // clever and rely on the saturated cast to bounds check.
     if (IsIntegerArithmeticSafe<int, T, U>::value)
-      return saturated_cast<V>(x - y);
+      return saturated_cast<V>(static_cast<int>(x) - static_cast<int>(y));
 
     int32_t result;
     int32_t x_i32 = checked_cast<int32_t>(x);