Chromium Code Reviews| 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) { |