Unsigned Integer Types
Overview
The library provides safe unsigned integer types that detect overflow, underflow, and other undefined behavior at runtime. These types are drop-in replacements for the standard unsigned integer types with added safety guarantees.
Available Types
The following types are provided in the boost::safe_numbers namespace:
namespace boost::safe_numbers {
using u8 = detail::unsigned_integer_basis<std::uint8_t>;
using u16 = detail::unsigned_integer_basis<std::uint16_t>;
using u32 = detail::unsigned_integer_basis<std::uint32_t>;
using u64 = detail::unsigned_integer_basis<std::uint64_t>;
using u128 = detail::unsigned_integer_basis<int128::uint128_t>;
} // namespace boost::safe_numbers
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.
Comparison Operators
Full three-way comparison is supported via operator<=>, which returns std::strong_ordering.
All comparison operators (<, ⇐, >, >=, ==, !=) are available.
Arithmetic Operators
All arithmetic operators perform runtime checks and throw exceptions when undefined behavior would occur.
Addition (operator+, operator+=)
Throws std::overflow_error if the result would exceed the maximum representable value.
Subtraction (operator-, operator-=)
Throws std::underflow_error if the result would be negative (wrap around).
Mixed-Width Operations are Prohibited
Operations between different width safe integer types are compile-time errors. To perform operations between different widths, explicitly convert to the same type first.
Saturating Arithmetic
For cases where throwing exceptions is not desired, saturating arithmetic functions are provided. These functions clamp the result to the representable range instead of throwing.
namespace boost::safe_numbers {
template <UnsignedLibType T>
constexpr T saturating_add(const T lhs, const T rhs) noexcept;
template <UnsignedLibType T>
constexpr T saturating_sub(const T lhs, const T rhs) noexcept;
template <UnsignedLibType T>
constexpr T saturating_mul(const T lhs, const T rhs) noexcept;
template <UnsignedLibType T>
constexpr T saturating_div(const T lhs, const T rhs);
template <UnsignedLibType T>
constexpr T saturating_mod(const T lhs, const T rhs);
} // namespace boost::safe_numbers
saturating_add
Returns the sum of two values, saturating at the maximum value on overflow (i.e., returns std::numeric_limits::max).
saturating_sub
Returns the difference of two values, saturating at the minimum value on underflow (i.e., returns std::numeric_limits::min).
saturating_mul
Returns the product of two values, saturating at the maximum value on overflow (i.e., returns std::numeric_limits::max).
Overflowing Arithmetic
This family of functions provides well-defined wrapping semantics as well as a flag to alert the consumer if overflow occurred.
This follows normal C family unsigned rollover where UINT_MAX + 1 == 0 and UINT_MIN - 1 == UINT_MAX.
namespace boost::safe_numbers {
template <UnsignedLibType T>
constexpr std::pair<T, bool> overflowing_add(const T lhs, const T rhs) noexcept;
template <UnsignedLibType T>
constexpr std::pair<T, bool> overflowing_sub(const T lhs, const T rhs) noexcept;
template <UnsignedLibType T>
constexpr std::pair<T, bool> overflowing_mul(const T lhs, const T rhs) noexcept;
template <UnsignedLibType T>
constexpr std::pair<T, bool> overflowing_div(const T lhs, const T rhs);
template <UnsignedLibType T>
constexpr std::pair<T, bool> overflowing_mod(const T lhs, const T rhs);
} // namespace boost::safe_numbers
overflowing_add
Returns the sum of two values, wrapping the sum and setting the bool in the return to true as required.
overflowing_sub
Returns the difference of two values, wrapping the difference and setting the bool in the return to true as required.
overflowing_mul
Returns the product of two values, wrapping the product and setting the bool in the return to true as required.
Exception Summary
| Operation | Exception Type | Condition |
|---|---|---|
|
|
The result exceeds maximum value |
|
|
The result would be negative |
|
|
The result exceeds maximum value |
|
|
Division by zero |
|
|
Modulo by zero |
|
|
Value is at maximum |
|
|
Value is zero |