Bug 798179 - Implement mozilla::MakeUnsigned. r=froydnj
authorJeff Walden <jwalden@mit.edu>
Tue, 05 Mar 2013 15:44:02 -0800
changeset 146152 094d54c0c9ea9db818d88beca4db95851bb1ecfa
parent 146151 e4473d563e0f290a838efcd2a21c348774ec558b
child 146153 b9c7d27d4b43dc57832837dff3c26896d359af76
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs798179
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 798179 - Implement mozilla::MakeUnsigned. r=froydnj
mfbt/TypeTraits.h
mfbt/tests/TestTypeTraits.cpp
--- a/mfbt/TypeTraits.h
+++ b/mfbt/TypeTraits.h
@@ -538,16 +538,84 @@ struct MakeSigned<T, CVRemoved, false>
  */
 template<typename T>
 struct MakeSigned
   : EnableIf<IsIntegral<T>::value && !IsSame<bool, typename RemoveCV<T>::Type>::value,
              typename detail::MakeSigned<T>
             >::Type
 {};
 
+namespace detail {
+
+template<typename T>
+struct CorrespondingUnsigned;
+
+template<>
+struct CorrespondingUnsigned<char> { typedef unsigned char Type; };
+template<>
+struct CorrespondingUnsigned<signed char> { typedef unsigned char Type; };
+template<>
+struct CorrespondingUnsigned<short> { typedef unsigned short Type; };
+template<>
+struct CorrespondingUnsigned<int> { typedef unsigned int Type; };
+template<>
+struct CorrespondingUnsigned<long> { typedef unsigned long Type; };
+template<>
+struct CorrespondingUnsigned<long long> { typedef unsigned long long Type; };
+
+
+template<typename T,
+         typename CVRemoved = typename RemoveCV<T>::Type,
+         bool IsUnsignedIntegerType = IsUnsigned<CVRemoved>::value &&
+                                      !IsSame<char, CVRemoved>::value>
+struct MakeUnsigned;
+
+template<typename T, typename CVRemoved>
+struct MakeUnsigned<T, CVRemoved, true>
+{
+    typedef T Type;
+};
+
+template<typename T, typename CVRemoved>
+struct MakeUnsigned<T, CVRemoved, false>
+  : WithCV<IsConst<T>::value, IsVolatile<T>::value,
+           typename CorrespondingUnsigned<CVRemoved>::Type>
+{};
+
+} // namespace detail
+
+/**
+ * MakeUnsigned produces the corresponding unsigned integer type for a given
+ * integral type T, with the const/volatile qualifiers of T.  T must be a
+ * possibly-const/volatile-qualified integral type that isn't bool.
+ *
+ * If T is already an unsigned integer type (not including char!), then T is
+ * produced.
+ *
+ * Otherwise, if T is an signed integer type, the unsigned variety of T, with
+ * T's const/volatile qualifiers, is produced.
+ *
+ * Otherwise, the unsigned integral type of the same size as T, with the lowest
+ * rank, with T's const/volatile qualifiers, is produced.  (This basically only
+ * acts to produce unsigned char when T = char.)
+ *
+ * mozilla::MakeUnsigned<signed long>::Type is unsigned long;
+ * mozilla::MakeUnsigned<volatile unsigned int>::Type is volatile unsigned int;
+ * mozilla::MakeUnsigned<const signed short>::Type is const unsigned short;
+ * mozilla::MakeUnsigned<const char>::Type is const unsigned char;
+ * mozilla::MakeUnsigned<bool> is an error;
+ * mozilla::MakeUnsigned<void*> is an error.
+ */
+template<typename T>
+struct MakeUnsigned
+  : EnableIf<IsIntegral<T>::value && !IsSame<bool, typename RemoveCV<T>::Type>::value,
+             typename detail::MakeUnsigned<T>
+            >::Type
+{};
+
 /* 20.9.7.4 Array modifications [meta.trans.arr] */
 
 /* 20.9.7.5 Pointer modifications [meta.trans.ptr] */
 
 /* 20.9.7.6 Other transformations [meta.trans.other] */
 
 /**
  * EnableIf is a struct containing a typedef of T if and only if B is true.
--- a/mfbt/tests/TestTypeTraits.cpp
+++ b/mfbt/tests/TestTypeTraits.cpp
@@ -7,16 +7,17 @@
 #include "mozilla/TypeTraits.h"
 
 using mozilla::IsBaseOf;
 using mozilla::IsConvertible;
 using mozilla::IsSame;
 using mozilla::IsSigned;
 using mozilla::IsUnsigned;
 using mozilla::MakeSigned;
+using mozilla::MakeUnsigned;
 
 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");
@@ -172,15 +173,41 @@ MOZ_STATIC_ASSERT((IsSame<MakeSigned<sig
 
 MOZ_STATIC_ASSERT((IsSame<MakeSigned<char>::Type, signed char>::value),
                   "char won't signify correctly");
 MOZ_STATIC_ASSERT((IsSame<MakeSigned<volatile char>::Type, volatile signed char>::value),
                   "volatile char won't signify correctly");
 MOZ_STATIC_ASSERT((IsSame<MakeSigned<const char>::Type, const signed char>::value),
                   "const char won't signify correctly");
 
+MOZ_STATIC_ASSERT((IsSame<MakeUnsigned<const signed char>::Type, const unsigned char>::value),
+                  "const signed char won't unsignify correctly");
+MOZ_STATIC_ASSERT((IsSame<MakeUnsigned<volatile signed short>::Type, volatile unsigned short>::value),
+                  "volatile signed short won't unsignify correctly");
+MOZ_STATIC_ASSERT((IsSame<MakeUnsigned<const volatile signed int>::Type, const volatile unsigned int>::value),
+                  "const volatile signed int won't unsignify correctly");
+MOZ_STATIC_ASSERT((IsSame<MakeUnsigned<signed long>::Type, unsigned long>::value),
+                  "signed long won't unsignify correctly");
+
+MOZ_STATIC_ASSERT((IsSame<MakeUnsigned<const unsigned char>::Type, const unsigned char>::value),
+                  "const unsigned char won't unsignify correctly");
+
+MOZ_STATIC_ASSERT((IsSame<MakeUnsigned<volatile unsigned short>::Type, volatile unsigned short>::value),
+                  "volatile unsigned short won't unsignify correctly");
+MOZ_STATIC_ASSERT((IsSame<MakeUnsigned<const volatile unsigned int>::Type, const volatile unsigned int>::value),
+                  "const volatile unsigned int won't unsignify correctly");
+MOZ_STATIC_ASSERT((IsSame<MakeUnsigned<unsigned long>::Type, unsigned long>::value),
+                  "signed long won't unsignify correctly");
+
+MOZ_STATIC_ASSERT((IsSame<MakeUnsigned<char>::Type, unsigned char>::value),
+                  "char won't unsignify correctly");
+MOZ_STATIC_ASSERT((IsSame<MakeUnsigned<volatile char>::Type, volatile unsigned char>::value),
+                  "volatile char won't unsignify correctly");
+MOZ_STATIC_ASSERT((IsSame<MakeUnsigned<const char>::Type, const unsigned char>::value),
+                  "const char won't unsignify correctly");
+
 int
 main()
 {
   CPlusPlus11IsBaseOf::StandardIsBaseOfTests();
   TestIsBaseOf();
   TestIsConvertible();
 }