Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Unified Diff: base/numerics/safe_math_impl.h

Issue 2600853004: Minor base/numerics cleanup (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/numerics/safe_conversions_impl.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/numerics/safe_math_impl.h
diff --git a/base/numerics/safe_math_impl.h b/base/numerics/safe_math_impl.h
index 65589baadb26a4e0d8382cc2cf59af10063a9e3a..9a47a27a08139ba01c4f8794ab7e3a0194f9e961 100644
--- a/base/numerics/safe_math_impl.h
+++ b/base/numerics/safe_math_impl.h
@@ -57,6 +57,7 @@ bool CheckedAddImpl(T x, T y, T* result) {
// Since the value of x+y is undefined if we have a signed type, we compute
// it using the unsigned type of the same size.
using UnsignedDst = typename std::make_unsigned<T>::type;
+ using SignedDst = typename std::make_signed<T>::type;
UnsignedDst ux = static_cast<UnsignedDst>(x);
UnsignedDst uy = static_cast<UnsignedDst>(y);
UnsignedDst uresult = static_cast<UnsignedDst>(ux + uy);
@@ -64,10 +65,8 @@ bool CheckedAddImpl(T x, T y, T* result) {
// Addition is valid if the sign of (x + y) is equal to either that of x or
// that of y.
return (std::is_signed<T>::value)
- ? HasSignBit(BinaryComplement(
- static_cast<UnsignedDst>((uresult ^ ux) & (uresult ^ uy))))
- : (BinaryComplement(x) >=
- y); // Unsigned is either valid or underflow.
+ ? static_cast<SignedDst>((uresult ^ ux) & (uresult ^ uy)) >= 0
+ : uresult >= uy; // Unsigned is either valid or underflow.
}
template <typename T, typename U, class Enable = void>
@@ -109,6 +108,7 @@ bool CheckedSubImpl(T x, T y, T* result) {
// Since the value of x+y is undefined if we have a signed type, we compute
// it using the unsigned type of the same size.
using UnsignedDst = typename std::make_unsigned<T>::type;
+ using SignedDst = typename std::make_signed<T>::type;
UnsignedDst ux = static_cast<UnsignedDst>(x);
UnsignedDst uy = static_cast<UnsignedDst>(y);
UnsignedDst uresult = static_cast<UnsignedDst>(ux - uy);
@@ -116,9 +116,8 @@ bool CheckedSubImpl(T x, T y, T* result) {
// Subtraction is valid if either x and y have same sign, or (x-y) and x have
// the same sign.
return (std::is_signed<T>::value)
- ? HasSignBit(BinaryComplement(
- static_cast<UnsignedDst>((uresult ^ ux) & (ux ^ uy))))
- : (x >= y);
+ ? static_cast<SignedDst>((uresult ^ ux) & (ux ^ uy)) >= 0
+ : x >= y;
}
template <typename T, typename U, class Enable = void>
@@ -180,11 +179,11 @@ bool CheckedMulImpl(T x, T y, T* result) {
// Since the value of x*y is potentially undefined if we have a signed type,
// we compute it using the unsigned type of the same size.
using UnsignedDst = typename std::make_unsigned<T>::type;
- const T is_negative = HasSignBit(x) ^ HasSignBit(y);
const UnsignedDst ux = SafeUnsignedAbs(x);
const UnsignedDst uy = SafeUnsignedAbs(y);
UnsignedDst uresult = static_cast<UnsignedDst>(ux * uy);
// This is a non-branching conditional negation.
+ const T is_negative = (x ^ y) < 0;
*result = static_cast<T>((uresult ^ -is_negative) + is_negative);
// This uses the unsigned overflow check on the absolute value, with a +1
// bound for a negative result.
« no previous file with comments | « base/numerics/safe_conversions_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698