Bitcoin ABC 0.32.4
P2P Digital Currency
overflow.h
Go to the documentation of this file.
1// Copyright (c) 2021-2022 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#ifndef BITCOIN_UTIL_OVERFLOW_H
6#define BITCOIN_UTIL_OVERFLOW_H
7
8#include <climits>
9#include <limits>
10#include <optional>
11
18// TODO: use template <std::integral T> afer we switch to C++20
19template <typename T>
20constexpr std::optional<T> CheckedLeftShift(T input, unsigned shift) noexcept {
21 if (shift == 0 || input == 0) {
22 return input;
23 }
24 // Avoid undefined c++ behaviour if shift is >= number of bits in T.
25 if (shift >= sizeof(T) * CHAR_BIT) {
26 return std::nullopt;
27 }
28 // If input << shift is too big to fit in T, return nullopt.
29 if (input > (std::numeric_limits<T>::max() >> shift)) {
30 return std::nullopt;
31 }
32 if (input < (std::numeric_limits<T>::min() >> shift)) {
33 return std::nullopt;
34 }
35 return input << shift;
36}
37
45// TODO: use template <std::integral T> afer we switch to C++20
46template <typename T>
47constexpr T SaturatingLeftShift(T input, unsigned shift) noexcept {
48 if (auto result{CheckedLeftShift(input, shift)}) {
49 return *result;
50 }
51 // If input << shift is too big to fit in T, return biggest positive or
52 // negative number that fits.
53 return input < 0 ? std::numeric_limits<T>::min()
54 : std::numeric_limits<T>::max();
55}
56
57#endif // BITCOIN_UTIL_OVERFLOW_H
constexpr T SaturatingLeftShift(T input, unsigned shift) noexcept
Left bit shift with safe minimum and maximum values.
Definition: overflow.h:47
constexpr std::optional< T > CheckedLeftShift(T input, unsigned shift) noexcept
Left bit shift with overflow checking.
Definition: overflow.h:20