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_CONVERSIONS_H_ | 5 #ifndef BASE_NUMERICS_SAFE_CONVERSIONS_H_ |
| 6 #define BASE_NUMERICS_SAFE_CONVERSIONS_H_ | 6 #define BASE_NUMERICS_SAFE_CONVERSIONS_H_ |
| 7 | 7 |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 | 9 |
| 10 #include <cassert> | 10 #include <cassert> |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 35 // if the type supplied to the template parameter can represent the value | 35 // if the type supplied to the template parameter can represent the value |
| 36 // passed as an argument to the function. | 36 // passed as an argument to the function. |
| 37 // IsValueNegative<>() - A convenience function that will accept any arithmetic | 37 // IsValueNegative<>() - A convenience function that will accept any arithmetic |
| 38 // type as an argument and will return whether the value is less than zero. | 38 // type as an argument and will return whether the value is less than zero. |
| 39 // Unsigned types always return false. | 39 // Unsigned types always return false. |
| 40 // StrictNumeric<> - A wrapper type that performs assignments and copies via | 40 // StrictNumeric<> - A wrapper type that performs assignments and copies via |
| 41 // the strict_cast<> template, and can perform valid arithmetic comparisons | 41 // the strict_cast<> template, and can perform valid arithmetic comparisons |
| 42 // across any range of arithmetic types. StrictNumeric is the return type | 42 // across any range of arithmetic types. StrictNumeric is the return type |
| 43 // for values extracted from a CheckedNumeric class instance. The raw | 43 // for values extracted from a CheckedNumeric class instance. The raw |
| 44 // arithmetic value is extracted via static_cast to the underlying type. | 44 // arithmetic value is extracted via static_cast to the underlying type. |
| 45 // StrictNum() - Creates a new StrictNumeric from the underlying type of the | |
| 46 // supplied arithmetic or StrictNumeric type. | |
| 45 | 47 |
| 46 // Convenience function that returns true if the supplied value is in range | 48 // Convenience function that returns true if the supplied value is in range |
| 47 // for the destination type. | 49 // for the destination type. |
| 48 template <typename Dst, typename Src> | 50 template <typename Dst, typename Src> |
| 49 constexpr bool IsValueInRangeForNumericType(Src value) { | 51 constexpr bool IsValueInRangeForNumericType(Src value) { |
| 50 return internal::DstRangeRelationToSrcRange<Dst>(value) == | 52 return internal::DstRangeRelationToSrcRange<Dst>(value) == |
| 51 internal::RANGE_VALID; | 53 internal::RANGE_VALID; |
| 52 } | 54 } |
| 53 | 55 |
| 54 // Convenience function for determining if a numeric value is negative without | 56 // Convenience function for determining if a numeric value is negative without |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 typename std::enable_if< | 224 typename std::enable_if< |
| 223 IsNumericRangeContained<Dst, T>::value>::type* = nullptr> | 225 IsNumericRangeContained<Dst, T>::value>::type* = nullptr> |
| 224 constexpr operator Dst() const { | 226 constexpr operator Dst() const { |
| 225 return static_cast<typename ArithmeticOrUnderlyingEnum<Dst>::type>(value_); | 227 return static_cast<typename ArithmeticOrUnderlyingEnum<Dst>::type>(value_); |
| 226 } | 228 } |
| 227 | 229 |
| 228 private: | 230 private: |
| 229 const T value_; | 231 const T value_; |
| 230 }; | 232 }; |
| 231 | 233 |
| 234 // Convience wrapper returns a StrictNumeric from the provided arithmetic type. | |
| 235 template <typename T> | |
| 236 constexpr StrictNumeric<typename UnderlyingType<T>::type> StrictNum( | |
|
dcheng
2016/12/03 21:34:29
Nit: usually we name the deducing helpers MakeFoo,
jschuh
2016/12/03 22:29:12
Fair. I'll fix it here and convert CheckNum to Mak
dcheng
2016/12/04 01:42:14
MakeStrict / MakeChecked almost feel too generic (
| |
| 237 const T value) { | |
| 238 return value; | |
| 239 } | |
| 240 | |
| 232 // Overload the ostream output operator to make logging work nicely. | 241 // Overload the ostream output operator to make logging work nicely. |
| 233 template <typename T> | 242 template <typename T> |
| 234 std::ostream& operator<<(std::ostream& os, const StrictNumeric<T>& value) { | 243 std::ostream& operator<<(std::ostream& os, const StrictNumeric<T>& value) { |
| 235 os << static_cast<T>(value); | 244 os << static_cast<T>(value); |
| 236 return os; | 245 return os; |
| 237 } | 246 } |
| 238 | 247 |
| 239 #define STRICT_COMPARISON_OP(NAME, OP) \ | 248 #define STRICT_COMPARISON_OP(NAME, OP) \ |
| 240 template <typename L, typename R, \ | 249 template <typename L, typename R, \ |
| 241 typename std::enable_if< \ | 250 typename std::enable_if< \ |
| 242 internal::IsStrictOp<L, R>::value>::type* = nullptr> \ | 251 internal::IsStrictOp<L, R>::value>::type* = nullptr> \ |
| 243 constexpr bool operator OP(const L lhs, const R rhs) { \ | 252 constexpr bool operator OP(const L lhs, const R rhs) { \ |
| 244 return SafeCompare<NAME, typename UnderlyingType<L>::type, \ | 253 return SafeCompare<NAME, typename UnderlyingType<L>::type, \ |
| 245 typename UnderlyingType<R>::type>(lhs, rhs); \ | 254 typename UnderlyingType<R>::type>(lhs, rhs); \ |
| 246 } | 255 } |
| 247 | 256 |
| 248 STRICT_COMPARISON_OP(IsLess, <); | 257 STRICT_COMPARISON_OP(IsLess, <); |
| 249 STRICT_COMPARISON_OP(IsLessOrEqual, <=); | 258 STRICT_COMPARISON_OP(IsLessOrEqual, <=); |
| 250 STRICT_COMPARISON_OP(IsGreater, >); | 259 STRICT_COMPARISON_OP(IsGreater, >); |
| 251 STRICT_COMPARISON_OP(IsGreaterOrEqual, >=); | 260 STRICT_COMPARISON_OP(IsGreaterOrEqual, >=); |
| 252 STRICT_COMPARISON_OP(IsEqual, ==); | 261 STRICT_COMPARISON_OP(IsEqual, ==); |
| 253 STRICT_COMPARISON_OP(IsNotEqual, !=); | 262 STRICT_COMPARISON_OP(IsNotEqual, !=); |
| 254 | 263 |
| 255 #undef STRICT_COMPARISON_OP | 264 #undef STRICT_COMPARISON_OP |
| 256 }; | 265 }; |
| 257 | 266 |
| 258 using internal::strict_cast; | 267 using internal::strict_cast; |
| 259 using internal::saturated_cast; | 268 using internal::saturated_cast; |
| 260 using internal::StrictNumeric; | 269 using internal::StrictNumeric; |
| 270 using internal::StrictNum; | |
| 261 | 271 |
| 262 // Explicitly make a shorter size_t typedef for convenience. | 272 // Explicitly make a shorter size_t typedef for convenience. |
| 263 typedef StrictNumeric<size_t> SizeT; | 273 typedef StrictNumeric<size_t> SizeT; |
| 264 | 274 |
| 265 } // namespace base | 275 } // namespace base |
| 266 | 276 |
| 267 #endif // BASE_NUMERICS_SAFE_CONVERSIONS_H_ | 277 #endif // BASE_NUMERICS_SAFE_CONVERSIONS_H_ |
| OLD | NEW |