Chromium Code Reviews| 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, |
|
Nico
2016/12/06 17:15:50
So this is unrelated to the change in the other fi
jschuh
2016/12/06 17:33:59
Unrelated. I'm naively hoping to fix all the float
|
| + 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 |