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 |