diff --git a/api/units/data_rate.h b/api/units/data_rate.h index 0d3d6530a7..78c2e0ed9a 100644 --- a/api/units/data_rate.h +++ b/api/units/data_rate.h @@ -65,7 +65,7 @@ class DataRate final : public rtc_units_impl::RelativeUnit { return ToFraction<8, T>(); } template - T kbps() const { + constexpr T kbps() const { return ToFraction<1000, T>(); } constexpr int64_t bps_or(int64_t fallback_value) const { @@ -84,7 +84,7 @@ class DataRate final : public rtc_units_impl::RelativeUnit { }; namespace data_rate_impl { -inline int64_t Microbits(const DataSize& size) { +inline constexpr int64_t Microbits(const DataSize& size) { constexpr int64_t kMaxBeforeConversion = std::numeric_limits::max() / 8000000; RTC_DCHECK_LE(size.bytes(), kMaxBeforeConversion) @@ -92,7 +92,7 @@ inline int64_t Microbits(const DataSize& size) { return size.bytes() * 8000000; } -inline int64_t MillibytePerSec(const DataRate& size) { +inline constexpr int64_t MillibytePerSec(const DataRate& size) { constexpr int64_t kMaxBeforeConversion = std::numeric_limits::max() / (1000 / 8); RTC_DCHECK_LE(size.bps(), kMaxBeforeConversion) @@ -101,31 +101,36 @@ inline int64_t MillibytePerSec(const DataRate& size) { } } // namespace data_rate_impl -inline DataRate operator/(const DataSize size, const TimeDelta duration) { +inline constexpr DataRate operator/(const DataSize size, + const TimeDelta duration) { return DataRate::bps(data_rate_impl::Microbits(size) / duration.us()); } -inline TimeDelta operator/(const DataSize size, const DataRate rate) { +inline constexpr TimeDelta operator/(const DataSize size, const DataRate rate) { return TimeDelta::us(data_rate_impl::Microbits(size) / rate.bps()); } -inline DataSize operator*(const DataRate rate, const TimeDelta duration) { +inline constexpr DataSize operator*(const DataRate rate, + const TimeDelta duration) { int64_t microbits = rate.bps() * duration.us(); return DataSize::bytes((microbits + 4000000) / 8000000); } -inline DataSize operator*(const TimeDelta duration, const DataRate rate) { +inline constexpr DataSize operator*(const TimeDelta duration, + const DataRate rate) { return rate * duration; } -inline DataSize operator/(const DataRate rate, const Frequency frequency) { +inline constexpr DataSize operator/(const DataRate rate, + const Frequency frequency) { int64_t millihertz = frequency.millihertz(); // Note that the value is truncated here reather than rounded, potentially // introducing an error of .5 bytes if rounding were expected. return DataSize::bytes(data_rate_impl::MillibytePerSec(rate) / millihertz); } -inline Frequency operator/(const DataRate rate, const DataSize size) { +inline constexpr Frequency operator/(const DataRate rate, const DataSize size) { return Frequency::millihertz(data_rate_impl::MillibytePerSec(rate) / size.bytes()); } -inline DataRate operator*(const DataSize size, const Frequency frequency) { +inline constexpr DataRate operator*(const DataSize size, + const Frequency frequency) { RTC_DCHECK(frequency.IsZero() || size.bytes() <= std::numeric_limits::max() / 8 / frequency.millihertz()); @@ -133,7 +138,8 @@ inline DataRate operator*(const DataSize size, const Frequency frequency) { size.bytes() * 8 * frequency.millihertz(); return DataRate::bps((millibits_per_second + 500) / 1000); } -inline DataRate operator*(const Frequency frequency, const DataSize size) { +inline constexpr DataRate operator*(const Frequency frequency, + const DataSize size) { return size * frequency; } diff --git a/api/units/data_size.h b/api/units/data_size.h index ca4c1da212..d294016489 100644 --- a/api/units/data_size.h +++ b/api/units/data_size.h @@ -32,12 +32,12 @@ class DataSize final : public rtc_units_impl::RelativeUnit { } template - static DataSize bytes(T bytes) { + static constexpr DataSize bytes(T bytes) { static_assert(std::is_arithmetic::value, ""); return FromValue(bytes); } template - T bytes() const { + constexpr T bytes() const { return ToValue(); } diff --git a/api/units/frequency.h b/api/units/frequency.h index aa54cb5db8..45561f4aee 100644 --- a/api/units/frequency.h +++ b/api/units/frequency.h @@ -32,21 +32,21 @@ class Frequency final : public rtc_units_impl::RelativeUnit { return FromFraction(1000, hertz); } template - static Frequency hertz(T hertz) { + static constexpr Frequency hertz(T hertz) { static_assert(std::is_arithmetic::value, ""); return FromFraction(1000, hertz); } template - static Frequency millihertz(T hertz) { + static constexpr Frequency millihertz(T hertz) { static_assert(std::is_arithmetic::value, ""); return FromValue(hertz); } template - T hertz() const { + constexpr T hertz() const { return ToFraction<1000, T>(); } template - T millihertz() const { + constexpr T millihertz() const { return ToValue(); } @@ -56,7 +56,8 @@ class Frequency final : public rtc_units_impl::RelativeUnit { static constexpr bool one_sided = true; }; -inline Frequency operator/(int64_t nominator, const TimeDelta& interval) { +inline constexpr Frequency operator/(int64_t nominator, + const TimeDelta& interval) { constexpr int64_t kKiloPerMicro = 1000 * 1000000; RTC_DCHECK_LE(nominator, std::numeric_limits::max() / kKiloPerMicro); RTC_CHECK(interval.IsFinite()); @@ -64,7 +65,8 @@ inline Frequency operator/(int64_t nominator, const TimeDelta& interval) { return Frequency::millihertz(nominator * kKiloPerMicro / interval.us()); } -inline TimeDelta operator/(int64_t nominator, const Frequency& frequency) { +inline constexpr TimeDelta operator/(int64_t nominator, + const Frequency& frequency) { constexpr int64_t kMegaPerMilli = 1000000 * 1000; RTC_DCHECK_LE(nominator, std::numeric_limits::max() / kMegaPerMilli); RTC_CHECK(frequency.IsFinite()); diff --git a/api/units/time_delta.h b/api/units/time_delta.h index 0c3fd9d0a8..030974f8c2 100644 --- a/api/units/time_delta.h +++ b/api/units/time_delta.h @@ -46,34 +46,34 @@ class TimeDelta final : public rtc_units_impl::RelativeUnit { return FromValue(us); } template - static TimeDelta seconds(T seconds) { + static constexpr TimeDelta seconds(T seconds) { static_assert(std::is_arithmetic::value, ""); return FromFraction(1'000'000, seconds); } template - static TimeDelta ms(T milliseconds) { + static constexpr TimeDelta ms(T milliseconds) { static_assert(std::is_arithmetic::value, ""); return FromFraction(1000, milliseconds); } template - static TimeDelta us(T microseconds) { + static constexpr TimeDelta us(T microseconds) { static_assert(std::is_arithmetic::value, ""); return FromValue(microseconds); } template - T seconds() const { + constexpr T seconds() const { return ToFraction<1000000, T>(); } template - T ms() const { + constexpr T ms() const { return ToFraction<1000, T>(); } template - T us() const { + constexpr T us() const { return ToValue(); } template - T ns() const { + constexpr T ns() const { return ToMultiple<1000, T>(); } @@ -87,7 +87,9 @@ class TimeDelta final : public rtc_units_impl::RelativeUnit { return ToValueOr(fallback_value); } - TimeDelta Abs() const { return TimeDelta::us(std::abs(us())); } + constexpr TimeDelta Abs() const { + return us() < 0 ? TimeDelta::us(-us()) : *this; + } private: friend class rtc_units_impl::UnitBase; diff --git a/api/units/timestamp.h b/api/units/timestamp.h index e12e99d982..f9ed408a22 100644 --- a/api/units/timestamp.h +++ b/api/units/timestamp.h @@ -44,30 +44,30 @@ class Timestamp final : public rtc_units_impl::UnitBase { } template - static Timestamp seconds(T seconds) { + static constexpr Timestamp seconds(T seconds) { static_assert(std::is_arithmetic::value, ""); return FromFraction(1'000'000, seconds); } template - static Timestamp ms(T milliseconds) { + static constexpr Timestamp ms(T milliseconds) { static_assert(std::is_arithmetic::value, ""); return FromFraction(1000, milliseconds); } template - static Timestamp us(T microseconds) { + static constexpr Timestamp us(T microseconds) { static_assert(std::is_arithmetic::value, ""); return FromValue(microseconds); } template - T seconds() const { + constexpr T seconds() const { return ToFraction<1000000, T>(); } template - T ms() const { + constexpr T ms() const { return ToFraction<1000, T>(); } template - T us() const { + constexpr T us() const { return ToValue(); } @@ -81,7 +81,7 @@ class Timestamp final : public rtc_units_impl::UnitBase { return ToValueOr(fallback_value); } - Timestamp operator+(const TimeDelta delta) const { + constexpr Timestamp operator+(const TimeDelta delta) const { if (IsPlusInfinity() || delta.IsPlusInfinity()) { RTC_DCHECK(!IsMinusInfinity()); RTC_DCHECK(!delta.IsMinusInfinity()); @@ -93,7 +93,7 @@ class Timestamp final : public rtc_units_impl::UnitBase { } return Timestamp::us(us() + delta.us()); } - Timestamp operator-(const TimeDelta delta) const { + constexpr Timestamp operator-(const TimeDelta delta) const { if (IsPlusInfinity() || delta.IsMinusInfinity()) { RTC_DCHECK(!IsMinusInfinity()); RTC_DCHECK(!delta.IsPlusInfinity()); @@ -105,7 +105,7 @@ class Timestamp final : public rtc_units_impl::UnitBase { } return Timestamp::us(us() - delta.us()); } - TimeDelta operator-(const Timestamp other) const { + constexpr TimeDelta operator-(const Timestamp other) const { if (IsPlusInfinity() || other.IsMinusInfinity()) { RTC_DCHECK(!IsMinusInfinity()); RTC_DCHECK(!other.IsPlusInfinity()); @@ -117,11 +117,11 @@ class Timestamp final : public rtc_units_impl::UnitBase { } return TimeDelta::us(us() - other.us()); } - Timestamp& operator-=(const TimeDelta delta) { + constexpr Timestamp& operator-=(const TimeDelta delta) { *this = *this - delta; return *this; } - Timestamp& operator+=(const TimeDelta delta) { + constexpr Timestamp& operator+=(const TimeDelta delta) { *this = *this + delta; return *this; } diff --git a/rtc_base/units/unit_base.h b/rtc_base/units/unit_base.h index b988f2801f..7196bae346 100644 --- a/rtc_base/units/unit_base.h +++ b/rtc_base/units/unit_base.h @@ -68,21 +68,21 @@ class UnitBase { constexpr bool operator<(const Unit_T& other) const { return value_ < other.value_; } - Unit_T RoundTo(const Unit_T& resolution) const { + constexpr Unit_T RoundTo(const Unit_T& resolution) const { RTC_DCHECK(IsFinite()); RTC_DCHECK(resolution.IsFinite()); RTC_DCHECK_GT(resolution.value_, 0); return Unit_T((value_ + resolution.value_ / 2) / resolution.value_) * resolution.value_; } - Unit_T RoundUpTo(const Unit_T& resolution) const { + constexpr Unit_T RoundUpTo(const Unit_T& resolution) const { RTC_DCHECK(IsFinite()); RTC_DCHECK(resolution.IsFinite()); RTC_DCHECK_GT(resolution.value_, 0); return Unit_T((value_ + resolution.value_ - 1) / resolution.value_) * resolution.value_; } - Unit_T RoundDownTo(const Unit_T& resolution) const { + constexpr Unit_T RoundDownTo(const Unit_T& resolution) const { RTC_DCHECK(IsFinite()); RTC_DCHECK(resolution.IsFinite()); RTC_DCHECK_GT(resolution.value_, 0); @@ -132,7 +132,8 @@ class UnitBase { } template - typename std::enable_if::value, T>::type ToValue() const { + constexpr typename std::enable_if::value, T>::type + ToValue() const { RTC_DCHECK(IsFinite()); return rtc::dchecked_cast(value_); } @@ -150,8 +151,8 @@ class UnitBase { } template - typename std::enable_if::value, T>::type ToFraction() - const { + constexpr typename std::enable_if::value, T>::type + ToFraction() const { RTC_DCHECK(IsFinite()); if (Unit_T::one_sided) { return rtc::dchecked_cast( @@ -175,8 +176,8 @@ class UnitBase { } template - typename std::enable_if::value, T>::type ToMultiple() - const { + constexpr typename std::enable_if::value, T>::type + ToMultiple() const { RTC_DCHECK_GE(ToValue(), std::numeric_limits::min() / Factor); RTC_DCHECK_LE(ToValue(), std::numeric_limits::max() / Factor); return rtc::dchecked_cast(ToValue() * Factor); @@ -200,9 +201,9 @@ class UnitBase { return std::numeric_limits::min(); } - Unit_T& AsSubClassRef() { return reinterpret_cast(*this); } + constexpr Unit_T& AsSubClassRef() { return static_cast(*this); } constexpr const Unit_T& AsSubClassRef() const { - return reinterpret_cast(*this); + return static_cast(*this); } // Assumes that n >= 0 and d > 0. static constexpr int64_t DivRoundPositiveToNearest(int64_t n, int64_t d) { @@ -222,14 +223,14 @@ class UnitBase { template class RelativeUnit : public UnitBase { public: - Unit_T Clamped(Unit_T min_value, Unit_T max_value) const { + constexpr Unit_T Clamped(Unit_T min_value, Unit_T max_value) const { return std::max(min_value, std::min(UnitBase::AsSubClassRef(), max_value)); } - void Clamp(Unit_T min_value, Unit_T max_value) { + constexpr void Clamp(Unit_T min_value, Unit_T max_value) { *this = Clamped(min_value, max_value); } - Unit_T operator+(const Unit_T other) const { + constexpr Unit_T operator+(const Unit_T other) const { if (this->IsPlusInfinity() || other.IsPlusInfinity()) { RTC_DCHECK(!this->IsMinusInfinity()); RTC_DCHECK(!other.IsMinusInfinity()); @@ -241,7 +242,7 @@ class RelativeUnit : public UnitBase { } return UnitBase::FromValue(this->ToValue() + other.ToValue()); } - Unit_T operator-(const Unit_T other) const { + constexpr Unit_T operator-(const Unit_T other) const { if (this->IsPlusInfinity() || other.IsMinusInfinity()) { RTC_DCHECK(!this->IsMinusInfinity()); RTC_DCHECK(!other.IsPlusInfinity()); @@ -253,11 +254,11 @@ class RelativeUnit : public UnitBase { } return UnitBase::FromValue(this->ToValue() - other.ToValue()); } - Unit_T& operator+=(const Unit_T other) { + constexpr Unit_T& operator+=(const Unit_T other) { *this = *this + other; return this->AsSubClassRef(); } - Unit_T& operator-=(const Unit_T other) { + constexpr Unit_T& operator-=(const Unit_T other) { *this = *this - other; return this->AsSubClassRef(); } @@ -266,18 +267,18 @@ class RelativeUnit : public UnitBase { other.template ToValue(); } template - typename std::enable_if::value, Unit_T>::type operator/( - const T& scalar) const { + constexpr typename std::enable_if::value, Unit_T>::type + operator/(const T& scalar) const { return UnitBase::FromValue( std::round(UnitBase::template ToValue() / scalar)); } - Unit_T operator*(const double scalar) const { + constexpr Unit_T operator*(double scalar) const { return UnitBase::FromValue(std::round(this->ToValue() * scalar)); } - Unit_T operator*(const int64_t scalar) const { + constexpr Unit_T operator*(int64_t scalar) const { return UnitBase::FromValue(this->ToValue() * scalar); } - Unit_T operator*(const int32_t scalar) const { + constexpr Unit_T operator*(int32_t scalar) const { return UnitBase::FromValue(this->ToValue() * scalar); } @@ -286,17 +287,15 @@ class RelativeUnit : public UnitBase { }; template -inline Unit_T operator*(const double scalar, const RelativeUnit other) { +inline constexpr Unit_T operator*(double scalar, RelativeUnit other) { return other * scalar; } template -inline Unit_T operator*(const int64_t scalar, - const RelativeUnit other) { +inline constexpr Unit_T operator*(int64_t scalar, RelativeUnit other) { return other * scalar; } template -inline Unit_T operator*(const int32_t& scalar, - const RelativeUnit other) { +inline constexpr Unit_T operator*(int32_t scalar, RelativeUnit other) { return other * scalar; } diff --git a/rtc_base/units/unit_base_unittest.cc b/rtc_base/units/unit_base_unittest.cc index ccb5ce05b3..02ead7ce0b 100644 --- a/rtc_base/units/unit_base_unittest.cc +++ b/rtc_base/units/unit_base_unittest.cc @@ -43,6 +43,10 @@ class TestUnit final : public rtc_units_impl::RelativeUnit { static constexpr bool one_sided = false; using RelativeUnit::RelativeUnit; }; +constexpr TestUnit TestUnitAddKilo(TestUnit value, int add_kilo) { + value += TestUnit::FromKilo(add_kilo); + return value; +} } // namespace namespace test { TEST(UnitBaseTest, ConstExpr) { @@ -62,6 +66,8 @@ TEST(UnitBaseTest, ConstExpr) { static_assert(kTestUnitKilo.ToKiloOr(0) == kValue, ""); static_assert(kTestUnitValue.ToValueOr(0) == kValue, ""); + static_assert(TestUnitAddKilo(kTestUnitValue, 2).ToValue() == kValue + 2000, + ""); } TEST(UnitBaseTest, GetBackSameValues) { diff --git a/test/scenario/scenario.cc b/test/scenario/scenario.cc index e4e4f8d2d0..232cf06d41 100644 --- a/test/scenario/scenario.cc +++ b/test/scenario/scenario.cc @@ -30,7 +30,6 @@ ABSL_FLAG(std::string, namespace webrtc { namespace test { namespace { -const Timestamp kSimulatedStartTime = Timestamp::seconds(100000); std::unique_ptr GetScenarioLogManager( std::string file_name) {