Bug 873585 - Silence a vacuous-comparison-against-0 warning when compiling with gcc 4.5, at least. Also make IsSigned/IsUnsigned actually work on floating-point types. r=froydnj
authorJeff Walden <jwalden@mit.edu>
Fri, 17 May 2013 11:07:02 -0700
changeset 132426 b0cb71ae891fabdc7d32ec02683f864ebba6d1a3
parent 132425 ac24924abe718b0a844f4698f7ffafa433a6bb6e
child 132427 dd2ffe93fb2f463f86e8efa4766ca4dde5179ac0
push id28269
push userjwalden@mit.edu
push dateMon, 20 May 2013 20:45:43 +0000
treeherdermozilla-inbound@b0cb71ae891f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs873585
milestone24.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 873585 - Silence a vacuous-comparison-against-0 warning when compiling with gcc 4.5, at least. Also make IsSigned/IsUnsigned actually work on floating-point types. r=froydnj
mfbt/TypeTraits.h
mfbt/tests/TestTypeTraits.cpp
--- a/mfbt/TypeTraits.h
+++ b/mfbt/TypeTraits.h
@@ -192,47 +192,76 @@ template<> struct IsPod<unsigned long>  
 template<> struct IsPod<long long>          : TrueType {};
 template<> struct IsPod<unsigned long long> : TrueType {};
 template<> struct IsPod<bool>               : TrueType {};
 template<> struct IsPod<float>              : TrueType {};
 template<> struct IsPod<double>             : TrueType {};
 template<> struct IsPod<wchar_t>            : TrueType {};
 template<typename T> struct IsPod<T*>       : TrueType {};
 
+namespace detail {
+
+template<typename T, bool = IsFloatingPoint<T>::value>
+struct IsSignedHelper;
+
+template<typename T>
+struct IsSignedHelper<T, true> : TrueType {};
+
+template<typename T>
+struct IsSignedHelper<T, false>
+  : IntegralConstant<bool, IsArithmetic<T>::value && T(-1) < T(1)>
+{};
+
+} // namespace detail
+
 /**
  * IsSigned determines whether a type is a signed arithmetic type.
  *
  * Don't use this if the type might be user-defined!  You might or might not get
  * a compile error, depending.
  *
  * mozilla::IsSigned<int>::value is true;
  * mozilla::IsSigned<const unsigned int>::value is false;
  * mozilla::IsSigned<unsigned char>::value is false;
  * mozilla::IsSigned<float>::value is true.
  */
 template<typename T>
-struct IsSigned
-  : IntegralConstant<bool, IsArithmetic<T>::value && T(-1) < T(0)>
+struct IsSigned : detail::IsSignedHelper<T> {};
+
+namespace detail {
+
+template<typename T, bool = IsFloatingPoint<T>::value>
+struct IsUnsignedHelper;
+
+template<typename T>
+struct IsUnsignedHelper<T, true> : FalseType {};
+
+template<typename T>
+struct IsUnsignedHelper<T, false>
+  : IntegralConstant<bool,
+                     IsArithmetic<T>::value &&
+                     (IsSame<typename RemoveCV<T>::Type, bool>::value ||
+                      T(1) < T(-1))>
 {};
 
+} // 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<int>::value is false;
  * mozilla::IsUnsigned<const unsigned int>::value is true;
  * mozilla::IsUnsigned<unsigned char>::value is true;
  * mozilla::IsUnsigned<float>::value is false.
  */
 template<typename T>
