It is allowed to construct a type-safe number from an integral value that doesn't match its underlying type:
class number_tag; typedef x::number<unsigned short, number_tag> number_t; number_t number{4};
Having to explicitly static_cast<unsigned short>
would get old pretty quickly. As a compromise, constructing or
assigning from an integral value throws an exception
if the integral value cannot be
represented by the number's underlying type.
overflows
() is available for preventative
measures:
class number_tag; typedef x::number<unsigned short, number_tag> number_t; int n; if (number_t::overflows(n)) { // n is too big to fit. }
truncate
() is a static method that checks the
given value, and if it is too big to be represented by the type-safe
number, the smallest or the largest value that can be represented by
the type-safe number gets returned:
class number_tag; typedef x::number<unsigned short, number_tag> number_t; number_t n; n=number_t::truncate(-1); // This sets n to 0
truncate
() returns the underlying integer type.
The parameter value gets returned, casted, if it can be represented
by the underlying integer type, or the underlying integer type's
minimum or maximum value, as appropriate.
truncate
() is also overloaded for
other type-safe number instances:
class number_tag; class bignumber_tag; typedef x::number<unsigned short, number_tag> number_t; typedef x::number<long long, bignumber_tag> bignumber_t; bignumber_t bn{-1}; number_t n; n=number_t::truncate(bn); // This sets n to 0
truncate
() is also overloaded for
floating point numbers, by truncating floating points outside of the
range, then rounding the floating point value.