| 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 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 793 }; | 793 }; |
| 794 | 794 |
| 795 template <typename T, NumericRepresentation type = | 795 template <typename T, NumericRepresentation type = |
| 796 GetNumericRepresentation<T>::value> | 796 GetNumericRepresentation<T>::value> |
| 797 class CheckedNumericState {}; | 797 class CheckedNumericState {}; |
| 798 | 798 |
| 799 // Integrals require quite a bit of additional housekeeping to manage state. | 799 // Integrals require quite a bit of additional housekeeping to manage state. |
| 800 template <typename T> | 800 template <typename T> |
| 801 class CheckedNumericState<T, NUMERIC_INTEGER> { | 801 class CheckedNumericState<T, NUMERIC_INTEGER> { |
| 802 private: | 802 private: |
| 803 // is_valid_ precedes value_ because member intializers in the constructors |
| 804 // are evaluated in field order, and is_valid_ must be read when initializing |
| 805 // value_. |
| 806 bool is_valid_; |
| 803 T value_; | 807 T value_; |
| 804 bool is_valid_; | |
| 805 | 808 |
| 806 public: | 809 public: |
| 807 template <typename Src, NumericRepresentation type> | 810 template <typename Src, NumericRepresentation type> |
| 808 friend class CheckedNumericState; | 811 friend class CheckedNumericState; |
| 809 | 812 |
| 810 constexpr CheckedNumericState() : value_(0), is_valid_(true) {} | 813 constexpr CheckedNumericState() : is_valid_(true), value_(0) {} |
| 811 | 814 |
| 812 template <typename Src> | 815 template <typename Src> |
| 813 constexpr CheckedNumericState(Src value, bool is_valid) | 816 constexpr CheckedNumericState(Src value, bool is_valid) |
| 814 : value_(static_cast<T>(value)), | 817 : is_valid_(is_valid && IsValueInRangeForNumericType<T>(value)), |
| 815 is_valid_(is_valid && IsValueInRangeForNumericType<T>(value)) { | 818 value_(is_valid_ ? static_cast<T>(value) : 0) { |
| 816 static_assert(std::numeric_limits<Src>::is_specialized, | 819 static_assert(std::numeric_limits<Src>::is_specialized, |
| 817 "Argument must be numeric."); | 820 "Argument must be numeric."); |
| 818 } | 821 } |
| 819 | 822 |
| 820 // Copy constructor. | 823 // Copy constructor. |
| 821 template <typename Src> | 824 template <typename Src> |
| 822 constexpr CheckedNumericState(const CheckedNumericState<Src>& rhs) | 825 constexpr CheckedNumericState(const CheckedNumericState<Src>& rhs) |
| 823 : value_(static_cast<T>(rhs.value())), is_valid_(rhs.IsValid()) {} | 826 : is_valid_(rhs.IsValid()), |
| 827 value_(is_valid_ ? static_cast<T>(rhs.value()) : 0) {} |
| 824 | 828 |
| 825 template <typename Src> | 829 template <typename Src> |
| 826 constexpr explicit CheckedNumericState( | 830 constexpr explicit CheckedNumericState( |
| 827 Src value, | 831 Src value, |
| 828 typename std::enable_if<std::numeric_limits<Src>::is_specialized, | 832 typename std::enable_if<std::numeric_limits<Src>::is_specialized, |
| 829 int>::type = 0) | 833 int>::type = 0) |
| 830 : value_(static_cast<T>(value)), | 834 : is_valid_(IsValueInRangeForNumericType<T>(value)), |
| 831 is_valid_(IsValueInRangeForNumericType<T>(value)) {} | 835 value_(is_valid_ ? static_cast<T>(value) : 0) {} |
| 832 | 836 |
| 833 constexpr bool is_valid() const { return is_valid_; } | 837 constexpr bool is_valid() const { return is_valid_; } |
| 834 constexpr T value() const { return value_; } | 838 constexpr T value() const { return value_; } |
| 835 }; | 839 }; |
| 836 | 840 |
| 837 // Floating points maintain their own validity, but need translation wrappers. | 841 // Floating points maintain their own validity, but need translation wrappers. |
| 838 template <typename T> | 842 template <typename T> |
| 839 class CheckedNumericState<T, NUMERIC_FLOATING> { | 843 class CheckedNumericState<T, NUMERIC_FLOATING> { |
| 840 private: | 844 private: |
| 841 T value_; | 845 T value_; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 using math = M<typename UnderlyingType<L>::type, | 909 using math = M<typename UnderlyingType<L>::type, |
| 906 typename UnderlyingType<R>::type, | 910 typename UnderlyingType<R>::type, |
| 907 void>; | 911 void>; |
| 908 using type = typename math::result_type; | 912 using type = typename math::result_type; |
| 909 }; | 913 }; |
| 910 | 914 |
| 911 } // namespace internal | 915 } // namespace internal |
| 912 } // namespace base | 916 } // namespace base |
| 913 | 917 |
| 914 #endif // BASE_NUMERICS_SAFE_MATH_IMPL_H_ | 918 #endif // BASE_NUMERICS_SAFE_MATH_IMPL_H_ |
| OLD | NEW |