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 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 bool is_valid_; | |
| 803 T value_; | 804 T value_; |
| 804 bool is_valid_; | |
| 805 | 805 |
| 806 public: | 806 public: |
| 807 template <typename Src, NumericRepresentation type> | 807 template <typename Src, NumericRepresentation type> |
| 808 friend class CheckedNumericState; | 808 friend class CheckedNumericState; |
| 809 | 809 |
| 810 constexpr CheckedNumericState() : value_(0), is_valid_(true) {} | 810 constexpr CheckedNumericState() : is_valid_(true), value_(0) {} |
| 811 | 811 |
| 812 template <typename Src> | 812 template <typename Src> |
| 813 constexpr CheckedNumericState(Src value, bool is_valid) | 813 constexpr CheckedNumericState(Src value, bool is_valid) |
| 814 : value_(static_cast<T>(value)), | 814 : is_valid_(is_valid && IsValueInRangeForNumericType<T>(value)), |
| 815 is_valid_(is_valid && IsValueInRangeForNumericType<T>(value)) { | 815 value_(is_valid_ ? static_cast<T>(value) : 0) { |
| 816 static_assert(std::numeric_limits<Src>::is_specialized, | 816 static_assert(std::numeric_limits<Src>::is_specialized, |
| 817 "Argument must be numeric."); | 817 "Argument must be numeric."); |
| 818 } | 818 } |
| 819 | 819 |
| 820 // Copy constructor. | 820 // Copy constructor. |
| 821 template <typename Src> | 821 template <typename Src> |
| 822 constexpr CheckedNumericState(const CheckedNumericState<Src>& rhs) | 822 constexpr CheckedNumericState(const CheckedNumericState<Src>& rhs) |
| 823 : value_(static_cast<T>(rhs.value())), is_valid_(rhs.IsValid()) {} | 823 : is_valid_(rhs.IsValid()), value_(static_cast<T>(rhs.value())) {} |
|
Nico
2016/12/02 16:46:10
This one probably needs this check too, still veri
jschuh
2016/12/02 17:19:15
Agreed, it will.
| |
| 824 | 824 |
| 825 template <typename Src> | 825 template <typename Src> |
| 826 constexpr explicit CheckedNumericState( | 826 constexpr explicit CheckedNumericState( |
| 827 Src value, | 827 Src value, |
| 828 typename std::enable_if<std::numeric_limits<Src>::is_specialized, | 828 typename std::enable_if<std::numeric_limits<Src>::is_specialized, |
| 829 int>::type = 0) | 829 int>::type = 0) |
| 830 : value_(static_cast<T>(value)), | 830 : is_valid_(IsValueInRangeForNumericType<T>(value)), |
| 831 is_valid_(IsValueInRangeForNumericType<T>(value)) {} | 831 value_(is_valid_ ? static_cast<T>(value) : 0) {} |
| 832 | 832 |
| 833 constexpr bool is_valid() const { return is_valid_; } | 833 constexpr bool is_valid() const { return is_valid_; } |
| 834 constexpr T value() const { return value_; } | 834 constexpr T value() const { return value_; } |
| 835 }; | 835 }; |
| 836 | 836 |
| 837 // Floating points maintain their own validity, but need translation wrappers. | 837 // Floating points maintain their own validity, but need translation wrappers. |
| 838 template <typename T> | 838 template <typename T> |
| 839 class CheckedNumericState<T, NUMERIC_FLOATING> { | 839 class CheckedNumericState<T, NUMERIC_FLOATING> { |
| 840 private: | 840 private: |
| 841 T value_; | 841 T value_; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 905 using math = M<typename UnderlyingType<L>::type, | 905 using math = M<typename UnderlyingType<L>::type, |
| 906 typename UnderlyingType<R>::type, | 906 typename UnderlyingType<R>::type, |
| 907 void>; | 907 void>; |
| 908 using type = typename math::result_type; | 908 using type = typename math::result_type; |
| 909 }; | 909 }; |
| 910 | 910 |
| 911 } // namespace internal | 911 } // namespace internal |
| 912 } // namespace base | 912 } // namespace base |
| 913 | 913 |
| 914 #endif // BASE_NUMERICS_SAFE_MATH_IMPL_H_ | 914 #endif // BASE_NUMERICS_SAFE_MATH_IMPL_H_ |
| OLD | NEW |