| 54 | // x and y must be signed integers. |
| 55 | template <typename T> |
| 56 | inline absl::optional<T> OverflowSafeAdd(T x, T y) { |
| 57 | static_assert(std::is_signed<T>::value, |
| 58 | "Only implemented for signed numbers T."); |
| 59 | static_assert(std::is_integral<T>::value, "Only implemented for integers T."); |
| 60 | // "Signed integer overflow occurs on integer addition iff the operands have |
| 61 | // the same sign and the sum has a sign opposite to that of the operands." |
| 62 | // Hacker's Delight 2nd ed, p 28. |
| 63 | using U = typename std::make_unsigned<T>::type; |
| 64 | const U ux = x; |
| 65 | const U uy = y; |
| 66 | const U usum = ux + uy; |
| 67 | const T sum = usum; |
| 68 | if (x >= 0 == y >= 0 && sum >= 0 != x >= 0) { |
| 69 | return absl::nullopt; |
| 70 | } |
| 71 | return sum; |
| 72 | } |
| 73 | |
| 74 | inline bool FitsInIntegralType(int64 x, PrimitiveType ty) { |
| 75 | switch (ty) { |