Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: base/numerics/README.md

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

Powered by Google App Engine
This is Rietveld 408576698