| Index: base/numerics/safe_conversions.h
|
| diff --git a/base/numerics/safe_conversions.h b/base/numerics/safe_conversions.h
|
| index 66b278ff3d3e41b3ce33f1d56bea183f12dc7b61..99cbef4ca814c669514c0a206e6162458ed8c8e5 100644
|
| --- a/base/numerics/safe_conversions.h
|
| +++ b/base/numerics/safe_conversions.h
|
| @@ -110,35 +110,35 @@ namespace internal {
|
| // that the specified numeric conversion will saturate by default rather than
|
| // overflow or underflow, and NaN assignment to an integral will return 0.
|
| // All boundary condition behaviors can be overriden with a custom handler.
|
| +template <template <typename>
|
| + class SaturationHandler = SaturatedCastDefaultHandler,
|
| + typename Dst,
|
| + typename Src>
|
| +constexpr Dst saturated_cast_impl(const Src value,
|
| + const RangeConstraint constraint) {
|
| + return constraint.IsValid()
|
| + ? static_cast<Dst>(value)
|
| + : (constraint.IsOverflow()
|
| + ? SaturationHandler<Dst>::HandleOverflow()
|
| + // Skip this check for integral Src, which cannot be NaN.
|
| + : (std::is_integral<Src>::value || constraint.IsUnderflow()
|
| + ? SaturationHandler<Dst>::HandleUnderflow()
|
| + : SaturationHandler<Dst>::HandleNaN()));
|
| +}
|
| +
|
| +// saturated_cast<> is analogous to static_cast<> for numeric types, except
|
| +// that the specified numeric conversion will saturate by default rather than
|
| +// overflow or underflow, and NaN assignment to an integral will return 0.
|
| +// All boundary condition behaviors can be overriden with a custom handler.
|
| template <typename Dst,
|
| template <typename>
|
| class SaturationHandler = SaturatedCastDefaultHandler,
|
| typename Src>
|
| constexpr Dst saturated_cast(Src value) {
|
| - static_assert(
|
| - SaturationHandler<Dst>::lowest() < SaturationHandler<Dst>::max(), "");
|
| - // While this looks like a lot of code, it's all constexpr and all but
|
| - // one variable are compile-time constants (enforced by a static_assert).
|
| - // So, it should evaluate to the minimum number of comparisons required
|
| - // for the range check, which is 0-3, depending on the exact source and
|
| - // destination types, and whatever custom range is specified.
|
| using SrcType = typename UnderlyingType<Src>::type;
|
| - return IsGreaterOrEqual<SrcType, Dst>::Test(
|
| - value, NarrowingRange<Dst, SrcType, SaturationHandler>::lowest())
|
| - ? (IsLessOrEqual<SrcType, Dst>::Test(
|
| - value,
|
| - NarrowingRange<Dst, SrcType, SaturationHandler>::max())
|
| - ? static_cast<Dst>(value)
|
| - : SaturationHandler<Dst>::HandleOverflow())
|
| - // This last branch is a little confusing. It's specifically to
|
| - // catch NaN when converting from float to integral.
|
| - : (std::is_integral<SrcType>::value ||
|
| - std::is_floating_point<Dst>::value ||
|
| - IsLessOrEqual<SrcType, Dst>::Test(
|
| - value, NarrowingRange<Dst, SrcType,
|
| - SaturationHandler>::max())
|
| - ? SaturationHandler<Dst>::HandleUnderflow()
|
| - : SaturationHandler<Dst>::HandleNaN());
|
| + return saturated_cast_impl<SaturationHandler, Dst>(
|
| + static_cast<SrcType>(value),
|
| + DstRangeRelationToSrcRange<Dst, SaturationHandler, SrcType>(value));
|
| }
|
|
|
| // strict_cast<> is analogous to static_cast<> for numeric types, except that
|
|
|