// Copyright (c) 2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_UTIL_OVERFLOW_H #define BITCOIN_UTIL_OVERFLOW_H #include #include #include template [[nodiscard]] bool AdditionOverflow(const T i, const T j) noexcept { static_assert(std::is_integral::value, "Integral required."); if constexpr (std::numeric_limits::is_signed) { return (i > 0 && j > std::numeric_limits::max() - i) || (i < 0 && j < std::numeric_limits::min() - i); } return std::numeric_limits::max() - i < j; } template [[nodiscard]] std::optional CheckedAdd(const T i, const T j) noexcept { if (AdditionOverflow(i, j)) { return std::nullopt; } return i + j; } template [[nodiscard]] T SaturatingAdd(const T i, const T j) noexcept { if constexpr (std::numeric_limits::is_signed) { if (i > 0 && j > std::numeric_limits::max() - i) { return std::numeric_limits::max(); } if (i < 0 && j < std::numeric_limits::min() - i) { return std::numeric_limits::min(); } } else { if (std::numeric_limits::max() - i < j) { return std::numeric_limits::max(); } } return i + j; } #endif // BITCOIN_UTIL_OVERFLOW_H