...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Safe Numerics |
This type holds a signed or unsigned integer in the closed range
[MIN, MAX]. A safe_signed_range<MIN, MAX, PP, EP>
or
safe_unsigned_range<MIN, MAX, PP, EP>
can be used
anywhere an arithmetic type is permitted. Any expression which uses either
of these types is guaranteed to return an arithmetically correct value or
to trap in some way.
PP |
Promotion Policy. A type which specifies the result type of an expression using safe types. |
EP |
Exception Policy. A type containing members which are called when a correct result cannot be returned |
Parameter | Requirements | Description |
---|---|---|
T |
std::is_integer<T> | The underlying type. Currently only built-in integer types are supported |
MIN |
must be a non-negative literal | The minimum non-negative integer value that this type may hold |
MAX |
must be a non-negative literal | The maximum non-negative integer value that this type may hold |
MIN <= MAX | must be a valid closed range | |
PP |
PromotionPolicy<PP> | Default value is |
EP |
Exception Policy<EP> | Default value is |
Implements all expressions and only those expressions supported by
the base type T. Note that all these expressions are
constexpr
. The result type of such an expression will be
another safe type. The actual type of the result of such an expression
will depend upon the specific promotion policy template parameter.
When a binary operand is applied to two instances of A
safe_signed_range<MIN, MAX, PP, EP>
or
safe_unsigned_range<MIN, MAX, PP, EP>
one of the
following must be true:
The promotion policies of the two operands must be the same or one of them must be void
The exception policies of the two operands must be the same or one of them must be void
If either of the above is not true, a compile error will result.
// Copyright (c) 2018 Robert Ramey // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include <exception> #include <iostream> #include <type_traits> #include <boost/safe_numerics/safe_integer.hpp> #include <boost/safe_numerics/safe_integer_range.hpp> #include <boost/safe_numerics/safe_integer_literal.hpp> #include <boost/safe_numerics/utility.hpp> using namespace boost::safe_numerics; int main(){ safe_unsigned_range<7, 24> i; // since the range is included in [0,255], the underlying type of i // will be an unsigned char. try{ i = 0; // throws out_of_range exception std::cout << "fails to detect erroneous assignment" << std::endl; } catch(std::exception & e){ // should arrive here } try{ i = 9; // ok - no exception expected } catch(std::exception & e){ std::cout << "erroneous error for legal assignment" << std::endl; } try{ i *= 9; // fails to compile because result can't fin in range std::cout << "fails to out of range result" << std::endl; } catch(std::exception & e){ // should arrive here } try{ i = -1; // throws out_of_range exception std::cout << "fails to detect erroneous assignment" << std::endl; } catch(std::exception & e){ // should arrive here } std::uint8_t j = 4; auto k = i + j; // if either or both types are safe types, the result is a safe type // determined by promotion policy. In this instance // the range of i is [7, 24] and the range of j is [0,255]. // so the type of k will be a safe type with a range of [7,279] static_assert( is_safe<decltype(k)>::value && std::numeric_limits<decltype(k)>::min() == 7 && std::numeric_limits<decltype(k)>::max() == 279, "k is a safe range of [7,279]" ); return 0; }