# PromotionPolicy<PP>

## Description

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.

    int x;
    char y;
    auto z = x + y

the type of `z` will be an `int`. This is a consequence for the standard rules for type promotion for C/C++ arithmetic. A key feature of library permits one to specify his own type promotion rules via a PromotionPolicy class.

## Notation

`PP` | A type that full fills the requirements of a PromotionPollicy
`T, U` | A type that is a model of the Numeric concept
`R` | An object of type modeling Numeric which can be used to construct a SafeNumeric type.

## Valid Expressions

Any operations which result in integers which cannot be represented as some Numeric type will throw an exception.These expressions return a type which can be used as the basis create a SafeNumeric type.

Expression | Return Value
--- | ---
`PP::addition_result<T, U>::type` | unspecified Numeric type
`PP::subtraction_result<T, U>::type` | unspecified Numeric type
`PP::multiplication_result<T, U>::type` | unspecified Numeric type
`PP::division_result<T, U>::type` | unspecified Numeric type
`PP::modulus_result<T, U>::type` | unspecified Numeric type
`PP::comparison_result<T, U>::type` | bool
`PP::left_shift_result<T, U>::type` | unspecified Numeric type
`PP::right_shift_result<T, u>::type` | unspecified Numeric type
`PP::bitwise_or_result<T, U>::type` | unspecified Numeric type
`PP::bitwise_and_result<T, U>::type` | unspecified Numeric type
`PP::bitwise_xor_result<T, U>::type` | unspecified Numeric type

## Models

The library contains a number of pre-made promotion policies:

- `boost::numeric::native`

  Use the normal C/C++ expression type promotion rules.

      int x;
      char y;
      auto z = x + y; // could result in overflow
      safe<int, native> sx;
      auto sz = sx + y; // standard C++ code which detects errors

  Type sz will be a SafeNumeric type based on `int`. If the result exceeds the maximum value that can be stored in an `int`, an error is detected.

  The `native` policy is documented in Promotion Policies - native.

- `boost::numeric::automatic`

  Use optimizing expression type promotion rules. These rules replace the normal C/C++ type promotion rules with other rules which are designed to result in more efficient computations. Expression types are promoted to the smallest type which can be guaranteed to hold the result without overflow. If there is no such type, the result will be checked for overflow. Consider the following example:

      int x;
      char y;
      auto z = x + y; // could result in overflow
      safe<int, automatic> sx;
      auto sz = sx + y;
          // sz is a safe type based on long
          // hence sz is guaranteed not to overflow.
      safe_unsigned_range<1, 4> a;
      safe_unsigned_range<2, 4> b;
      auto c = a + b; // c will be a safe type with a range [3,8] and cannot overflow

  Type sz will be a SafeNumeric type which is guaranteed to hold he result of x + y. In this case that will be a long int (or perhaps a long long) depending upon the compiler and machine architecture. In this case, there will be no need for any special checking on the result and there can be no overflow.

  Type of c will be a signed character as that type can be guaranteed to hold the sum so no overflow checking is done.

  This policy is documented in Promotion Policies - automatic

- boost::numeric::cpp

  Use expression type promotion rules to emulate another processor. When this policy is used, C++ type for safe integers follows the rules that a compiler on the target processor would use. This permits one to test code destined for a one processor on the another one. One situation there this can be very, very useful is when testing code destined for a micro controller which doesn't have the logging, debugging, input/output facilities of a desktop.

      // specify a promotion policy to support proper emulation of
      // PIC 18f2520 types on the desktop
      using pic16_promotion = boost::numeric::cpp<
          8,  // char      8 bits
          16, // short     16 bits
          16, // int       16 bits
          16, // long      16 bits
          32  // long long 32 bits
      >;
      ...
      safe<std::uint16_t, pic16_promotion> x, y;
      ...

      x + y; // detect possible overflow on the pic.

  For a complete example see Safety Critical Embedded Controller.

## Header

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