Chromium Code Reviews| Index: base/numerics/safe_math_impl.h |
| diff --git a/base/numerics/safe_math_impl.h b/base/numerics/safe_math_impl.h |
| index 08f2e88345f34d62870dcf16c569b126304f06f6..6c8dd836a4047249d25c5d51955e040a8ad800b7 100644 |
| --- a/base/numerics/safe_math_impl.h |
| +++ b/base/numerics/safe_math_impl.h |
| @@ -90,6 +90,25 @@ struct PositionOfSignBit { |
| size_t>::type value = 8 * sizeof(Integer) - 1; |
| }; |
| +// This is used for UnsignedAbs, where we need to support floating-point |
| +// template instantiations even though we don't actually support the operations. |
| +// However, there is no corresponding implementation of e.g. CheckedUnsignedAbs, |
| +// so the float versions will not compile. |
| +template <typename Numeric, |
| + bool IsInteger = std::numeric_limits<Numeric>::is_integer, |
| + bool IsFloat = std::numeric_limits<Numeric>::is_iec559> |
| +struct UnsignedOrFloatForSize; |
| + |
| +template <typename Numeric> |
| +struct UnsignedOrFloatForSize<Numeric, true, false> { |
| + typedef typename UnsignedIntegerForSize<Numeric>::type type; |
| +}; |
| + |
| +template <typename Numeric> |
| +struct UnsignedOrFloatForSize<Numeric, false, true> { |
| + typedef typename Numeric type; |
| +}; |
| + |
| // Helper templates for integer manipulations. |
| template <typename T> |
| @@ -289,6 +308,26 @@ CheckedAbs(T value, RangeConstraint* validity) { |
| return value; |
| } |
| +template <typename T> |
| +typename enable_if<std::numeric_limits<T>::is_integer && |
| + std::numeric_limits<T>::is_signed, |
| + typename UnsignedIntegerForSize<T>::type>::type |
| +CheckedUnsignedAbs(T value) { |
| + typedef typename UnsignedIntegerForSize<T>::type UnsignedT; |
| + return value == std::numeric_limits<T>::min() |
| + ? static_cast<UnsignedT>(std::numeric_limits<T>::max()) + 1 |
| + : static_cast<UnsignedT>(std::abs(value)); |
| +} |
| + |
| +template <typename T> |
| +typename enable_if<std::numeric_limits<T>::is_integer && |
| + !std::numeric_limits<T>::is_signed, |
| + T>::type |
| +CheckedUnsignedAbs(T value) { |
| + // Absolute value of a positive is just its identiy. |
|
Jeffrey Yasskin
2015/09/15 23:58:25
"T is unsigned, so |value| must already be positiv
|
| + return value; |
| +} |
| + |
| // These are the floating point stubs that the compiler needs to see. Only the |
| // negation operation is ever called. |
| #define BASE_FLOAT_ARITHMETIC_STUBS(NAME) \ |