Bug 798179 - Implement mozilla::MakeUnsigned. r=froydnj

--HG--
extra : rebase_source : fdd1fe8841d1bc42c1758cd4d477969b3f382b30
This commit is contained in:
Jeff Walden 2013-03-05 15:44:02 -08:00
parent ccd085af07
commit 6249325181
2 changed files with 95 additions and 0 deletions

View File

@ -543,6 +543,74 @@ struct MakeSigned
>::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] */

View File

@ -12,6 +12,7 @@ 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");
@ -177,6 +178,32 @@ MOZ_STATIC_ASSERT((IsSame<MakeSigned<volatile char>::Type, volatile signed char>
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()
{