Index: ui/gfx/geometry/rect.h |
diff --git a/ui/gfx/geometry/rect.h b/ui/gfx/geometry/rect.h |
index 17266fe03fb7c3f385df26746ff660e466087820..29b0db26c89875615754e181320a84689e8613e2 100644 |
--- a/ui/gfx/geometry/rect.h |
+++ b/ui/gfx/geometry/rect.h |
@@ -206,25 +206,45 @@ class GFX_EXPORT Rect { |
gfx::Point origin_; |
gfx::Size size_; |
+ static constexpr bool AddWouldOverflow(int a, int b) { |
+ return a > 0 && b > std::numeric_limits<int>::max() - a; |
enne (OOO)
2016/09/21 00:48:24
danakj: I feel like these are things I'd want to u
|
+ } |
+ static constexpr bool AddWouldUnderflow(int a, int b) { |
+ return a < 0 && b < std::numeric_limits<int>::min() - a; |
+ } |
+ static constexpr bool SubtractWouldOverflow(int a, int b) { |
+ return b < 0 && a > std::numeric_limits<int>::max() + b; |
+ } |
+ static constexpr bool SubtractWouldUnderflow(int a, int b) { |
+ return b > 0 && a < std::numeric_limits<int>::min() + b; |
+ } |
+ |
+ static constexpr int SafeAdd(int a, int b) { |
+ return AddWouldOverflow(a, b) |
+ ? std::numeric_limits<int>::max() |
+ : AddWouldUnderflow(a, b) ? std::numeric_limits<int>::min() |
+ : a + b; |
+ } |
+ static constexpr int SafeSubtract(int a, int b) { |
+ return SubtractWouldOverflow(a, b) |
+ ? std::numeric_limits<int>::max() |
+ : SubtractWouldUnderflow(a, b) ? std::numeric_limits<int>::min() |
+ : a - b; |
+ } |
+ |
// Clamp the size to avoid integer overflow in bottom() and right(). |
- // There are three conditions to determine whether there is a potential |
- // overflow: |
- // 1) Origin > 0: if the origin is a negative value, origin + size will |
- // definitely be less than int_max. |
- // 2) size > 0: if size <= 0, it will be clamped to 0 making x + 0 valid for |
- // all x. |
- // 3) We cast the values to unsigned int because the compiler can optimize |
- // this check away entirely but it is not smart enough to know that it |
- // won't overflow. It can't overflow since origin is positive ensured by |
- // part 1). If size > int_max - origin it will overflow when added to |
- // origin. |
+ // This returns the width given an origin and a width. |
static constexpr int GetClampedValue(int origin, int size) { |
- return origin > 0 && size > 0 && |
- static_cast<unsigned>(std::numeric_limits<int>::max() - |
- origin) < static_cast<unsigned>(size) |
+ return AddWouldOverflow(origin, size) |
? std::numeric_limits<int>::max() - origin |
: size; |
} |
+ |
+ // Returns a clamped width given a right and a left, assuming right > left. |
+ static constexpr int GetClampedWidthFromExtents(int left, int right) { |
+ return SubtractWouldOverflow(right, left) ? std::numeric_limits<int>::max() |
+ : right - left; |
+ } |
}; |
inline bool operator==(const Rect& lhs, const Rect& rhs) { |