| 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_H_ | 5 #ifndef BASE_NUMERICS_SAFE_MATH_H_ |
| 6 #define BASE_NUMERICS_SAFE_MATH_H_ | 6 #define BASE_NUMERICS_SAFE_MATH_H_ |
| 7 | 7 |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 | 9 |
| 10 #include <limits> | 10 #include <limits> |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 } | 93 } |
| 94 | 94 |
| 95 // This is not an explicit constructor because we want a seamless conversion | 95 // This is not an explicit constructor because we want a seamless conversion |
| 96 // from StrictNumeric types. | 96 // from StrictNumeric types. |
| 97 template <typename Src> | 97 template <typename Src> |
| 98 constexpr CheckedNumeric( | 98 constexpr CheckedNumeric( |
| 99 StrictNumeric<Src> value) // NOLINT(runtime/explicit) | 99 StrictNumeric<Src> value) // NOLINT(runtime/explicit) |
| 100 : state_(static_cast<Src>(value)) {} | 100 : state_(static_cast<Src>(value)) {} |
| 101 | 101 |
| 102 // IsValid() is the public API to test if a CheckedNumeric is currently valid. | 102 // IsValid() is the public API to test if a CheckedNumeric is currently valid. |
| 103 constexpr bool IsValid() const { return state_.is_valid(); } | 103 // A range checked destination type can be supplied using the Dst template |
| 104 // parameter, which will trigger a CHECK if the value is not in bounds for |
| 105 // the destination. |
| 106 template <typename Dst = T> |
| 107 constexpr bool IsValid() const { |
| 108 return state_.is_valid() && |
| 109 IsValueInRangeForNumericType<Dst>(state_.value()); |
| 110 } |
| 104 | 111 |
| 105 // ValueOrDie() The primary accessor for the underlying value. If the current | 112 // ValueOrDie() The primary accessor for the underlying value. If the current |
| 106 // state is not valid it will CHECK and crash. | 113 // state is not valid it will CHECK and crash. |
| 107 constexpr T ValueOrDie() const { | 114 // A range checked destination type can be supplied using the Dst template |
| 108 return IsValid() ? state_.value() : CheckOnFailure::HandleFailure<T>(); | 115 // parameter, which will trigger a CHECK if the value is not in bounds for |
| 116 // the destination. |
| 117 // The CHECK behavior can be overridden by supplying a handler as a |
| 118 // template parameter, for test code, etc. However, the handler cannot access |
| 119 // the underlying value, and it is not available through other means. |
| 120 template <typename Dst = T, class CheckHandler = CheckOnFailure> |
| 121 constexpr Dst ValueOrDie() const { |
| 122 return IsValid<Dst>() ? state_.value() |
| 123 : CheckHandler::template HandleFailure<Dst>(); |
| 109 } | 124 } |
| 110 | 125 |
| 111 // ValueOrDefault(T default_value) A convenience method that returns the | 126 // ValueOrDefault(T default_value) A convenience method that returns the |
| 112 // current value if the state is valid, and the supplied default_value for | 127 // current value if the state is valid, and the supplied default_value for |
| 113 // any other state. | 128 // any other state. |
| 114 constexpr T ValueOrDefault(T default_value) const { | 129 // A range checked destination type can be supplied using the Dst template |
| 115 return IsValid() ? state_.value() : default_value; | 130 // parameter. WARNING: This function may fail to compile or CHECK at runtime |
| 131 // if the supplied default_value is not within range of the destination type. |
| 132 template <typename Dst = T, typename Src> |
| 133 constexpr Dst ValueOrDefault(const Src default_value) const { |
| 134 return IsValid<Dst>() ? state_.value() : checked_cast<Dst>(default_value); |
| 116 } | 135 } |
| 117 | 136 |
| 118 // ValueFloating() - Since floating point values include their validity state, | 137 // ValueFloating() - Since floating point values include their validity state, |
| 119 // we provide an easy method for extracting them directly, without a risk of | 138 // we provide an easy method for extracting them directly, without a risk of |
| 120 // crashing on a CHECK. | 139 // crashing on a CHECK. |
| 121 constexpr T ValueFloating() const { | 140 // A range checked destination type can be supplied using the Dst template |
| 122 static_assert(std::numeric_limits<T>::is_iec559, "Argument must be float."); | 141 // parameter. |
| 123 return state_.value(); | 142 template <typename Dst = T> |
| 143 constexpr Dst ValueFloating() const { |
| 144 static_assert(std::numeric_limits<T>::is_iec559, |
| 145 "Type must be floating point."); |
| 146 static_assert(std::numeric_limits<Dst>::is_iec559, |
| 147 "Type must be floating point."); |
| 148 return static_cast<Dst>(state_.value()); |
| 124 } | 149 } |
| 125 | 150 |
| 126 // Returns a checked numeric of the specified type, cast from the current | 151 // Returns a checked numeric of the specified type, cast from the current |
| 127 // CheckedNumeric. If the current state is invalid or the destination cannot | 152 // CheckedNumeric. If the current state is invalid or the destination cannot |
| 128 // represent the result then the returned CheckedNumeric will be invalid. | 153 // represent the result then the returned CheckedNumeric will be invalid. |
| 129 template <typename Dst> | 154 template <typename Dst> |
| 130 constexpr CheckedNumeric<typename UnderlyingType<Dst>::type> Cast() const { | 155 constexpr CheckedNumeric<typename UnderlyingType<Dst>::type> Cast() const { |
| 131 return *this; | 156 return *this; |
| 132 } | 157 } |
| 133 | 158 |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 using internal::CheckMod; | 392 using internal::CheckMod; |
| 368 using internal::CheckLsh; | 393 using internal::CheckLsh; |
| 369 using internal::CheckRsh; | 394 using internal::CheckRsh; |
| 370 using internal::CheckAnd; | 395 using internal::CheckAnd; |
| 371 using internal::CheckOr; | 396 using internal::CheckOr; |
| 372 using internal::CheckXor; | 397 using internal::CheckXor; |
| 373 | 398 |
| 374 } // namespace base | 399 } // namespace base |
| 375 | 400 |
| 376 #endif // BASE_NUMERICS_SAFE_MATH_H_ | 401 #endif // BASE_NUMERICS_SAFE_MATH_H_ |
| OLD | NEW |