Bug 1097512 - Allow using compound operators where the LHS and RHS are both CheckedInt<T>. r=jwalden+bmo

This commit is contained in:
Matthew Gregan 2014-11-14 16:13:23 +13:00
parent 56034c2859
commit 1f133d4dff
2 changed files with 84 additions and 17 deletions

View File

@ -574,30 +574,35 @@ public:
const CheckedInt<U>& aRhs);
template<typename U>
CheckedInt& operator +=(U aRhs);
CheckedInt& operator +=(const CheckedInt<T>& aRhs);
template<typename U>
friend CheckedInt<U> operator -(const CheckedInt<U>& aLhs,
const CheckedInt<U>& aRhs);
template<typename U>
CheckedInt& operator -=(U aRhs);
CheckedInt& operator -=(const CheckedInt<T>& aRhs);
template<typename U>
friend CheckedInt<U> operator *(const CheckedInt<U>& aLhs,
const CheckedInt<U>& aRhs);
template<typename U>
CheckedInt& operator *=(U aRhs);
CheckedInt& operator *=(const CheckedInt<T>& aRhs);
template<typename U>
friend CheckedInt<U> operator /(const CheckedInt<U>& aLhs,
const CheckedInt<U>& aRhs);
template<typename U>
CheckedInt& operator /=(U aRhs);
CheckedInt& operator /=(const CheckedInt<T>& aRhs);
template<typename U>
friend CheckedInt<U> operator %(const CheckedInt<U>& aLhs,
const CheckedInt<U>& aRhs);
template<typename U>
CheckedInt& operator %=(U aRhs);
CheckedInt& operator %=(const CheckedInt<T>& aRhs);
CheckedInt operator -() const
{
@ -723,23 +728,29 @@ castToCheckedInt(U aU)
return detail::CastToCheckedIntImpl<T, U>::run(aU);
}
#define MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(OP, COMPOUND_OP) \
template<typename T> \
template<typename U> \
CheckedInt<T>& CheckedInt<T>::operator COMPOUND_OP(U aRhs) \
{ \
*this = *this OP castToCheckedInt<T>(aRhs); \
return *this; \
} \
template<typename T, typename U> \
inline CheckedInt<T> operator OP(const CheckedInt<T>& aLhs, U aRhs) \
{ \
return aLhs OP castToCheckedInt<T>(aRhs); \
} \
template<typename T, typename U> \
inline CheckedInt<T> operator OP(U aLhs, const CheckedInt<T>& aRhs) \
{ \
return castToCheckedInt<T>(aLhs) OP aRhs; \
#define MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(OP, COMPOUND_OP) \
template<typename T> \
template<typename U> \
CheckedInt<T>& CheckedInt<T>::operator COMPOUND_OP(U aRhs) \
{ \
*this = *this OP castToCheckedInt<T>(aRhs); \
return *this; \
} \
template<typename T> \
CheckedInt<T>& CheckedInt<T>::operator COMPOUND_OP(const CheckedInt<T>& aRhs) \
{ \
*this = *this OP aRhs; \
return *this; \
} \
template<typename T, typename U> \
inline CheckedInt<T> operator OP(const CheckedInt<T>& aLhs, U aRhs) \
{ \
return aLhs OP castToCheckedInt<T>(aRhs); \
} \
template<typename T, typename U> \
inline CheckedInt<T> operator OP(U aLhs, const CheckedInt<T>& aRhs) \
{ \
return castToCheckedInt<T>(aLhs) OP aRhs; \
}
MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(+, +=)

View File

@ -422,6 +422,62 @@ void test()
VERIFY_IS_FALSE(someInvalid == 1);
VERIFY_IS_FALSE(1 == someInvalid);
// Check that compound operators work when both sides of the expression
// are checked integers
{
CheckedInt<T> x = one;
x += two;
VERIFY(x == three);
}
{
CheckedInt<T> x = two;
x -= one;
VERIFY(x == one);
}
{
CheckedInt<T> x = one;
x *= two;
VERIFY(x == two);
}
{
CheckedInt<T> x = four;
x /= two;
VERIFY(x == two);
}
{
CheckedInt<T> x = three;
x %= two;
VERIFY(x == one);
}
// Check that compound operators work when both sides of the expression
// are checked integers and the right-hand side is invalid
{
CheckedInt<T> x = one;
x += someInvalid;
VERIFY_IS_INVALID(x);
}
{
CheckedInt<T> x = two;
x -= someInvalid;
VERIFY_IS_INVALID(x);
}
{
CheckedInt<T> x = one;
x *= someInvalid;
VERIFY_IS_INVALID(x);
}
{
CheckedInt<T> x = four;
x /= someInvalid;
VERIFY_IS_INVALID(x);
}
{
CheckedInt<T> x = three;
x %= someInvalid;
VERIFY_IS_INVALID(x);
}
// Check simple casting between different signedness and sizes.
{
CheckedInt<uint8_t> foo = CheckedInt<uint16_t>(2).toChecked<uint8_t>();