WebKit Bugzilla
Attachment 361445 Details for
Bug 194263
: clampTo(): do not convert the input to double when dealing with integers
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-194263-20190207142725.patch (text/plain), 28.46 KB, created by
Benjamin Poulain
on 2019-02-07 14:27:26 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Benjamin Poulain
Created:
2019-02-07 14:27:26 PST
Size:
28.46 KB
patch
obsolete
>Subversion Revision: 241111 >diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog >index 65684330426e758849b51e259223d37e3270e59e..6427d3f6bdb7676517a5347d0cb148379d71a00d 100644 >--- a/Source/WTF/ChangeLog >+++ b/Source/WTF/ChangeLog >@@ -1,3 +1,23 @@ >+2019-02-06 Benjamin Poulain <benjamin@webkit.org> >+ >+ clampTo(): do not convert the input to double when dealing with integers >+ https://bugs.webkit.org/show_bug.cgi?id=194263 >+ <rdar://problem/47692312> >+ >+ Reviewed by Darin Adler. >+ >+ Previously, every use of clampTo() was converting the input to double, >+ doing the comparison in double, then casting back to whatever type was needed. >+ >+ In many case, that was very wasteful. WebKit has many cases of clampTo() with >+ the same type as input/output, or with integer types of different size/sign. >+ >+ This patch adds a few versions of clampTo() for the common cases seen in WebKit. >+ In each case, I tried to minimize the amount of conversion needed at runtime. >+ >+ * wtf/MathExtras.h: >+ (clampTo): >+ > 2019-02-05 Keith Rollin <krollin@apple.com> > > Enable the automatic checking and regenerations of .xcfilelists during builds >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index f496024ce162c248c55b417751be1bea9b264c5e..eb7703c17d1a07fb39b7ccf73cbc8c29e8d15437 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,19 @@ >+2019-02-06 Benjamin Poulain <benjamin@webkit.org> >+ >+ clampTo(): do not convert the input to double when dealing with integers >+ https://bugs.webkit.org/show_bug.cgi?id=194263 >+ <rdar://problem/47692312> >+ >+ Reviewed by Darin Adler. >+ >+ Make the calls to clampTo<float>() unambiguous. >+ >+ * page/FrameView.cpp: >+ (WebCore::FrameView::computeUpdatedLayoutViewportRect): >+ * rendering/style/RenderStyle.h: >+ (WebCore::RenderStyle::setOpacity): >+ (WebCore::RenderStyle::setShapeImageThreshold): >+ > 2019-02-06 Keith Rollin <krollin@apple.com> > > Update .xcfilelist files >diff --git a/Source/WTF/wtf/MathExtras.h b/Source/WTF/wtf/MathExtras.h >index 5eef198790cb1ee86490d49ee1e7e69a5c92a32a..6e177009d72e7e71cabc0b77cffadff8c4b0be35 100644 >--- a/Source/WTF/wtf/MathExtras.h >+++ b/Source/WTF/wtf/MathExtras.h >@@ -123,15 +123,110 @@ template<> constexpr float defaultMinimumForClamp() { return -std::numeric_limit > template<> constexpr double defaultMinimumForClamp() { return -std::numeric_limits<double>::max(); } > template<typename T> constexpr T defaultMaximumForClamp() { return std::numeric_limits<T>::max(); } > >-template<typename T> inline T clampTo(double value, T min = defaultMinimumForClamp<T>(), T max = defaultMaximumForClamp<T>()) >+// Same type in and out. >+template<typename TargetType, typename SourceType> >+typename std::enable_if<std::is_same<TargetType, SourceType>::value, TargetType>::type >+clampTo(SourceType value, TargetType min = defaultMinimumForClamp<TargetType>(), TargetType max = defaultMaximumForClamp<TargetType>()) > { >- if (value >= static_cast<double>(max)) >+ if (value >= max) > return max; >- if (value <= static_cast<double>(min)) >+ if (value <= min) > return min; >- return static_cast<T>(value); >+ return value; >+} >+ >+// Floating point source. >+template<typename TargetType, typename SourceType> >+typename std::enable_if<!std::is_same<TargetType, SourceType>::value >+ && std::is_floating_point<SourceType>::value >+ && !(std::is_floating_point<TargetType>::value && sizeof(TargetType) > sizeof(SourceType)), TargetType>::type >+clampTo(SourceType value, TargetType min = defaultMinimumForClamp<TargetType>(), TargetType max = defaultMaximumForClamp<TargetType>()) >+{ >+ if (value >= static_cast<SourceType>(max)) >+ return max; >+ if (value <= static_cast<SourceType>(min)) >+ return min; >+ return static_cast<TargetType>(value); >+} >+ >+template<typename TargetType, typename SourceType> >+typename std::enable_if<!std::is_same<TargetType, SourceType>::value >+ && std::is_floating_point<SourceType>::value >+ && std::is_floating_point<TargetType>::value >+ && (sizeof(TargetType) > sizeof(SourceType)), TargetType>::type >+clampTo(SourceType value, TargetType min = defaultMinimumForClamp<TargetType>(), TargetType max = defaultMaximumForClamp<TargetType>()) >+{ >+ TargetType convertedValue = static_cast<TargetType>(value); >+ if (convertedValue >= max) >+ return max; >+ if (convertedValue <= min) >+ return min; >+ return convertedValue; >+} >+ >+// Source and Target have the same sign and Source is larger or equal to Target >+template<typename TargetType, typename SourceType> >+typename std::enable_if<!std::is_same<TargetType, SourceType>::value >+ && std::numeric_limits<SourceType>::is_integer >+ && std::numeric_limits<TargetType>::is_integer >+ && std::numeric_limits<TargetType>::is_signed == std::numeric_limits<SourceType>::is_signed >+ && sizeof(SourceType) >= sizeof(TargetType), TargetType>::type >+clampTo(SourceType value, TargetType min = defaultMinimumForClamp<TargetType>(), TargetType max = defaultMaximumForClamp<TargetType>()) >+{ >+ if (value >= static_cast<SourceType>(max)) >+ return max; >+ if (value <= static_cast<SourceType>(min)) >+ return min; >+ return static_cast<TargetType>(value); >+} >+ >+// Clamping a unsigned integer to the max signed value. >+template<typename TargetType, typename SourceType> >+typename std::enable_if<!std::is_same<TargetType, SourceType>::value >+ && std::numeric_limits<SourceType>::is_integer >+ && std::numeric_limits<TargetType>::is_integer >+ && std::numeric_limits<TargetType>::is_signed >+ && !std::numeric_limits<SourceType>::is_signed >+ && sizeof(SourceType) >= sizeof(TargetType), TargetType>::type >+clampTo(SourceType value) >+{ >+ TargetType max = std::numeric_limits<TargetType>::max(); >+ if (value >= static_cast<SourceType>(max)) >+ return max; >+ return static_cast<TargetType>(value); >+} >+ >+// Clamping a signed integer into a valid unsigned integer. >+template<typename TargetType, typename SourceType> >+typename std::enable_if<!std::is_same<TargetType, SourceType>::value >+ && std::numeric_limits<SourceType>::is_integer >+ && std::numeric_limits<TargetType>::is_integer >+ && !std::numeric_limits<TargetType>::is_signed >+ && std::numeric_limits<SourceType>::is_signed >+ && sizeof(SourceType) == sizeof(TargetType), TargetType>::type >+clampTo(SourceType value) >+{ >+ if (value < 0) >+ return 0; >+ return static_cast<TargetType>(value); >+} >+ >+template<typename TargetType, typename SourceType> >+typename std::enable_if<!std::is_same<TargetType, SourceType>::value >+ && std::numeric_limits<SourceType>::is_integer >+ && std::numeric_limits<TargetType>::is_integer >+ && !std::numeric_limits<TargetType>::is_signed >+ && std::numeric_limits<SourceType>::is_signed >+ && (sizeof(SourceType) > sizeof(TargetType)), TargetType>::type >+clampTo(SourceType value) >+{ >+ if (value < 0) >+ return 0; >+ TargetType max = std::numeric_limits<TargetType>::max(); >+ if (value >= static_cast<SourceType>(max)) >+ return max; >+ return static_cast<TargetType>(value); > } >-template<> inline long long int clampTo(double, long long int, long long int); // clampTo does not support long long ints. > > inline int clampToInteger(double value) > { >diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp >index 5a9ded2ec03842295580881c920f13477da82466..aabc02bfc1d608d1ef1360b49bfc47badc1c7239 100644 >--- a/Source/WebCore/page/FrameView.cpp >+++ b/Source/WebCore/page/FrameView.cpp >@@ -1530,8 +1530,8 @@ LayoutRect FrameView::computeUpdatedLayoutViewportRect(const LayoutRect& layoutV > // The max stable layout viewport origin really depends on the size of the layout viewport itself, so we need to adjust the location of the layout viewport one final time to make sure it does not end up out of bounds of the document. > // Without this adjustment (and with using the non-constrained unobscuredContentRect's size as the size of the layout viewport) the layout viewport can be pushed past the bounds of the document during rubber-banding, and cannot be pushed > // back in until the user scrolls back in the other direction. >- layoutViewportOrigin.setX(clampTo<float>(layoutViewportOrigin.x(), 0, documentRect.width() - layoutViewportRect.width())); >- layoutViewportOrigin.setY(clampTo<float>(layoutViewportOrigin.y(), 0, documentRect.height() - layoutViewportRect.height())); >+ layoutViewportOrigin.setX(clampTo<float>(layoutViewportOrigin.x().toFloat(), 0, documentRect.width() - layoutViewportRect.width())); >+ layoutViewportOrigin.setY(clampTo<float>(layoutViewportOrigin.y().toFloat(), 0, documentRect.height() - layoutViewportRect.height())); > } > layoutViewportRect.setLocation(layoutViewportOrigin); > >diff --git a/Source/WebCore/rendering/style/RenderStyle.h b/Source/WebCore/rendering/style/RenderStyle.h >index 324efe58cd09e9e44ac86209c8a3249816d02c43..69650df20f08e9de9325fdff067e477222b1348a 100644 >--- a/Source/WebCore/rendering/style/RenderStyle.h >+++ b/Source/WebCore/rendering/style/RenderStyle.h >@@ -1055,7 +1055,7 @@ public: > void setTextStrokeWidth(float w) { SET_VAR(m_rareInheritedData, textStrokeWidth, w); } > void setTextFillColor(const Color& c) { SET_VAR(m_rareInheritedData, textFillColor, c); } > void setCaretColor(const Color& c) { SET_VAR(m_rareInheritedData, caretColor, c); } >- void setOpacity(float f) { float v = clampTo<float>(f, 0, 1); SET_VAR(m_rareNonInheritedData, opacity, v); } >+ void setOpacity(float f) { float v = clampTo<float>(f, 0.f, 1.f); SET_VAR(m_rareNonInheritedData, opacity, v); } > void setAppearance(ControlPart a) { SET_VAR(m_rareNonInheritedData, appearance, a); } > // For valid values of box-align see http://www.w3.org/TR/2009/WD-css3-flexbox-20090723/#alignment > void setBoxAlign(BoxAlignment a) { SET_NESTED_VAR(m_rareNonInheritedData, deprecatedFlexibleBox, align, static_cast<unsigned>(a)); } >@@ -2196,7 +2196,7 @@ inline void RenderStyle::setShapeOutside(RefPtr<ShapeValue>&& value) > > inline void RenderStyle::setShapeImageThreshold(float shapeImageThreshold) > { >- float clampedShapeImageThreshold = clampTo<float>(shapeImageThreshold, 0, 1); >+ float clampedShapeImageThreshold = clampTo<float>(shapeImageThreshold, 0.f, 1.f); > SET_VAR(m_rareNonInheritedData, shapeImageThreshold, clampedShapeImageThreshold); > } > >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 274d3391091900035518a9741b5dcdf964d4e7c2..0ffd160ed5210f37bcbdbb0c7abfe2a9e0aec36e 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,18 @@ >+2019-02-06 Benjamin Poulain <benjamin@webkit.org> >+ >+ clampTo(): do not convert the input to double when dealing with integers >+ https://bugs.webkit.org/show_bug.cgi?id=194263 >+ <rdar://problem/47692312> >+ >+ Reviewed by Darin Adler. >+ >+ * TestWebKitAPI/Tests/WTF/MathExtras.cpp: >+ (TestWebKitAPI::testClampFloatingPointToFloatingPoint): >+ (TestWebKitAPI::testClampFloatingPointToInteger): >+ (TestWebKitAPI::testClampSameSignIntegers): >+ (TestWebKitAPI::testClampUnsignedToSigned): >+ (TestWebKitAPI::testClampSignedToUnsigned): >+ > 2019-02-06 Keith Rollin <krollin@apple.com> > > Really enable the automatic checking and regenerations of .xcfilelists during builds >diff --git a/Tools/TestWebKitAPI/Tests/WTF/MathExtras.cpp b/Tools/TestWebKitAPI/Tests/WTF/MathExtras.cpp >index 1789a0eb8b07730b9a3d12c05393f459ba9eae6d..c74e3c9e5474f69897e94612595475c2d6e3bd2e 100644 >--- a/Tools/TestWebKitAPI/Tests/WTF/MathExtras.cpp >+++ b/Tools/TestWebKitAPI/Tests/WTF/MathExtras.cpp >@@ -1,5 +1,6 @@ > /* > * Copyright (C) 2012 Intel Corporation >+ * Copyright (C) 2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -174,6 +175,238 @@ TEST(WTF, clampToUnsignedLongLong) > EXPECT_EQ(clampTo<unsigned>(-1), 0u); > } > >+#if !COMPILER(MSVC) >+template<typename TargetType, typename SourceType> >+static void testClampFloatingPointToFloatingPoint() >+{ >+ // No clamping. >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(0)), static_cast<TargetType>(0)); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(1)), static_cast<TargetType>(1)); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(1.5)), static_cast<TargetType>(1.5)); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(-1)), static_cast<TargetType>(-1)); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(-1.5)), static_cast<TargetType>(-1.5)); >+ >+ // Explicit boundaries, clamped or not. >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(-42), static_cast<SourceType>(-42.5)), static_cast<TargetType>(-42)); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(-43), static_cast<SourceType>(-42.5)), static_cast<TargetType>(static_cast<SourceType>(-42.5))); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(42), static_cast<SourceType>(41), static_cast<SourceType>(42.5)), static_cast<TargetType>(42)); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(43), static_cast<SourceType>(41), static_cast<SourceType>(42.5)), static_cast<TargetType>(static_cast<SourceType>(42.5))); >+ >+ // Integer bounds. >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::max()) + 1), static_cast<TargetType>(std::numeric_limits<int32_t>::max()) + 1); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int64_t>::max())), static_cast<TargetType>(std::numeric_limits<int64_t>::max())); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::max()) + 1), static_cast<TargetType>(std::numeric_limits<int32_t>::max()) + 1); >+ >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::min())), static_cast<TargetType>(std::numeric_limits<int32_t>::min())); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int64_t>::min())), static_cast<TargetType>(std::numeric_limits<int64_t>::min())); >+ >+ if (std::is_same<TargetType, double>::value && std::is_same<SourceType, float>::value) { >+ // If the source is float and target is double, the input of those cases has lost bits in float. >+ // In that case, we also round the expectation to float. >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::max())), static_cast<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::max()))); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::min()) - 1), static_cast<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::min()) - 1)); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::min()) - 1), static_cast<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::min()) - 1)); >+ } else { >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::max())), static_cast<TargetType>(std::numeric_limits<int32_t>::max())); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::min()) - 1), static_cast<TargetType>(std::numeric_limits<int32_t>::min()) - 1); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::min()) - 1), static_cast<TargetType>(std::numeric_limits<int32_t>::min()) - 1); >+ } >+ >+ // At the limit. >+ EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<TargetType>::max()), std::numeric_limits<TargetType>::max()); >+ EXPECT_EQ(clampTo<TargetType>(-std::numeric_limits<TargetType>::max()), -std::numeric_limits<TargetType>::max()); >+ >+ // At Epsilon from the limit. >+ TargetType epsilon = std::numeric_limits<TargetType>::epsilon(); >+ EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<TargetType>::max() - epsilon), std::numeric_limits<TargetType>::max() - epsilon); >+ EXPECT_EQ(clampTo<TargetType>(-std::numeric_limits<TargetType>::max() + epsilon), -std::numeric_limits<TargetType>::max() + epsilon); >+ >+ // Infinity. >+ EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<SourceType>::infinity()), std::numeric_limits<TargetType>::max()); >+ EXPECT_EQ(clampTo<TargetType>(-std::numeric_limits<SourceType>::infinity()), -std::numeric_limits<TargetType>::max()); >+} >+ >+TEST(WTF, clampFloatingPointToFloatingPoint) >+{ >+ testClampFloatingPointToFloatingPoint<float, float>(); >+ testClampFloatingPointToFloatingPoint<double, double>(); >+ >+ testClampFloatingPointToFloatingPoint<double, float>(); >+ testClampFloatingPointToFloatingPoint<float, double>(); >+ >+ // Large double into smaller float. >+ EXPECT_EQ(clampTo<float>(static_cast<double>(std::numeric_limits<float>::max())), std::numeric_limits<float>::max()); >+ EXPECT_EQ(clampTo<float>(-static_cast<double>(std::numeric_limits<float>::max())), -std::numeric_limits<float>::max()); >+ EXPECT_EQ(clampTo<float>(static_cast<double>(std::numeric_limits<float>::max()) + 1), std::numeric_limits<float>::max()); >+ EXPECT_EQ(clampTo<float>(-static_cast<double>(std::numeric_limits<float>::max()) - 1), -std::numeric_limits<float>::max()); >+ EXPECT_EQ(clampTo<float>(std::numeric_limits<double>::max()), std::numeric_limits<float>::max()); >+ EXPECT_EQ(clampTo<float>(-std::numeric_limits<double>::max()), -std::numeric_limits<float>::max()); >+ >+ float floatEspilon = std::numeric_limits<float>::epsilon(); >+ double doubleEspilon = std::numeric_limits<double>::epsilon(); >+ EXPECT_EQ(clampTo<float>(static_cast<double>(std::numeric_limits<float>::max()) + doubleEspilon), std::numeric_limits<float>::max()); >+ EXPECT_EQ(clampTo<float>(static_cast<double>(std::numeric_limits<float>::max()) - doubleEspilon), std::numeric_limits<float>::max()); >+ EXPECT_EQ(clampTo<float>(static_cast<double>(std::numeric_limits<float>::max()) + floatEspilon), std::numeric_limits<float>::max()); >+ EXPECT_EQ(clampTo<float>(static_cast<double>(std::numeric_limits<float>::max()) - floatEspilon), std::numeric_limits<float>::max() - floatEspilon); >+} >+#endif // !COMPILER(MSVC) >+ >+template<typename FloatingPointType> >+static void testClampFloatingPointToInteger() >+{ >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(0)), 0); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(1)), 1); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(-1)), -1); >+ if (std::is_same<FloatingPointType, double>::value) >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::max()) - 1.f), std::numeric_limits<int32_t>::max() - 1); >+ else >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::max()) - 1.f), std::numeric_limits<int32_t>::max()); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::max())), std::numeric_limits<int32_t>::max()); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::max()) + 1.f), std::numeric_limits<int32_t>::max()); >+ >+ if (std::is_same<FloatingPointType, double>::value) >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::min()) + 1.f), std::numeric_limits<int32_t>::min() + 1); >+ else >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::min()) + 1.f), std::numeric_limits<int32_t>::min()); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::min())), std::numeric_limits<int32_t>::min()); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::min()) - 1.f), std::numeric_limits<int32_t>::min()); >+ >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<uint32_t>::max())), std::numeric_limits<int32_t>::max()); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<uint32_t>::max()) + 1.f), std::numeric_limits<int32_t>::max()); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<uint32_t>::min())), 0.f); >+ >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int64_t>::max())), std::numeric_limits<int32_t>::max()); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int64_t>::max()) + 1.f), std::numeric_limits<int32_t>::max()); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int64_t>::min())), std::numeric_limits<int32_t>::min()); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int64_t>::min()) - 1.f), std::numeric_limits<int32_t>::min()); >+ >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<uint64_t>::max())), std::numeric_limits<int32_t>::max()); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<uint64_t>::max()) + 1.f), std::numeric_limits<int32_t>::max()); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<uint64_t>::min())), 0.f); >+ >+ FloatingPointType epsilon = std::numeric_limits<FloatingPointType>::epsilon(); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::max()) - epsilon), std::numeric_limits<int32_t>::max()); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::max()) + epsilon), std::numeric_limits<int32_t>::max()); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::min()) - epsilon), std::numeric_limits<int32_t>::min()); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::min()) + epsilon), std::numeric_limits<int32_t>::min()); >+ >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<FloatingPointType>::infinity())), std::numeric_limits<int32_t>::max()); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(-std::numeric_limits<FloatingPointType>::infinity())), std::numeric_limits<int32_t>::min()); >+} >+ >+TEST(WTF, clampFloatToInt) >+{ >+ testClampFloatingPointToInteger<float>(); >+ testClampFloatingPointToInteger<double>(); >+ >+ // 2**24 = 16777216, the largest integer representable exactly as float. >+ EXPECT_EQ(clampTo<int32_t>(static_cast<float>(16777215)), 16777215); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<float>(16777216)), 16777216); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<float>(16777217)), 16777216); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<double>(16777216)), 16777216); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<double>(16777217)), 16777217); >+ >+ EXPECT_EQ(clampTo<int16_t>(static_cast<float>(16777215)), std::numeric_limits<int16_t>::max()); >+ EXPECT_EQ(clampTo<int16_t>(static_cast<float>(16777216)), std::numeric_limits<int16_t>::max()); >+ EXPECT_EQ(clampTo<int16_t>(static_cast<float>(16777217)), std::numeric_limits<int16_t>::max()); >+ >+ // 2**53 = 9007199254740992, the largest integer representable exactly as double. >+ EXPECT_EQ(clampTo<uint64_t>(static_cast<double>(9007199254740991)), static_cast<uint64_t>(9007199254740991)); >+ EXPECT_EQ(clampTo<uint64_t>(static_cast<double>(9007199254740992)), static_cast<uint64_t>(9007199254740992)); >+ EXPECT_EQ(clampTo<uint64_t>(static_cast<double>(9007199254740993)), static_cast<uint64_t>(9007199254740992)); >+ >+ EXPECT_EQ(clampTo<int32_t>(static_cast<double>(9007199254740991)), std::numeric_limits<int32_t>::max()); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<double>(9007199254740992)), std::numeric_limits<int32_t>::max()); >+ EXPECT_EQ(clampTo<int32_t>(static_cast<double>(9007199254740993)), std::numeric_limits<int32_t>::max()); >+} >+ >+template<typename TargetType, typename SourceType> >+static void testClampSameSignIntegers() >+{ >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(0)), static_cast<TargetType>(0)); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(1)), static_cast<TargetType>(1)); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(-1)), std::numeric_limits<TargetType>::is_signed ? static_cast<TargetType>(-1) : std::numeric_limits<TargetType>::max()); >+ >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::min())), std::numeric_limits<TargetType>::min()); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::max())), std::numeric_limits<TargetType>::max()); >+ >+ EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<SourceType>::min()), std::numeric_limits<TargetType>::min()); >+ EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<SourceType>::max()), std::numeric_limits<TargetType>::max()); >+} >+ >+TEST(WTF, clampSameSignIntegers) >+{ >+ testClampSameSignIntegers<char, char>(); >+ testClampSameSignIntegers<unsigned char, unsigned char>(); >+ testClampSameSignIntegers<char, int32_t>(); >+ testClampSameSignIntegers<unsigned char, uint32_t>(); >+ testClampSameSignIntegers<char, int64_t>(); >+ testClampSameSignIntegers<unsigned char, uint64_t>(); >+ >+ testClampSameSignIntegers<int32_t, int32_t>(); >+ testClampSameSignIntegers<uint32_t, uint32_t>(); >+ testClampSameSignIntegers<int32_t, int64_t>(); >+ testClampSameSignIntegers<uint32_t, uint64_t>(); >+ testClampSameSignIntegers<int16_t, int64_t>(); >+ testClampSameSignIntegers<uint16_t, uint64_t>(); >+} >+ >+template<typename TargetType, typename SourceType> >+static void testClampUnsignedToSigned() >+{ >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(0)), static_cast<TargetType>(0)); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(1)), static_cast<TargetType>(1)); >+ >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::max()) - 1), std::numeric_limits<TargetType>::max() - 1); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::max())), std::numeric_limits<TargetType>::max()); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::max()) + 1), std::numeric_limits<TargetType>::max()); >+ EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<SourceType>::max()), std::numeric_limits<TargetType>::max()); >+ EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<SourceType>::max() - 1), std::numeric_limits<TargetType>::max()); >+} >+ >+TEST(WTF, clampUnsignedToSigned) >+{ >+ testClampUnsignedToSigned<char, unsigned char>(); >+ testClampUnsignedToSigned<char, uint32_t>(); >+ testClampUnsignedToSigned<int32_t, uint32_t>(); >+ testClampUnsignedToSigned<int64_t, uint64_t>(); >+ testClampUnsignedToSigned<int32_t, uint64_t>(); >+ testClampUnsignedToSigned<int16_t, uint32_t>(); >+ testClampUnsignedToSigned<int16_t, uint64_t>(); >+} >+ >+template<typename TargetType, typename SourceType> >+static void testClampSignedToUnsigned() >+{ >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(0)), static_cast<TargetType>(0)); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(1)), static_cast<TargetType>(1)); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(-1)), static_cast<TargetType>(0)); >+ >+ if (sizeof(TargetType) < sizeof(SourceType)) { >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::min())), static_cast<TargetType>(0)); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::max()) - 1), std::numeric_limits<TargetType>::max() - 1); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::max())), std::numeric_limits<TargetType>::max()); >+ EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::max()) + 1), std::numeric_limits<TargetType>::max()); >+ } >+ >+ EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<SourceType>::min()), static_cast<TargetType>(0)); >+ if (sizeof(TargetType) < sizeof(SourceType)) >+ EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<SourceType>::max()), std::numeric_limits<TargetType>::max()); >+ else >+ EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<SourceType>::max()), static_cast<TargetType>(std::numeric_limits<SourceType>::max())); >+} >+ >+TEST(WTF, clampSignedToUnsigned) >+{ >+ testClampSignedToUnsigned<unsigned char, char>(); >+ testClampSignedToUnsigned<unsigned char, int32_t>(); >+ testClampSignedToUnsigned<uint32_t, int32_t>(); >+ testClampSignedToUnsigned<uint64_t, int64_t>(); >+ testClampSignedToUnsigned<uint32_t, int64_t>(); >+ testClampSignedToUnsigned<uint16_t, int32_t>(); >+ testClampSignedToUnsigned<uint16_t, int64_t>(); >+} >+ > TEST(WTF, roundUpToPowerOfTwo) > { > EXPECT_EQ(WTF::roundUpToPowerOfTwo(UINT32_MAX), 0U);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 194263
:
361143
|
361236
|
361273
|
361445
|
361473
|
361492