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_ |