Bug 847480 - Copy the existing mozilla::Abs as mozilla::DeprecatedAbs, to allow mozilla::Abs to return an unsigned type when possible. r=Ms2ger

This commit is contained in:
Jeff Walden 2013-03-05 15:43:23 -08:00
parent 23bfd4b872
commit 77565ad0f3

View File

@ -49,6 +49,73 @@ EuclidLCM(IntegerType a, IntegerType b)
namespace detail { namespace detail {
template<typename T>
struct AllowDeprecatedAbsFixed : FalseType {};
template<> struct AllowDeprecatedAbsFixed<int8_t> : TrueType {};
template<> struct AllowDeprecatedAbsFixed<int16_t> : TrueType {};
template<> struct AllowDeprecatedAbsFixed<int32_t> : TrueType {};
template<> struct AllowDeprecatedAbsFixed<int64_t> : TrueType {};
template<typename T>
struct AllowDeprecatedAbs : AllowDeprecatedAbsFixed<T> {};
template<> struct AllowDeprecatedAbs<char> : IntegralConstant<bool, char(-1) < char(0)> {};
template<> struct AllowDeprecatedAbs<signed char> : TrueType {};
template<> struct AllowDeprecatedAbs<short> : TrueType {};
template<> struct AllowDeprecatedAbs<int> : TrueType {};
template<> struct AllowDeprecatedAbs<long> : TrueType {};
template<> struct AllowDeprecatedAbs<long long> : TrueType {};
template<> struct AllowDeprecatedAbs<float> : TrueType {};
template<> struct AllowDeprecatedAbs<double> : TrueType {};
template<> struct AllowDeprecatedAbs<long double> : 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<typename T>
inline typename mozilla::EnableIf<detail::AllowDeprecatedAbs<T>::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-<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;
}
template<>
inline float
DeprecatedAbs<float>(const float f)
{
return fabsf(f);
}
template<>
inline double
DeprecatedAbs<double>(const double d)
{
return fabs(d);
}
template<>
inline long double
DeprecatedAbs<long double>(const long double d)
{
return fabsl(d);
}
namespace detail {
// For now mozilla::Abs only takes intN_T, the signed natural types, and // 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, // float/double/long double. Feel free to add overloads for other standard,
// signed types if you need them. // signed types if you need them.