Home | History | Annotate | only in /external/libchrome/base/numerics
Up to higher level directory
NameDateSize
BUILD.gn22-Oct-2020890
checked_math.h22-Oct-202014.4K
checked_math_impl.h22-Oct-202022.3K
clamped_math.h22-Oct-20208.9K
clamped_math_impl.h22-Oct-202012.5K
math_constants.h22-Oct-2020436
ranges.h22-Oct-2020759
README.md22-Oct-202018.1K
safe_conversions.h22-Oct-202014.1K
safe_conversions_arm_impl.h22-Oct-20201.8K
safe_conversions_impl.h22-Oct-202033.6K
safe_math.h22-Oct-2020400
safe_math_arm_impl.h22-Oct-20204K
safe_math_clang_gcc_impl.h22-Oct-20204.8K
safe_math_shared_impl.h22-Oct-20208.4K

README.md

      1 # `base/numerics`
      2 
      3 This directory contains a dependency-free, header-only library of templates
      4 providing well-defined semantics for safely and performantly handling a variety
      5 of numeric operations, including most common arithmetic operations and
      6 conversions.
      7 
      8 The public API is broken out into the following header files:
      9 
     10 *   `checked_math.h` contains the `CheckedNumeric` template class and helper
     11     functions for performing arithmetic and conversion operations that detect
     12     errors and boundary conditions (e.g. overflow, truncation, etc.).
     13 *   `clamped_math.h` contains the `ClampedNumeric` template class and
     14     helper functions for performing fast, clamped (i.e. non-sticky saturating)
     15     arithmetic operations and conversions.
     16 *   `safe_conversions.h` contains the `StrictNumeric` template class and
     17     a collection of custom casting templates and helper functions for safely
     18     converting between a range of numeric types.
     19 *   `safe_math.h` includes all of the previously mentioned headers.
     20 
     21 *** aside
     22 **Note:** The `Numeric` template types implicitly convert from C numeric types
     23 and `Numeric` templates that are convertable to an underlying C numeric type.
     24 The conversion priority for `Numeric` type coercions is:
     25 
     26 *   `StrictNumeric` coerces to `ClampedNumeric` and `CheckedNumeric`
     27 *   `ClampedNumeric` coerces to `CheckedNumeric`
     28 ***
     29 
     30 [TOC]
     31 
     32 ## Common patterns and use-cases
     33 
     34 The following covers the preferred style for the most common uses of this
     35 library. Please don't cargo-cult from anywhere else. 
     36 
     37 ### Performing checked arithmetic conversions
     38 
     39 The `checked_cast` template converts between arbitrary arithmetic types, and is
     40 used for cases where a conversion failure should result in program termination:
     41 
     42 ```cpp
     43 // Crash if signed_value is out of range for buff_size.
     44 size_t buff_size = checked_cast<size_t>(signed_value);
     45 ```
     46 
     47 ### Performing saturated (clamped) arithmetic conversions
     48 
     49 The `saturated_cast` template converts between arbitrary arithmetic types, and
     50 is used in cases where an out-of-bounds source value should be saturated to the
     51 corresponding maximum or minimum of the destination type:
     52 
     53 ```cpp
     54 // Convert from float with saturation to INT_MAX, INT_MIN, or 0 for NaN.
     55 int int_value = saturated_cast<int>(floating_point_value);
     56 ```
     57 
     58 ### Enforcing arithmetic conversions at compile-time
     59 
     60 The `strict_cast` enforces type restrictions at compile-time and results in
     61 emitted code that is identical to a normal `static_cast`. However, a
     62 `strict_cast` assignment will fail to compile if the destination type cannot
     63 represent the full range of the source type:
     64 
     65 ```cpp
     66 // Throw a compiler error if byte_value is changed to an out-of-range-type.
     67 int int_value = strict_cast<int>(byte_value);
     68 ```
     69 
     70 You can also enforce these compile-time restrictions on function parameters by
     71 using the `StrictNumeric` template:
     72 
     73 ```cpp
     74 // Throw a compiler error if the size argument cannot be represented by a
     75 // size_t (e.g. passing an int will fail to compile).
     76 bool AllocateBuffer(void** buffer, StrictCast<size_t> size);
     77 ```
     78 
     79 ### Comparing values between arbitrary arithmetic types
     80 
     81 Both the `StrictNumeric` and `ClampedNumeric` types provide well defined
     82 comparisons between arbitrary arithmetic types. This allows you to perform
     83 comparisons that are not legal or would trigger compiler warnings or errors
     84 under the normal arithmetic promotion rules:
     85 
     86 ```cpp
     87 bool foo(unsigned value, int upper_bound) {
     88   // Converting to StrictNumeric allows this comparison to work correctly.
     89   if (MakeStrictNum(value) >= upper_bound)
     90     return false;
     91 ```
     92 
     93 *** note
     94 **Warning:** Do not perform manual conversions using the comparison operators.
     95 Instead, use the cast templates described in the previous sections, or the
     96 constexpr template functions `IsValueInRangeForNumericType` and
     97 `IsTypeInRangeForNumericType`, as these templates properly handle the full range
     98 of corner cases and employ various optimizations.
     99 ***
    100 
    101 ### Calculating a buffer size (checked arithmetic)
    102 
    103 When making exact calculationssuch as for buffer lengthsit's often necessary
    104 to know when those calculations trigger an overflow, undefined behavior, or
    105 other boundary conditions. The `CheckedNumeric` template does this by storing
    106 a bit determining whether or not some arithmetic operation has occured that
    107 would put the variable in an "invalid" state. Attempting to extract the value
    108 from a variable in an invalid state will trigger a check/trap condition, that
    109 by default will result in process termination.
    110 
    111 Here's an example of a buffer calculation using a `CheckedNumeric` type (note:
    112 the AssignIfValid method will trigger a compile error if the result is ignored).
    113 
    114 ```cpp
    115 // Calculate the buffer size and detect if an overflow occurs.
    116 size_t size;
    117 if (!CheckAdd(kHeaderSize, CheckMul(count, kItemSize)).AssignIfValid(&size)) {
    118   // Handle an overflow error...
    119 }
    120 ```
    121 
    122 ### Calculating clamped coordinates (non-sticky saturating arithmetic)
    123 
    124 Certain classes of calculationssuch as coordinate calculationsrequire
    125 well-defined semantics that always produce a valid result on boundary
    126 conditions. The `ClampedNumeric` template addresses this by providing
    127 performant, non-sticky saturating arithmetic operations.
    128 
    129 Here's an example of using a `ClampedNumeric` to calculate an operation
    130 insetting a rectangle.
    131 
    132 ```cpp
    133 // Use clamped arithmetic since inset calculations might overflow.
    134 void Rect::Inset(int left, int top, int right, int bottom) {
    135   origin_ += Vector2d(left, top);
    136   set_width(ClampSub(width(), ClampAdd(left, right)));
    137   set_height(ClampSub(height(), ClampAdd(top, bottom)));
    138 }
    139 ```
    140 
    141 *** note
    142 The `ClampedNumeric` type is not "sticky", which means the saturation is not
    143 retained across individual operations. As such, one arithmetic operation may
    144 result in a saturated value, while the next operation may then "desaturate"
    145 the value. Here's an example:
    146 
    147 ```cpp
    148 ClampedNumeric<int> value = INT_MAX;
    149 ++value;  // value is still INT_MAX, due to saturation.
    150 --value;  // value is now (INT_MAX - 1), because saturation is not sticky.
    151 ```
    152 
    153 ***
    154 
    155 ## Conversion functions and StrictNumeric<> in safe_conversions.h
    156 
    157 This header includes a collection of helper `constexpr` templates for safely
    158 performing a range of conversions, assignments, and tests.
    159 
    160 ### Safe casting templates
    161 
    162 *   `as_signed()` - Returns the supplied integral value as a signed type of
    163     the same width.
    164 *   `as_unsigned()` - Returns the supplied integral value as an unsigned type
    165     of the same width.
    166 *   `checked_cast<>()` - Analogous to `static_cast<>` for numeric types, except
    167     that by default it will trigger a crash on an out-of-bounds conversion (e.g.
    168     overflow, underflow, NaN to integral) or a compile error if the conversion
    169     error can be detected at compile time. The crash handler can be overridden
    170     to perform a behavior other than crashing.
    171 *   `saturated_cast<>()` - Analogous to `static_cast` for numeric types, except
    172     that it returns a saturated result when the specified numeric conversion
    173     would otherwise overflow or underflow. An NaN source returns 0 by
    174     default, but can be overridden to return a different result.
    175 *   `strict_cast<>()` - Analogous to `static_cast` for numeric types, except
    176     this causes a compile failure if the destination type is not large
    177     enough to contain any value in the source type. It performs no runtime
    178     checking and thus introduces no runtime overhead.
    179 
    180 ### Other helper and conversion functions
    181 
    182 *   `IsValueInRangeForNumericType<>()` - A convenience function that returns
    183     true if the type supplied as the template parameter can represent the value
    184     passed as an argument to the function.
    185 *   `IsTypeInRangeForNumericType<>()` - A convenience function that evaluates
    186     entirely at compile-time and returns true if the destination type (first
    187     template parameter) can represent the full range of the source type
    188     (second template parameter).
    189 *   `IsValueNegative()` - A convenience function that will accept any
    190     arithmetic type as an argument and will return whether the value is less
    191     than zero. Unsigned types always return false.
    192 *   `SafeUnsignedAbs()` - Returns the absolute value of the supplied integer
    193     parameter as an unsigned result (thus avoiding an overflow if the value
    194     is the signed, two's complement minimum).
    195 
    196 ### StrictNumeric<>
    197 
    198 `StrictNumeric<>` is a wrapper type that performs assignments and copies via
    199 the `strict_cast` template, and can perform valid arithmetic comparisons
    200 across any range of arithmetic types. `StrictNumeric` is the return type for
    201 values extracted from a `CheckedNumeric` class instance. The raw numeric value
    202 is extracted via `static_cast` to the underlying type or any type with
    203 sufficient range to represent the underlying type.
    204 
    205 *   `MakeStrictNum()` - Creates a new `StrictNumeric` from the underlying type
    206     of the supplied arithmetic or StrictNumeric type.
    207 *   `SizeT` - Alias for `StrictNumeric<size_t>`.
    208 
    209 ## CheckedNumeric<> in checked_math.h
    210 
    211 `CheckedNumeric<>` implements all the logic and operators for detecting integer
    212 boundary conditions such as overflow, underflow, and invalid conversions.
    213 The `CheckedNumeric` type implicitly converts from floating point and integer
    214 data types, and contains overloads for basic arithmetic operations (i.e.: `+`,
    215 `-`, `*`, `/` for all types and `%`, `<<`, `>>`, `&`, `|`, `^` for integers).
    216 However, *the [variadic template functions
    217 ](#CheckedNumeric_in-checked_math_h-Non_member-helper-functions)
    218 are the prefered API,* as they remove type ambiguities and help prevent a number
    219 of common errors. The variadic functions can also be more performant, as they
    220 eliminate redundant expressions that are unavoidable with the with the operator
    221 overloads. (Ideally the compiler should optimize those away, but better to avoid
    222 them in the first place.)
    223 
    224 Type promotions are a slightly modified version of the [standard C/C++ numeric
    225 promotions
    226 ](http://en.cppreference.com/w/cpp/language/implicit_conversion#Numeric_promotions)
    227 with the two differences being that *there is no default promotion to int*
    228 and *bitwise logical operations always return an unsigned of the wider type.*
    229 
    230 ### Members
    231 
    232 The unary negation, increment, and decrement operators are supported, along
    233 with the following unary arithmetic methods, which return a new
    234 `CheckedNumeric` as a result of the operation:
    235 
    236 *   `Abs()` - Absolute value.
    237 *   `UnsignedAbs()` - Absolute value as an equal-width unsigned underlying type
    238     (valid for only integral types).
    239 *   `Max()` - Returns whichever is greater of the current instance or argument.
    240     The underlying return type is whichever has the greatest magnitude.
    241 *   `Min()` - Returns whichever is lowest of the current instance or argument.
    242     The underlying return type is whichever has can represent the lowest
    243     number in the smallest width (e.g. int8_t over unsigned, int over
    244     int8_t, and float over int).
    245 
    246 The following are for converting `CheckedNumeric` instances:
    247 
    248 *   `type` - The underlying numeric type.
    249 *   `AssignIfValid()` - Assigns the underlying value to the supplied
    250     destination pointer if the value is currently valid and within the
    251     range supported by the destination type. Returns true on success.
    252 *   `Cast<>()` - Instance method returning a `CheckedNumeric` derived from
    253     casting the current instance to a `CheckedNumeric` of the supplied
    254     destination type.
    255 
    256 *** aside
    257 The following member functions return a `StrictNumeric`, which is valid for
    258 comparison and assignment operations, but will trigger a compile failure on
    259 attempts to assign to a type of insufficient range. The underlying value can
    260 be extracted by an explicit `static_cast` to the underlying type or any type
    261 with sufficient range to represent the underlying type.
    262 ***
    263 
    264 *   `IsValid()` - Returns true if the underlying numeric value is valid (i.e.
    265     has not wrapped or saturated and is not the result of an invalid
    266     conversion).
    267 *   `ValueOrDie()` - Returns the underlying value. If the state is not valid
    268     this call will trigger a crash by default (but may be overridden by
    269     supplying an alternate handler to the template).
    270 *   `ValueOrDefault()` - Returns the current value, or the supplied default if
    271     the state is not valid (but will not crash).
    272 
    273 **Comparison operators are explicitly not provided** for `CheckedNumeric`
    274 types because they could result in a crash if the type is not in a valid state.
    275 Patterns like the following should be used instead:
    276 
    277 ```cpp
    278 // Either input or padding (or both) may be arbitrary sizes.
    279 size_t buff_size;
    280 if (!CheckAdd(input, padding, kHeaderLength).AssignIfValid(&buff_size) ||
    281      buff_size >= kMaxBuffer) {
    282   // Handle an error...
    283 } else {
    284   // Do stuff on success...
    285 }
    286 ```
    287 
    288 ### Non-member helper functions
    289 
    290 The following variadic convenience functions, which accept standard arithmetic
    291 or `CheckedNumeric` types, perform arithmetic operations, and return a
    292 `CheckedNumeric` result. The supported functions are:
    293 
    294 *   `CheckAdd()` - Addition.
    295 *   `CheckSub()` - Subtraction.
    296 *   `CheckMul()` - Multiplication.
    297 *   `CheckDiv()` - Division.
    298 *   `CheckMod()` - Modulus (integer only).
    299 *   `CheckLsh()` - Left integer shift (integer only).
    300 *   `CheckRsh()` - Right integer shift (integer only).
    301 *   `CheckAnd()` - Bitwise AND (integer only with unsigned result).
    302 *   `CheckOr()`  - Bitwise OR (integer only with unsigned result).
    303 *   `CheckXor()` - Bitwise XOR (integer only with unsigned result).
    304 *   `CheckMax()` - Maximum of supplied arguments.
    305 *   `CheckMin()` - Minimum of supplied arguments.
    306 
    307 The following wrapper functions can be used to avoid the template
    308 disambiguator syntax when converting a destination type.
    309 
    310 *   `IsValidForType<>()` in place of: `a.template IsValid<>()`
    311 *   `ValueOrDieForType<>()` in place of: `a.template ValueOrDie<>()`
    312 *   `ValueOrDefaultForType<>()` in place of: `a.template ValueOrDefault<>()`
    313 
    314 The following general utility methods is are useful for converting from
    315 arithmetic types to `CheckedNumeric` types:
    316 
    317 *   `MakeCheckedNum()` - Creates a new `CheckedNumeric` from the underlying type
    318     of the supplied arithmetic or directly convertible type.
    319 
    320 ## ClampedNumeric<> in clamped_math.h
    321 
    322 `ClampedNumeric<>` implements all the logic and operators for clamped
    323 (non-sticky saturating) arithmetic operations and conversions. The
    324 `ClampedNumeric` type implicitly converts back and forth between floating point
    325 and integer data types, saturating on assignment as appropriate. It contains
    326 overloads for basic arithmetic operations (i.e.: `+`, `-`, `*`, `/` for
    327 all types and `%`, `<<`, `>>`, `&`, `|`, `^` for integers) along with comparison
    328 operators for arithmetic types of any size. However, *the [variadic template
    329 functions
    330 ](#ClampedNumeric_in-clamped_math_h-Non_member-helper-functions)
    331 are the prefered API,* as they remove type ambiguities and help prevent
    332 a number of common errors. The variadic functions can also be more performant,
    333 as they eliminate redundant expressions that are unavoidable with the operator
    334 overloads. (Ideally the compiler should optimize those away, but better to avoid
    335 them in the first place.)
    336 
    337 Type promotions are a slightly modified version of the [standard C/C++ numeric
    338 promotions
    339 ](http://en.cppreference.com/w/cpp/language/implicit_conversion#Numeric_promotions)
    340 with the two differences being that *there is no default promotion to int*
    341 and *bitwise logical operations always return an unsigned of the wider type.*
    342 
    343 *** aside
    344 Most arithmetic operations saturate normally, to the numeric limit in the
    345 direction of the sign. The potentially unusual cases are:
    346 
    347 *   **Division:** Division by zero returns the saturated limit in the direction
    348     of sign of the dividend (first argument). The one exception is 0/0, which
    349 	returns zero (although logically is NaN).
    350 *   **Modulus:** Division by zero returns the dividend (first argument).
    351 *   **Left shift:** Non-zero values saturate in the direction of the signed
    352     limit (max/min), even for shifts larger than the bit width. 0 shifted any
    353     amount results in 0.
    354 *   **Right shift:** Negative values saturate to -1. Positive or 0 saturates
    355     to 0. (Effectively just an unbounded arithmetic-right-shift.)
    356 *   **Bitwise operations:** No saturation; bit pattern is identical to
    357     non-saturated bitwise operations.
    358 ***
    359 
    360 ### Members
    361 
    362 The unary negation, increment, and decrement operators are supported, along
    363 with the following unary arithmetic methods, which return a new
    364 `ClampedNumeric` as a result of the operation:
    365 
    366 *   `Abs()` - Absolute value.
    367 *   `UnsignedAbs()` - Absolute value as an equal-width unsigned underlying type
    368     (valid for only integral types).
    369 *   `Max()` - Returns whichever is greater of the current instance or argument.
    370     The underlying return type is whichever has the greatest magnitude.
    371 *   `Min()` - Returns whichever is lowest of the current instance or argument.
    372     The underlying return type is whichever has can represent the lowest
    373     number in the smallest width (e.g. int8_t over unsigned, int over
    374     int8_t, and float over int).
    375 
    376 The following are for converting `ClampedNumeric` instances:
    377 
    378 *   `type` - The underlying numeric type.
    379 *   `RawValue()` - Returns the raw value as the underlying arithmetic type. This
    380     is useful when e.g. assigning to an auto type or passing as a deduced
    381     template parameter.
    382 *   `Cast<>()` - Instance method returning a `ClampedNumeric` derived from
    383     casting the current instance to a `ClampedNumeric` of the supplied
    384     destination type.
    385 
    386 ### Non-member helper functions
    387 
    388 The following variadic convenience functions, which accept standard arithmetic
    389 or `ClampedNumeric` types, perform arithmetic operations, and return a
    390 `ClampedNumeric` result. The supported functions are:
    391 
    392 *   `ClampAdd()` - Addition.
    393 *   `ClampSub()` - Subtraction.
    394 *   `ClampMul()` - Multiplication.
    395 *   `ClampDiv()` - Division.
    396 *   `ClampMod()` - Modulus (integer only).
    397 *   `ClampLsh()` - Left integer shift (integer only).
    398 *   `ClampRsh()` - Right integer shift (integer only).
    399 *   `ClampAnd()` - Bitwise AND (integer only with unsigned result).
    400 *   `ClampOr()`  - Bitwise OR (integer only with unsigned result).
    401 *   `ClampXor()` - Bitwise XOR (integer only with unsigned result).
    402 *   `ClampMax()` - Maximum of supplied arguments.
    403 *   `ClampMin()` - Minimum of supplied arguments.
    404 
    405 The following is a general utility method that is useful for converting
    406 to a `ClampedNumeric` type:
    407 
    408 *   `MakeClampedNum()` - Creates a new `ClampedNumeric` from the underlying type
    409     of the supplied arithmetic or directly convertible type.
    410