Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(226)

Unified Diff: base/numerics/safe_conversions.h

Issue 2554803002: Cleanup some undefined floating point behavior in base/numerics (Closed)
Patch Set: compile fix Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | base/numerics/safe_math_impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/numerics/safe_conversions.h
diff --git a/base/numerics/safe_conversions.h b/base/numerics/safe_conversions.h
index 98086039073bc21ec84474046fb904e12dfd3151..5aaba9b3311a395835602b13b3ee8954b814e1be 100644
--- a/base/numerics/safe_conversions.h
+++ b/base/numerics/safe_conversions.h
@@ -106,10 +106,15 @@ struct SaturatedCastNaNBehaviorReturnZero {
};
namespace internal {
-// This wrapper is used for C++11 constexpr support by avoiding the declaration
-// of local variables in the saturated_cast template function.
-// TODO(jschuh): convert this back to a switch once we support C++14.
-template <typename Dst, class NaNHandler, typename Src>
+// These wrappers are used for C++11 constexpr support by avoiding both the
+// declaration of local variables and invalid evaluation resulting from the
+// lack of "constexpr if" support in the saturated_cast template function.
+// TODO(jschuh): Convert to single function with a switch once we support C++14.
+template <
+ typename Dst,
+ class NaNHandler,
+ typename Src,
+ typename std::enable_if<std::is_integral<Dst>::value>::type* = nullptr>
constexpr Dst saturated_cast_impl(const Src value,
const RangeConstraint constraint) {
return constraint == RANGE_VALID
@@ -121,6 +126,22 @@ constexpr Dst saturated_cast_impl(const Src value,
: NaNHandler::template HandleFailure<Dst>()));
}
+template <typename Dst,
+ class NaNHandler,
+ typename Src,
+ typename std::enable_if<std::is_floating_point<Dst>::value>::type* =
+ nullptr>
+constexpr Dst saturated_cast_impl(const Src value,
+ const RangeConstraint constraint) {
+ return constraint == RANGE_VALID
+ ? static_cast<Dst>(value)
+ : (constraint == RANGE_UNDERFLOW
+ ? -std::numeric_limits<Dst>::infinity()
+ : (constraint == RANGE_OVERFLOW
+ ? std::numeric_limits<Dst>::infinity()
+ : std::numeric_limits<Dst>::quiet_NaN()));
+}
+
// saturated_cast<> is analogous to static_cast<> for numeric types, except
// that the specified numeric conversion will saturate rather than overflow or
// underflow. NaN assignment to an integral will defer the behavior to a
@@ -130,12 +151,8 @@ template <typename Dst,
typename Src>
constexpr Dst saturated_cast(Src value) {
using SrcType = typename UnderlyingType<Src>::type;
- return std::is_floating_point<Dst>::value
- ? static_cast<Dst>(
- static_cast<SrcType>(value)) // Floating point optimization.
- : internal::saturated_cast_impl<Dst, NaNHandler>(
- value,
- internal::DstRangeRelationToSrcRange<Dst, SrcType>(value));
+ return internal::saturated_cast_impl<Dst, NaNHandler>(
+ value, internal::DstRangeRelationToSrcRange<Dst, SrcType>(value));
}
// strict_cast<> is analogous to static_cast<> for numeric types, except that
« no previous file with comments | « no previous file | base/numerics/safe_math_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698