Bug 869238 - Silence various -Wtype-limit warnings in Casting.h when instantiated with types with various size relationships. r=froydnj

This commit is contained in:
Jeff Walden 2013-05-06 16:38:42 -07:00
parent b4f8ba9013
commit 56d0d2cd0f

View File

@ -31,17 +31,43 @@ struct BoundsCheckImpl;
// that are obviously the same type (and will undergo no further conversions),
// even when it's not strictly necessary, for explicitness.
enum UUComparison { FromIsBigger, FromIsNotBigger };
// Unsigned-to-unsigned range check
template<typename From, typename To,
UUComparison = (sizeof(From) > sizeof(To)) ? FromIsBigger : FromIsNotBigger>
struct UnsignedUnsignedCheck;
template<typename From, typename To>
struct UnsignedUnsignedCheck<From, To, FromIsBigger>
{
public:
static bool check(const From from) {
return from <= From(To(-1));
}
};
template<typename From, typename To>
struct UnsignedUnsignedCheck<From, To, FromIsNotBigger>
{
public:
static bool check(const From from) {
return true;
}
};
template<typename From, typename To>
struct BoundsCheckImpl<From, To, FromIsUnsigned, ToIsUnsigned>
{
public:
static bool check(const From from) {
typedef typename Conditional<sizeof(From) >= sizeof(To), From, To>::Type
LargerType;
return LargerType(from) <= LargerType(To(-1));
return UnsignedUnsignedCheck<From, To>::check(from);
}
};
// Signed-to-unsigned range check
template<typename From, typename To>
struct BoundsCheckImpl<From, To, FromIsSigned, ToIsUnsigned>
{
@ -50,34 +76,60 @@ struct BoundsCheckImpl<From, To, FromIsSigned, ToIsUnsigned>
if (from < 0)
return false;
if (sizeof(To) >= sizeof(From))
return To(from) <= To(-1);
return true;
return from <= From(To(-1));
}
};
// Unsigned-to-signed range check
enum USComparison { FromIsSmaller, FromIsNotSmaller };
template<typename From, typename To,
USComparison = sizeof(From) < sizeof(To) ? FromIsSmaller : FromIsNotSmaller>
struct UnsignedSignedCheck;
template<typename From, typename To>
struct UnsignedSignedCheck<From, To, FromIsSmaller>
{
public:
static bool check(const From from) {
return true;
}
};
template<typename From, typename To>
struct UnsignedSignedCheck<From, To, FromIsNotSmaller>
{
public:
static bool check(const From from) {
const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1);
return from <= From(MaxValue);
}
};
template<typename From, typename To>
struct BoundsCheckImpl<From, To, FromIsUnsigned, ToIsSigned>
{
public:
static bool check(const From from) {
if (sizeof(From) < sizeof(To))
return true;
const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1);
return from <= From(MaxValue);
return UnsignedSignedCheck<From, To>::check(from);
}
};
// Signed-to-signed range check
template<typename From, typename To>
struct BoundsCheckImpl<From, To, FromIsSigned, ToIsSigned>
{
public:
static bool check(const From from) {
typedef typename Conditional<sizeof(To) >= sizeof(From), To, From>::Type
LargerType;
if (sizeof(From) <= sizeof(To))
return true;
const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1);
const To MinValue = -MaxValue - To(1);
return LargerType(MinValue) <= LargerType(from) &&
LargerType(from) <= LargerType(MaxValue);
return From(MinValue) <= from &&
From(from) <= From(MaxValue);
}
};