From ef9bcd17a5ff6f8818b0c4eecae1f493bb58fb66 Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Fri, 17 Jun 2022 10:18:21 +0200 Subject: [PATCH] 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 Commit-Queue: Danil Chapovalov Cr-Commit-Position: refs/heads/main@{#37250} --- rtc_base/units/unit_base.h | 18 +++++++++++------- rtc_base/units/unit_base_unittest.cc | 5 +++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/rtc_base/units/unit_base.h b/rtc_base/units/unit_base.h index 0cd6a61215..bbf7300a16 100644 --- a/rtc_base/units/unit_base.h +++ b/rtc_base/units/unit_base.h @@ -266,14 +266,18 @@ class RelativeUnit : public UnitBase { return UnitBase::template ToValue() / other.template ToValue(); } - template - constexpr typename std::enable_if::value, Unit_T>::type - operator/(const T& scalar) const { - return UnitBase::FromValue( - std::round(UnitBase::template ToValue() / scalar)); + template >* = nullptr> + Unit_T operator/(T scalar) const { + return UnitBase::FromValue(std::llround(this->ToValue() / scalar)); } - constexpr Unit_T operator*(double scalar) const { - return UnitBase::FromValue(std::round(this->ToValue() * scalar)); + template >* = nullptr> + constexpr Unit_T operator/(T scalar) const { + return UnitBase::FromValue(this->ToValue() / scalar); + } + Unit_T operator*(double scalar) const { + return UnitBase::FromValue(std::llround(this->ToValue() * scalar)); } constexpr Unit_T operator*(int64_t scalar) const { return UnitBase::FromValue(this->ToValue() * scalar); diff --git a/rtc_base/units/unit_base_unittest.cc b/rtc_base/units/unit_base_unittest.cc index 9eb0c33ae5..258d7d1268 100644 --- a/rtc_base/units/unit_base_unittest.cc +++ b/rtc_base/units/unit_base_unittest.cc @@ -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) {