author | Jeff Walden <jwalden@mit.edu> |
Tue, 05 Mar 2013 15:44:02 -0800 | |
changeset 134661 | 094d54c0c9ea9db818d88beca4db95851bb1ecfa |
parent 134660 | e4473d563e0f290a838efcd2a21c348774ec558b |
child 134662 | b9c7d27d4b43dc57832837dff3c26896d359af76 |
push id | 24810 |
push user | ryanvm@gmail.com |
push date | Wed, 12 Jun 2013 01:03:01 +0000 |
treeherder | mozilla-central@cc35f8929768 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | froydnj |
bugs | 798179 |
milestone | 24.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
|
mfbt/TypeTraits.h | file | annotate | diff | comparison | revisions | |
mfbt/tests/TestTypeTraits.cpp | file | annotate | diff | comparison | revisions |
--- 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(); }