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

Side by Side Diff: base/numerics/safe_math.h

Issue 2502083002: Restructure ArithmeticPromotion to support alternate promotions (Closed)
Patch Set: nit Created 4 years, 1 month 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
« no previous file with comments | « no previous file | base/numerics/safe_math_impl.h » ('j') | base/numerics/safe_math_impl.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_NUMERICS_SAFE_MATH_H_ 5 #ifndef BASE_NUMERICS_SAFE_MATH_H_
6 #define BASE_NUMERICS_SAFE_MATH_H_ 6 #define BASE_NUMERICS_SAFE_MATH_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <limits> 10 #include <limits>
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 CheckedNumericState<T> state_; 188 CheckedNumericState<T> state_;
189 }; 189 };
190 190
191 // This is the boilerplate for the standard arithmetic operator overloads. A 191 // This is the boilerplate for the standard arithmetic operator overloads. A
192 // macro isn't the prettiest solution, but it beats rewriting these five times. 192 // macro isn't the prettiest solution, but it beats rewriting these five times.
193 // Some details worth noting are: 193 // Some details worth noting are:
194 // * We apply the standard arithmetic promotions. 194 // * We apply the standard arithmetic promotions.
195 // * We skip range checks for floating points. 195 // * We skip range checks for floating points.
196 // * We skip range checks for destination integers with sufficient range. 196 // * We skip range checks for destination integers with sufficient range.
197 // TODO(jschuh): extract these out into templates. 197 // TODO(jschuh): extract these out into templates.
198 #define BASE_NUMERIC_ARITHMETIC_OPERATORS(NAME, OP, COMPOUND_OP) \ 198 #define BASE_NUMERIC_ARITHMETIC_OPERATORS(NAME, OP, COMPOUND_OP, PROMOTION) \
199 /* Binary arithmetic operator for CheckedNumerics of the same type. */ \ 199 /* Binary arithmetic operator for CheckedNumerics of the same type. */ \
200 template <typename L, typename R> \ 200 template <typename L, typename R> \
201 CheckedNumeric<typename ArithmeticPromotion<L, R>::type> operator OP( \ 201 CheckedNumeric<typename ArithmeticPromotion<PROMOTION, L, R>::type> \
202 const CheckedNumeric<L>& lhs, const CheckedNumeric<R>& rhs) { \ 202 operator OP(const CheckedNumeric<L>& lhs, const CheckedNumeric<R>& rhs) { \
203 using P = typename ArithmeticPromotion<L, R>::type; \ 203 using P = typename ArithmeticPromotion<PROMOTION, L, R>::type; \
204 if (!rhs.IsValid() || !lhs.IsValid()) \ 204 if (!rhs.IsValid() || !lhs.IsValid()) \
205 return CheckedNumeric<P>(0, false); \ 205 return CheckedNumeric<P>(0, false); \
206 /* Floating point always takes the fast path */ \ 206 /* Floating point always takes the fast path */ \
207 if (std::is_floating_point<L>::value || std::is_floating_point<R>::value) \ 207 if (std::is_floating_point<L>::value || std::is_floating_point<R>::value) \
208 return CheckedNumeric<P>(lhs.ValueUnsafe() OP rhs.ValueUnsafe()); \ 208 return CheckedNumeric<P>(lhs.ValueUnsafe() OP rhs.ValueUnsafe()); \
209 P result = 0; \ 209 P result = 0; \
210 bool is_valid = \ 210 bool is_valid = \
211 Checked##NAME(lhs.ValueUnsafe(), rhs.ValueUnsafe(), &result); \ 211 Checked##NAME(lhs.ValueUnsafe(), rhs.ValueUnsafe(), &result); \
212 return CheckedNumeric<P>(result, is_valid); \ 212 return CheckedNumeric<P>(result, is_valid); \
213 } \ 213 } \
214 /* Assignment arithmetic operator implementation from CheckedNumeric. */ \ 214 /* Assignment arithmetic operator implementation from CheckedNumeric. */ \
215 template <typename L> \ 215 template <typename L> \
216 template <typename R> \ 216 template <typename R> \
217 CheckedNumeric<L>& CheckedNumeric<L>::operator COMPOUND_OP(R rhs) { \ 217 CheckedNumeric<L>& CheckedNumeric<L>::operator COMPOUND_OP(R rhs) { \
218 *this = *this OP rhs; \ 218 *this = *this OP rhs; \
219 return *this; \ 219 return *this; \
220 } \ 220 } \
221 /* Binary arithmetic operator for left CheckedNumeric and right numeric. */ \ 221 /* Binary arithmetic operator for left CheckedNumeric and right numeric. */ \
222 template <typename L, typename R, \ 222 template <typename L, typename R, \
223 typename std::enable_if<std::is_arithmetic<R>::value>::type* = \ 223 typename std::enable_if<std::is_arithmetic<R>::value>::type* = \
224 nullptr> \ 224 nullptr> \
225 CheckedNumeric<typename ArithmeticPromotion<L, R>::type> operator OP( \ 225 CheckedNumeric<typename ArithmeticPromotion<PROMOTION, L, R>::type> \
226 const CheckedNumeric<L>& lhs, R rhs) { \ 226 operator OP(const CheckedNumeric<L>& lhs, R rhs) { \
227 return lhs OP CheckedNumeric<R>(rhs); \ 227 return lhs OP CheckedNumeric<R>(rhs); \
228 } \ 228 } \
229 /* Binary arithmetic operator for left numeric and right CheckedNumeric. */ \ 229 /* Binary arithmetic operator for left numeric and right CheckedNumeric. */ \
230 template <typename L, typename R, \ 230 template <typename L, typename R, \
231 typename std::enable_if<std::is_arithmetic<L>::value>::type* = \ 231 typename std::enable_if<std::is_arithmetic<L>::value>::type* = \
232 nullptr> \ 232 nullptr> \
233 CheckedNumeric<typename ArithmeticPromotion<L, R>::type> operator OP( \ 233 CheckedNumeric<typename ArithmeticPromotion<PROMOTION, L, R>::type> \
234 L lhs, const CheckedNumeric<R>& rhs) { \ 234 operator OP(L lhs, const CheckedNumeric<R>& rhs) { \
235 return CheckedNumeric<L>(lhs) OP rhs; \ 235 return CheckedNumeric<L>(lhs) OP rhs; \
236 } 236 }
237 237
238 BASE_NUMERIC_ARITHMETIC_OPERATORS(Add, +, += ) 238 BASE_NUMERIC_ARITHMETIC_OPERATORS(Add, +, +=, MAX_EXPONENT_PROMOTION)
239 BASE_NUMERIC_ARITHMETIC_OPERATORS(Sub, -, -= ) 239 BASE_NUMERIC_ARITHMETIC_OPERATORS(Sub, -, -=, MAX_EXPONENT_PROMOTION)
240 BASE_NUMERIC_ARITHMETIC_OPERATORS(Mul, *, *= ) 240 BASE_NUMERIC_ARITHMETIC_OPERATORS(Mul, *, *=, MAX_EXPONENT_PROMOTION)
Tom Sepez 2016/11/15 22:31:17 Shouldn't multiplicaton be BIG_ENOUGH_PROMOTION?
jschuh 2016/11/15 22:38:49 It is, but in the intermediate representation for
241 BASE_NUMERIC_ARITHMETIC_OPERATORS(Div, /, /= ) 241 BASE_NUMERIC_ARITHMETIC_OPERATORS(Div, /, /=, MAX_EXPONENT_PROMOTION)
242 BASE_NUMERIC_ARITHMETIC_OPERATORS(Mod, %, %= ) 242 BASE_NUMERIC_ARITHMETIC_OPERATORS(Mod, %, %=, MAX_EXPONENT_PROMOTION)
243 243
244 #undef BASE_NUMERIC_ARITHMETIC_OPERATORS 244 #undef BASE_NUMERIC_ARITHMETIC_OPERATORS
245 245
246 } // namespace internal 246 } // namespace internal
247 247
248 using internal::CheckedNumeric; 248 using internal::CheckedNumeric;
249 249
250 } // namespace base 250 } // namespace base
251 251
252 #endif // BASE_NUMERICS_SAFE_MATH_H_ 252 #endif // BASE_NUMERICS_SAFE_MATH_H_
OLDNEW
« no previous file with comments | « no previous file | base/numerics/safe_math_impl.h » ('j') | base/numerics/safe_math_impl.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698