# `base/numerics`

This directory contains a dependency-free, header-only library of templates
providing well-defined semantics for safely and performantly handling a variety
of numeric operations, including most common arithmetic operations and
conversions.

The public API is broken out into the following header files:

*   `checked_math.h` contains the `CheckedNumeric` template class and helper
    functions for performing arithmetic and conversion operations that detect
    errors and boundary conditions (e.g. overflow, truncation, etc.).
*   `clamped_math.h` contains the `ClampedNumeric` template class and
    helper functions for performing fast, clamped (i.e. non-sticky saturating)
    arithmetic operations and conversions.
*   `safe_conversions.h` contains the `StrictNumeric` template class and
    a collection of custom casting templates and helper functions for safely
    converting between a range of numeric types.
*   `safe_math.h` includes all of the previously mentioned headers.

*** aside
**Note:** The `Numeric` template types implicitly convert from C numeric types
and `Numeric` templates that are convertable to an underlying C numeric type.
The conversion priority for `Numeric` type coercions is:

*   `StrictNumeric` coerces to `ClampedNumeric` and `CheckedNumeric`
*   `ClampedNumeric` coerces to `CheckedNumeric`
***

[TOC]

## Common patterns and use-cases

The following covers the preferred style for the most common uses of this
library. Please don't cargo-cult from anywhere else. 😉

### Performing checked arithmetic conversions

The `checked_cast` template converts between arbitrary arithmetic types, and is
used for cases where a conversion failure should result in program termination:

```cpp
// Crash if signed_value is out of range for buff_size.
size_t buff_size = checked_cast<size_t>(signed_value);
```

### Performing saturated (clamped) arithmetic conversions

The `saturated_cast` template converts between arbitrary arithmetic types, and
is used in cases where an out-of-bounds source value should be saturated to the
corresponding maximum or minimum of the destination type:

```cpp
// Convert from float with saturation to INT_MAX, INT_MIN, or 0 for NaN.
int int_value = saturated_cast<int>(floating_point_value);
```

### Enforcing arithmetic conversions at compile-time

The `strict_cast` enforces type restrictions at compile-time and results in
emitted code that is identical to a normal `static_cast`. However, a
`strict_cast` assignment will fail to compile if the destination type cannot
represent the full range of the source type:

```cpp
// Throw a compiler error if byte_value is changed to an out-of-range-type.
int int_value = strict_cast<int>(byte_value);
```

You can also enforce these compile-time restrictions on function parameters by
using the `StrictNumeric` template:

```cpp
// Throw a compiler error if the size argument cannot be represented by a
// size_t (e.g. passing an int will fail to compile).
bool AllocateBuffer(void** buffer, StrictCast<size_t> size);
```

### Comparing values between arbitrary arithmetic types

Both the `StrictNumeric` and `ClampedNumeric` types provide well defined
comparisons between arbitrary arithmetic types. This allows you to perform
comparisons that are not legal or would trigger compiler warnings or errors
under the normal arithmetic promotion rules:

```cpp
bool foo(unsigned value, int upper_bound) {
  // Converting to StrictNumeric allows this comparison to work correctly.
  if (MakeStrictNum(value) >= upper_bound)
    return false;
```

*** note
**Warning:** Do not perform manual conversions using the comparison operators.
Instead, use the cast templates described in the previous sections, or the
constexpr template functions `IsValueInRangeForNumericType` and
`IsTypeInRangeForNumericType`, as these templates properly handle the full range
of corner cases and employ various optimizations.
***

### Calculating a buffer size (checked arithmetic)

When making exact calculations—such as for buffer lengths—it's often necessary
to know when those calculations trigger an overflow, undefined behavior, or
other boundary conditions. The `CheckedNumeric` template does this by storing
a bit determining whether or not some arithmetic operation has occured that
would put the variable in an "invalid" state. Attempting to extract the value
from a variable in an invalid state will trigger a check/trap condition, that
by default will result in process termination.

Here's an example of a buffer calculation using a `CheckedNumeric` type (note:
the AssignIfValid method will trigger a compile error if the result is ignored).

```cpp
// Calculate the buffer size and detect if an overflow occurs.
size_t size;
if (!CheckAdd(kHeaderSize, CheckMul(count, kItemSize)).AssignIfValid(&size)) {
  // Handle an overflow error...
}
```

