diff options
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/overflow.h | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/src/common/overflow.h b/src/common/overflow.h index 44d8e7e73..e765c0d89 100644 --- a/src/common/overflow.h +++ b/src/common/overflow.h | |||
| @@ -19,4 +19,21 @@ inline T WrappingAdd(T lhs, T rhs) { | |||
| 19 | return BitCast<T>(lhs_u + rhs_u); | 19 | return BitCast<T>(lhs_u + rhs_u); |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | template <typename T> | ||
| 23 | requires(std::is_integral_v<T> && std::is_signed_v<T>) | ||
| 24 | inline bool CanAddWithoutOverflow(T lhs, T rhs) { | ||
| 25 | #ifdef _MSC_VER | ||
| 26 | if (lhs >= 0 && rhs >= 0) { | ||
| 27 | return WrappingAdd(lhs, rhs) >= std::max(lhs, rhs); | ||
| 28 | } else if (lhs < 0 && rhs < 0) { | ||
| 29 | return WrappingAdd(lhs, rhs) <= std::min(lhs, rhs); | ||
| 30 | } else { | ||
| 31 | return true; | ||
| 32 | } | ||
| 33 | #else | ||
| 34 | T res; | ||
| 35 | return !__builtin_add_overflow(lhs, rhs, &res); | ||
| 36 | #endif | ||
| 37 | } | ||
| 38 | |||
| 22 | } // namespace Common | 39 | } // namespace Common |