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_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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 99 } | 99 } |
| 100 | 100 |
| 101 // This is not an explicit constructor because we want a seamless conversion | 101 // This is not an explicit constructor because we want a seamless conversion |
| 102 // from StrictNumeric types. | 102 // from StrictNumeric types. |
| 103 template <typename Src> | 103 template <typename Src> |
| 104 constexpr CheckedNumeric( | 104 constexpr CheckedNumeric( |
| 105 StrictNumeric<Src> value) // NOLINT(runtime/explicit) | 105 StrictNumeric<Src> value) // NOLINT(runtime/explicit) |
| 106 : state_(static_cast<Src>(value)) {} | 106 : state_(static_cast<Src>(value)) {} |
| 107 | 107 |
| 108 // IsValid() is the public API to test if a CheckedNumeric is currently valid. | 108 // IsValid() is the public API to test if a CheckedNumeric is currently valid. |
| 109 constexpr bool IsValid() const { return state_.is_valid(); } | 109 // A range checked destination type can be supplied using the Dst template |
| 110 // parameter, which will trigger a CHECK if the value is not in bounds for | |
| 111 // the destination. | |
| 112 template <typename Dst = T> | |
| 113 constexpr bool IsValid() const { | |
| 114 return state_.is_valid() && | |
| 115 IsValueInRangeForNumericType<Dst>(state_.value()); | |
| 116 } | |
| 110 | 117 |
| 111 // ValueOrDie() The primary accessor for the underlying value. If the current | 118 // ValueOrDie() The primary accessor for the underlying value. If the current |
| 112 // state is not valid it will CHECK and crash. | 119 // state is not valid it will CHECK and crash. |
| 113 constexpr T ValueOrDie() const { | 120 // A range checked destination type can be supplied using the Dst template |
| 114 return IsValid() ? state_.value() : CheckOnFailure::HandleFailure<T>(); | 121 // parameter, which will trigger a CHECK if the value is not in bounds for |
|
scottmg
2016/11/24 20:23:37
This comment is misleading since there's an overri
jschuh
2016/11/25 14:56:39
I've tweaked the comment, and I'm okay with the ov
| |
| 122 // the destination. | |
| 123 // The CHECK behavior can be overridden by supplying a handler as a | |
| 124 // template parameter, however the value cannot be extracted by the handler. | |
| 125 template <typename Dst = T, class CheckHandler = CheckOnFailure> | |
| 126 constexpr Dst ValueOrDie() const { | |
| 127 return IsValid<Dst>() ? state_.value() | |
| 128 : CheckHandler::template HandleFailure<Dst>(); | |
| 115 } | 129 } |
| 116 | 130 |
| 117 // ValueOrDefault(T default_value) A convenience method that returns the | 131 // ValueOrDefault(T default_value) A convenience method that returns the |
| 118 // current value if the state is valid, and the supplied default_value for | 132 // current value if the state is valid, and the supplied default_value for |
| 119 // any other state. | 133 // any other state. |
| 120 constexpr T ValueOrDefault(T default_value) const { | 134 // A range checked destination type can be supplied using the Dst template |
| 121 return IsValid() ? state_.value() : default_value; | 135 // parameter, which will trigger a CHECK if the value is not in bounds for |
| 136 // the destination. | |
| 137 template <typename Dst = T, typename Src> | |
| 138 constexpr Dst ValueOrDefault(const Src default_value) const { | |
|
scottmg
2016/11/24 20:23:37
Similar for the other ones, ValueOrDefault() and V
jschuh
2016/11/25 14:56:39
This comment was actually wrong, so I fixed it.
| |
| 139 return IsValueInRangeForNumericType<Dst>(default_value) && IsValid<Dst>() | |
| 140 ? state_.value() | |
| 141 : static_cast<Dst>(default_value); | |
| 122 } | 142 } |
| 123 | 143 |
| 124 // ValueFloating() - Since floating point values include their validity state, | 144 // ValueFloating() - Since floating point values include their validity state, |
| 125 // we provide an easy method for extracting them directly, without a risk of | 145 // we provide an easy method for extracting them directly, without a risk of |
| 126 // crashing on a CHECK. | 146 // crashing on a CHECK. |
| 127 constexpr T ValueFloating() const { | 147 // A range checked destination type can be supplied using the Dst template |
| 128 static_assert(std::numeric_limits<T>::is_iec559, "Argument must be float."); | 148 // parameter, which will trigger a CHECK if the value is not in bounds for |
| 129 return state_.value(); | 149 // the destination. |
| 150 template <typename Dst = T> | |
| 151 constexpr Dst ValueFloating() const { | |
| 152 static_assert(std::numeric_limits<T>::is_iec559, | |
| 153 "Type must be floating point."); | |
| 154 static_assert(std::numeric_limits<Dst>::is_iec559, | |
| 155 "Type must be floating point."); | |
| 156 return static_cast<Dst>(state_.value()); | |
| 130 } | 157 } |
| 131 | 158 |
| 132 // Returns a checked numeric of the specified type, cast from the current | 159 // Returns a checked numeric of the specified type, cast from the current |
| 133 // CheckedNumeric. If the current state is invalid or the destination cannot | 160 // CheckedNumeric. If the current state is invalid or the destination cannot |
| 134 // represent the result then the returned CheckedNumeric will be invalid. | 161 // represent the result then the returned CheckedNumeric will be invalid. |
| 135 template <typename Dst> | 162 template <typename Dst> |
| 136 constexpr CheckedNumeric<typename UnderlyingType<Dst>::type> Cast() const { | 163 constexpr CheckedNumeric<typename UnderlyingType<Dst>::type> Cast() const { |
| 137 return *this; | 164 return *this; |
| 138 } | 165 } |
| 139 | 166 |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 354 using internal::CheckSub; | 381 using internal::CheckSub; |
| 355 using internal::CheckMul; | 382 using internal::CheckMul; |
| 356 using internal::CheckDiv; | 383 using internal::CheckDiv; |
| 357 using internal::CheckMod; | 384 using internal::CheckMod; |
| 358 using internal::CheckLsh; | 385 using internal::CheckLsh; |
| 359 using internal::CheckRsh; | 386 using internal::CheckRsh; |
| 360 | 387 |
| 361 } // namespace base | 388 } // namespace base |
| 362 | 389 |
| 363 #endif // BASE_NUMERICS_SAFE_MATH_H_ | 390 #endif // BASE_NUMERICS_SAFE_MATH_H_ |
| OLD | NEW |