Bug 1288603 - Remove NumericLimits.h because all platforms have numeric_limits<char16_t>. r=froydnj
authorChris Peterson <cpeterson@mozilla.com>
Fri, 22 Jul 2016 22:05:45 -0700
changeset 348538 d8af5416b0627e13948a3e400ba0e9f152a5ee48
parent 348537 0a819a2a98f684748b9fe59363ec3f994e16f4a0
child 348539 bf7c4e797f762c0de3e92e8ec19eec47a95ce92d
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1288603
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1288603 - Remove NumericLimits.h because all platforms have numeric_limits<char16_t>. r=froydnj
js/src/ctypes/CTypes.cpp
mfbt/NumericLimits.h
mfbt/Saturate.h
mfbt/moz.build
mfbt/tests/TestSaturate.cpp
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -3,19 +3,19 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ctypes/CTypes.h"
 
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/NumericLimits.h"
 #include "mozilla/Vector.h"
 
+#include <limits>
 #include <math.h>
 #include <stdint.h>
 
 #if defined(XP_WIN)
 #include <float.h>
 #endif
 
 #if defined(SOLARIS)
@@ -43,17 +43,16 @@
 #include "gc/Policy.h"
 #include "gc/Zone.h"
 #include "js/Vector.h"
 
 #include "jsatominlines.h"
 #include "jsobjinlines.h"
 
 using namespace std;
