OLD | NEW |
(Empty) | |
| 1 # `base/numerics` |
| 2 |
| 3 This directory contains templates providing well-defined semantics for safely |
| 4 handling a variety of numeric operations, including most common arithmetic |
| 5 operations and conversions. |
| 6 |
| 7 The public API is broken out into the following header files: |
| 8 |
| 9 * `checked_math.h` contains the `CheckedNumeric` template class and helper |
| 10 functions for performing arithmetic and conversion operations that detect |
| 11 errors and boundary conditions (e.g. overflow, truncation, etc.). |
| 12 * `clamped_math.h` contains the `ClampedNumeric` template class and |
| 13 helper functions for performing fast, clamped (i.e. non-sticky saturating) |
| 14 arithmetic operations and conversions. |
| 15 * `safe_conversions.h` contains the `StrictNumeric` template class and |
| 16 a collection of custom casting templates and helper functions for safely |
| 17 converting between a range of numeric types. |
| 18 * `safe_math.h` includes all of the previously mentioned headers. |
| 19 |
| 20 *** aside |
| 21 **Note:** The `Numeric` template types implicitly convert from C numeric types |
| 22 and `Numeric` templates that are convertable to an underlying C numeric type. |
| 23 The conversion priority for `Numeric` type coercions is: |
| 24 |
| 25 * `StrictNumeric` coerces to `ClampedNumeric` and `CheckedNumeric` |
| 26 * `ClampedNumeric` coerces to `CheckedNumeric` |
| 27 *** |
| 28 |
| 29 [TOC] |
| 30 |
| 31 ## Conversion functions and `StrictNumeric<>` in `safe_conversions.h` |
| 32 |
| 33 This header includes a collection of helper `constexpr` templates for safely |
| 34 performing a range of conversions, assignments, and tests. |
| 35 |
| 36 ### Safe casting templates |
| 37 |
| 38 * `as_signed()` - Returns the supplied integral value as a signed type of |
| 39 the same width. |
| 40 * `as_unsigned()` - Returns the supplied integral value as an unsigned type |
| 41 of the same width. |
| 42 * `checked_cast<>()` - Analogous to `static_cast<>` for numeric types, except |
| 43 that by default it will trigger a crash on an out-of-bounds conversion (e.g. |
| 44 overflow, underflow, NaN to integral) or a compile error if the conversion |
| 45 error can be detected at compile time. The crash handler can be overridden |
| 46 to perform a behavior other than crashing. |
| 47 * `saturated_cast<>()` - Analogous to `static_cast` for numeric types, except |
| 48 that it returns a saturated result when the specified numeric conversion |
| 49 would otherwise overflow or underflow. An NaN source returns 0 by |
| 50 default, but can be overridden to return a different result. |
| 51 * `strict_cast<>()` - Analogous to `static_cast` for numeric types, except |
| 52 this causes a compile failure if the destination type is not large |
| 53 enough to contain any value in the source type. It performs no runtime |
| 54 checking and thus introduces no runtime overhead. |
| 55 |
| 56 ### Other helper and conversion functions |
| 57 |
| 58 * `IsValueInRangeForNumericType<>()` - A convenience function that returns |
| 59 true if the type supplied to the template parameter can represent the value |
| 60 passed as an argument to the function. |
| 61 * `IsValueNegative()` - A convenience function that will accept any |
| 62 arithmetic type as an argument and will return whether the value is less |
| 63 than zero. Unsigned types always return false. |
| 64 * `SafeUnsignedAbs()` - Returns the absolute value of the supplied integer |
| 65 parameter as an unsigned result (thus avoiding an overflow if the value |
| 66 is the signed, two's complement minimum). |
| 67 |
| 68 ### `StrictNumeric<>` |
| 69 |
| 70 `StrictNumeric<>` is a wrapper type that performs assignments and copies via |
| 71 the `strict_cast` template, and can perform valid arithmetic comparisons |
| 72 across any range of arithmetic types. `StrictNumeric` is the return type for |
| 73 values extracted from a `CheckedNumeric` class instance. The raw numeric value |
| 74 is extracted via `static_cast` to the underlying type or any type with |
| 75 sufficient range to represent the underlying type. |
| 76 |
| 77 * `MakeStrictNum()` - Creates a new `StrictNumeric` from the underlying type |
| 78 of the supplied arithmetic or StrictNumeric type. |
| 79 * `SizeT` - Alias for `StrictNumeric<size_t>`. |
| 80 |
| 81 ## `CheckedNumeric<>` in `checked_math.h` |
| 82 |
| 83 `CheckedNumeric<>` implements all the logic and operators for detecting integer |
| 84 boundary conditions such as overflow, underflow, and invalid conversions. |
| 85 The `CheckedNumeric` type implicitly converts from floating point and integer |
| 86 data types, and contains overloads for basic arithmetic operations (i.e.: `+`, |
| 87 `-`, `*`, `/` for all types and `%`, `<<`, `>>`, `&`, `|`, `^` for integers). |
| 88 Type promotions are a slightly modified version of the [standard C/C++ numeric |
| 89 promotions |
| 90 ](http://en.cppreference.com/w/cpp/language/implicit_conversion#Numeric_promotio
ns) |
| 91 with the two differences being that there is no default promotion to int |
| 92 and bitwise logical operations always return an unsigned of the wider type. |
| 93 |
| 94 ### Members |
| 95 |
| 96 The unary negation, increment, and decrement operators are supported, along |
| 97 with the following unary arithmetic methods, which return a new |
| 98 `CheckedNumeric` as a result of the operation: |
| 99 |
| 100 * `Abs()` - Absolute value. |
| 101 * `UnsignedAbs()` - Absolute value as an equal-width unsigned underlying type |
| 102 (valid for only integral types). |
| 103 * `Max()` - Returns whichever is greater of the current instance or argument. |
| 104 The underlying return type is whichever has the greatest magnitude. |
| 105 * `Min()` - Returns whichever is lowest of the current instance or argument. |
| 106 The underlying return type is whichever has can represent the lowest |
| 107 number in the smallest width (e.g. int8_t over unsigned, int over |
| 108 int8_t, and float over int). |
| 109 |
| 110 The following are for converting `CheckedNumeric` instances: |
| 111 |
| 112 * `type` - The underlying numeric type. |
| 113 * `AssignIfValid()` - Assigns the underlying value to the supplied |
| 114 destination pointer if the value is currently valid and within the |
| 115 range supported by the destination type. Returns true on success. |
| 116 * `Cast<>()` - Instance method returning a `CheckedNumeric` derived from |
| 117 casting the current instance to a `CheckedNumeric` of the supplied |
| 118 destination type. |
| 119 |
| 120 *** aside |
| 121 The following member functions return a `StrictNumeric`, which is valid for |
| 122 comparison and assignment operations, but will trigger a compile failure on |
| 123 attempts to assign to a type of insufficient range. The underlying value can |
| 124 be extracted by an explicit `static_cast` to the underlying type or any type |
| 125 with sufficient range to represent the underlying type. |
| 126 *** |
| 127 |
| 128 * `IsValid()` - Returns true if the underlying numeric value is valid (i.e. |
| 129 has not wrapped or saturated and is not the result of an invalid |
| 130 conversion). |
| 131 * `ValueOrDie()` - Returns the underlying value. If the state is not valid |
| 132 this call will trigger a crash by default (but may be overridden by |
| 133 supplying an alternate handler to the template). |
| 134 * `ValueOrDefault()` - Returns the current value, or the supplied default if |
| 135 the state is not valid (but will not crash). |
| 136 |
| 137 **Comparison operators are explicitly not provided** for `CheckedNumeric` |
| 138 types because they could result in a crash if the type is not in a valid state. |
| 139 Patterns like the following should be used instead: |
| 140 |
| 141 ```cpp |
| 142 CheckedNumeric<size_t> checked_size = untrusted_input_value; |
| 143 checked_size += HEADER LENGTH; |
| 144 if (checked_size.IsValid() && checked_size.ValueOrDie() < buffer_size) { |
| 145 \\ Do stuff on success... |
| 146 } else { |
| 147 \\ Handle an error... |
| 148 } |
| 149 ``` |
| 150 |
| 151 ### Non-member helper functions |
| 152 |
| 153 The following variadic convenience functions, which accept standard arithmetic |
| 154 or `CheckedNumeric` types, perform arithmetic operations, and return a |
| 155 `CheckedNumeric` result. The supported functions are: |
| 156 |
| 157 * `CheckAdd()` - Addition. |
| 158 * `CheckSub()` - Subtraction. |
| 159 * `CheckMul()` - Multiplication. |
| 160 * `CheckDiv()` - Division. |
| 161 * `CheckMod()` - Modulus (integer only). |
| 162 * `CheckLsh()` - Left integer shift (integer only). |
| 163 * `CheckRsh()` - Right integer shift (integer only). |
| 164 * `CheckAnd()` - Bitwise AND (integer only with unsigned result). |
| 165 * `CheckOr()` - Bitwise OR (integer only with unsigned result). |
| 166 * `CheckXor()` - Bitwise XOR (integer only with unsigned result). |
| 167 * `CheckMax()` - Maximum of supplied arguments. |
| 168 * `CheckMin()` - Minimum of supplied arguments. |
| 169 |
| 170 The following wrapper functions can be used to avoid the template |
| 171 disambiguator syntax when converting a destination type. |
| 172 |
| 173 * `IsValidForType<>()` in place of: `a.template IsValid<>()` |
| 174 * `ValueOrDieForType<>()` in place of: `a.template ValueOrDie<>()` |
| 175 * `ValueOrDefaultForType<>()` in place of: `a.template ValueOrDefault<>()` |
| 176 |
| 177 The following general utility methods is are useful for converting from |
| 178 arithmetic types to `CheckedNumeric` types: |
| 179 |
| 180 * `MakeCheckedNum()` - Creates a new `CheckedNumeric` from the underlying type |
| 181 of the supplied arithmetic or directly convertible type. |
| 182 |
| 183 ## `ClampedNumeric<>` in `clamped_math.h` |
| 184 |
| 185 `ClampedNumeric<>` implements all the logic and operators for clamped |
| 186 (non-sticky saturating) arithmetic operations and conversions. The |
| 187 `ClampedNumeric` type implicitly converts back and forth between floating point |
| 188 and integer data types, saturating on assignment as appropriate. It contains |
| 189 overloads for basic arithmetic operations (i.e.: `+`, `-`, `*`, `/` for |
| 190 all types and `%`, `<<`, `>>`, `&`, `|`, `^` for integers) along with comparison |
| 191 operators for arithmetic types of any size. Type promotions are a slightly |
| 192 modified version of the [standard C/C++ numeric promotions |
| 193 ](http://en.cppreference.com/w/cpp/language/implicit_conversion#Numeric_promotio
ns) |
| 194 with the two differences being that there is no default promotion to int and |
| 195 bitwise logical operations always return an unsigned of the wider type. |
| 196 |
| 197 *** aside |
| 198 Most arithmetic operations saturate normally, to the numeric limit in the |
| 199 direction of the sign. The potentially unusual cases are: |
| 200 |
| 201 * **Division:** Division by zero returns the saturated limit in the direction |
| 202 of sign of the dividend (first argument). The one exception is 0/0, which |
| 203 returns zero (although logically is NaN). |
| 204 * **Modulus:** Division by zero returns the dividend (first argument). |
| 205 * **Left shift:** Non-zero values saturate in the direction of the signed |
| 206 limit (max/min), even for shifts larger than the bit width. 0 shifted any |
| 207 amount results in 0. |
| 208 * **Right shift:** Negative values saturate to -1. Positive or 0 saturates |
| 209 to 0. |
| 210 * **Bitwise operations:** No saturation; bit pattern is identical to |
| 211 non-saturated bitwise operations. |
| 212 *** |
| 213 |
| 214 ### Members |
| 215 |
| 216 The unary negation, increment, and decrement operators are supported, along |
| 217 with the following unary arithmetic methods, which return a new |
| 218 `ClampedNumeric` as a result of the operation: |
| 219 |
| 220 * `Abs()` - Absolute value. |
| 221 * `UnsignedAbs()` - Absolute value as an equal-width unsigned underlying type |
| 222 (valid for only integral types). |
| 223 * `Max()` - Returns whichever is greater of the current instance or argument. |
| 224 The underlying return type is whichever has the greatest magnitude. |
| 225 * `Min()` - Returns whichever is lowest of the current instance or argument. |
| 226 The underlying return type is whichever has can represent the lowest |
| 227 number in the smallest width (e.g. int8_t over unsigned, int over |
| 228 int8_t, and float over int). |
| 229 |
| 230 The following are for converting `ClampedNumeric` instances: |
| 231 |
| 232 * `type` - The underlying numeric type. |
| 233 * `Cast<>()` - Instance method returning a `ClampedNumeric` derived from |
| 234 casting the current instance to a `ClampedNumeric` of the supplied |
| 235 destination type. |
| 236 |
| 237 ### Non-member helper functions |
| 238 |
| 239 The following variadic convenience functions, which accept standard arithmetic |
| 240 or `ClampedNumeric` types, perform arithmetic operations, and return a |
| 241 `ClampedNumeric` result. The supported functions are: |
| 242 |
| 243 * `ClampAdd()` - Addition. |
| 244 * `ClampSub()` - Subtraction. |
| 245 * `ClampMul()` - Multiplication. |
| 246 * `ClampDiv()` - Division. |
| 247 * `ClampMod()` - Modulus (integer only). |
| 248 * `ClampLsh()` - Left integer shift (integer only). |
| 249 * `ClampRsh()` - Right integer shift (integer only). |
| 250 * `ClampAnd()` - Bitwise AND (integer only with unsigned result). |
| 251 * `ClampOr()` - Bitwise OR (integer only with unsigned result). |
| 252 * `ClampXor()` - Bitwise XOR (integer only with unsigned result). |
| 253 * `ClampMax()` - Maximum of supplied arguments. |
| 254 * `ClampMin()` - Minimum of supplied arguments. |
| 255 |
| 256 The following is a general utility method that is useful for converting |
| 257 to a `ClampedNumeric` type: |
| 258 |
| 259 * `MakeClampedNum()` - Creates a new `ClampedNumeric` from the underlying type |
| 260 of the supplied arithmetic or directly convertible type. |
OLD | NEW |