Chromium Code Reviews| 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 <stddef.h> | 8 #include <stddef.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 | 10 |
| (...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 595 *result = static_cast<V>(tmp); | 595 *result = static_cast<V>(tmp); |
| 596 return IsValueInRangeForNumericType<V>(tmp); | 596 return IsValueInRangeForNumericType<V>(tmp); |
| 597 } | 597 } |
| 598 return false; | 598 return false; |
| 599 } | 599 } |
| 600 }; | 600 }; |
| 601 | 601 |
| 602 template <typename T, typename U, class Enable = void> | 602 template <typename T, typename U, class Enable = void> |
| 603 struct CheckedAndOp {}; | 603 struct CheckedAndOp {}; |
| 604 | 604 |
| 605 // For simplicity we support only unsigned integers. | 605 // For simplicity we support only unsigned integer results. |
| 606 template <typename T, typename U> | 606 template <typename T, typename U> |
| 607 struct CheckedAndOp<T, | 607 struct CheckedAndOp<T, |
| 608 U, | 608 U, |
| 609 typename std::enable_if<std::is_integral<T>::value && | 609 typename std::enable_if<std::is_integral<T>::value && |
| 610 std::is_integral<U>::value && | 610 std::is_integral<U>::value>::type> { |
| 611 !std::is_signed<T>::value && | 611 using result_type = typename UnsignedIntegerForSize< |
| 612 !std::is_signed<U>::value>::type> { | 612 typename ArithmeticPromotion<MAX_EXPONENT_PROMOTION, T, U>::type>::type; |
|
scottmg
2016/11/28 16:37:14
Sorry, I don't understand how this works. Can you
jschuh
2016/11/28 17:54:31
It will accept -1 because signed to unsigned conve
| |
| 613 using result_type = | |
| 614 typename ArithmeticPromotion<MAX_EXPONENT_PROMOTION, T, U>::type; | |
| 615 template <typename V = result_type> | 613 template <typename V = result_type> |
| 616 static bool Do(T x, U y, V* result) { | 614 static bool Do(T x, U y, V* result) { |
| 617 result_type tmp = x & y; | 615 result_type tmp = static_cast<result_type>(x) & static_cast<result_type>(y); |
| 618 *result = static_cast<V>(tmp); | 616 *result = static_cast<V>(tmp); |
| 619 return IsValueInRangeForNumericType<V>(tmp); | 617 return IsValueInRangeForNumericType<V>(tmp); |
| 620 } | 618 } |
| 621 }; | 619 }; |
| 622 | 620 |
| 623 template <typename T, typename U, class Enable = void> | 621 template <typename T, typename U, class Enable = void> |
| 624 struct CheckedOrOp {}; | 622 struct CheckedOrOp {}; |
| 625 | 623 |
| 626 // For simplicity we support only unsigned integers. | 624 // For simplicity we support only unsigned integers. |
| 627 template <typename T, typename U> | 625 template <typename T, typename U> |
| 628 struct CheckedOrOp<T, | 626 struct CheckedOrOp<T, |
| 629 U, | 627 U, |
| 630 typename std::enable_if<std::is_integral<T>::value && | 628 typename std::enable_if<std::is_integral<T>::value && |
| 631 std::is_integral<U>::value && | 629 std::is_integral<U>::value>::type> { |
| 632 !std::is_signed<T>::value && | 630 using result_type = typename UnsignedIntegerForSize< |
| 633 !std::is_signed<U>::value>::type> { | 631 typename ArithmeticPromotion<MAX_EXPONENT_PROMOTION, T, U>::type>::type; |
| 634 using result_type = | |
| 635 typename ArithmeticPromotion<MAX_EXPONENT_PROMOTION, T, U>::type; | |
| 636 template <typename V = result_type> | 632 template <typename V = result_type> |
| 637 static bool Do(T x, U y, V* result) { | 633 static bool Do(T x, U y, V* result) { |
| 638 result_type tmp = x | y; | 634 result_type tmp = static_cast<result_type>(x) | static_cast<result_type>(y); |
| 639 *result = static_cast<V>(tmp); | 635 *result = static_cast<V>(tmp); |
| 640 return IsValueInRangeForNumericType<V>(tmp); | 636 return IsValueInRangeForNumericType<V>(tmp); |
| 641 } | 637 } |
| 642 }; | 638 }; |
| 643 | 639 |
| 644 template <typename T, typename U, class Enable = void> | 640 template <typename T, typename U, class Enable = void> |
| 645 struct CheckedXorOp {}; | 641 struct CheckedXorOp {}; |
| 646 | 642 |
| 647 // For simplicity we support only unsigned integers. | 643 // For simplicity we support only unsigned integers. |
| 648 template <typename T, typename U> | 644 template <typename T, typename U> |
| 649 struct CheckedXorOp<T, | 645 struct CheckedXorOp<T, |
| 650 U, | 646 U, |
| 651 typename std::enable_if<std::is_integral<T>::value && | 647 typename std::enable_if<std::is_integral<T>::value && |
| 652 std::is_integral<U>::value && | 648 std::is_integral<U>::value>::type> { |
| 653 !std::is_signed<T>::value && | 649 using result_type = typename UnsignedIntegerForSize< |
| 654 !std::is_signed<U>::value>::type> { | 650 typename ArithmeticPromotion<MAX_EXPONENT_PROMOTION, T, U>::type>::type; |
| 655 using result_type = | |
| 656 typename ArithmeticPromotion<MAX_EXPONENT_PROMOTION, T, U>::type; | |
| 657 template <typename V = result_type> | 651 template <typename V = result_type> |
| 658 static bool Do(T x, U y, V* result) { | 652 static bool Do(T x, U y, V* result) { |
| 659 result_type tmp = x ^ y; | 653 result_type tmp = static_cast<result_type>(x) ^ static_cast<result_type>(y); |
| 660 *result = static_cast<V>(tmp); | 654 *result = static_cast<V>(tmp); |
| 661 return IsValueInRangeForNumericType<V>(tmp); | 655 return IsValueInRangeForNumericType<V>(tmp); |
| 662 } | 656 } |
| 663 }; | 657 }; |
| 664 | 658 |
| 665 template <typename T> | 659 template <typename T> |
| 666 typename std::enable_if<std::numeric_limits<T>::is_integer && | 660 typename std::enable_if<std::numeric_limits<T>::is_integer && |
| 667 std::numeric_limits<T>::is_signed, | 661 std::numeric_limits<T>::is_signed, |
| 668 bool>::type | 662 bool>::type |
| 669 CheckedNeg(T value, T* result) { | 663 CheckedNeg(T value, T* result) { |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 911 using math = M<typename UnderlyingType<L>::type, | 905 using math = M<typename UnderlyingType<L>::type, |
| 912 typename UnderlyingType<R>::type, | 906 typename UnderlyingType<R>::type, |
| 913 void>; | 907 void>; |
| 914 using type = typename math::result_type; | 908 using type = typename math::result_type; |
| 915 }; | 909 }; |
| 916 | 910 |
| 917 } // namespace internal | 911 } // namespace internal |
| 918 } // namespace base | 912 } // namespace base |
| 919 | 913 |
| 920 #endif // BASE_NUMERICS_SAFE_MATH_IMPL_H_ | 914 #endif // BASE_NUMERICS_SAFE_MATH_IMPL_H_ |
| OLD | NEW |