diff options
Diffstat (limited to 'src/util/overflow.h')
-rw-r--r-- | src/util/overflow.h | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/src/util/overflow.h b/src/util/overflow.h index 5982af8d04..6b7dd1e8fd 100644 --- a/src/util/overflow.h +++ b/src/util/overflow.h @@ -6,13 +6,14 @@ #define BITCOIN_UTIL_OVERFLOW_H #include <limits> +#include <optional> #include <type_traits> template <class T> [[nodiscard]] bool AdditionOverflow(const T i, const T j) noexcept { static_assert(std::is_integral<T>::value, "Integral required."); - if (std::numeric_limits<T>::is_signed) { + if constexpr (std::numeric_limits<T>::is_signed) { return (i > 0 && j > std::numeric_limits<T>::max() - i) || (i < 0 && j < std::numeric_limits<T>::min() - i); } @@ -28,4 +29,22 @@ template <class T> return i + j; } +template <class T> +[[nodiscard]] T SaturatingAdd(const T i, const T j) noexcept +{ + if constexpr (std::numeric_limits<T>::is_signed) { + if (i > 0 && j > std::numeric_limits<T>::max() - i) { + return std::numeric_limits<T>::max(); + } + if (i < 0 && j < std::numeric_limits<T>::min() - i) { + return std::numeric_limits<T>::min(); + } + } else { + if (std::numeric_limits<T>::max() - i < j) { + return std::numeric_limits<T>::max(); + } + } + return i + j; +} + #endif // BITCOIN_UTIL_OVERFLOW_H |