diff --git a/mfbt/MathAlgorithms.h b/mfbt/MathAlgorithms.h index f94dad1407d2..147bab678fd0 100644 --- a/mfbt/MathAlgorithms.h +++ b/mfbt/MathAlgorithms.h @@ -49,6 +49,73 @@ EuclidLCM(IntegerType a, IntegerType b) namespace detail { +template +struct AllowDeprecatedAbsFixed : FalseType {}; + +template<> struct AllowDeprecatedAbsFixed : TrueType {}; +template<> struct AllowDeprecatedAbsFixed : TrueType {}; +template<> struct AllowDeprecatedAbsFixed : TrueType {}; +template<> struct AllowDeprecatedAbsFixed : TrueType {}; + +template +struct AllowDeprecatedAbs : AllowDeprecatedAbsFixed {}; + +template<> struct AllowDeprecatedAbs : IntegralConstant {}; +template<> struct AllowDeprecatedAbs : TrueType {}; +template<> struct AllowDeprecatedAbs : TrueType {}; +template<> struct AllowDeprecatedAbs : TrueType {}; +template<> struct AllowDeprecatedAbs : TrueType {}; +template<> struct AllowDeprecatedAbs : TrueType {}; +template<> struct AllowDeprecatedAbs : TrueType {}; +template<> struct AllowDeprecatedAbs : TrueType {}; +template<> struct AllowDeprecatedAbs : TrueType {}; + +} // namespace detail + +// DO NOT USE DeprecatedAbs. It exists only until its callers can be converted +// to Abs below, and it will be removed when all callers have been changed. +template +inline typename mozilla::EnableIf::value, T>::Type +DeprecatedAbs(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- 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; +} + +template<> +inline float +DeprecatedAbs(const float f) +{ + return fabsf(f); +} + +template<> +inline double +DeprecatedAbs(const double d) +{ + return fabs(d); +} + +template<> +inline long double +DeprecatedAbs(const long double d) +{ + return fabsl(d); +} + +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.