Boost C++ Libraries of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

This is the documentation for a snapshot of the develop branch, built from commit 4e6c143b17.
Library Documentation Index

Safe Numerics



Associated Types
Valid Expressions
Note on Usage of std::numeric_limits


A type is Numeric if it has the properties of a number.

More specifically, a type T is Numeric if there exists a specialization of std::numeric_limits<T>. See the documentation for the standard library class numeric_limits. The standard library includes such specializations for all the built-in numeric types. Note that this concept is distinct from the C++ standard library type traits is_integral and is_arithmetic. These latter fulfill the requirement of the concept Numeric. But there are types T which fulfill this concept for which is_arithmetic<T>::value == false. For example see safe_signed_integer<int>.


T, U, V A type that is a model of Numeric
t, u An object of a type modeling Numeric

Associated Types

std::numeric_limits<T> The numeric_limits class template provides a C++ program with information about various properties of the implementation's representation of the arithmetic types. See C++ standard

Valid Expressions

In addition to the expressions defined in Assignable the following expressions must be valid. Any operations which result in integers which cannot be represented as some Numeric type will throw an exception.

Table 1. General

Expression Return Type Return Value
std::numeric_limits<T>::is_bounded bool true or false
std::numeric_limits<T>::is_integer bool true or false
std::numeric_limits<T>::is_signed bool true or false
std::numeric_limits<T>::is_specialized bool true

Table 2. Unary Operators

Expression Return Type Semantics
-t T Invert sign
+t T unary plus - a no op
t-- T post decrement
t++ T post increment
--t T pre decrement
++t T pre increment

Table 3. Binary Operators

Expression Return Type Semantics
t - u V subtract u from t
t + u V add u to t
t * u V multiply t by u
t / u T divide t by u
t % u T t modulus u
t < u bool true if t less than u, false otherwise
t <= u bool true if t less than or equal to u, false otherwise
t > u bool true if t greater than u, false otherwise
t >= u bool true if t greater than or equal to u, false otherwise
t == u bool true if t equal to u, false otherwise
t != u bool true if t not equal to u, false otherwise
t = u T assign value of u to t
t += u T add u to t and assign to t
t -= u T subtract u from t and assign to t
t *= u T multiply t by u and assign to t
t /= u T divide t by u and assign to t


int, float, safe_signed_integer<int>, safe_signed_range<int>, checked_result<int>, etc.


#include <boost/safe_numerics/concepts/numeric.hpp>

Note on Usage of std::numeric_limits

We define the word "Numeric" in terms of the operations which are supported by "Numeric" types. This is in line with the current and historical usage of the word "concept" in the context of C++. It is also common to define compile time predicates such as "is_numeric<T>" to permit one to include expressions in his code which will generated a compile time error if the specified type (T) does not support the operations required. But this is not always true. In the C++ standard library there is a predicate is_arithmetic<T> whose name might suggest that it should return true for any type which supports the operations above. But this is not the case. The standard defines is_arithmetic<T> as true for any of the builtin types int, long, float, double, etc and false for any other types. So even if a user defined type U were to support the operations above, is_arithmetic<U> would still return false. This is quite unintuitive and not a good match for our purposes. Hence we define our own term "Numeric" to designate any type T which:

  • Supports the operations above

  • Specializes the standard type numeric_limits

while following the C++ standard in using is_arithmetic<T>, is_integral<T> to detect specific types only. The standard types are useful in various aspects of the implementation - which of course is done in terms of the standard types.

This in turn raises another question: Is it "legal" to specialize std::numeric_limits for one's own types such as safe<int>. In my view the standard is ambiguous on this. See various interpretations:

In any case, it seems pretty clear that no harm will come of it. In spite of the consideration given to this issue, it turns out that the found no real need to implement these predicates. For example, there is no "is_numeric<T>" implemented as part of the safe numerics library. This may change in the future though. Even if not used, defining and maintaining these type requirements in this document has been very valuable in keeping the concepts and code more unified and understandable.

Remember that above considerations apply to other numeric types used in this library even though we don't explicitly repeat this information for every case.