Chromium Code Reviews| Index: base/numerics/safe_conversions.h |
| diff --git a/base/numerics/safe_conversions.h b/base/numerics/safe_conversions.h |
| index d9b77f76d50700bd0686de12ae22390d341776ad..8dd58266afc6f38bb7c8e82149af8b18405e583c 100644 |
| --- a/base/numerics/safe_conversions.h |
| +++ b/base/numerics/safe_conversions.h |
| @@ -58,6 +58,68 @@ inline Dst saturated_cast(Src value) { |
| return static_cast<Dst>(value); |
| } |
| +// strict_cast<> is analogous to static_cast<> for numeric types, except that |
| +// it will cause a compile failure if the destination type is not large enough |
| +// to contain any value in the source type. It performs no runtime checking. |
| +template <typename Dst, typename Src> |
| +inline Dst strict_cast(Src value) { |
| + static_assert(std::numeric_limits<Src>::is_specialized, |
| + "Argument must be numeric."); |
| + static_assert(std::numeric_limits<Dst>::is_specialized, |
| + "Result must be numeric."); |
| + static_assert((internal::StaticDstRangeRelationToSrcRange<Dst, Src>::value == |
| + internal::NUMERIC_RANGE_CONTAINED), |
| + "The numeric conversion is out of range for this type. You " |
| + "should probably use one of the following conversion " |
| + "mechanisms on the value you want to pass:\n" |
| + "- base::checked_cast\n" |
| + "- base::saturated_cast\n" |
| + "- base::CheckedNumeric"); |
| + |
| + return static_cast<Dst>(value); |
| +} |
| + |
| +// StrictNumeric implements compile time range checking between numeric types by |
| +// wrapping assignment operations in a strict_cast. This class is intended to be |
| +// used for function arguments and return types, to ensure the destination type |
| +// can always contain the source type. This is essentially the same as enforcing |
| +// -Wconversion in gcc and C4302 warnings on MSVC, but it can be applied |
| +// incrementally at API boundaries, making it easier to convert code so that it |
| +// compiles cleanly with truncation warnings enabled. |
| +// This template should introduce no runtime overhead, but it also provides no |
| +// runtime checking of any of the associated mathematical operations. Use |
| +// CheckedNumeric for runtime range checks of tha actual value being assigned. |
| +template <typename T> |
| +class StrictNumeric { |
| + public: |
| + typedef T type; |
| + |
| + StrictNumeric() : value_(0) {} |
| + |
| + // Copy constructor. |
| + template <typename Src> |
| + StrictNumeric(const StrictNumeric<Src>& rhs) |
| + : value_(strict_cast<T>(rhs.value_)) {} |
| + |
| + // This is not an explicit constructor because we implicitly upgrade regular |
| + // numerics to StrictNumerics to make them easier to use. |
| + template <typename Src> |
| + StrictNumeric(Src value) |
| + : value_(strict_cast<T>(value)) {} |
| + |
| + // The numeric cast operator basically handles all the magic. |
| + template <typename Dst> |
| + operator Dst() const { |
| + return strict_cast<Dst>(value_); |
| + } |
| + |
| + private: |
| + T value_; |
| +}; |
| + |
| +// Explicitly make a shorter typedef for convenience. |
| +typedef StrictNumeric<size_t> SSizeT; |
|
rickyz (no longer on Chrome)
2015/05/27 22:50:53
This name could potentially be confused with ssize
|
| + |
| } // namespace base |
| #endif // BASE_NUMERICS_SAFE_CONVERSIONS_H_ |