# SafeNumeric<T>

## Description

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. These operations return safe types rather than built-in types.

## Refinement of

Numeric or Integer

## Notation

Symbol | Description
--- | ---
`T, U` | Types fulfilling Numeric or Integer type requirements.
t, u | objects of types T, U
S | A type fulfilling SafeNumeric type requirements
s, s1, s2 | objects of types S
op | C++ infix operator supported by underlying type T
prefix_op | C++ prefix operator: -, +, ~, ++, -- supported by underlying type T
postfix_op | C++ postfix operator:++, -- supported by underlying type T
assign_op | C++ assignment operator

## Associated Types

`PromotionPolicy`

In C++ expressions, arguments must be of the same type. If they are not, all arguments are converted to a common type in accordance with rules of the C++ standard. For some applications of the safe numerics library, we might want conversions which are different than the standard ones. This class type implements the conversion functions that are to be used with the safe numeric type being instantiated.

`ExceptionPolicy` | The exception policy specifies what is to occur when a safe operation cannot return a valid result. A type is an ExceptionPolicy if it has specific functions for handling exceptional events that occur in the course of safe numeric operations.

## Valid Expressions

Expression | Result Type | Description
--- | --- | ---
`s op t` | unspecified S | invoke C++ operator op and return another SafeNumeric type.
`t op s` | unspecified S | invoke C++ operator op and return another SafeNumeric type.
`s1 op s2` | unspecified S | invoke C++ operator op and return another SafeNumeric type.
`prefix_op S` | unspecified S | invoke C++ operator `prefix_op` and return another SafeNumeric type.
`S postfix_op` | unspecified S | invoke C++ operator `postfix_op` and return another SafeNumeric type.
`s assign_op t` | S & | convert t to type S and assign it to s.
`t assign_op s` | T & | convert s to type T and assign it to s. If the value t cannot be represented as an instance of type S, it is an error.
`S(t)` | S | construct an instance of S from a value of type T. In this case, T is referred to as the base type of S. If the value t cannot be represented as an instance of type S, it is an exception condition is invoked.
`S` | S | construct an uninitialized instance of S.
`T(s)` | T | implicit conversion of the value of s to type T. If the value of s cannot be correctly represented as a type T, an exception condition is invoked.
`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, an exception condition is invoked.
`is_safe<S>` | `std::true_type` | type trait to query whether any type S fulfills the requirements for a SafeNumeric type.
`get_promotion_policy<S>` | S | Retrieve the `PromotionPolicy` `which is used by the specified safe type`.
`get_exception_policy<S>` | S | Retrieve the `ExceptionPolicy` which is used by the specified safe type.
`base_type<S>::type` | T | Retrieve the base type of a given safe type.
`base_value(s)` | T | Retrieve the value of an instance of a safe type. This is equivalent to `static_cast<base_type<S>>(s)`.

- The result of any binary operation where one or both of the operands is a SafeNumeric type is also a SafeNumeric type. The specific type is determined by the promotion rules implement in the PromotionPolicy returned by get_promotion_policy<S> where S is the result type.

- All the expressions in the above table are `constexpr` expressions.

- Binary expressions which are not assignments and whose operands are both safe types require that promotion and exception policies of the operands be identical.

- `Operations on safe types are supported if and only if the same operation is supported on the underlying types. For example, the binary operations |`, `&`, `^` and `~` operations defined for safe unsigned integer types. But they are not defined for floating point types. Currently the are also defined for signed integer types. It's not clear that this is the correct decision. On one hand, usage of these operators on signed types is almost certainly an error in program logic. But trapping this as an error conflicts with the goal of making safe types "drop-in" replacements for the corresponding built-in types. In light of this, these operators are currently supported as they are for normal built-in types.

- Safe Numeric types will be implicitly converted to built-in types when appropriate. Here's an example:

      void f(int);

      int main(){
          long x;
          f(x);         // OK - builtin implicit version
          safe<long> y;
          f(y);
          return 0;
      }

  This behavior supports the concept of `safe<T>` as being a "drop-in" replacement for a `T`.

## Invariants

The fundamental requirement of a SafeNumeric type is that it implements all C++ operations permitted on its 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..). But no implementation should return an arithmetically incorrect result.

## Models

`safe<T>`

`safe_signed_range<-11, 11>`

`safe_unsigned_range<0, 11>`

`safe_signed_literal<4>`

## Header

`#include <boost/safe_numerics/concepts/safe_numeric.hpp>`