![]() |
Safe Numerics |
This holds an arithmetic value which can be used as a replacement for built-in C++ arithmetic values. These types differ from their built-in counter parts in that the are guaranteed not to produce invalid arithmetic results.
| Symbol | Description |
|---|---|
T, U |
Types fulfilling Numeric type requirements |
| t, u | objects of types T, U |
| S, S1, S2 | A type fulfilling SafeNumeric type requirements |
| s, s1, s2 | objects of types S |
| op | C++ infix operator |
| prefix_op | C++ prefix operator |
| postfix_op | C++ postfix operator |
| assign_op | C++ assignment operator |
| Expression | Result Type | Description |
|---|---|---|
s op t |
unspecified S | invoke safe C++ operator op and return another SafeNumeric type. |
t op s |
unspecified S | invoke safe C++ operator op and return another SafeNumeric type. |
s1 op s2 |
unspecified S | invoke safe C++ operator op and return another SafeNumeric type. |
prefix_op S |
unspecified S | invoke safe C++ operator |
S postfix_op |
unspecified S | invoke safe C++ operator |
s assign_op t |
S1 | convert t to type S1 and assign it to s1. If the value t cannot be represented as an instance of type S1, it is an error. |
S(t) |
unspecified S | construct a instance of S from a value of type T. f the value t cannot be represented as an instance of type S1, it is an error. |
S |
S | construct a uninitialized instance of S. |
is_safe<S> |
std::true_type or
std::false_type
|
type trait to query whether any type T fulfills the requirements for a SafeNumeric type. |
static_cast<T>(s) |
T | convert the value of s to type T. If the value of s cannot be correctly represented as a type T, it is an error. Note that implicit casting from a safe type to a built-in integer type is expressly prohibited and should invoke a compile time error. |
Result of any binary operation where one or both of the operands is a SafeNumeric type is also a SafeNumeric type.
All the expressions in the above table are
constexpr expressions
Binary expressions which are not assignments require that promotion and exception policies be identical.
Safe Numeric operators will NOT perform standard numeric conversions in order to convert to built-in types.
void f(int); int main(){ long x; f(x); // OK - builtin implicit version safe<long> y; f(y); // compile time error return 0; }
This behavior prevents a safe<T> from
being a "drop-in" replacement for a T.
There are no explicit complexity guarantees here. However, it would be very surprising if any implementation were to be more complex that O(0);
The fundamental requirement of a SafeNumeric type is that implements all C++ operations permitted on it's base type in a way the prevents the return of an incorrect arithmetic result. Various implementations of this concept may handle circumstances which produce such results differently ( throw exception, compile time trap, etc..) no implementation should return an arithmetically incorrect result.