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