### Calculating clamped coordinates (non-sticky saturating arithmetic)

Certain classes of calculations—such as coordinate calculations—require
well-defined semantics that always produce a valid result on boundary
conditions. The `ClampedNumeric` template addresses this by providing
performant, non-sticky saturating arithmetic operations.

Here's an example of using a `ClampedNumeric` to calculate an operation
insetting a rectangle.

```cpp
// Use clamped arithmetic since inset calculations might overflow.
void Rect::Inset(int left, int top, int right, int bottom) {
  origin_ += Vector2d(left, top);
  set_width(ClampSub(width(), ClampAdd(left, right)));
  set_height(ClampSub(height(), ClampAdd(top, bottom)));
}
```

*** note
The `ClampedNumeric` type is not "sticky", which means the saturation is not
retained across individual operations. As such, one arithmetic operation may
result in a saturated value, while the next operation may then "desaturate"
the value. Here's an example:

```cpp
ClampedNumeric<int> value = INT_MAX;
++value;  // value is still INT_MAX, due to saturation.
--value;  // value is now (INT_MAX - 1), because saturation is not sticky.
```

***

## Conversion functions and StrictNumeric<> in safe_conversions.h

This header includes a collection of helper `constexpr` templates for safely
performing a range of conversions, assignments, and tests.

### Safe casting templates

*   `as_signed()` - Returns the supplied integral value as a signed type of
    the same width.
*   `as_unsigned()` - Returns the supplied integral value as an unsigned type
    of the same width.
*   `checked_cast<>()` - Analogous to `static_cast<>` for numeric types, except
    that by default it will trigger a crash on an out-of-bounds conversion (e.g.
    overflow, underflow, NaN to integral) or a compile error if the conversion
    error can be detected at compile time. The crash handler can be overridden
    to perform a behavior other than crashing.
*   `saturated_cast<>()` - Analogous to `static_cast` for numeric types, except
    that it returns a saturated result when the specified numeric conversion
    would otherwise overflow or underflow. An NaN source returns 0 by
    default, but can be overridden to return a different result.
*   `strict_cast<>()` - Analogous to `static_cast` for numeric types, except
    this causes a compile failure if the destination type is not large
    enough to contain any value in the source type. It performs no runtime
    checking and thus introduces no runtime overhead.

### Other helper and conversion functions

*   `IsValueInRangeForNumericType<>()` - A convenience function that returns
    true if the type supplied as the template parameter can represent the value
    passed as an argument to the function.
*   `IsTypeInRangeForNumericType<>()` - A convenience function that evaluates
    entirely at compile-time and returns true if the destination type (first
    template parameter) can represent the full range of the source type
    (second template parameter).
*   `IsValueNegative()` - A convenience function that will accept any
    arithmetic type as an argument and will return whether the value is less
    than zero. Unsigned types always return false.
