зеркало из https://github.com/mozilla/gecko-dev.git
Bug 874764 - Add CheckedInt support for operator%. - r=bjacob,waldo
This commit is contained in:
Родитель
63eccd6385
Коммит
75ab2ff473
|
@ -450,6 +450,44 @@ IsDivValid(T x, T y)
|
|||
!(IsSigned<T>::value && x == MinValue<T>::value && y == T(-1));
|
||||
}
|
||||
|
||||
template<typename T, bool IsTSigned = IsSigned<T>::value>
|
||||
struct IsModValidImpl;
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
IsModValid(T x, T y)
|
||||
{
|
||||
return IsModValidImpl<T>::run(x, y);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mod is pretty simple.
|
||||
* For now, let's just use the ANSI C definition:
|
||||
* If x or y are negative, the results are implementation defined.
|
||||
* Consider these invalid.
|
||||
* Undefined for y=0.
|
||||
* The result will never exceed either x or y.
|
||||
*
|
||||
* Checking that x>=0 is a warning when T is unsigned.
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
struct IsModValidImpl<T, false> {
|
||||
static inline bool run(T x, T y) {
|
||||
return y >= 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct IsModValidImpl<T, true> {
|
||||
static inline bool run(T x, T y) {
|
||||
if (x < 0)
|
||||
return false;
|
||||
|
||||
return y >= 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, bool IsSigned = IsSigned<T>::value>
|
||||
struct NegateImpl;
|
||||
|
||||
|
@ -619,22 +657,31 @@ class CheckedInt
|
|||
const CheckedInt<U>& rhs);
|
||||
template<typename U>
|
||||
CheckedInt& operator +=(U rhs);
|
||||
|
||||
template<typename U>
|
||||
friend CheckedInt<U> operator -(const CheckedInt<U>& lhs,
|
||||
const CheckedInt<U>& rhs);
|
||||
template<typename U>
|
||||
CheckedInt& operator -=(U rhs);
|
||||
|
||||
template<typename U>
|
||||
friend CheckedInt<U> operator *(const CheckedInt<U>& lhs,
|
||||
const CheckedInt<U>& rhs);
|
||||
template<typename U>
|
||||
CheckedInt& operator *=(U rhs);
|
||||
|
||||
template<typename U>
|
||||
friend CheckedInt<U> operator /(const CheckedInt<U>& lhs,
|
||||
const CheckedInt<U>& rhs);
|
||||
template<typename U>
|
||||
CheckedInt& operator /=(U rhs);
|
||||
|
||||
template<typename U>
|
||||
friend CheckedInt<U> operator %(const CheckedInt<U>& lhs,
|
||||
const CheckedInt<U>& rhs);
|
||||
template<typename U>
|
||||
CheckedInt& operator %=(U rhs);
|
||||
|
||||
CheckedInt operator -() const
|
||||
{
|
||||
return detail::NegateImpl<T>::negate(*this);
|
||||
|
@ -726,6 +773,7 @@ MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Add, +)
|
|||
MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Sub, -)
|
||||
MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mul, *)
|
||||
MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Div, /)
|
||||
MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mod, %)
|
||||
|
||||
#undef MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR
|
||||
|
||||
|
@ -786,6 +834,7 @@ MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(+, +=)
|
|||
MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(*, *=)
|
||||
MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(-, -=)
|
||||
MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(/, /=)
|
||||
MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(%, %=)
|
||||
|
||||
#undef MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS
|
||||
|
||||
|
|
|
@ -190,6 +190,26 @@ void test()
|
|||
VERIFY_IS_INVALID(one - min + min);
|
||||
}
|
||||
|
||||
/* Modulo checks */
|
||||
VERIFY_IS_INVALID(zero % zero);
|
||||
VERIFY_IS_INVALID(one % zero);
|
||||
VERIFY_IS_VALID(zero % one);
|
||||
VERIFY_IS_VALID(zero % max);
|
||||
VERIFY_IS_VALID(one % max);
|
||||
VERIFY_IS_VALID(max % one);
|
||||
VERIFY_IS_VALID(max % max);
|
||||
if (isTSigned) {
|
||||
const CheckedInt<T> minusOne = zero - one;
|
||||
VERIFY_IS_INVALID(minusOne % minusOne);
|
||||
VERIFY_IS_INVALID(zero % minusOne);
|
||||
VERIFY_IS_INVALID(one % minusOne);
|
||||
VERIFY_IS_INVALID(minusOne % one);
|
||||
|
||||
VERIFY_IS_INVALID(min % min);
|
||||
VERIFY_IS_INVALID(zero % min);
|
||||
VERIFY_IS_INVALID(min % one);
|
||||
}
|
||||
|
||||
/* Unary operator- checks */
|
||||
|
||||
const CheckedInt<T> negOne = -one;
|
||||
|
@ -347,10 +367,15 @@ void test()
|
|||
VERIFY_IS_INVALID(someInvalid / one);
|
||||
VERIFY_IS_INVALID(zero / someInvalid);
|
||||
VERIFY_IS_INVALID(one / someInvalid);
|
||||
VERIFY_IS_INVALID(someInvalid % zero);
|
||||
VERIFY_IS_INVALID(someInvalid % one);
|
||||
VERIFY_IS_INVALID(zero % someInvalid);
|
||||
VERIFY_IS_INVALID(one % someInvalid);
|
||||
VERIFY_IS_INVALID(someInvalid + someInvalid);
|
||||
VERIFY_IS_INVALID(someInvalid - someInvalid);
|
||||
VERIFY_IS_INVALID(someInvalid * someInvalid);
|
||||
VERIFY_IS_INVALID(someInvalid / someInvalid);
|
||||
VERIFY_IS_INVALID(someInvalid % someInvalid);
|
||||
|
||||
/* Check that mixing checked integers with plain integers in expressions is allowed */
|
||||
|
||||
|
@ -382,6 +407,13 @@ void test()
|
|||
x /= 2;
|
||||
VERIFY(x == two);
|
||||
}
|
||||
VERIFY(three % 2 == one);
|
||||
VERIFY(3 % two == one);
|
||||
{
|
||||
CheckedInt<T> x = three;
|
||||
x %= 2;
|
||||
VERIFY(x == one);
|
||||
}
|
||||
|
||||
VERIFY(one == 1);
|
||||
VERIFY(1 == one);
|
||||
|
|
Загрузка…
Ссылка в новой задаче