aboutsummaryrefslogtreecommitdiff
path: root/src/util/overflow.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/overflow.h')
-rw-r--r--src/util/overflow.h21
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