diff --git a/mfbt/TypeTraits.h b/mfbt/TypeTraits.h index ab594fd4bb28..3184221ec598 100644 --- a/mfbt/TypeTraits.h +++ b/mfbt/TypeTraits.h @@ -417,26 +417,30 @@ namespace detail { template::value, + bool = IsIntegral::value, typename NoCV = typename RemoveCV::Type> struct IsSignedHelper; +// Floating point is signed. template -struct IsSignedHelper : TrueType {}; +struct IsSignedHelper : TrueType {}; +// Integral is conditionally signed. template -struct IsSignedHelper - : IntegralConstant::value && NoCV(-1) < NoCV(1)> +struct IsSignedHelper + : IntegralConstant {}; +// Non-floating point, non-integral is not signed. +template +struct IsSignedHelper : FalseType {}; + } // namespace detail /** * IsSigned determines whether a type is a signed arithmetic type. |char| is * considered a signed type if it has the same representation as |signed char|. * - * Don't use this if the type might be user-defined! You might or might not get - * a compile error, depending. - * * mozilla::IsSigned::value is true; * mozilla::IsSigned::value is false; * mozilla::IsSigned::value is false; @@ -449,27 +453,30 @@ namespace detail { template::value, + bool = IsIntegral::value, typename NoCV = typename RemoveCV::Type> struct IsUnsignedHelper; +// Floating point is not unsigned. template -struct IsUnsignedHelper : FalseType {}; +struct IsUnsignedHelper : FalseType {}; +// Integral is conditionally unsigned. template -struct IsUnsignedHelper +struct IsUnsignedHelper : IntegralConstant::value && - (IsSame::value || NoCV(1) < NoCV(-1))> + (IsSame::value || bool(NoCV(1) < NoCV(-1)))> {}; +// Non-floating point, non-integral is not unsigned. +template +struct IsUnsignedHelper : FalseType {}; + } // namespace detail /** * IsUnsigned determines whether a type is an unsigned arithmetic type. * - * Don't use this if the type might be user-defined! You might or might not get - * a compile error, depending. - * * mozilla::IsUnsigned::value is false; * mozilla::IsUnsigned::value is true; * mozilla::IsUnsigned::value is true; diff --git a/mfbt/tests/TestTypeTraits.cpp b/mfbt/tests/TestTypeTraits.cpp index cc0057aed6e2..eef8a867f9fd 100644 --- a/mfbt/tests/TestTypeTraits.cpp +++ b/mfbt/tests/TestTypeTraits.cpp @@ -153,6 +153,16 @@ static_assert(IsSigned::value, static_assert(!IsUnsigned::value, "const volatile long double shouldn't be unsigned"); +class NotIntConstructible +{ + NotIntConstructible(int) MOZ_DELETE; +}; + +static_assert(!IsSigned::value, + "non-arithmetic types are not signed"); +static_assert(!IsUnsigned::value, + "non-arithmetic types are not unsigned"); + namespace CPlusPlus11IsBaseOf { // Adapted from C++11 ยง 20.9.6.