-using mozilla::NumericLimits;
 
 using JS::AutoCheckCannotGC;
 
 namespace js {
 namespace ctypes {
 
 template <typename CharT>
 size_t
@@ -2493,17 +2492,17 @@ JS_STATIC_ASSERT(sizeof(char) == 1);
 JS_STATIC_ASSERT(sizeof(short) == 2);
 JS_STATIC_ASSERT(sizeof(int) == 4);
 JS_STATIC_ASSERT(sizeof(unsigned) == 4);
 JS_STATIC_ASSERT(sizeof(long) == 4 || sizeof(long) == 8);
 JS_STATIC_ASSERT(sizeof(long long) == 8);
 JS_STATIC_ASSERT(sizeof(size_t) == sizeof(uintptr_t));
 JS_STATIC_ASSERT(sizeof(float) == 4);
 JS_STATIC_ASSERT(sizeof(PRFuncPtr) == sizeof(void*));
-JS_STATIC_ASSERT(NumericLimits<double>::is_signed);
+JS_STATIC_ASSERT(numeric_limits<double>::is_signed);
 
 // Templated helper to convert FromType to TargetType, for the default case
 // where the trivial POD constructor will do.
 template<class TargetType, class FromType>
 struct ConvertImpl {
   static MOZ_ALWAYS_INLINE TargetType Convert(FromType d) {
     return TargetType(d);
   }
@@ -2558,77 +2557,77 @@ static MOZ_ALWAYS_INLINE bool IsAlwaysEx
   // This means that:
   // 1) TargetType must be the same or more bits wide as FromType. For integers
   //    represented in 'n' bits, unsigned variants will have 'n' digits while
   //    signed will have 'n - 1'. For floating point types, 'digits' is the
   //    mantissa width.
   // 2) If FromType is signed, TargetType must also be signed. (Floating point
   //    types are always signed.)
   // 3) If TargetType is an exact integral type, FromType must be also.
-  if (NumericLimits<TargetType>::digits < NumericLimits<FromType>::digits)
-    return false;
-
-  if (NumericLimits<FromType>::is_signed &&
-      !NumericLimits<TargetType>::is_signed)
-    return false;
-
-  if (!NumericLimits<FromType>::is_exact &&
-      NumericLimits<TargetType>::is_exact)
+  if (numeric_limits<TargetType>::digits < numeric_limits<FromType>::digits)
+    return false;
+
+  if (numeric_limits<FromType>::is_signed &&
+      !numeric_limits<TargetType>::is_signed)
+    return false;
+
+  if (!numeric_limits<FromType>::is_exact &&
+      numeric_limits<TargetType>::is_exact)
     return false;
 
   return true;
 }
 
 // Templated helper to determine if FromType 'i' converts losslessly to
 // TargetType 'j'. Default case where both types are the same signedness.
 template<class TargetType, class FromType, bool TargetSigned, bool FromSigned>
 struct IsExactImpl {
   static MOZ_ALWAYS_INLINE bool Test(FromType i, TargetType j) {
-    JS_STATIC_ASSERT(NumericLimits<TargetType>::is_exact);
+    JS_STATIC_ASSERT(numeric_limits<TargetType>::is_exact);
     return FromType(j) == i;
   }
 };
 
 // Specialization where TargetType is unsigned, FromType is signed.
 template<class TargetType, class FromType>
 struct IsExactImpl<TargetType, FromType, false, true> {
   static MOZ_ALWAYS_INLINE bool Test(FromType i, TargetType j) {
-    JS_STATIC_ASSERT(NumericLimits<TargetType>::is_exact);
+    JS_STATIC_ASSERT(numeric_limits<TargetType>::is_exact);
     return i >= 0 && FromType(j) == i;
   }
 };
 
 // Specialization where TargetType is signed, FromType is unsigned.
 template<class TargetType, class FromType>
 struct IsExactImpl<TargetType, FromType, true, false> {
   static MOZ_ALWAYS_INLINE bool Test(FromType i, TargetType j) {
-    JS_STATIC_ASSERT(NumericLimits<TargetType>::is_exact);
+    JS_STATIC_ASSERT(numeric_limits<TargetType>::is_exact);
     return TargetType(i) >= 0 && FromType(j) == i;
   }
 };
 
 // Convert FromType 'i' to TargetType 'result', returning true iff 'result'
 // is an exact representation of 'i'.
 template<class TargetType, class FromType>
 static MOZ_ALWAYS_INLINE bool ConvertExact(FromType i, TargetType* result)
 {
   // Require that TargetType is integral, to simplify conversion.
-  JS_STATIC_ASSERT(NumericLimits<TargetType>::is_exact);
+  JS_STATIC_ASSERT(numeric_limits<TargetType>::is_exact);
 
   *result = Convert<TargetType>(i);
 
   // See if we can avoid a dynamic check.
   if (IsAlwaysExact<TargetType, FromType>())
     return true;
 
   // Return 'true' if 'i' is exactly representable in 'TargetType'.
   return IsExactImpl<TargetType,
                      FromType,
-                     NumericLimits<TargetType>::is_signed,
-                     NumericLimits<FromType>::is_signed>::Test(i, *result);
+                     numeric_limits<TargetType>::is_signed,
+                     numeric_limits<FromType>::is_signed>::Test(i, *result);
 }
 
 // Templated helper to determine if Type 'i' is negative. Default case
 // where IntegerType is unsigned.
 template<class Type, bool IsSigned>
 struct IsNegativeImpl {
   static MOZ_ALWAYS_INLINE bool Test(Type i) {
     return false;
@@ -2642,17 +2641,17 @@ struct IsNegativeImpl<Type, true> {
     return i < 0;
   }
 };
 
 // Determine whether Type 'i' is negative.
 template<class Type>
 static MOZ_ALWAYS_INLINE bool IsNegative(Type i)
 {
-  return IsNegativeImpl<Type, NumericLimits<Type>::is_signed>::Test(i);
+  return IsNegativeImpl<Type, numeric_limits<Type>::is_signed>::Test(i);
 }
 
 // Implicitly convert val to bool, allowing bool, int, and double
 // arguments numerically equal to 0 or 1.
 static bool
 jsvalToBool(JSContext* cx, Value val, bool* result)
 {
   if (val.isBoolean()) {
@@ -2676,17 +2675,17 @@ jsvalToBool(JSContext* cx, Value val, bo
 
 // Implicitly convert val to IntegerType, allowing bool, int, double,
 // Int64, UInt64, and CData integer types 't' where all values of 't' are
 // representable by IntegerType.
 template<class IntegerType>
 static bool
 jsvalToInteger(JSContext* cx, Value val, IntegerType* result)
 {
-  JS_STATIC_ASSERT(NumericLimits<IntegerType>::is_exact);
+  JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
 
   if (val.isInt32()) {
     // Make sure the integer fits in the alotted precision, and has the right
     // sign.
     int32_t i = val.toInt32();
     return ConvertExact(i, result);
   }
   if (val.isDouble()) {
@@ -2766,17 +2765,17 @@ jsvalToInteger(JSContext* cx, Value val,
 
 // Implicitly convert val to FloatType, allowing int, double,
 // Int64, UInt64, and CData numeric types 't' where all values of 't' are
 // representable by FloatType.
 template<class FloatType>
 static bool
 jsvalToFloat(JSContext* cx, Value val, FloatType* result)
 {
-  JS_STATIC_ASSERT(!NumericLimits<FloatType>::is_exact);
+  JS_STATIC_ASSERT(!numeric_limits<FloatType>::is_exact);
 
   // The following casts may silently throw away some bits, but there's
   // no good way around it. Sternly requiring that the 64-bit double
   // argument be exactly representable as a 32-bit float is
   // unrealistic: it would allow 1/2 to pass but not 1/3.
   if (val.isInt32()) {
     *result = FloatType(val.toInt32());
     return true;
@@ -2824,25 +2823,25 @@ jsvalToFloat(JSContext* cx, Value val, F
   return false;
 }
 
 template <class IntegerType, class CharT>
 static bool
 StringToInteger(JSContext* cx, CharT* cp, size_t length, IntegerType* result,
                 bool* overflow)
 {
-  JS_STATIC_ASSERT(NumericLimits<IntegerType>::is_exact);
+  JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
 
   const CharT* end = cp + length;
   if (cp == end)
     return false;
 
   IntegerType sign = 1;
   if (cp[0] == '-') {
-    if (!NumericLimits<IntegerType>::is_signed)
+    if (!numeric_limits<IntegerType>::is_signed)
       return false;
 
     sign = -1;
     ++cp;
   }
 
   // Assume base-10, unless the string begins with '0x' or '0X'.
   IntegerType base = 10;
@@ -2901,17 +2900,17 @@ StringToInteger(JSContext* cx, JSString*
 template<class IntegerType>
 static bool
 jsvalToBigInteger(JSContext* cx,
                   Value val,
                   bool allowString,
                   IntegerType* result,
                   bool* overflow)
 {
-  JS_STATIC_ASSERT(NumericLimits<IntegerType>::is_exact);
+  JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
 
   if (val.isInt32()) {
     // Make sure the integer fits in the alotted precision, and has the right
     // sign.
     int32_t i = val.toInt32();
     return ConvertExact(i, result);
   }
   if (val.isDouble()) {
@@ -2973,17 +2972,17 @@ jsvalToSize(JSContext* cx, Value val, bo
 // (This is common code shared by jsvalToSize and the Int64/UInt64 constructors.)
 template<class IntegerType>
 static bool
 jsidToBigInteger(JSContext* cx,
                  jsid val,
                  bool allowString,
                  IntegerType* result)
 {
-  JS_STATIC_ASSERT(NumericLimits<IntegerType>::is_exact);
+  JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
 
   if (JSID_IS_INT(val)) {
     // Make sure the integer fits in the alotted precision, and has the right
     // sign.
     int32_t i = JSID_TO_INT(val);
     return ConvertExact(i, result);
   }
   if (allowString && JSID_IS_STRING(val)) {
@@ -3022,17 +3021,17 @@ SizeTojsval(JSContext* cx, size_t size, 
   return true;
 }
 
 // Forcefully convert val to IntegerType when explicitly requested.
 template<class IntegerType>
 static bool
 jsvalToIntegerExplicit(Value val, IntegerType* result)
 {
-  JS_STATIC_ASSERT(NumericLimits<IntegerType>::is_exact);
+  JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
 
   if (val.isDouble()) {
     // Convert -Inf, Inf, and NaN to 0; otherwise, convert by C-style cast.
     double d = val.toDouble();
     *result = mozilla::IsFinite(d) ? IntegerType(d) : 0;
     return true;
   }
   if (val.isObject()) {
@@ -3103,17 +3102,17 @@ jsvalToPtrExplicit(JSContext* cx, Value 
   }
   return false;
 }
 
 template<class IntegerType, class CharType, size_t N, class AP>
 void
 IntegerToString(IntegerType i, int radix, mozilla::Vector<CharType, N, AP>& result)
 {
-  JS_STATIC_ASSERT(NumericLimits<IntegerType>::is_exact);
+  JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
 
   // The buffer must be big enough for all the bits of IntegerType to fit,
   // in base-2, including '-'.
   CharType buffer[sizeof(IntegerType) * 8 + 1];
   CharType* end = buffer + sizeof(buffer) / sizeof(CharType);
   CharType* cp = end;
 
   // Build the string in reverse. We use multiplication and subtraction
@@ -3190,32 +3189,32 @@ ConvertToJS(JSContext* cx,
   }
   CTYPES_FOR_EACH_INT_TYPE(INT_CASE)
 #undef INT_CASE
 #define WRAPPED_INT_CASE(name, type, ffiType)                                  \
   case TYPE_##name: {                                                          \
     /* Return an Int64 or UInt64 object - do not convert to a JS number. */    \
     uint64_t value;                                                            \
     RootedObject proto(cx);                                                    \
-    if (!NumericLimits<type>::is_signed) {                                     \
+    if (!numeric_limits<type>::is_signed) {                                    \
       value = *static_cast<type*>(data);                                       \
       /* Get ctypes.UInt64.prototype from ctypes.CType.prototype. */           \
       proto = CType::GetProtoFromType(cx, typeObj, SLOT_UINT64PROTO);          \
       if (!proto)                                                              \
         return false;                                                          \
     } else {                                                                   \
       value = int64_t(*static_cast<type*>(data));                              \
       /* Get ctypes.Int64.prototype from ctypes.CType.prototype. */            \
       proto = CType::GetProtoFromType(cx, typeObj, SLOT_INT64PROTO);           \
       if (!proto)                                                              \
         return false;                                                          \
     }                                                                          \
                                                                                \
     JSObject* obj = Int64Base::Construct(cx, proto, value,                     \
-      !NumericLimits<type>::is_signed);                                        \
+      !numeric_limits<type>::is_signed);                                       \
     if (!obj)                                                                  \
       return false;                                                            \
     result.setObject(*obj);                                                    \
     break;                                                                     \
   }
   CTYPES_FOR_EACH_WRAPPED_INT_TYPE(WRAPPED_INT_CASE)
 #undef WRAPPED_INT_CASE
 #define FLOAT_CASE(name, type, ffiType)                                        \
@@ -4167,17 +4166,17 @@ BuildDataSource(JSContext* cx,
     /* Serialize as a primitive decimal integer. */                            \
     IntegerToString(*static_cast<type*>(data), 10, result);                    \
     break;
   CTYPES_FOR_EACH_INT_TYPE(INTEGRAL_CASE)
 #undef INTEGRAL_CASE
 #define WRAPPED_INT_CASE(name, type, ffiType)                                  \
   case TYPE_##name:                                                            \
     /* Serialize as a wrapped decimal integer. */                              \
-    if (!NumericLimits<type>::is_signed)                                       \
+    if (!numeric_limits<type>::is_signed)                                      \
       AppendString(result, "ctypes.UInt64(\"");                                \
     else                                                                       \
       AppendString(result, "ctypes.Int64(\"");                                 \
                                                                                \
     IntegerToString(*static_cast<type*>(data), 10, result);                    \
     AppendString(result, "\")");                                               \
     break;
   CTYPES_FOR_EACH_WRAPPED_INT_TYPE(WRAPPED_INT_CASE)
deleted file mode 100644
--- a/mfbt/NumericLimits.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Compatibility with std::numeric_limits<char16_t>. */
-
-#ifndef mozilla_NumericLimits_h
-#define mozilla_NumericLimits_h
-
-#include "mozilla/Char16.h"
-
-#include <limits>
-#include <stdint.h>
-
-namespace mozilla {
-
-/**
- * The NumericLimits class provides a compatibility layer with
- * std::numeric_limits for char16_t, otherwise it is exactly the same as
- * std::numeric_limits.  Code which does not need std::numeric_limits<char16_t>
- * should avoid using NumericLimits.
- */
-template<typename T>
-class NumericLimits : public std::numeric_limits<T>
-{
-};
-
-template<>
-class NumericLimits<char16_t> : public std::numeric_limits<uint16_t>
-{
-  // char16_t and uint16_t numeric limits should be exactly the same.
-};
-
-} // namespace mozilla
-
-#endif /* mozilla_NumericLimits_h */
--- a/mfbt/Saturate.h
+++ b/mfbt/Saturate.h
@@ -6,19 +6,20 @@
 
 /* Provides saturation arithmetics for scalar types. */
 
 #ifndef mozilla_Saturate_h
 #define mozilla_Saturate_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/Move.h"
-#include "mozilla/NumericLimits.h"
 #include "mozilla/TypeTraits.h"
 
+#include <limits>
+
 namespace mozilla {
 namespace detail {
 
 /**
  * |SaturateOp<T>| wraps scalar values for saturation arithmetics. Usage:
  *
  *    uint32_t value = 1;
  *
@@ -58,31 +59,31 @@ public:
   {
     return T(mValue) -= aRhs;
   }
 
   // Compound operators
 
   const T& operator+=(const T& aRhs) const
   {
-    const T min = NumericLimits<T>::min();
-    const T max = NumericLimits<T>::max();
+    const T min = std::numeric_limits<T>::min();
+    const T max = std::numeric_limits<T>::max();
 
     if (aRhs > static_cast<T>(0)) {
       mValue = (max - aRhs) < mValue ? max : mValue + aRhs;
     } else {
       mValue = (min - aRhs) > mValue ? min : mValue + aRhs;
     }
     return mValue;
   }
 
   const T& operator-=(const T& aRhs) const
   {
-    const T min = NumericLimits<T>::min();
-    const T max = NumericLimits<T>::max();
+    const T min = std::numeric_limits<T>::min();
+    const T max = std::numeric_limits<T>::max();
 
     if (aRhs > static_cast<T>(0)) {
       mValue = (min + aRhs) > mValue ? min : mValue - aRhs;
     } else {
       mValue = (max + aRhs) < mValue ? max : mValue - aRhs;
     }
     return mValue;
   }
--- a/mfbt/moz.build
+++ b/mfbt/moz.build
@@ -57,17 +57,16 @@ EXPORTS.mozilla = [
     'MathAlgorithms.h',
     'Maybe.h',
     'MaybeOneOf.h',
     'MemoryChecking.h',
     'MemoryReporting.h',
     'Move.h',
     'NotNull.h',
     'NullPtr.h',
-    'NumericLimits.h',
     'Opaque.h',
     'Pair.h',
     'PodOperations.h',
     'Poison.h',
     'Range.h',
     'RangedArray.h',
     'RangedPtr.h',
     'ReentrancyGuard.h',
--- a/mfbt/tests/TestSaturate.cpp
+++ b/mfbt/tests/TestSaturate.cpp
@@ -2,20 +2,20 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <mozilla/Saturate.h>
 
 #include <mozilla/Assertions.h>
-#include <mozilla/NumericLimits.h>
+
+#include <limits>
 
 using mozilla::detail::Saturate;
-using mozilla::NumericLimits;
 
 #define A(a) MOZ_RELEASE_ASSERT(a, "Test \'" #a "\'  failed.")
 
 static const unsigned long sNumOps = 32;
 
 template<typename T>
 static T
 StartValue()
@@ -45,33 +45,33 @@ StartValue<int32_t>()
   return 0;
 }
 
 template<>
 uint8_t
 StartValue<uint8_t>()
 {
   // Picking a value near middle of uint8_t's range.
-  return static_cast<uint8_t>(NumericLimits<int8_t>::max());
+  return static_cast<uint8_t>(std::numeric_limits<int8_t>::max());
 }
 
 template<>
 uint16_t
 StartValue<uint16_t>()
 {
   // Picking a value near middle of uint16_t's range.
-  return static_cast<uint8_t>(NumericLimits<int16_t>::max());
+  return static_cast<uint8_t>(std::numeric_limits<int16_t>::max());
 }
 
 template<>
 uint32_t
 StartValue<uint32_t>()
 {
   // Picking a value near middle of uint32_t's range.
-  return static_cast<uint8_t>(NumericLimits<int32_t>::max());
+  return static_cast<uint8_t>(std::numeric_limits<int32_t>::max());
 }
 
 // Add
 //
 
 template<typename T>
 static void
 TestPrefixIncr()
@@ -149,51 +149,51 @@ TestSub()
 
 // Corner cases near bounds
 //
 
 template<typename T>
 static void
 TestUpperBound()
 {
-  Saturate<T> satValue(NumericLimits<T>::max());
+  Saturate<T> satValue(std::numeric_limits<T>::max());
 
-  A(--satValue == (NumericLimits<T>::max() - 1));
-  A(++satValue == (NumericLimits<T>::max()));
-  A(++satValue == (NumericLimits<T>::max())); // don't overflow here
-  A(++satValue == (NumericLimits<T>::max())); // don't overflow here
-  A(--satValue == (NumericLimits<T>::max() - 1)); // back at (max - 1)
-  A(--satValue == (NumericLimits<T>::max() - 2));
+  A(--satValue == (std::numeric_limits<T>::max() - 1));
+  A(++satValue == (std::numeric_limits<T>::max()));
+  A(++satValue == (std::numeric_limits<T>::max())); // don't overflow here
+  A(++satValue == (std::numeric_limits<T>::max())); // don't overflow here
+  A(--satValue == (std::numeric_limits<T>::max() - 1)); // back at (max - 1)
+  A(--satValue == (std::numeric_limits<T>::max() - 2));
 }
 
 template<typename T>
 static void
 TestLowerBound()
 {
-  Saturate<T> satValue(NumericLimits<T>::min());
+  Saturate<T> satValue(std::numeric_limits<T>::min());
 
-  A(++satValue == (NumericLimits<T>::min() + 1));
-  A(--satValue == (NumericLimits<T>::min()));
-  A(--satValue == (NumericLimits<T>::min())); // don't overflow here
-  A(--satValue == (NumericLimits<T>::min())); // don't overflow here
-  A(++satValue == (NumericLimits<T>::min() + 1)); // back at (max + 1)
-  A(++satValue == (NumericLimits<T>::min() + 2));
+  A(++satValue == (std::numeric_limits<T>::min() + 1));
+  A(--satValue == (std::numeric_limits<T>::min()));
+  A(--satValue == (std::numeric_limits<T>::min())); // don't overflow here
+  A(--satValue == (std::numeric_limits<T>::min())); // don't overflow here
+  A(++satValue == (std::numeric_limits<T>::min() + 1)); // back at (max + 1)
+  A(++satValue == (std::numeric_limits<T>::min() + 2));
 }
 
 // Framework
 //
 
 template<typename T>
 static void
 TestAll()
 {
   // Assert that we don't accidently hit type's range limits in tests.
   const T value = StartValue<T>();
-  A(NumericLimits<T>::min() + static_cast<T>(sNumOps) <= value);
-  A(NumericLimits<T>::max() - static_cast<T>(sNumOps) >= value);
+  A(std::numeric_limits<T>::min() + static_cast<T>(sNumOps) <= value);
+  A(std::numeric_limits<T>::max() - static_cast<T>(sNumOps) >= value);
 
   TestPrefixIncr<T>();
   TestPostfixIncr<T>();
   TestAdd<T>();
 
   TestPrefixDecr<T>();
   TestPostfixDecr<T>();
   TestSub<T>();