Bug 847480 - Make mozilla::Abs return the unsigned type, for the integral types. r=bjacob
authorJeff Walden <jwalden@mit.edu>
Tue, 05 Mar 2013 15:43:38 -0800
changeset 124710 eb393a9ef207cc8de47d100bdc2ef7ed5a42dfd0
parent 124709 a92b863e4fbd43f3ff3bffcb14cffc3413975454
child 124711 1338c63a370bb2c030b73276a72eedc835eceb01
push id24433
push useremorley@mozilla.com
push dateThu, 14 Mar 2013 12:21:10 +0000
treeherdermozilla-central@96af92fa87fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbjacob
bugs847480
milestone22.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 847480 - Make mozilla::Abs return the unsigned type, for the integral types. r=bjacob
mfbt/MathAlgorithms.h
--- a/mfbt/MathAlgorithms.h
+++ b/mfbt/MathAlgorithms.h
@@ -116,55 +116,44 @@ DeprecatedAbs<long double>(const long do
 
 namespace detail {
 
 // For now mozilla::Abs only takes intN_T, the signed natural types, and
 // float/double/long double.  Feel free to add overloads for other standard,
 // signed types if you need them.
 
 template<typename T>
-struct SupportedForAbsFixed : FalseType {};
+struct AbsReturnTypeFixed;
 
-template<> struct SupportedForAbsFixed<int8_t> : TrueType {};
-template<> struct SupportedForAbsFixed<int16_t> : TrueType {};
-template<> struct SupportedForAbsFixed<int32_t> : TrueType {};
-template<> struct SupportedForAbsFixed<int64_t> : TrueType {};
+template<> struct AbsReturnTypeFixed<int8_t> { typedef uint8_t Type; };
+template<> struct AbsReturnTypeFixed<int16_t> { typedef uint16_t Type; };
+template<> struct AbsReturnTypeFixed<int32_t> { typedef uint32_t Type; };
+template<> struct AbsReturnTypeFixed<int64_t> { typedef uint64_t Type; };
 
 template<typename T>
-struct SupportedForAbs : SupportedForAbsFixed<T> {};
+struct AbsReturnType : AbsReturnTypeFixed<T> {};
 
-template<> struct SupportedForAbs<char> : IntegralConstant<bool, char(-1) < char(0)> {};
-template<> struct SupportedForAbs<signed char> : TrueType {};
-template<> struct SupportedForAbs<short> : TrueType {};
-template<> struct SupportedForAbs<int> : TrueType {};
-template<> struct SupportedForAbs<long> : TrueType {};
-template<> struct SupportedForAbs<long long> : TrueType {};
-template<> struct SupportedForAbs<float> : TrueType {};
-template<> struct SupportedForAbs<double> : TrueType {};
-template<> struct SupportedForAbs<long double> : TrueType {};
+template<> struct AbsReturnType<char> : EnableIf<char(-1) < char(0), unsigned char> {};
+template<> struct AbsReturnType<signed char> { typedef unsigned char Type; };
+template<> struct AbsReturnType<short> { typedef unsigned short Type; };
+template<> struct AbsReturnType<int> { typedef unsigned int Type; };
+template<> struct AbsReturnType<long> { typedef unsigned long Type; };
+template<> struct AbsReturnType<long long> { typedef unsigned long long Type; };
+template<> struct AbsReturnType<float> { typedef float Type; };
+template<> struct AbsReturnType<double> { typedef double Type; };
+template<> struct AbsReturnType<long double> { typedef long double Type; };
 
 } // namespace detail
 
 template<typename T>
-inline typename mozilla::EnableIf<detail::SupportedForAbs<T>::value, T>::Type
+inline typename detail::AbsReturnType<T>::Type
 Abs(const T t)
 {
-  // The absolute value of the smallest possible value of a signed-integer type
-  // won't fit in that type (on twos-complement systems -- and we're blithely
-  // assuming we're on such systems, for the non-<stdint.h> types listed above),
-  // so assert that the input isn't that value.
-  //
-  // This is the case if: the value is non-negative; or if adding one (giving a
-  // value in the range [-maxvalue, 0]), then negating (giving a value in the
-  // range [0, maxvalue]), doesn't produce maxvalue (because in twos-complement,
-  // (minvalue + 1) == -maxvalue).
-  MOZ_ASSERT(t >= 0 ||
-             -(t + 1) != T((1ULL << (CHAR_BIT * sizeof(T) - 1)) - 1),
-             "You can't negate the smallest possible negative integer!");
-  return t >= 0 ? t : -t;
+  typedef typename detail::AbsReturnType<T>::Type ReturnType;
+  return t >= 0 ? ReturnType(t) : ~ReturnType(t) + 1;
 }
 
 template<>
 inline float
 Abs<float>(const float f)
 {
   return fabsf(f);
 }