diff --git a/net/dcsctp/public/BUILD.gn b/net/dcsctp/public/BUILD.gn index 863b90378b..dc23df673a 100644 --- a/net/dcsctp/public/BUILD.gn +++ b/net/dcsctp/public/BUILD.gn @@ -46,11 +46,15 @@ if (rtc_include_tests) { deps = [ ":strong_alias", + ":types", "../../../rtc_base:checks", "../../../rtc_base:gunit_helpers", "../../../rtc_base:rtc_base_approved", "../../../test:test_support", ] - sources = [ "strong_alias_test.cc" ] + sources = [ + "strong_alias_test.cc", + "types_test.cc", + ] } } diff --git a/net/dcsctp/public/types.h b/net/dcsctp/public/types.h index 0b22fa8b41..b87fd4e79a 100644 --- a/net/dcsctp/public/types.h +++ b/net/dcsctp/public/types.h @@ -11,6 +11,8 @@ #ifndef NET_DCSCTP_PUBLIC_TYPES_H_ #define NET_DCSCTP_PUBLIC_TYPES_H_ +#include + #include "net/dcsctp/public/strong_alias.h" namespace dcsctp { @@ -29,10 +31,74 @@ using TimeoutID = StrongAlias; using IsUnordered = StrongAlias; // Duration, as milliseconds. Overflows after 24 days. -using DurationMs = StrongAlias; +class DurationMs : public StrongAlias { + public: + constexpr explicit DurationMs(const UnderlyingType& v) + : StrongAlias(v) {} -// Current time, in milliseconds since a client-defined epoch.ยด -using TimeMs = StrongAlias; + // Convenience methods for working with time. + constexpr DurationMs& operator+=(DurationMs d) { + value_ += d.value_; + return *this; + } + constexpr DurationMs& operator-=(DurationMs d) { + value_ -= d.value_; + return *this; + } + template + constexpr DurationMs& operator*=(T factor) { + value_ *= factor; + return *this; + } +}; + +constexpr inline DurationMs operator+(DurationMs lhs, DurationMs rhs) { + return lhs += rhs; +} +constexpr inline DurationMs operator-(DurationMs lhs, DurationMs rhs) { + return lhs -= rhs; +} +template +constexpr inline DurationMs operator*(DurationMs lhs, T rhs) { + return lhs *= rhs; +} +template +constexpr inline DurationMs operator*(T lhs, DurationMs rhs) { + return rhs *= lhs; +} +constexpr inline int32_t operator/(DurationMs lhs, DurationMs rhs) { + return lhs.value() / rhs.value(); +} + +// Represents time, in milliseconds since a client-defined epoch. +class TimeMs : public StrongAlias { + public: + constexpr explicit TimeMs(const UnderlyingType& v) + : StrongAlias(v) {} + + // Convenience methods for working with time. + constexpr TimeMs& operator+=(DurationMs d) { + value_ += *d; + return *this; + } + constexpr TimeMs& operator-=(DurationMs d) { + value_ -= *d; + return *this; + } +}; + +constexpr inline TimeMs operator+(TimeMs lhs, DurationMs rhs) { + return lhs += rhs; +} +constexpr inline TimeMs operator+(DurationMs lhs, TimeMs rhs) { + return rhs += lhs; +} +constexpr inline TimeMs operator-(TimeMs lhs, DurationMs rhs) { + return lhs -= rhs; +} +constexpr inline DurationMs operator-(TimeMs lhs, TimeMs rhs) { + return DurationMs(*lhs - *rhs); +} } // namespace dcsctp diff --git a/net/dcsctp/public/types_test.cc b/net/dcsctp/public/types_test.cc new file mode 100644 index 0000000000..d3d1240751 --- /dev/null +++ b/net/dcsctp/public/types_test.cc @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include "net/dcsctp/public/types.h" + +#include "rtc_base/gunit.h" +#include "test/gmock.h" + +namespace dcsctp { +namespace { + +TEST(TypesTest, DurationOperators) { + DurationMs d1(10); + DurationMs d2(25); + EXPECT_EQ(d1 + d2, DurationMs(35)); + EXPECT_EQ(d2 - d1, DurationMs(15)); + + d1 += d2; + EXPECT_EQ(d1, DurationMs(35)); + + d1 -= DurationMs(5); + EXPECT_EQ(d1, DurationMs(30)); + + d1 *= 1.5; + EXPECT_EQ(d1, DurationMs(45)); + + EXPECT_EQ(DurationMs(10) * 2, DurationMs(20)); +} + +TEST(TypesTest, TimeOperators) { + EXPECT_EQ(TimeMs(250) + DurationMs(100), TimeMs(350)); + EXPECT_EQ(DurationMs(250) + TimeMs(100), TimeMs(350)); + EXPECT_EQ(TimeMs(250) - DurationMs(100), TimeMs(150)); + EXPECT_EQ(TimeMs(250) - TimeMs(100), DurationMs(150)); + + TimeMs t1(150); + t1 -= DurationMs(50); + EXPECT_EQ(t1, TimeMs(100)); + t1 += DurationMs(200); + EXPECT_EQ(t1, TimeMs(300)); +} + +} // namespace +} // namespace dcsctp diff --git a/net/dcsctp/timer/fake_timeout.h b/net/dcsctp/timer/fake_timeout.h index 06e3085a5b..265b34edfa 100644 --- a/net/dcsctp/timer/fake_timeout.h +++ b/net/dcsctp/timer/fake_timeout.h @@ -33,7 +33,7 @@ class FakeTimeout : public Timeout { void Start(DurationMs duration_ms, TimeoutID timeout_id) override { timeout_id_ = timeout_id; - expiry_ = TimeMs(*get_time_() + *duration_ms); + expiry_ = get_time_() + duration_ms; } void Stop() override { expiry_ = InfiniteFuture(); } diff --git a/net/dcsctp/timer/timer_test.cc b/net/dcsctp/timer/timer_test.cc index 263f535dab..9533234895 100644 --- a/net/dcsctp/timer/timer_test.cc +++ b/net/dcsctp/timer/timer_test.cc @@ -30,7 +30,7 @@ class TimerTest : public testing::Test { } void AdvanceTimeAndRunTimers(DurationMs duration) { - now_ = TimeMs(*now_ + *duration); + now_ = now_ + duration; for (TimeoutID timeout_id : timeout_manager_.RunTimers()) { manager_.HandleTimeout(timeout_id);