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

Unified Diff: base/numerics/safe_conversions.h

Issue 2585043002: Improve saturated_cast performance (Closed)
Patch Set: fix comment nit 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_conversions_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 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
« no previous file with comments | « no previous file | base/numerics/safe_conversions_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698