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

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

Issue 2529413002: Loosen restrictions on CheckedNumeric bitwise operators (Closed)
Patch Set: more tests Created 4 years 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 | « base/numerics/safe_math.h ('k') | base/numerics/safe_numerics_unittest.cc » ('j') | no next file with comments »
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_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
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;
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
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_
OLDNEW
« no previous file with comments | « base/numerics/safe_math.h ('k') | base/numerics/safe_numerics_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698