| OLD | NEW |
| 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_IMPL_H_ | 5 #ifndef BASE_NUMERICS_SAFE_MATH_IMPL_H_ |
| 6 #define BASE_NUMERICS_SAFE_MATH_IMPL_H_ | 6 #define BASE_NUMERICS_SAFE_MATH_IMPL_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <cmath> | 10 #include <cmath> |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 sizeof(Integer) * 2, | 83 sizeof(Integer) * 2, |
| 84 std::numeric_limits<Integer>::is_signed>::type>::type type; | 84 std::numeric_limits<Integer>::is_signed>::type>::type type; |
| 85 }; | 85 }; |
| 86 | 86 |
| 87 template <typename Integer> | 87 template <typename Integer> |
| 88 struct PositionOfSignBit { | 88 struct PositionOfSignBit { |
| 89 static const typename enable_if<std::numeric_limits<Integer>::is_integer, | 89 static const typename enable_if<std::numeric_limits<Integer>::is_integer, |
| 90 size_t>::type value = 8 * sizeof(Integer) - 1; | 90 size_t>::type value = 8 * sizeof(Integer) - 1; |
| 91 }; | 91 }; |
| 92 | 92 |
| 93 // This is used for UnsignedAbs, where we need to support floating-point |
| 94 // template instantiations even though we don't actually support the operations. |
| 95 // However, there is no corresponding implementation of e.g. CheckedUnsignedAbs, |
| 96 // so the float versions will not compile. |
| 97 template <typename Numeric, |
| 98 bool IsInteger = std::numeric_limits<Numeric>::is_integer, |
| 99 bool IsFloat = std::numeric_limits<Numeric>::is_iec559> |
| 100 struct UnsignedOrFloatForSize; |
| 101 |
| 102 template <typename Numeric> |
| 103 struct UnsignedOrFloatForSize<Numeric, true, false> { |
| 104 typedef typename UnsignedIntegerForSize<Numeric>::type type; |
| 105 }; |
| 106 |
| 107 template <typename Numeric> |
| 108 struct UnsignedOrFloatForSize<Numeric, false, true> { |
| 109 typedef Numeric type; |
| 110 }; |
| 111 |
| 93 // Helper templates for integer manipulations. | 112 // Helper templates for integer manipulations. |
| 94 | 113 |
| 95 template <typename T> | 114 template <typename T> |
| 96 bool HasSignBit(T x) { | 115 bool HasSignBit(T x) { |
| 97 // Cast to unsigned since right shift on signed is undefined. | 116 // Cast to unsigned since right shift on signed is undefined. |
| 98 return !!(static_cast<typename UnsignedIntegerForSize<T>::type>(x) >> | 117 return !!(static_cast<typename UnsignedIntegerForSize<T>::type>(x) >> |
| 99 PositionOfSignBit<T>::value); | 118 PositionOfSignBit<T>::value); |
| 100 } | 119 } |
| 101 | 120 |
| 102 // This wrapper undoes the standard integer promotions. | 121 // This wrapper undoes the standard integer promotions. |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 *validity = | 296 *validity = |
| 278 value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW; | 297 value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW; |
| 279 return static_cast<T>(std::abs(value)); | 298 return static_cast<T>(std::abs(value)); |
| 280 } | 299 } |
| 281 | 300 |
| 282 template <typename T> | 301 template <typename T> |
| 283 typename enable_if< | 302 typename enable_if< |
| 284 std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed, | 303 std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed, |
| 285 T>::type | 304 T>::type |
| 286 CheckedAbs(T value, RangeConstraint* validity) { | 305 CheckedAbs(T value, RangeConstraint* validity) { |
| 287 // Absolute value of a positive is just its identiy. | 306 // T is unsigned, so |value| must already be positive. |
| 288 *validity = RANGE_VALID; | 307 *validity = RANGE_VALID; |
| 289 return value; | 308 return value; |
| 290 } | 309 } |
| 291 | 310 |
| 311 template <typename T> |
| 312 typename enable_if<std::numeric_limits<T>::is_integer && |
| 313 std::numeric_limits<T>::is_signed, |
| 314 typename UnsignedIntegerForSize<T>::type>::type |
| 315 CheckedUnsignedAbs(T value) { |
| 316 typedef typename UnsignedIntegerForSize<T>::type UnsignedT; |
| 317 return value == std::numeric_limits<T>::min() |
| 318 ? static_cast<UnsignedT>(std::numeric_limits<T>::max()) + 1 |
| 319 : static_cast<UnsignedT>(std::abs(value)); |
| 320 } |
| 321 |
| 322 template <typename T> |
| 323 typename enable_if<std::numeric_limits<T>::is_integer && |
| 324 !std::numeric_limits<T>::is_signed, |
| 325 T>::type |
| 326 CheckedUnsignedAbs(T value) { |
| 327 // T is unsigned, so |value| must already be positive. |
| 328 return value; |
| 329 } |
| 330 |
| 292 // These are the floating point stubs that the compiler needs to see. Only the | 331 // These are the floating point stubs that the compiler needs to see. Only the |
| 293 // negation operation is ever called. | 332 // negation operation is ever called. |
| 294 #define BASE_FLOAT_ARITHMETIC_STUBS(NAME) \ | 333 #define BASE_FLOAT_ARITHMETIC_STUBS(NAME) \ |
| 295 template <typename T> \ | 334 template <typename T> \ |
| 296 typename enable_if<std::numeric_limits<T>::is_iec559, T>::type \ | 335 typename enable_if<std::numeric_limits<T>::is_iec559, T>::type \ |
| 297 Checked##NAME(T, T, RangeConstraint*) { \ | 336 Checked##NAME(T, T, RangeConstraint*) { \ |
| 298 NOTREACHED(); \ | 337 NOTREACHED(); \ |
| 299 return 0; \ | 338 return 0; \ |
| 300 } | 339 } |
| 301 | 340 |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 sizeof(T) >= (2 * sizeof(Lhs)) && | 531 sizeof(T) >= (2 * sizeof(Lhs)) && |
| 493 StaticDstRangeRelationToSrcRange<T, Rhs>::value != | 532 StaticDstRangeRelationToSrcRange<T, Rhs>::value != |
| 494 NUMERIC_RANGE_CONTAINED && | 533 NUMERIC_RANGE_CONTAINED && |
| 495 sizeof(T) >= (2 * sizeof(Rhs)); | 534 sizeof(T) >= (2 * sizeof(Rhs)); |
| 496 }; | 535 }; |
| 497 | 536 |
| 498 } // namespace internal | 537 } // namespace internal |
| 499 } // namespace base | 538 } // namespace base |
| 500 | 539 |
| 501 #endif // BASE_NUMERICS_SAFE_MATH_IMPL_H_ | 540 #endif // BASE_NUMERICS_SAFE_MATH_IMPL_H_ |
| OLD | NEW |