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.

Construction

Default Construction

Values are default-initialized to zero.

Explicit Construction from Underlying Type

Construction from the underlying type is explicit to prevent accidental conversions.

Construction from bool is Prohibited

Constructing from bool is a compile-time error.

Type Conversions

Explicit Conversion to Underlying Types

Conversion to other unsigned integral types is explicit.

Narrowing Conversions are Prohibited

Narrowing conversions cause a compile-time error.

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).

Multiplication (operator*, operator*=)

Throws std::overflow_error if the result would exceed the maximum representable value.

Division (operator/, operator/=)

Throws std::domain_error if dividing by zero.

Modulo (operator%, operator%=)

Throws std::domain_error if the divisor is zero.

Increment and Decrement Operators

Pre-increment and Post-increment (++)

Throws std::overflow_error if the value is already at the maximum.

Pre-decrement and Post-decrement (--)

Throws std::underflow_error if the value is already zero.

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).

saturating_div

Returns the quotient of two values, and throws std::range_error in the event of division by 0. Otherwise, overflow and underflow are impossible.

saturating_div

Returns the remainder of two values, and throws std::range_error in the event of division by 0. Otherwise, overflow and underflow are impossible.

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.

overflowing_div

Returns the quotient of two values, and throws std::range_error in the event of division by 0. Otherwise, overflow and underflow are impossible.

overflowing_mod

Returns the remainder of two values, and throws std::range_error in the event of division by 0. Otherwise, overflow and underflow are impossible.

Exception Summary

Operation Exception Type Condition

+, +=

std::overflow_error

The result exceeds maximum value

-, -=

std::underflow_error

The result would be negative

*, *=

std::overflow_error

The result exceeds maximum value

/, /=, saturating_div

std::domain_error

Division by zero

%, %=, saturating_mod

std::domain_error

Modulo by zero

++ (pre/post)

std::overflow_error

Value is at maximum

-- (pre/post)

std::underflow_error

Value is zero

Constexpr Support

All operations are constexpr-compatible. Overflow at compile time results in a compiler error.