Index: webrtc/base/safe_minmax_unittest.cc |
diff --git a/webrtc/base/safe_minmax_unittest.cc b/webrtc/base/safe_minmax_unittest.cc |
index 519158b6ed78c1e04d377918cf32d2b990a21670..1709a28b15c5874620570e57f3575232cb950c67 100644 |
--- a/webrtc/base/safe_minmax_unittest.cc |
+++ b/webrtc/base/safe_minmax_unittest.cc |
@@ -18,8 +18,9 @@ namespace rtc { |
namespace { |
-// Functions that check that SafeMin() and SafeMax() return the specified type. |
-// The functions that end in "R" use an explicitly given return type. |
+// Functions that check that SafeMin(), SafeMax(), and SafeClamp() return the |
+// specified type. The functions that end in "R" use an explicitly given return |
+// type. |
template <typename T1, typename T2, typename Tmin, typename Tmax> |
constexpr bool TypeCheckMinMax() { |
@@ -41,6 +42,21 @@ constexpr bool TypeCheckMaxR() { |
decltype(SafeMax<R>(std::declval<T1>(), std::declval<T2>())), R>::value; |
} |
+template <typename T, typename L, typename H, typename R> |
+constexpr bool TypeCheckClamp() { |
+ return std::is_same<decltype(SafeClamp(std::declval<T>(), std::declval<L>(), |
+ std::declval<H>())), |
+ R>::value; |
+} |
+ |
+template <typename T, typename L, typename H, typename R> |
+constexpr bool TypeCheckClampR() { |
+ return std::is_same<decltype(SafeClamp<R>(std::declval<T>(), |
+ std::declval<L>(), |
+ std::declval<H>())), |
+ R>::value; |
+} |
+ |
// clang-format off |
// SafeMin/SafeMax: Check that all combinations of signed/unsigned 8/64 bits |
@@ -62,6 +78,73 @@ static_assert(TypeCheckMinMax<uint64_t, uint8_t, uint8_t, uint64_t>(), ""); |
static_assert(TypeCheckMinMax<uint64_t, int64_t, int64_t, uint64_t>(), ""); |
static_assert(TypeCheckMinMax<uint64_t, uint64_t, uint64_t, uint64_t>(), ""); |
+// SafeClamp: Check that all combinations of signed/unsigned 8/64 bits give the |
+// correct result type. |
+static_assert(TypeCheckClamp< int8_t, int8_t, int8_t, int8_t>(), ""); |
+static_assert(TypeCheckClamp< int8_t, int8_t, uint8_t, int8_t>(), ""); |
+static_assert(TypeCheckClamp< int8_t, int8_t, int64_t, int8_t>(), ""); |
+static_assert(TypeCheckClamp< int8_t, int8_t, uint64_t, int8_t>(), ""); |
+static_assert(TypeCheckClamp< int8_t, uint8_t, int8_t, int8_t>(), ""); |
+static_assert(TypeCheckClamp< int8_t, uint8_t, uint8_t, uint8_t>(), ""); |
+static_assert(TypeCheckClamp< int8_t, uint8_t, int64_t, int16_t>(), ""); |
+static_assert(TypeCheckClamp< int8_t, uint8_t, uint64_t, int16_t>(), ""); |
+static_assert(TypeCheckClamp< int8_t, int64_t, int8_t, int8_t>(), ""); |
+static_assert(TypeCheckClamp< int8_t, int64_t, uint8_t, int16_t>(), ""); |
+static_assert(TypeCheckClamp< int8_t, int64_t, int64_t, int64_t>(), ""); |
+static_assert(TypeCheckClamp< int8_t, int64_t, uint64_t, int64_t>(), ""); |
+static_assert(TypeCheckClamp< int8_t, uint64_t, int8_t, int8_t>(), ""); |
+static_assert(TypeCheckClamp< int8_t, uint64_t, uint8_t, int16_t>(), ""); |
+static_assert(TypeCheckClamp< int8_t, uint64_t, int64_t, int64_t>(), ""); |
+static_assert(TypeCheckClamp< int8_t, uint64_t, uint64_t, uint64_t>(), ""); |
+static_assert(TypeCheckClamp< uint8_t, int8_t, int8_t, int8_t>(), ""); |
+static_assert(TypeCheckClamp< uint8_t, int8_t, uint8_t, uint8_t>(), ""); |
+static_assert(TypeCheckClamp< uint8_t, int8_t, int64_t, int16_t>(), ""); |
+static_assert(TypeCheckClamp< uint8_t, int8_t, uint64_t, uint8_t>(), ""); |
+static_assert(TypeCheckClamp< uint8_t, uint8_t, int8_t, uint8_t>(), ""); |
+static_assert(TypeCheckClamp< uint8_t, uint8_t, uint8_t, uint8_t>(), ""); |
+static_assert(TypeCheckClamp< uint8_t, uint8_t, int64_t, uint8_t>(), ""); |
+static_assert(TypeCheckClamp< uint8_t, uint8_t, uint64_t, uint8_t>(), ""); |
+static_assert(TypeCheckClamp< uint8_t, int64_t, int8_t, int8_t>(), ""); |
+static_assert(TypeCheckClamp< uint8_t, int64_t, uint8_t, uint8_t>(), ""); |
+static_assert(TypeCheckClamp< uint8_t, int64_t, int64_t, int64_t>(), ""); |
+static_assert(TypeCheckClamp< uint8_t, int64_t, uint64_t, uint64_t>(), ""); |
+static_assert(TypeCheckClamp< uint8_t, uint64_t, int8_t, uint8_t>(), ""); |
+static_assert(TypeCheckClamp< uint8_t, uint64_t, uint8_t, uint8_t>(), ""); |
+static_assert(TypeCheckClamp< uint8_t, uint64_t, int64_t, uint64_t>(), ""); |
+static_assert(TypeCheckClamp< uint8_t, uint64_t, uint64_t, uint64_t>(), ""); |
+static_assert(TypeCheckClamp< int64_t, int8_t, int8_t, int8_t>(), ""); |
+static_assert(TypeCheckClamp< int64_t, int8_t, uint8_t, int16_t>(), ""); |
+static_assert(TypeCheckClamp< int64_t, int8_t, int64_t, int64_t>(), ""); |
+static_assert(TypeCheckClamp< int64_t, int8_t, uint64_t, int64_t>(), ""); |
+static_assert(TypeCheckClamp< int64_t, uint8_t, int8_t, int8_t>(), ""); |
+static_assert(TypeCheckClamp< int64_t, uint8_t, uint8_t, int16_t>(), ""); |
+static_assert(TypeCheckClamp< int64_t, uint8_t, int64_t, int64_t>(), ""); |
+static_assert(TypeCheckClamp< int64_t, uint8_t, uint64_t, int64_t>(), ""); |
+static_assert(TypeCheckClamp< int64_t, int64_t, int8_t, int64_t>(), ""); |
+static_assert(TypeCheckClamp< int64_t, int64_t, uint8_t, int64_t>(), ""); |
+static_assert(TypeCheckClamp< int64_t, int64_t, int64_t, int64_t>(), ""); |
+static_assert(TypeCheckClamp< int64_t, int64_t, uint64_t, int64_t>(), ""); |
+static_assert(TypeCheckClamp< int64_t, uint64_t, int8_t, int8_t>(), ""); |
+static_assert(TypeCheckClamp< int64_t, uint64_t, uint8_t, int16_t>(), ""); |
+static_assert(TypeCheckClamp< int64_t, uint64_t, int64_t, int64_t>(), ""); |
+static_assert(TypeCheckClamp< int64_t, uint64_t, uint64_t, uint64_t>(), ""); |
+static_assert(TypeCheckClamp<uint64_t, int8_t, int8_t, int8_t>(), ""); |
+static_assert(TypeCheckClamp<uint64_t, int8_t, uint8_t, uint8_t>(), ""); |
+static_assert(TypeCheckClamp<uint64_t, int8_t, int64_t, int64_t>(), ""); |
+static_assert(TypeCheckClamp<uint64_t, int8_t, uint64_t, uint64_t>(), ""); |
+static_assert(TypeCheckClamp<uint64_t, uint8_t, int8_t, uint8_t>(), ""); |
+static_assert(TypeCheckClamp<uint64_t, uint8_t, uint8_t, uint8_t>(), ""); |
+static_assert(TypeCheckClamp<uint64_t, uint8_t, int64_t, uint64_t>(), ""); |
+static_assert(TypeCheckClamp<uint64_t, uint8_t, uint64_t, uint64_t>(), ""); |
+static_assert(TypeCheckClamp<uint64_t, int64_t, int8_t, int8_t>(), ""); |
+static_assert(TypeCheckClamp<uint64_t, int64_t, uint8_t, uint8_t>(), ""); |
+static_assert(TypeCheckClamp<uint64_t, int64_t, int64_t, int64_t>(), ""); |
+static_assert(TypeCheckClamp<uint64_t, int64_t, uint64_t, uint64_t>(), ""); |
+static_assert(TypeCheckClamp<uint64_t, uint64_t, int8_t, uint8_t>(), ""); |
+static_assert(TypeCheckClamp<uint64_t, uint64_t, uint8_t, uint8_t>(), ""); |
+static_assert(TypeCheckClamp<uint64_t, uint64_t, int64_t, uint64_t>(), ""); |
+static_assert(TypeCheckClamp<uint64_t, uint64_t, uint64_t, uint64_t>(), ""); |
+ |
enum DefaultE { kFoo = -17 }; |
enum UInt8E : uint8_t { kBar = 17 }; |
@@ -76,6 +159,35 @@ static_assert(TypeCheckMinMax< UInt8E, unsigned, uint8_t, unsigned>(), ""); |
static_assert(TypeCheckMinMax< UInt8E, DefaultE, int, int>(), ""); |
static_assert(TypeCheckMinMax< UInt8E, UInt8E, uint8_t, uint8_t>(), ""); |
+// SafeClamp: Check that we can use enum types. |
+static_assert(TypeCheckClamp<unsigned, unsigned, unsigned, unsigned>(), ""); |
+static_assert(TypeCheckClamp<unsigned, unsigned, DefaultE, unsigned>(), ""); |
+static_assert(TypeCheckClamp<unsigned, unsigned, UInt8E, uint8_t>(), ""); |
+static_assert(TypeCheckClamp<unsigned, DefaultE, unsigned, unsigned>(), ""); |
+static_assert(TypeCheckClamp<unsigned, DefaultE, DefaultE, int>(), ""); |
+static_assert(TypeCheckClamp<unsigned, DefaultE, UInt8E, uint8_t>(), ""); |
+static_assert(TypeCheckClamp<unsigned, UInt8E, unsigned, unsigned>(), ""); |
+static_assert(TypeCheckClamp<unsigned, UInt8E, DefaultE, unsigned>(), ""); |
+static_assert(TypeCheckClamp<unsigned, UInt8E, UInt8E, uint8_t>(), ""); |
+static_assert(TypeCheckClamp<DefaultE, unsigned, unsigned, unsigned>(), ""); |
+static_assert(TypeCheckClamp<DefaultE, unsigned, DefaultE, int>(), ""); |
+static_assert(TypeCheckClamp<DefaultE, unsigned, UInt8E, int16_t>(), ""); |
+static_assert(TypeCheckClamp<DefaultE, DefaultE, unsigned, int>(), ""); |
+static_assert(TypeCheckClamp<DefaultE, DefaultE, DefaultE, int>(), ""); |
+static_assert(TypeCheckClamp<DefaultE, DefaultE, UInt8E, int>(), ""); |
+static_assert(TypeCheckClamp<DefaultE, UInt8E, unsigned, int>(), ""); |
+static_assert(TypeCheckClamp<DefaultE, UInt8E, DefaultE, int>(), ""); |
+static_assert(TypeCheckClamp<DefaultE, UInt8E, UInt8E, int16_t>(), ""); |
+static_assert(TypeCheckClamp< UInt8E, unsigned, unsigned, unsigned>(), ""); |
+static_assert(TypeCheckClamp< UInt8E, unsigned, DefaultE, unsigned>(), ""); |
+static_assert(TypeCheckClamp< UInt8E, unsigned, UInt8E, uint8_t>(), ""); |
+static_assert(TypeCheckClamp< UInt8E, DefaultE, unsigned, unsigned>(), ""); |
+static_assert(TypeCheckClamp< UInt8E, DefaultE, DefaultE, int>(), ""); |
+static_assert(TypeCheckClamp< UInt8E, DefaultE, UInt8E, uint8_t>(), ""); |
+static_assert(TypeCheckClamp< UInt8E, UInt8E, unsigned, uint8_t>(), ""); |
+static_assert(TypeCheckClamp< UInt8E, UInt8E, DefaultE, uint8_t>(), ""); |
+static_assert(TypeCheckClamp< UInt8E, UInt8E, UInt8E, uint8_t>(), ""); |
+ |
using ld = long double; |
// SafeMin/SafeMax: Check that all floating-point combinations give the |
@@ -90,6 +202,36 @@ static_assert(TypeCheckMinMax< ld, float, ld, ld>(), ""); |
static_assert(TypeCheckMinMax< ld, double, ld, ld>(), ""); |
static_assert(TypeCheckMinMax< ld, ld, ld, ld>(), ""); |
+// SafeClamp: Check that all floating-point combinations give the correct |
+// result type. |
+static_assert(TypeCheckClamp< float, float, float, float>(), ""); |
+static_assert(TypeCheckClamp< float, float, double, double>(), ""); |
+static_assert(TypeCheckClamp< float, float, ld, ld>(), ""); |
+static_assert(TypeCheckClamp< float, double, float, double>(), ""); |
+static_assert(TypeCheckClamp< float, double, double, double>(), ""); |
+static_assert(TypeCheckClamp< float, double, ld, ld>(), ""); |
+static_assert(TypeCheckClamp< float, ld, float, ld>(), ""); |
+static_assert(TypeCheckClamp< float, ld, double, ld>(), ""); |
+static_assert(TypeCheckClamp< float, ld, ld, ld>(), ""); |
+static_assert(TypeCheckClamp<double, float, float, double>(), ""); |
+static_assert(TypeCheckClamp<double, float, double, double>(), ""); |
+static_assert(TypeCheckClamp<double, float, ld, ld>(), ""); |
+static_assert(TypeCheckClamp<double, double, float, double>(), ""); |
+static_assert(TypeCheckClamp<double, double, double, double>(), ""); |
+static_assert(TypeCheckClamp<double, double, ld, ld>(), ""); |
+static_assert(TypeCheckClamp<double, ld, float, ld>(), ""); |
+static_assert(TypeCheckClamp<double, ld, double, ld>(), ""); |
+static_assert(TypeCheckClamp<double, ld, ld, ld>(), ""); |
+static_assert(TypeCheckClamp< ld, float, float, ld>(), ""); |
+static_assert(TypeCheckClamp< ld, float, double, ld>(), ""); |
+static_assert(TypeCheckClamp< ld, float, ld, ld>(), ""); |
+static_assert(TypeCheckClamp< ld, double, float, ld>(), ""); |
+static_assert(TypeCheckClamp< ld, double, double, ld>(), ""); |
+static_assert(TypeCheckClamp< ld, double, ld, ld>(), ""); |
+static_assert(TypeCheckClamp< ld, ld, float, ld>(), ""); |
+static_assert(TypeCheckClamp< ld, ld, double, ld>(), ""); |
+static_assert(TypeCheckClamp< ld, ld, ld, ld>(), ""); |
+ |
// clang-format on |
// SafeMin/SafeMax: Check some cases of explicitly specified return type. The |
@@ -103,12 +245,24 @@ static_assert(TypeCheckMinR<uint32_t, uint64_t, uint32_t>(), ""); |
static_assert(TypeCheckMaxR<uint32_t, int32_t, uint32_t>(), ""); |
// static_assert(TypeCheckMaxR<uint32_t, int32_t, int32_t>(), ""); |
+// SafeClamp: Check some cases of explicitly specified return type. The |
+// commented-out lines give compilation errors due to the requested return type |
+// being too small. |
+static_assert(TypeCheckClampR<int16_t, int8_t, uint8_t, int16_t>(), ""); |
+static_assert(TypeCheckClampR<int16_t, int8_t, uint8_t, int32_t>(), ""); |
+// static_assert(TypeCheckClampR<int16_t, int8_t, uint8_t, uint32_t>(), ""); |
+ |
template <typename T1, typename T2, typename Tmin, typename Tmax> |
constexpr bool CheckMinMax(T1 a, T2 b, Tmin min, Tmax max) { |
return TypeCheckMinMax<T1, T2, Tmin, Tmax>() && SafeMin(a, b) == min && |
SafeMax(a, b) == max; |
} |
+template <typename T, typename L, typename H, typename R> |
+bool CheckClamp(T x, L min, H max, R clamped) { |
+ return TypeCheckClamp<T, L, H, R>() && SafeClamp(x, min, max) == clamped; |
+} |
+ |
// SafeMin/SafeMax: Check a few values. |
static_assert(CheckMinMax(int8_t{1}, int8_t{-1}, int8_t{-1}, int8_t{1}), ""); |
static_assert(CheckMinMax(uint8_t{1}, int8_t{-1}, int8_t{-1}, uint8_t{1}), ""); |
@@ -127,6 +281,18 @@ static_assert(CheckMinMax(std::numeric_limits<int32_t>::min(), |
// static_assert(CheckMinMax(1.f, 2, 1.f, 2.f), ""); |
static_assert(CheckMinMax(1.f, 0.0, 0.0, 1.0), ""); |
+// SafeClamp: Check a few values. |
+TEST(SafeMinmaxTest, Clamp) { |
+ EXPECT_TRUE(CheckClamp(int32_t{-1000000}, std::numeric_limits<int16_t>::min(), |
+ std::numeric_limits<int16_t>::max(), |
+ std::numeric_limits<int16_t>::min())); |
+ EXPECT_TRUE(CheckClamp(uint32_t{1000000}, std::numeric_limits<int16_t>::min(), |
+ std::numeric_limits<int16_t>::max(), |
+ std::numeric_limits<int16_t>::max())); |
+ EXPECT_TRUE(CheckClamp(3.f, -1.0, 1.f, 1.0)); |
+ EXPECT_TRUE(CheckClamp(3.0, -1.f, 1.f, 1.0)); |
+} |
+ |
} // namespace |
// clang-format off |
@@ -145,4 +311,35 @@ uint32_t TestMinSafe(uint32_t a, uint32_t b) { return SafeMin(a, b); } |
// clang-format on |
+int32_t TestClampRef(int32_t x, int32_t a, int32_t b) { |
ossu
2017/06/12 12:21:36
What are these (TestClampRef/TestClampSafe)for? I
kwiberg-webrtc
2017/06/12 17:28:12
See the comment on lines 300-304. I'll try to rear
|
+ return std::max(a, std::min(x, b)); |
+} |
+uint32_t TestClampRef(uint32_t x, uint32_t a, uint32_t b) { |
+ return std::max(a, std::min(x, b)); |
+} |
+int32_t TestClampSafe(int32_t x, int32_t a, int32_t b) { |
+ return SafeClamp(x, a, b); |
+} |
+int32_t TestClampSafe(int32_t x, int32_t a, uint32_t b) { |
+ return SafeClamp(x, a, b); |
+} |
+int32_t TestClampSafe(int32_t x, uint32_t a, int32_t b) { |
+ return SafeClamp(x, a, b); |
+} |
+uint32_t TestClampSafe(int32_t x, uint32_t a, uint32_t b) { |
+ return SafeClamp(x, a, b); |
+} |
+int32_t TestClampSafe(uint32_t x, int32_t a, int32_t b) { |
+ return SafeClamp(x, a, b); |
+} |
+uint32_t TestClampSafe(uint32_t x, int32_t a, uint32_t b) { |
+ return SafeClamp(x, a, b); |
+} |
+int32_t TestClampSafe(uint32_t x, uint32_t a, int32_t b) { |
+ return SafeClamp(x, a, b); |
+} |
+uint32_t TestClampSafe(uint32_t x, uint32_t a, uint32_t b) { |
+ return SafeClamp(x, a, b); |
+} |
+ |
} // namespace rtc |