*   `SafeUnsignedAbs()` - Returns the absolute value of the supplied integer
    parameter as an unsigned result (thus avoiding an overflow if the value
    is the signed, two's complement minimum).

### StrictNumeric<>

`StrictNumeric<>` is a wrapper type that performs assignments and copies via
the `strict_cast` template, and can perform valid arithmetic comparisons
across any range of arithmetic types. `StrictNumeric` is the return type for
values extracted from a `CheckedNumeric` class instance. The raw numeric value
is extracted via `static_cast` to the underlying type or any type with
sufficient range to represent the underlying type.

*   `MakeStrictNum()` - Creates a new `StrictNumeric` from the underlying type
    of the supplied arithmetic or StrictNumeric type.
*   `SizeT` - Alias for `StrictNumeric<size_t>`.

## CheckedNumeric<> in checked_math.h

`CheckedNumeric<>` implements all the logic and operators for detecting integer
boundary conditions such as overflow, underflow, and invalid conversions.
The `CheckedNumeric` type implicitly converts from floating point and integer
data types, and contains overloads for basic arithmetic operations (i.e.: `+`,
`-`, `*`, `/` for all types and `%`, `<<`, `>>`, `&`, `|`, `^` for integers).
However, *the [variadic template functions
](#CheckedNumeric_in-checked_math_h-Non_member-helper-functions)
are the prefered API,* as they remove type ambiguities and help prevent a number
of common errors. The variadic functions can also be more performant, as they
eliminate redundant expressions that are unavoidable with the with the operator
overloads. (Ideally the compiler should optimize those away, but better to avoid
them in the first place.)

Type promotions are a slightly modified version of the [standard C/C++ numeric
promotions
](http://en.cppreference.com/w/cpp/language/implicit_conversion#Numeric_promotions)
with the two differences being that *there is no default promotion to int*
and *bitwise logical operations always return an unsigned of the wider type.*

### Members

The unary negation, increment, and decrement operators are supported, along
with the following unary arithmetic methods, which return a new
`CheckedNumeric` as a result of the operation:

*   `Abs()` - Absolute value.
*   `UnsignedAbs()` - Absolute value as an equal-width unsigned underlying type
    (valid for only integral types).
*   `Max()` - Returns whichever is greater of the current instance or argument.
    The underlying return type is whichever has the greatest magnitude.
*   `Min()` - Returns whichever is lowest of the current instance or argument.
    The underlying return type is whichever has can represent the lowest
    number in the smallest width (e.g. int8_t over unsigned, int over
    int8_t, and float over int).

The following are for converting `CheckedNumeric` instances:

*   `type` - The underlying numeric type.
*   `AssignIfValid()` - Assigns the underlying value to the supplied
    destination pointer if the value is currently valid and within the
    range supported by the destination type. Returns true on success.
*   `Cast<>()` - Instance method returning a `CheckedNumeric` derived from
    casting the current instance to a `CheckedNumeric` of the supplied
    destination type.

*** aside
The following member functions return a `StrictNumeric`, which is valid for
comparison and assignment operations, but will trigger a compile failure on
attempts to assign to a type of insufficient range. The underlying value can
be extracted by an explicit `static_cast` to the underlying type or any type
with sufficient range to represent the underlying type.
***

*   `IsValid()` - Returns true if the underlying numeric value is valid (i.e.
    has not wrapped or saturated and is not the result of an invalid
    conversion).
*   `ValueOrDie()` - Returns the underlying value. If the state is not valid
    this call will trigger a crash by default (but may be overridden by
    supplying an alternate handler to the template).
*   `ValueOrDefault()` - Returns the current value, or the supplied default if
    the state is not valid (but will not crash).

**Comparison operators are explicitly not provided** for `CheckedNumeric`
types because they could result in a crash if the type is not in a valid state.
Patterns like the following should be used instead:

```cpp
// Either input or padding (or both) may be arbitrary sizes.
size_t buff_size;
if (!CheckAdd(input, padding, kHeaderLength).AssignIfValid(&buff_size) ||
     buff_size >= kMaxBuffer) {
  // Handle an error...
} else {
  // Do stuff on success...
}
```

### Non-member helper functions

The following variadic convenience functions, which accept standard arithmetic
or `CheckedNumeric` types, perform arithmetic operations, and return a
`CheckedNumeric` result. The supported functions are:

*   `CheckAdd()` - Addition.
*   `CheckSub()` - Subtraction.
*   `CheckMul()` - Multiplication.
*   `CheckDiv()` - Division.
*   `CheckMod()` - Modulus (integer only).
*   `CheckLsh()` - Left integer shift (integer only).
*   `CheckRsh()` - Right integer shift (integer only).
*   `CheckAnd()` - Bitwise AND (integer only with unsigned result).
*   `CheckOr()`  - Bitwise OR (integer only with unsigned result).
*   `CheckXor()` - Bitwise XOR (integer only with unsigned result).
*   `CheckMax()` - Maximum of supplied arguments.
*   `CheckMin()` - Minimum of supplied arguments.

The following wrapper functions can be used to avoid the template
disambiguator syntax when converting a destination type.

*   `IsValidForType<>()` in place of: `a.template IsValid<>()`
*   `ValueOrDieForType<>()` in place of: `a.template ValueOrDie<>()`
*   `ValueOrDefaultForType<>()` in place of: `a.template ValueOrDefault<>()`

The following general utility methods is are useful for converting from
arithmetic types to `CheckedNumeric` types:

*   `MakeCheckedNum()` - Creates a new `CheckedNumeric` from the underlying type
    of the supplied arithmetic or directly convertible type.

## ClampedNumeric<> in clamped_math.h

`ClampedNumeric<>` implements all the logic and operators for clamped
(non-sticky saturating) arithmetic operations and conversions. The
`ClampedNumeric` type implicitly converts back and forth between floating point
and integer data types, saturating on assignment as appropriate. It contains
overloads for basic arithmetic operations (i.e.: `+`, `-`, `*`, `/` for
all types and `%`, `<<`, `>>`, `&`, `|`, `^` for integers) along with comparison
operators for arithmetic types of any size. However, *the [variadic template
functions
](#ClampedNumeric_in-clamped_math_h-Non_member-helper-functions)
are the prefered API,* as they remove type ambiguities and help prevent
a number of common errors. The variadic functions can also be more performant,
as they eliminate redundant expressions that are unavoidable with the operator
overloads. (Ideally the compiler should optimize those away, but better to avoid
them in the first place.)

Type promotions are a slightly modified version of the [standard C/C++ numeric
promotions
](http://en.cppreference.com/w/cpp/language/implicit_conversion#Numeric_promotions)
with the two differences being that *there is no default promotion to int*
and *bitwise logical operations always return an unsigned of the wider type.*

*** aside
Most arithmetic operations saturate normally, to the numeric limit in the
direction of the sign. The potentially unusual cases are:

*   **Division:** Division by zero returns the saturated limit in the direction
    of sign of the dividend (first argument). The one exception is 0/0, which
	returns zero (although logically is NaN).
*   **Modulus:** Division by zero returns the dividend (first argument).
*   **Left shift:** Non-zero values saturate in the direction of the signed
    limit (max/min), even for shifts larger than the bit width. 0 shifted any
    amount results in 0.
*   **Right shift:** Negative values saturate to -1. Positive or 0 saturates
    to 0. (Effectively just an unbounded arithmetic-right-shift.)
*   **Bitwise operations:** No saturation; bit pattern is identical to
    non-saturated bitwise operations.
***

### Members

The unary negation, increment, and decrement operators are supported, along
with the following unary arithmetic methods, which return a new
`ClampedNumeric` as a result of the operation:

*   `Abs()` - Absolute value.
*   `UnsignedAbs()` - Absolute value as an equal-width unsigned underlying type
    (valid for only integral types).
*   `Max()` - Returns whichever is greater of the current instance or argument.
    The underlying return type is whichever has the greatest magnitude.
*   `Min()` - Returns whichever is lowest of the current instance or argument.
    The underlying return type is whichever has can represent the lowest
    number in the smallest width (e.g. int8_t over unsigned, int over
    int8_t, and float over int).

The following are for converting `ClampedNumeric` instances:

*   `type` - The underlying numeric type.
*   `RawValue()` - Returns the raw value as the underlying arithmetic type. This
    is useful when e.g. assigning to an auto type or passing as a deduced
    template parameter.
*   `Cast<>()` - Instance method returning a `ClampedNumeric` derived from
    casting the current instance to a `ClampedNumeric` of the supplied
    destination type.

### Non-member helper functions

The following variadic convenience functions, which accept standard arithmetic
or `ClampedNumeric` types, perform arithmetic operations, and return a
`ClampedNumeric` result. The supported functions are:

*   `ClampAdd()` - Addition.
*   `ClampSub()` - Subtraction.
*   `ClampMul()` - Multiplication.
*   `ClampDiv()` - Division.
*   `ClampMod()` - Modulus (integer only).
*   `ClampLsh()` - Left integer shift (integer only).
*   `ClampRsh()` - Right integer shift (integer only).
*   `ClampAnd()` - Bitwise AND (integer only with unsigned result).
*   `ClampOr()`  - Bitwise OR (integer only with unsigned result).
*   `ClampXor()` - Bitwise XOR (integer only with unsigned result).
*   `ClampMax()` - Maximum of supplied arguments.
*   `ClampMin()` - Minimum of supplied arguments.

The following is a general utility method that is useful for converting
to a `ClampedNumeric` type:

*   `MakeClampedNum()` - Creates a new `ClampedNumeric` from the underlying type
    of the supplied arithmetic or directly convertible type.
