summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base/numerics/clamped_math.h5
-rw-r--r--base/numerics/saturated_arithmetic.h40
-rw-r--r--base/numerics/saturated_arithmetic_arm.h30
-rw-r--r--base/numerics/saturated_arithmetic_unittest.cc72
-rw-r--r--ui/gfx/geometry/point.h18
-rw-r--r--ui/gfx/geometry/rect.cc19
-rw-r--r--ui/gfx/geometry/rect.h2
-rw-r--r--ui/gfx/geometry/size.cc6
-rw-r--r--ui/gfx/geometry/vector2d.cc10
9 files changed, 32 insertions, 170 deletions
diff --git a/base/numerics/clamped_math.h b/base/numerics/clamped_math.h
index 799043aa3d..620bfd8f07 100644
--- a/base/numerics/clamped_math.h
+++ b/base/numerics/clamped_math.h
@@ -176,6 +176,11 @@ class ClampedNumeric {
value_);
}
+ // This method extracts the raw integer value without saturating it to the
+ // destination type as the conversion operator does. This is useful when
+ // e.g. assigning to an auto type or passing as a deduced template parameter.
+ constexpr T RawValue() const { return value_; }
+
private:
T value_;
diff --git a/base/numerics/saturated_arithmetic.h b/base/numerics/saturated_arithmetic.h
index 74fbba808d..504fcd8f79 100644
--- a/base/numerics/saturated_arithmetic.h
+++ b/base/numerics/saturated_arithmetic.h
@@ -22,46 +22,6 @@
namespace base {
-ALWAYS_INLINE int32_t SaturatedAddition(int32_t a, int32_t b) {
- uint32_t ua = a;
- uint32_t ub = b;
- uint32_t result = ua + ub;
-
- // Can only overflow if the signed bit of the two values match. If the
- // signed bit of the result and one of the values differ it overflowed.
- // The branch compiles to a CMOVNS instruction on x86.
- if (~(ua ^ ub) & (result ^ ua) & (1 << 31))
- return std::numeric_limits<int>::max() + (ua >> 31);
-
- return result;
-}
-
-ALWAYS_INLINE int32_t SaturatedSubtraction(int32_t a, int32_t b) {
- uint32_t ua = a;
- uint32_t ub = b;
- uint32_t result = ua - ub;
-
- // Can only overflow if the signed bit of the two input values differ. If
- // the signed bit of the result and the first value differ it overflowed.
- // The branch compiles to a CMOVNS instruction on x86.
- if ((ua ^ ub) & (result ^ ua) & (1 << 31))
- return std::numeric_limits<int>::max() + (ua >> 31);
-
- return result;
-}
-
-ALWAYS_INLINE int32_t SaturatedNegative(int32_t a) {
- if (UNLIKELY(a == std::numeric_limits<int>::min()))
- return std::numeric_limits<int>::max();
- return -a;
-}
-
-ALWAYS_INLINE int32_t SaturatedAbsolute(int32_t a) {
- if (a >= 0)
- return a;
- return SaturatedNegative(a);
-}
-
ALWAYS_INLINE int GetMaxSaturatedSetResultForTesting(int fractional_shift) {
// For C version the set function maxes out to max int, this differs from
// the ARM asm version, see saturated_arithmetic_arm.h for the equivalent asm
diff --git a/base/numerics/saturated_arithmetic_arm.h b/base/numerics/saturated_arithmetic_arm.h
index 732f5f2c1f..21701aa40f 100644
--- a/base/numerics/saturated_arithmetic_arm.h
+++ b/base/numerics/saturated_arithmetic_arm.h
@@ -9,36 +9,6 @@
namespace base {
-inline int32_t SaturatedAddition(int32_t a, int32_t b) {
- int32_t result;
-
- asm("qadd %[output],%[first],%[second]"
- : [output] "=r"(result)
- : [first] "r"(a), [second] "r"(b));
-
- return result;
-}
-
-inline int32_t SaturatedSubtraction(int32_t a, int32_t b) {
- int32_t result;
-
- asm("qsub %[output],%[first],%[second]"
- : [output] "=r"(result)
- : [first] "r"(a), [second] "r"(b));
-
- return result;
-}
-
-inline int32_t SaturatedNegative(int32_t a) {
- return SaturatedSubtraction(0, a);
-}
-
-inline int32_t SaturatedAbsolute(int32_t a) {
- if (a >= 0)
- return a;
- return SaturatedNegative(a);
-}
-
inline int GetMaxSaturatedSetResultForTesting(int fractional_shift) {
// For ARM Asm version the set function maxes out to the biggest
// possible integer part with the fractional part zero'd out.
diff --git a/base/numerics/saturated_arithmetic_unittest.cc b/base/numerics/saturated_arithmetic_unittest.cc
index 498f5b7710..aa323c2e0e 100644
--- a/base/numerics/saturated_arithmetic_unittest.cc
+++ b/base/numerics/saturated_arithmetic_unittest.cc
@@ -12,78 +12,6 @@
namespace base {
-TEST(SaturatedArithmeticTest, Addition) {
- int int_max = std::numeric_limits<int>::max();
- int int_min = std::numeric_limits<int>::min();
-
- EXPECT_EQ(0, SaturatedAddition(0, 0));
- EXPECT_EQ(1, SaturatedAddition(0, 1));
- EXPECT_EQ(100, SaturatedAddition(0, 100));
- EXPECT_EQ(150, SaturatedAddition(100, 50));
-
- EXPECT_EQ(-1, SaturatedAddition(0, -1));
- EXPECT_EQ(0, SaturatedAddition(1, -1));
- EXPECT_EQ(50, SaturatedAddition(100, -50));
- EXPECT_EQ(-50, SaturatedAddition(50, -100));
-
- EXPECT_EQ(int_max - 1, SaturatedAddition(int_max - 1, 0));
- EXPECT_EQ(int_max, SaturatedAddition(int_max - 1, 1));
- EXPECT_EQ(int_max, SaturatedAddition(int_max - 1, 2));
- EXPECT_EQ(int_max - 1, SaturatedAddition(0, int_max - 1));
- EXPECT_EQ(int_max, SaturatedAddition(1, int_max - 1));
- EXPECT_EQ(int_max, SaturatedAddition(2, int_max - 1));
- EXPECT_EQ(int_max, SaturatedAddition(int_max - 1, int_max - 1));
- EXPECT_EQ(int_max, SaturatedAddition(int_max, int_max));
-
- EXPECT_EQ(int_min, SaturatedAddition(int_min, 0));
- EXPECT_EQ(int_min + 1, SaturatedAddition(int_min + 1, 0));
- EXPECT_EQ(int_min + 2, SaturatedAddition(int_min + 1, 1));
- EXPECT_EQ(int_min + 3, SaturatedAddition(int_min + 1, 2));
- EXPECT_EQ(int_min, SaturatedAddition(int_min + 1, -1));
- EXPECT_EQ(int_min, SaturatedAddition(int_min + 1, -2));
- EXPECT_EQ(int_min + 1, SaturatedAddition(0, int_min + 1));
- EXPECT_EQ(int_min, SaturatedAddition(-1, int_min + 1));
- EXPECT_EQ(int_min, SaturatedAddition(-2, int_min + 1));
-
- EXPECT_EQ(int_max / 2 + 10000, SaturatedAddition(int_max / 2, 10000));
- EXPECT_EQ(int_max, SaturatedAddition(int_max / 2 + 1, int_max / 2 + 1));
- EXPECT_EQ(-1, SaturatedAddition(int_min, int_max));
-}
-
-TEST(SaturatedArithmeticTest, Subtraction) {
- int int_max = std::numeric_limits<int>::max();
- int int_min = std::numeric_limits<int>::min();
-
- EXPECT_EQ(0, SaturatedSubtraction(0, 0));
- EXPECT_EQ(-1, SaturatedSubtraction(0, 1));
- EXPECT_EQ(-100, SaturatedSubtraction(0, 100));
- EXPECT_EQ(50, SaturatedSubtraction(100, 50));
-
- EXPECT_EQ(1, SaturatedSubtraction(0, -1));
- EXPECT_EQ(2, SaturatedSubtraction(1, -1));
- EXPECT_EQ(150, SaturatedSubtraction(100, -50));
- EXPECT_EQ(150, SaturatedSubtraction(50, -100));
-
- EXPECT_EQ(int_max, SaturatedSubtraction(int_max, 0));
- EXPECT_EQ(int_max - 1, SaturatedSubtraction(int_max, 1));
- EXPECT_EQ(int_max - 1, SaturatedSubtraction(int_max - 1, 0));
- EXPECT_EQ(int_max, SaturatedSubtraction(int_max - 1, -1));
- EXPECT_EQ(int_max, SaturatedSubtraction(int_max - 1, -2));
- EXPECT_EQ(-int_max + 1, SaturatedSubtraction(0, int_max - 1));
- EXPECT_EQ(-int_max, SaturatedSubtraction(-1, int_max - 1));
- EXPECT_EQ(-int_max - 1, SaturatedSubtraction(-2, int_max - 1));
- EXPECT_EQ(-int_max - 1, SaturatedSubtraction(-3, int_max - 1));
-
- EXPECT_EQ(int_min, SaturatedSubtraction(int_min, 0));
- EXPECT_EQ(int_min + 1, SaturatedSubtraction(int_min + 1, 0));
- EXPECT_EQ(int_min, SaturatedSubtraction(int_min + 1, 1));
- EXPECT_EQ(int_min, SaturatedSubtraction(int_min + 1, 2));
-
- EXPECT_EQ(0, SaturatedSubtraction(int_min, int_min));
- EXPECT_EQ(0, SaturatedSubtraction(int_max, int_max));
- EXPECT_EQ(int_max, SaturatedSubtraction(int_max, int_min));
-}
-
TEST(SaturatedArithmeticTest, SetSigned) {
int int_max = std::numeric_limits<int>::max();
int int_min = std::numeric_limits<int>::min();
diff --git a/ui/gfx/geometry/point.h b/ui/gfx/geometry/point.h
index bb248d5432..b1ba5065de 100644
--- a/ui/gfx/geometry/point.h
+++ b/ui/gfx/geometry/point.h
@@ -9,7 +9,7 @@
#include <string>
#include <tuple>
-#include "base/numerics/saturated_arithmetic.h"
+#include "base/numerics/clamped_math.h"
#include "build/build_config.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/gfx_export.h"
@@ -56,18 +56,18 @@ class GFX_EXPORT Point {
}
void Offset(int delta_x, int delta_y) {
- x_ = base::SaturatedAddition(x_, delta_x);
- y_ = base::SaturatedAddition(y_, delta_y);
+ x_ = base::ClampAdd(x_, delta_x);
+ y_ = base::ClampAdd(y_, delta_y);
}
void operator+=(const Vector2d& vector) {
- x_ = base::SaturatedAddition(x_, vector.x());
- y_ = base::SaturatedAddition(y_, vector.y());
+ x_ = base::ClampAdd(x_, vector.x());
+ y_ = base::ClampAdd(y_, vector.y());
}
void operator-=(const Vector2d& vector) {
- x_ = base::SaturatedSubtraction(x_, vector.x());
- y_ = base::SaturatedSubtraction(y_, vector.y());
+ x_ = base::ClampSub(x_, vector.x());
+ y_ = base::ClampSub(y_, vector.y());
}
void SetToMin(const Point& other);
@@ -116,8 +116,8 @@ inline Point operator-(const Point& lhs, const Vector2d& rhs) {
}
inline Vector2d operator-(const Point& lhs, const Point& rhs) {
- return Vector2d(base::SaturatedSubtraction(lhs.x(), rhs.x()),
- base::SaturatedSubtraction(lhs.y(), rhs.y()));
+ return Vector2d(base::ClampSub(lhs.x(), rhs.x()),
+ base::ClampSub(lhs.y(), rhs.y()));
}
inline Point PointAtOffsetFromOrigin(const Vector2d& offset_from_origin) {
diff --git a/ui/gfx/geometry/rect.cc b/ui/gfx/geometry/rect.cc
index b5ceda5829..a1735d028c 100644
--- a/ui/gfx/geometry/rect.cc
+++ b/ui/gfx/geometry/rect.cc
@@ -15,7 +15,7 @@
#endif
#include "base/logging.h"
-#include "base/numerics/saturated_arithmetic.h"
+#include "base/numerics/clamped_math.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "ui/gfx/geometry/insets.h"
@@ -69,8 +69,8 @@ static void SaturatedClampRange(int min, int max, int* origin, int* span) {
return;
}
- int effective_span = base::SaturatedSubtraction(max, min);
- int span_loss = base::SaturatedSubtraction(max, min + effective_span);
+ int effective_span = base::ClampSub(max, min);
+ int span_loss = base::ClampSub(max, base::ClampAdd(min, effective_span));
// If the desired width is within the limits of ints, we can just
// use the simple computations to represent the range precisely.
@@ -83,12 +83,13 @@ static void SaturatedClampRange(int min, int max, int* origin, int* span) {
// Now we have to approximate. If one of min or max is close enough
// to zero we choose to represent that one precisely. The other side is
// probably practically "infinite", so we move it.
- if (base::SaturatedAbsolute(max) < std::numeric_limits<int>::max() / 2) {
+ if (base::SafeUnsignedAbs(max) <
+ base::as_unsigned(std::numeric_limits<int>::max() / 2)) {
// Maintain origin + span == max.
*span = effective_span;
*origin = max - effective_span;
- } else if (base::SaturatedAbsolute(min) <
- std::numeric_limits<int>::max() / 2) {
+ } else if (base::SafeUnsignedAbs(min) <
+ base::as_unsigned(std::numeric_limits<int>::max() / 2)) {
// Maintain origin == min.
*span = effective_span;
*origin = min;
@@ -116,10 +117,8 @@ void Rect::Inset(int left, int top, int right, int bottom) {
origin_ += Vector2d(left, top);
// left+right might overflow/underflow, but width() - (left+right) might
// overflow as well.
- set_width(base::SaturatedSubtraction(width(),
- base::SaturatedAddition(left, right)));
- set_height(base::SaturatedSubtraction(height(),
- base::SaturatedAddition(top, bottom)));
+ set_width(base::ClampSub(width(), base::ClampAdd(left, right)));
+ set_height(base::ClampSub(height(), base::ClampAdd(top, bottom)));
}
void Rect::Offset(int horizontal, int vertical) {
diff --git a/ui/gfx/geometry/rect.h b/ui/gfx/geometry/rect.h
index 1858d44d2c..4e914b8ca6 100644
--- a/ui/gfx/geometry/rect.h
+++ b/ui/gfx/geometry/rect.h
@@ -227,7 +227,7 @@ class GFX_EXPORT Rect {
// Clamp the size to avoid integer overflow in bottom() and right().
// This returns the width given an origin and a width.
- // TODO(enne): this should probably use base::SaturatedAddition, but that
+ // TODO(enne): this should probably use base::ClampAdd, but that
// function is not a constexpr.
static constexpr int GetClampedValue(int origin, int size) {
return AddWouldOverflow(origin, size)
diff --git a/ui/gfx/geometry/size.cc b/ui/gfx/geometry/size.cc
index 69486723a1..781b84d7f5 100644
--- a/ui/gfx/geometry/size.cc
+++ b/ui/gfx/geometry/size.cc
@@ -12,8 +12,8 @@
#include <ApplicationServices/ApplicationServices.h>
#endif
+#include "base/numerics/clamped_math.h"
#include "base/numerics/safe_math.h"
-#include "base/numerics/saturated_arithmetic.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "ui/gfx/geometry/safe_integer_conversions.h"
@@ -58,8 +58,8 @@ base::CheckedNumeric<int> Size::GetCheckedArea() const {
}
void Size::Enlarge(int grow_width, int grow_height) {
- SetSize(base::SaturatedAddition(width(), grow_width),
- base::SaturatedAddition(height(), grow_height));
+ SetSize(base::ClampAdd(width(), grow_width),
+ base::ClampAdd(height(), grow_height));
}
void Size::SetToMin(const Size& other) {
diff --git a/ui/gfx/geometry/vector2d.cc b/ui/gfx/geometry/vector2d.cc
index 2b4875c39c..0ce3b20baa 100644
--- a/ui/gfx/geometry/vector2d.cc
+++ b/ui/gfx/geometry/vector2d.cc
@@ -6,7 +6,7 @@
#include <cmath>
-#include "base/numerics/saturated_arithmetic.h"
+#include "base/numerics/clamped_math.h"
#include "base/strings/stringprintf.h"
namespace gfx {
@@ -16,13 +16,13 @@ bool Vector2d::IsZero() const {
}
void Vector2d::Add(const Vector2d& other) {
- x_ = base::SaturatedAddition(other.x_, x_);
- y_ = base::SaturatedAddition(other.y_, y_);
+ x_ = base::ClampAdd(other.x_, x_);
+ y_ = base::ClampAdd(other.y_, y_);
}
void Vector2d::Subtract(const Vector2d& other) {
- x_ = base::SaturatedSubtraction(x_, other.x_);
- y_ = base::SaturatedSubtraction(y_, other.y_);
+ x_ = base::ClampSub(x_, other.x_);
+ y_ = base::ClampSub(y_, other.y_);
}
int64_t Vector2d::LengthSquared() const {