Make webrtc units division by integer constexpr

std::round is not constexpr until c++23 and force conversion to floating point which is unnecessary for integer devision

For integer division change rounding to 'round down' from 'round to nearest' as less surprising.

Bug: webrtc:13756
Change-Id: I9c2382bafc9ddccb0f54d6e7bf8cac4f2a3175a1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/265863
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37250}
This commit is contained in:
Danil Chapovalov 2022-06-17 10:18:21 +02:00 committed by WebRTC LUCI CQ
parent d970b0901b
commit ef9bcd17a5
2 changed files with 16 additions and 7 deletions

View file

@ -266,14 +266,18 @@ class RelativeUnit : public UnitBase<Unit_T> {
return UnitBase<Unit_T>::template ToValue<double>() /
other.template ToValue<double>();
}
template <typename T>
constexpr typename std::enable_if<std::is_arithmetic<T>::value, Unit_T>::type
operator/(const T& scalar) const {
return UnitBase<Unit_T>::FromValue(
std::round(UnitBase<Unit_T>::template ToValue<int64_t>() / scalar));
template <typename T,
typename std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
Unit_T operator/(T scalar) const {
return UnitBase<Unit_T>::FromValue(std::llround(this->ToValue() / scalar));
}
constexpr Unit_T operator*(double scalar) const {
return UnitBase<Unit_T>::FromValue(std::round(this->ToValue() * scalar));
template <typename T,
typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
constexpr Unit_T operator/(T scalar) const {
return UnitBase<Unit_T>::FromValue(this->ToValue() / scalar);
}
Unit_T operator*(double scalar) const {
return UnitBase<Unit_T>::FromValue(std::llround(this->ToValue() * scalar));
}
constexpr Unit_T operator*(int64_t scalar) const {
return UnitBase<Unit_T>::FromValue(this->ToValue() * scalar);

View file

@ -68,6 +68,7 @@ TEST(UnitBaseTest, ConstExpr) {
static_assert(kTestUnitValue.ToValueOr(0) == kValue, "");
static_assert(TestUnitAddKilo(kTestUnitValue, 2).ToValue() == kValue + 2000,
"");
static_assert(TestUnit::FromValue(500) / 2 == TestUnit::FromValue(250));
}
TEST(UnitBaseTest, GetBackSameValues) {
@ -216,6 +217,10 @@ TEST(UnitBaseTest, MathOperations) {
EXPECT_EQ(mutable_delta, TestUnit::FromKilo(kValueA + kValueB));
mutable_delta -= TestUnit::FromKilo(kValueB);
EXPECT_EQ(mutable_delta, TestUnit::FromKilo(kValueA));
// Division by an int rounds towards zero to follow regular int division.
EXPECT_EQ(TestUnit::FromValue(789) / 10, TestUnit::FromValue(78));
EXPECT_EQ(TestUnit::FromValue(-789) / 10, TestUnit::FromValue(-78));
}
TEST(UnitBaseTest, InfinityOperations) {