-struct IsUnsigned
-  : IntegralConstant<bool, IsArithmetic<T>::value && T(0) < T(-1)>
-{};
+struct IsUnsigned : detail::IsUnsignedHelper<T> {};
 
 /* 20.9.5 Type property queries [meta.unary.prop.query] */
 
 /* 20.9.6 Relationships between types [meta.rel] */
 
 /**
  * IsSame tests whether two types are the same type.
  *
--- a/mfbt/tests/TestTypeTraits.cpp
+++ b/mfbt/tests/TestTypeTraits.cpp
@@ -3,16 +3,67 @@
  * 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/Assertions.h"
 #include "mozilla/TypeTraits.h"
 
 using mozilla::IsBaseOf;
 using mozilla::IsConvertible;
+using mozilla::IsSigned;
+using mozilla::IsUnsigned;
+
+MOZ_STATIC_ASSERT(!IsSigned<bool>::value, "bool shouldn't be signed");
+MOZ_STATIC_ASSERT(IsUnsigned<bool>::value, "bool should be unsigned");
+
+MOZ_STATIC_ASSERT(!IsSigned<const bool>::value, "const bool shouldn't be signed");
+MOZ_STATIC_ASSERT(IsUnsigned<const bool>::value, "const bool should be unsigned");
+
+MOZ_STATIC_ASSERT(!IsSigned<volatile bool>::value, "volatile bool shouldn't be signed");
+MOZ_STATIC_ASSERT(IsUnsigned<volatile bool>::value, "volatile bool should be unsigned");
+
+MOZ_STATIC_ASSERT(!IsSigned<unsigned char>::value, "unsigned char shouldn't be signed");
+MOZ_STATIC_ASSERT(IsUnsigned<unsigned char>::value, "unsigned char should be unsigned");
+MOZ_STATIC_ASSERT(IsSigned<signed char>::value, "signed char should be signed");
+MOZ_STATIC_ASSERT(!IsUnsigned<signed char>::value, "signed char shouldn't be unsigned");
+
+MOZ_STATIC_ASSERT(!IsSigned<unsigned short>::value, "unsigned short shouldn't be signed");
+MOZ_STATIC_ASSERT(IsUnsigned<unsigned short>::value, "unsigned short should be unsigned");
+MOZ_STATIC_ASSERT(IsSigned<short>::value, "short should be signed");
+MOZ_STATIC_ASSERT(!IsUnsigned<short>::value, "short shouldn't be unsigned");
+
+MOZ_STATIC_ASSERT(!IsSigned<unsigned int>::value, "unsigned int shouldn't be signed");
+MOZ_STATIC_ASSERT(IsUnsigned<unsigned int>::value, "unsigned int should be unsigned");
+MOZ_STATIC_ASSERT(IsSigned<int>::value, "int should be signed");
+MOZ_STATIC_ASSERT(!IsUnsigned<int>::value, "int shouldn't be unsigned");
+
+MOZ_STATIC_ASSERT(!IsSigned<unsigned long>::value, "unsigned long shouldn't be signed");
+MOZ_STATIC_ASSERT(IsUnsigned<unsigned long>::value, "unsigned long should be unsigned");
+MOZ_STATIC_ASSERT(IsSigned<long>::value, "long should be signed");
+MOZ_STATIC_ASSERT(!IsUnsigned<long>::value, "long shouldn't be unsigned");
+
+MOZ_STATIC_ASSERT(IsSigned<float>::value, "float should be signed");
+MOZ_STATIC_ASSERT(!IsUnsigned<float>::value, "float shouldn't be unsigned");
+
+MOZ_STATIC_ASSERT(IsSigned<const float>::value, "const float should be signed");
+MOZ_STATIC_ASSERT(!IsUnsigned<const float>::value, "const float shouldn't be unsigned");
+
+MOZ_STATIC_ASSERT(IsSigned<double>::value, "double should be signed");
+MOZ_STATIC_ASSERT(!IsUnsigned<double>::value, "double shouldn't be unsigned");
+
+MOZ_STATIC_ASSERT(IsSigned<volatile double>::value, "volatile double should be signed");
+MOZ_STATIC_ASSERT(!IsUnsigned<volatile double>::value, "volatile double shouldn't be unsigned");
+
+MOZ_STATIC_ASSERT(IsSigned<long double>::value, "long double should be signed");
+MOZ_STATIC_ASSERT(!IsUnsigned<long double>::value, "long double shouldn't be unsigned");
+
+MOZ_STATIC_ASSERT(IsSigned<const volatile long double>::value,
+                  "const volatile long double should be signed");
+MOZ_STATIC_ASSERT(!IsUnsigned<const volatile long double>::value,
+                  "const volatile long double shouldn't be unsigned");
 
 namespace CPlusPlus11IsBaseOf {
 
 // Adapted from C++11 ยง 20.9.6.
 struct B {};
 struct B1 : B {};
 struct B2 : B {};
 struct D : private B1, private B2 {};