Adds infinite addition and subtraction to time units.

This prepares for allowing use making arithmetic operators constexpr.

This also makes it easier to use for comparisons with offsets.
Now a > b + 10 ms works even if b is infinite.

Bug: webrtc:9574
Change-Id: Ie36092b72c2ec0f0c541641199a39155f5a796f3
Reviewed-on: https://webrtc-review.googlesource.com/96820
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24530}
This commit is contained in:
Sebastian Jansson 2018-08-30 13:58:38 +02:00 committed by Commit Bot
parent 16e27a1dc5
commit 88c1a9ecbc
4 changed files with 65 additions and 4 deletions

View file

@ -188,17 +188,35 @@ class TimeDelta {
return microseconds_ == timedelta_impl::kMinusInfinityVal;
}
TimeDelta operator+(const TimeDelta& other) const {
if (IsPlusInfinity() || other.IsPlusInfinity()) {
RTC_DCHECK(!IsMinusInfinity());
RTC_DCHECK(!other.IsMinusInfinity());
return PlusInfinity();
} else if (IsMinusInfinity() || other.IsMinusInfinity()) {
RTC_DCHECK(!IsPlusInfinity());
RTC_DCHECK(!other.IsPlusInfinity());
return MinusInfinity();
}
return TimeDelta::us(us() + other.us());
}
TimeDelta operator-(const TimeDelta& other) const {
if (IsPlusInfinity() || other.IsMinusInfinity()) {
RTC_DCHECK(!IsMinusInfinity());
RTC_DCHECK(!other.IsPlusInfinity());
return PlusInfinity();
} else if (IsMinusInfinity() || other.IsPlusInfinity()) {
RTC_DCHECK(!IsPlusInfinity());
RTC_DCHECK(!other.IsMinusInfinity());
return MinusInfinity();
}
return TimeDelta::us(us() - other.us());
}
TimeDelta& operator-=(const TimeDelta& other) {
microseconds_ -= other.us();
*this = *this - other;
return *this;
}
TimeDelta& operator+=(const TimeDelta& other) {
microseconds_ += other.us();
*this = *this + other;
return *this;
}
constexpr double operator/(const TimeDelta& other) const {

View file

@ -164,6 +164,26 @@ TEST(TimeDeltaTest, MathOperations) {
EXPECT_EQ(TimeDelta::us(-kValueA).Abs().us(), kValueA);
EXPECT_EQ(TimeDelta::us(kValueA).Abs().us(), kValueA);
TimeDelta mutable_delta = TimeDelta::ms(kValueA);
mutable_delta += TimeDelta::ms(kValueB);
EXPECT_EQ(mutable_delta, TimeDelta::ms(kValueA + kValueB));
mutable_delta -= TimeDelta::ms(kValueB);
EXPECT_EQ(mutable_delta, TimeDelta::ms(kValueA));
}
TEST(TimeDeltaTest, InfinityOperations) {
const int64_t kValue = 267;
const TimeDelta finite = TimeDelta::ms(kValue);
EXPECT_TRUE((TimeDelta::PlusInfinity() + finite).IsPlusInfinity());
EXPECT_TRUE((TimeDelta::PlusInfinity() - finite).IsPlusInfinity());
EXPECT_TRUE((finite + TimeDelta::PlusInfinity()).IsPlusInfinity());
EXPECT_TRUE((finite - TimeDelta::MinusInfinity()).IsPlusInfinity());
EXPECT_TRUE((TimeDelta::MinusInfinity() + finite).IsMinusInfinity());
EXPECT_TRUE((TimeDelta::MinusInfinity() - finite).IsMinusInfinity());
EXPECT_TRUE((finite + TimeDelta::MinusInfinity()).IsMinusInfinity());
EXPECT_TRUE((finite - TimeDelta::PlusInfinity()).IsMinusInfinity());
}
} // namespace test
} // namespace webrtc

View file

@ -162,17 +162,23 @@ class Timestamp {
return TimeDelta::us(us() - other.us());
}
Timestamp operator-(const TimeDelta& delta) const {
RTC_DCHECK(!delta.IsPlusInfinity());
if (IsInfinite() || delta.IsMinusInfinity())
return Infinity();
return Timestamp::us(us() - delta.us());
}
Timestamp operator+(const TimeDelta& delta) const {
RTC_DCHECK(!delta.IsMinusInfinity());
if (IsInfinite() || delta.IsPlusInfinity())
return Infinity();
return Timestamp::us(us() + delta.us());
}
Timestamp& operator-=(const TimeDelta& other) {
microseconds_ -= other.us();
*this = *this - other;
return *this;
}
Timestamp& operator+=(const TimeDelta& other) {
microseconds_ += other.us();
*this = *this + other;
return *this;
}
constexpr bool operator==(const Timestamp& other) const {

View file

@ -118,10 +118,27 @@ TEST(UnitConversionTest, TimestampAndTimeDeltaMath) {
const Timestamp time_a = Timestamp::ms(kValueA);
const Timestamp time_b = Timestamp::ms(kValueB);
const TimeDelta delta_a = TimeDelta::ms(kValueA);
const TimeDelta delta_b = TimeDelta::ms(kValueB);
EXPECT_EQ((time_a - time_b), TimeDelta::ms(kValueA - kValueB));
EXPECT_EQ((time_b - delta_a), Timestamp::ms(kValueB - kValueA));
EXPECT_EQ((time_b + delta_a), Timestamp::ms(kValueB + kValueA));
Timestamp mutable_time = time_a;
mutable_time += delta_b;
EXPECT_EQ(mutable_time, time_a + delta_b);
mutable_time -= delta_b;
EXPECT_EQ(mutable_time, time_a);
}
TEST(UnitConversionTest, InfinityOperations) {
const int64_t kValue = 267;
const Timestamp finite_time = Timestamp::ms(kValue);
const TimeDelta finite_delta = TimeDelta::ms(kValue);
EXPECT_TRUE((Timestamp::Infinity() + finite_delta).IsInfinite());
EXPECT_TRUE((Timestamp::Infinity() - finite_delta).IsInfinite());
EXPECT_TRUE((finite_time + TimeDelta::PlusInfinity()).IsInfinite());
EXPECT_TRUE((finite_time - TimeDelta::MinusInfinity()).IsInfinite());
}
} // namespace test
} // namespace webrtc