Signed Integer Types
Description
The library provides safe signed integer types that detect overflow, underflow, division by zero, and other undefined behavior at runtime. These types are drop-in replacements for the standard signed integer types with added safety guarantees.
| Type | Underlying Type | Width | Min | Max |
|---|---|---|---|---|
|
|
8 bits |
-128 |
127 |
|
|
16 bits |
-32,768 |
32,767 |
|
|
32 bits |
-2,147,483,648 |
2,147,483,647 |
|
|
64 bits |
-9,223,372,036,854,775,808 |
9,223,372,036,854,775,807 |
|
|
128 bits |
-170,141,183,460,469,231,731,687,303,715,884,105,728 |
170,141,183,460,469,231,731,687,303,715,884,105,727 |
Each type exposes a basis_type member type alias that refers to the underlying integer type, allowing conversion back to built-in types when needed.
#include <boost/safe_numbers/signed_integers.hpp>
namespace boost::safe_numbers {
using i8 = detail::signed_integer_basis<std::int8_t>;
using i16 = detail::signed_integer_basis<std::int16_t>;
using i32 = detail::signed_integer_basis<std::int32_t>;
using i64 = detail::signed_integer_basis<std::int64_t>;
using i128 = detail::signed_integer_basis<int128::int128_t>;
template <signed_integral BasisType>
class signed_integer_basis {
public:
using basis_type = BasisType;
// Construction
constexpr signed_integer_basis() noexcept = default;
explicit constexpr signed_integer_basis(BasisType val) noexcept;
template <typename T>
requires std::is_same_v<T, bool>
explicit constexpr signed_integer_basis(T) noexcept = delete; // bool prohibited
// Conversion to underlying types
template <signed_integral OtherBasis>
explicit constexpr operator OtherBasis() const;
// Comparison operators
friend constexpr auto operator<=>(signed_integer_basis lhs, signed_integer_basis rhs) noexcept
-> std::strong_ordering = default;
// Unary operators
constexpr auto operator+() const noexcept -> signed_integer_basis;
constexpr auto operator-() const -> signed_integer_basis;
// Compound assignment operators (arithmetic)
template <signed_integral OtherBasis>
constexpr auto operator+=(signed_integer_basis<OtherBasis> rhs) -> signed_integer_basis&;
template <signed_integral OtherBasis>
constexpr auto operator-=(signed_integer_basis<OtherBasis> rhs) -> signed_integer_basis&;
template <signed_integral OtherBasis>
constexpr auto operator*=(signed_integer_basis<OtherBasis> rhs) -> signed_integer_basis&;
template <signed_integral OtherBasis>
constexpr auto operator/=(signed_integer_basis<OtherBasis> rhs) -> signed_integer_basis&;
template <signed_integral OtherBasis>
constexpr auto operator%=(signed_integer_basis<OtherBasis> rhs) -> signed_integer_basis&;
// Increment and decrement operators
constexpr auto operator++() -> signed_integer_basis&;
constexpr auto operator++(int) -> signed_integer_basis;
constexpr auto operator--() -> signed_integer_basis&;
constexpr auto operator--(int) -> signed_integer_basis;
}; // class signed_integer_basis
// Arithmetic operators (throw on overflow/underflow)
template <signed_integral BasisType>
constexpr auto operator+(signed_integer_basis<BasisType> lhs,
signed_integer_basis<BasisType> rhs) -> signed_integer_basis<BasisType>;
template <signed_integral BasisType>
constexpr auto operator-(signed_integer_basis<BasisType> lhs,
signed_integer_basis<BasisType> rhs) -> signed_integer_basis<BasisType>;
template <signed_integral BasisType>
constexpr auto operator*(signed_integer_basis<BasisType> lhs,
signed_integer_basis<BasisType> rhs) -> signed_integer_basis<BasisType>;
template <signed_integral BasisType>
constexpr auto operator/(signed_integer_basis<BasisType> lhs,
signed_integer_basis<BasisType> rhs) -> signed_integer_basis<BasisType>;
template <signed_integral BasisType>
constexpr auto operator%(signed_integer_basis<BasisType> lhs,
signed_integer_basis<BasisType> rhs) -> signed_integer_basis<BasisType>;
} // namespace boost::safe_numbers
Increment and Decrement Operators
constexpr auto operator++() -> signed_integer_basis&;
constexpr auto operator++(int) -> signed_integer_basis;
constexpr auto operator--() -> signed_integer_basis&;
constexpr auto operator--(int) -> signed_integer_basis;
-
++(pre/post): Throwsstd::overflow_errorif the value is already atstd::numeric_limits<BasisType>::max() -
--(pre/post): Throwsstd::underflow_errorif the value is already atstd::numeric_limits<BasisType>::min()
Unary Operators
constexpr auto operator+() const noexcept -> signed_integer_basis;
constexpr auto operator-() const -> signed_integer_basis;
-
+: Returns a copy of the value (identity). -
-: Throwsstd::domain_errorif the value isstd::numeric_limits<BasisType>::min(), since negating the minimum value of a two’s complement signed integer overflows.
Mixed-Width Operations
Operations between different width safe signed integer types are compile-time errors. The operands must be promoted to a common type explicitly before performing the operation.
auto a = i16{100};
auto b = i32{200};
// auto result = a + b; // Compile error: mismatched types
auto result = static_cast<i32>(a) + b; // OK: explicit promotion