Adds constexpr create functions for units.
This adds new constexpr create function for DataSize, DataRate, TimeDelta and Timestamp. The names are capitalized to mirror the naming scheme of the previously constexpr methods (Zero and Infinity create functions). They are also kept longer since they are not expected to be used in complex expressions. Bug: webrtc:9574 Change-Id: I5950548718675050fc5d66699de295455c310861 Reviewed-on: https://webrtc-review.googlesource.com/91161 Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Commit-Queue: Sebastian Jansson <srte@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24218}
This commit is contained in:

committed by
Commit Bot

parent
133cff009b
commit
c1c8b8e836
@ -44,6 +44,18 @@ class DataRate {
|
|||||||
static constexpr DataRate Infinity() {
|
static constexpr DataRate Infinity() {
|
||||||
return DataRate(data_rate_impl::kPlusInfinityVal);
|
return DataRate(data_rate_impl::kPlusInfinityVal);
|
||||||
}
|
}
|
||||||
|
template <int64_t bps>
|
||||||
|
static constexpr DataRate BitsPerSec() {
|
||||||
|
static_assert(bps >= 0, "");
|
||||||
|
static_assert(bps < data_rate_impl::kPlusInfinityVal, "");
|
||||||
|
return DataRate(bps);
|
||||||
|
}
|
||||||
|
template <int64_t kbps>
|
||||||
|
static constexpr DataRate KilobitsPerSec() {
|
||||||
|
static_assert(kbps >= 0, "");
|
||||||
|
static_assert(kbps < data_rate_impl::kPlusInfinityVal / 1000, "");
|
||||||
|
return DataRate(kbps * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
typename T,
|
typename T,
|
||||||
@ -89,49 +101,53 @@ class DataRate {
|
|||||||
}
|
}
|
||||||
template <typename T = int64_t>
|
template <typename T = int64_t>
|
||||||
typename std::enable_if<std::is_integral<T>::value, T>::type kbps() const {
|
typename std::enable_if<std::is_integral<T>::value, T>::type kbps() const {
|
||||||
return rtc::dchecked_cast<T>((bps() + 500) / 1000);
|
RTC_DCHECK(IsFinite());
|
||||||
|
return rtc::dchecked_cast<T>(UnsafeKilobitsPerSec());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<std::is_floating_point<T>::value, T>::type bps()
|
typename std::enable_if<std::is_floating_point<T>::value,
|
||||||
const {
|
T>::type constexpr bps() const {
|
||||||
if (IsInfinite()) {
|
return IsInfinite() ? std::numeric_limits<T>::infinity() : bits_per_sec_;
|
||||||
return std::numeric_limits<T>::infinity();
|
|
||||||
} else {
|
|
||||||
return bits_per_sec_;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<std::is_floating_point<T>::value, T>::type kbps()
|
typename std::enable_if<std::is_floating_point<T>::value,
|
||||||
const {
|
T>::type constexpr kbps() const {
|
||||||
return bps<T>() * 1e-3;
|
return bps<T>() * 1e-3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr int64_t bps_or(int64_t fallback_value) const {
|
||||||
|
return IsFinite() ? bits_per_sec_ : fallback_value;
|
||||||
|
}
|
||||||
|
constexpr int64_t kbps_or(int64_t fallback_value) const {
|
||||||
|
return IsFinite() ? UnsafeKilobitsPerSec() : fallback_value;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr bool IsZero() const { return bits_per_sec_ == 0; }
|
constexpr bool IsZero() const { return bits_per_sec_ == 0; }
|
||||||
constexpr bool IsInfinite() const {
|
constexpr bool IsInfinite() const {
|
||||||
return bits_per_sec_ == data_rate_impl::kPlusInfinityVal;
|
return bits_per_sec_ == data_rate_impl::kPlusInfinityVal;
|
||||||
}
|
}
|
||||||
constexpr bool IsFinite() const { return !IsInfinite(); }
|
constexpr bool IsFinite() const { return !IsInfinite(); }
|
||||||
|
|
||||||
double operator/(const DataRate& other) const {
|
constexpr double operator/(const DataRate& other) const {
|
||||||
return bps<double>() / other.bps<double>();
|
return bps<double>() / other.bps<double>();
|
||||||
}
|
}
|
||||||
bool operator==(const DataRate& other) const {
|
constexpr bool operator==(const DataRate& other) const {
|
||||||
return bits_per_sec_ == other.bits_per_sec_;
|
return bits_per_sec_ == other.bits_per_sec_;
|
||||||
}
|
}
|
||||||
bool operator!=(const DataRate& other) const {
|
constexpr bool operator!=(const DataRate& other) const {
|
||||||
return bits_per_sec_ != other.bits_per_sec_;
|
return bits_per_sec_ != other.bits_per_sec_;
|
||||||
}
|
}
|
||||||
bool operator<=(const DataRate& other) const {
|
constexpr bool operator<=(const DataRate& other) const {
|
||||||
return bits_per_sec_ <= other.bits_per_sec_;
|
return bits_per_sec_ <= other.bits_per_sec_;
|
||||||
}
|
}
|
||||||
bool operator>=(const DataRate& other) const {
|
constexpr bool operator>=(const DataRate& other) const {
|
||||||
return bits_per_sec_ >= other.bits_per_sec_;
|
return bits_per_sec_ >= other.bits_per_sec_;
|
||||||
}
|
}
|
||||||
bool operator>(const DataRate& other) const {
|
constexpr bool operator>(const DataRate& other) const {
|
||||||
return bits_per_sec_ > other.bits_per_sec_;
|
return bits_per_sec_ > other.bits_per_sec_;
|
||||||
}
|
}
|
||||||
bool operator<(const DataRate& other) const {
|
constexpr bool operator<(const DataRate& other) const {
|
||||||
return bits_per_sec_ < other.bits_per_sec_;
|
return bits_per_sec_ < other.bits_per_sec_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,6 +156,9 @@ class DataRate {
|
|||||||
// more recognizable.
|
// more recognizable.
|
||||||
explicit constexpr DataRate(int64_t bits_per_second)
|
explicit constexpr DataRate(int64_t bits_per_second)
|
||||||
: bits_per_sec_(bits_per_second) {}
|
: bits_per_sec_(bits_per_second) {}
|
||||||
|
constexpr int64_t UnsafeKilobitsPerSec() const {
|
||||||
|
return (bits_per_sec_ + 500) / 1000;
|
||||||
|
}
|
||||||
int64_t bits_per_sec_;
|
int64_t bits_per_sec_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,10 +15,19 @@ namespace webrtc {
|
|||||||
namespace test {
|
namespace test {
|
||||||
|
|
||||||
TEST(DataRateTest, ConstExpr) {
|
TEST(DataRateTest, ConstExpr) {
|
||||||
|
constexpr int64_t kValue = 12345;
|
||||||
constexpr DataRate kDataRateZero = DataRate::Zero();
|
constexpr DataRate kDataRateZero = DataRate::Zero();
|
||||||
constexpr DataRate kDataRateInf = DataRate::Infinity();
|
constexpr DataRate kDataRateInf = DataRate::Infinity();
|
||||||
static_assert(kDataRateZero.IsZero(), "");
|
static_assert(kDataRateZero.IsZero(), "");
|
||||||
static_assert(kDataRateInf.IsInfinite(), "");
|
static_assert(kDataRateInf.IsInfinite(), "");
|
||||||
|
static_assert(kDataRateInf.bps_or(-1) == -1, "");
|
||||||
|
static_assert(kDataRateInf > kDataRateZero, "");
|
||||||
|
|
||||||
|
constexpr DataRate kDataRateBps = DataRate::BitsPerSec<kValue>();
|
||||||
|
constexpr DataRate kDataRateKbps = DataRate::KilobitsPerSec<kValue>();
|
||||||
|
static_assert(kDataRateBps.bps<double>() == kValue, "");
|
||||||
|
static_assert(kDataRateBps.bps_or(0) == kValue, "");
|
||||||
|
static_assert(kDataRateKbps.kbps_or(0) == kValue, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DataRateTest, GetBackSameValues) {
|
TEST(DataRateTest, GetBackSameValues) {
|
||||||
|
@ -33,6 +33,12 @@ class DataSize {
|
|||||||
static constexpr DataSize Infinity() {
|
static constexpr DataSize Infinity() {
|
||||||
return DataSize(data_size_impl::kPlusInfinityVal);
|
return DataSize(data_size_impl::kPlusInfinityVal);
|
||||||
}
|
}
|
||||||
|
template <int64_t bytes>
|
||||||
|
static constexpr DataSize Bytes() {
|
||||||
|
static_assert(bytes >= 0, "");
|
||||||
|
static_assert(bytes < data_size_impl::kPlusInfinityVal, "");
|
||||||
|
return DataSize(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
typename T,
|
typename T,
|
||||||
@ -64,13 +70,13 @@ class DataSize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<std::is_floating_point<T>::value, T>::type bytes()
|
constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
||||||
const {
|
bytes() const {
|
||||||
if (IsInfinite()) {
|
return IsInfinite() ? std::numeric_limits<T>::infinity() : bytes_;
|
||||||
return std::numeric_limits<T>::infinity();
|
|
||||||
} else {
|
|
||||||
return bytes_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr int64_t bytes_or(int64_t fallback_value) const {
|
||||||
|
return IsFinite() ? bytes_ : fallback_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool IsZero() const { return bytes_ == 0; }
|
constexpr bool IsZero() const { return bytes_ == 0; }
|
||||||
@ -92,23 +98,27 @@ class DataSize {
|
|||||||
bytes_ += other.bytes();
|
bytes_ += other.bytes();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
double operator/(const DataSize& other) const {
|
constexpr double operator/(const DataSize& other) const {
|
||||||
return bytes<double>() / other.bytes<double>();
|
return bytes<double>() / other.bytes<double>();
|
||||||
}
|
}
|
||||||
bool operator==(const DataSize& other) const {
|
constexpr bool operator==(const DataSize& other) const {
|
||||||
return bytes_ == other.bytes_;
|
return bytes_ == other.bytes_;
|
||||||
}
|
}
|
||||||
bool operator!=(const DataSize& other) const {
|
constexpr bool operator!=(const DataSize& other) const {
|
||||||
return bytes_ != other.bytes_;
|
return bytes_ != other.bytes_;
|
||||||
}
|
}
|
||||||
bool operator<=(const DataSize& other) const {
|
constexpr bool operator<=(const DataSize& other) const {
|
||||||
return bytes_ <= other.bytes_;
|
return bytes_ <= other.bytes_;
|
||||||
}
|
}
|
||||||
bool operator>=(const DataSize& other) const {
|
constexpr bool operator>=(const DataSize& other) const {
|
||||||
return bytes_ >= other.bytes_;
|
return bytes_ >= other.bytes_;
|
||||||
}
|
}
|
||||||
bool operator>(const DataSize& other) const { return bytes_ > other.bytes_; }
|
constexpr bool operator>(const DataSize& other) const {
|
||||||
bool operator<(const DataSize& other) const { return bytes_ < other.bytes_; }
|
return bytes_ > other.bytes_;
|
||||||
|
}
|
||||||
|
constexpr bool operator<(const DataSize& other) const {
|
||||||
|
return bytes_ < other.bytes_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit constexpr DataSize(int64_t bytes) : bytes_(bytes) {}
|
explicit constexpr DataSize(int64_t bytes) : bytes_(bytes) {}
|
||||||
|
@ -15,10 +15,18 @@ namespace webrtc {
|
|||||||
namespace test {
|
namespace test {
|
||||||
|
|
||||||
TEST(DataSizeTest, ConstExpr) {
|
TEST(DataSizeTest, ConstExpr) {
|
||||||
|
constexpr int64_t kValue = 12345;
|
||||||
constexpr DataSize kDataSizeZero = DataSize::Zero();
|
constexpr DataSize kDataSizeZero = DataSize::Zero();
|
||||||
constexpr DataSize kDataSizeInf = DataSize::Infinity();
|
constexpr DataSize kDataSizeInf = DataSize::Infinity();
|
||||||
static_assert(kDataSizeZero.IsZero(), "");
|
static_assert(kDataSizeZero.IsZero(), "");
|
||||||
static_assert(kDataSizeInf.IsInfinite(), "");
|
static_assert(kDataSizeInf.IsInfinite(), "");
|
||||||
|
static_assert(kDataSizeInf.bytes_or(-1) == -1, "");
|
||||||
|
static_assert(kDataSizeInf > kDataSizeZero, "");
|
||||||
|
|
||||||
|
constexpr DataSize kDataSize = DataSize::Bytes<kValue>();
|
||||||
|
static_assert(kDataSize.bytes_or(-1) == kValue, "");
|
||||||
|
|
||||||
|
EXPECT_EQ(kDataSize.bytes(), kValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DataSizeTest, GetBackSameValues) {
|
TEST(DataSizeTest, GetBackSameValues) {
|
||||||
|
@ -42,6 +42,24 @@ class TimeDelta {
|
|||||||
static constexpr TimeDelta MinusInfinity() {
|
static constexpr TimeDelta MinusInfinity() {
|
||||||
return TimeDelta(timedelta_impl::kMinusInfinityVal);
|
return TimeDelta(timedelta_impl::kMinusInfinityVal);
|
||||||
}
|
}
|
||||||
|
template <int64_t seconds>
|
||||||
|
static constexpr TimeDelta Seconds() {
|
||||||
|
static_assert(seconds > timedelta_impl::kMinusInfinityVal / 1000000, "");
|
||||||
|
static_assert(seconds < timedelta_impl::kPlusInfinityVal / 1000000, "");
|
||||||
|
return TimeDelta(seconds * 1000000);
|
||||||
|
}
|
||||||
|
template <int64_t ms>
|
||||||
|
static constexpr TimeDelta Millis() {
|
||||||
|
static_assert(ms > timedelta_impl::kMinusInfinityVal / 1000, "");
|
||||||
|
static_assert(ms < timedelta_impl::kPlusInfinityVal / 1000, "");
|
||||||
|
return TimeDelta(ms * 1000);
|
||||||
|
}
|
||||||
|
template <int64_t us>
|
||||||
|
static constexpr TimeDelta Micros() {
|
||||||
|
static_assert(us > timedelta_impl::kMinusInfinityVal, "");
|
||||||
|
static_assert(us < timedelta_impl::kPlusInfinityVal, "");
|
||||||
|
return TimeDelta(us);
|
||||||
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
typename T,
|
typename T,
|
||||||
@ -98,12 +116,13 @@ class TimeDelta {
|
|||||||
|
|
||||||
template <typename T = int64_t>
|
template <typename T = int64_t>
|
||||||
typename std::enable_if<std::is_integral<T>::value, T>::type seconds() const {
|
typename std::enable_if<std::is_integral<T>::value, T>::type seconds() const {
|
||||||
return rtc::dchecked_cast<T>((us() + (us() >= 0 ? 500000 : -500000)) /
|
RTC_DCHECK(IsFinite());
|
||||||
1000000);
|
return rtc::dchecked_cast<T>(UnsafeSeconds());
|
||||||
}
|
}
|
||||||
template <typename T = int64_t>
|
template <typename T = int64_t>
|
||||||
typename std::enable_if<std::is_integral<T>::value, T>::type ms() const {
|
typename std::enable_if<std::is_integral<T>::value, T>::type ms() const {
|
||||||
return rtc::dchecked_cast<T>((us() + (us() >= 0 ? 500 : -500)) / 1000);
|
RTC_DCHECK(IsFinite());
|
||||||
|
return rtc::dchecked_cast<T>(UnsafeMillis());
|
||||||
}
|
}
|
||||||
template <typename T = int64_t>
|
template <typename T = int64_t>
|
||||||
typename std::enable_if<std::is_integral<T>::value, T>::type us() const {
|
typename std::enable_if<std::is_integral<T>::value, T>::type us() const {
|
||||||
@ -118,32 +137,39 @@ class TimeDelta {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<std::is_floating_point<T>::value, T>::type seconds()
|
constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
||||||
const {
|
seconds() const {
|
||||||
return us<T>() * 1e-6;
|
return us<T>() * 1e-6;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<std::is_floating_point<T>::value, T>::type ms()
|
constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
||||||
const {
|
ms() const {
|
||||||
return us<T>() * 1e-3;
|
return us<T>() * 1e-3;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<std::is_floating_point<T>::value, T>::type us()
|
constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
||||||
const {
|
us() const {
|
||||||
if (IsPlusInfinity()) {
|
return IsPlusInfinity()
|
||||||
return std::numeric_limits<T>::infinity();
|
? std::numeric_limits<T>::infinity()
|
||||||
} else if (IsMinusInfinity()) {
|
: IsMinusInfinity() ? -std::numeric_limits<T>::infinity()
|
||||||
return -std::numeric_limits<T>::infinity();
|
: microseconds_;
|
||||||
} else {
|
|
||||||
return microseconds_;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<std::is_floating_point<T>::value, T>::type ns()
|
constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
||||||
const {
|
ns() const {
|
||||||
return us<T>() * 1e3;
|
return us<T>() * 1e3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr int64_t seconds_or(int64_t fallback_value) const {
|
||||||
|
return IsFinite() ? UnsafeSeconds() : fallback_value;
|
||||||
|
}
|
||||||
|
constexpr int64_t ms_or(int64_t fallback_value) const {
|
||||||
|
return IsFinite() ? UnsafeMillis() : fallback_value;
|
||||||
|
}
|
||||||
|
constexpr int64_t us_or(int64_t fallback_value) const {
|
||||||
|
return IsFinite() ? microseconds_ : fallback_value;
|
||||||
|
}
|
||||||
|
|
||||||
TimeDelta Abs() const { return TimeDelta::us(std::abs(us())); }
|
TimeDelta Abs() const { return TimeDelta::us(std::abs(us())); }
|
||||||
constexpr bool IsZero() const { return microseconds_ == 0; }
|
constexpr bool IsZero() const { return microseconds_ == 0; }
|
||||||
constexpr bool IsFinite() const { return !IsInfinite(); }
|
constexpr bool IsFinite() const { return !IsInfinite(); }
|
||||||
@ -171,30 +197,36 @@ class TimeDelta {
|
|||||||
microseconds_ += other.us();
|
microseconds_ += other.us();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
double operator/(const TimeDelta& other) const {
|
constexpr double operator/(const TimeDelta& other) const {
|
||||||
return us<double>() / other.us<double>();
|
return us<double>() / other.us<double>();
|
||||||
}
|
}
|
||||||
bool operator==(const TimeDelta& other) const {
|
constexpr bool operator==(const TimeDelta& other) const {
|
||||||
return microseconds_ == other.microseconds_;
|
return microseconds_ == other.microseconds_;
|
||||||
}
|
}
|
||||||
bool operator!=(const TimeDelta& other) const {
|
constexpr bool operator!=(const TimeDelta& other) const {
|
||||||
return microseconds_ != other.microseconds_;
|
return microseconds_ != other.microseconds_;
|
||||||
}
|
}
|
||||||
bool operator<=(const TimeDelta& other) const {
|
constexpr bool operator<=(const TimeDelta& other) const {
|
||||||
return microseconds_ <= other.microseconds_;
|
return microseconds_ <= other.microseconds_;
|
||||||
}
|
}
|
||||||
bool operator>=(const TimeDelta& other) const {
|
constexpr bool operator>=(const TimeDelta& other) const {
|
||||||
return microseconds_ >= other.microseconds_;
|
return microseconds_ >= other.microseconds_;
|
||||||
}
|
}
|
||||||
bool operator>(const TimeDelta& other) const {
|
constexpr bool operator>(const TimeDelta& other) const {
|
||||||
return microseconds_ > other.microseconds_;
|
return microseconds_ > other.microseconds_;
|
||||||
}
|
}
|
||||||
bool operator<(const TimeDelta& other) const {
|
constexpr bool operator<(const TimeDelta& other) const {
|
||||||
return microseconds_ < other.microseconds_;
|
return microseconds_ < other.microseconds_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit constexpr TimeDelta(int64_t us) : microseconds_(us) {}
|
explicit constexpr TimeDelta(int64_t us) : microseconds_(us) {}
|
||||||
|
constexpr int64_t UnsafeSeconds() const {
|
||||||
|
return (microseconds_ + (microseconds_ >= 0 ? 500000 : -500000)) / 1000000;
|
||||||
|
}
|
||||||
|
constexpr int64_t UnsafeMillis() const {
|
||||||
|
return (microseconds_ + (microseconds_ >= 0 ? 500 : -500)) / 1000;
|
||||||
|
}
|
||||||
int64_t microseconds_;
|
int64_t microseconds_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -220,7 +252,6 @@ inline TimeDelta operator*(const int32_t& scalar, const TimeDelta& delta) {
|
|||||||
inline TimeDelta operator/(const TimeDelta& delta, const int64_t& scalar) {
|
inline TimeDelta operator/(const TimeDelta& delta, const int64_t& scalar) {
|
||||||
return TimeDelta::us(delta.us() / scalar);
|
return TimeDelta::us(delta.us() / scalar);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToString(const TimeDelta& value);
|
std::string ToString(const TimeDelta& value);
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
|
@ -15,12 +15,24 @@
|
|||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace test {
|
namespace test {
|
||||||
TEST(TimeDeltaTest, ConstExpr) {
|
TEST(TimeDeltaTest, ConstExpr) {
|
||||||
|
constexpr int64_t kValue = -12345;
|
||||||
constexpr TimeDelta kTimeDeltaZero = TimeDelta::Zero();
|
constexpr TimeDelta kTimeDeltaZero = TimeDelta::Zero();
|
||||||
constexpr TimeDelta kTimeDeltaPlusInf = TimeDelta::PlusInfinity();
|
constexpr TimeDelta kTimeDeltaPlusInf = TimeDelta::PlusInfinity();
|
||||||
constexpr TimeDelta kTimeDeltaMinusInf = TimeDelta::MinusInfinity();
|
constexpr TimeDelta kTimeDeltaMinusInf = TimeDelta::MinusInfinity();
|
||||||
static_assert(kTimeDeltaZero.IsZero(), "");
|
static_assert(kTimeDeltaZero.IsZero(), "");
|
||||||
static_assert(kTimeDeltaPlusInf.IsPlusInfinity(), "");
|
static_assert(kTimeDeltaPlusInf.IsPlusInfinity(), "");
|
||||||
static_assert(kTimeDeltaMinusInf.IsMinusInfinity(), "");
|
static_assert(kTimeDeltaMinusInf.IsMinusInfinity(), "");
|
||||||
|
static_assert(kTimeDeltaPlusInf.ms_or(-1) == -1, "");
|
||||||
|
|
||||||
|
static_assert(kTimeDeltaPlusInf > kTimeDeltaZero, "");
|
||||||
|
|
||||||
|
constexpr TimeDelta kTimeDeltaSeconds = TimeDelta::Seconds<kValue>();
|
||||||
|
constexpr TimeDelta kTimeDeltaMs = TimeDelta::Millis<kValue>();
|
||||||
|
constexpr TimeDelta kTimeDeltaUs = TimeDelta::Micros<kValue>();
|
||||||
|
|
||||||
|
static_assert(kTimeDeltaSeconds.seconds_or(0) == kValue, "");
|
||||||
|
static_assert(kTimeDeltaMs.ms_or(0) == kValue, "");
|
||||||
|
static_assert(kTimeDeltaUs.us_or(0) == kValue, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TimeDeltaTest, GetBackSameValues) {
|
TEST(TimeDeltaTest, GetBackSameValues) {
|
||||||
|
@ -35,6 +35,24 @@ class Timestamp {
|
|||||||
static constexpr Timestamp Infinity() {
|
static constexpr Timestamp Infinity() {
|
||||||
return Timestamp(timestamp_impl::kPlusInfinityVal);
|
return Timestamp(timestamp_impl::kPlusInfinityVal);
|
||||||
}
|
}
|
||||||
|
template <int64_t seconds>
|
||||||
|
static constexpr Timestamp Seconds() {
|
||||||
|
static_assert(seconds >= 0, "");
|
||||||
|
static_assert(seconds < timestamp_impl::kPlusInfinityVal / 1000000, "");
|
||||||
|
return Timestamp(seconds * 1000000);
|
||||||
|
}
|
||||||
|
template <int64_t ms>
|
||||||
|
static constexpr Timestamp Millis() {
|
||||||
|
static_assert(ms >= 0, "");
|
||||||
|
static_assert(ms < timestamp_impl::kPlusInfinityVal / 1000, "");
|
||||||
|
return Timestamp(ms * 1000);
|
||||||
|
}
|
||||||
|
template <int64_t us>
|
||||||
|
static constexpr Timestamp Micros() {
|
||||||
|
static_assert(us >= 0, "");
|
||||||
|
static_assert(us < timestamp_impl::kPlusInfinityVal, "");
|
||||||
|
return Timestamp(us);
|
||||||
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
typename T,
|
typename T,
|
||||||
@ -92,11 +110,13 @@ class Timestamp {
|
|||||||
|
|
||||||
template <typename T = int64_t>
|
template <typename T = int64_t>
|
||||||
typename std::enable_if<std::is_integral<T>::value, T>::type seconds() const {
|
typename std::enable_if<std::is_integral<T>::value, T>::type seconds() const {
|
||||||
return rtc::dchecked_cast<T>((us() + 500000) / 1000000);
|
RTC_DCHECK(IsFinite());
|
||||||
|
return rtc::dchecked_cast<T>(UnsafeSeconds());
|
||||||
}
|
}
|
||||||
template <typename T = int64_t>
|
template <typename T = int64_t>
|
||||||
typename std::enable_if<std::is_integral<T>::value, T>::type ms() const {
|
typename std::enable_if<std::is_integral<T>::value, T>::type ms() const {
|
||||||
return rtc::dchecked_cast<T>((us() + 500) / 1000);
|
RTC_DCHECK(IsFinite());
|
||||||
|
return rtc::dchecked_cast<T>(UnsafeMillis());
|
||||||
}
|
}
|
||||||
template <typename T = int64_t>
|
template <typename T = int64_t>
|
||||||
typename std::enable_if<std::is_integral<T>::value, T>::type us() const {
|
typename std::enable_if<std::is_integral<T>::value, T>::type us() const {
|
||||||
@ -105,23 +125,29 @@ class Timestamp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<std::is_floating_point<T>::value, T>::type seconds()
|
constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
||||||
const {
|
seconds() const {
|
||||||
return us<T>() * 1e-6;
|
return us<T>() * 1e-6;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<std::is_floating_point<T>::value, T>::type ms()
|
constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
||||||
const {
|
ms() const {
|
||||||
return us<T>() * 1e-3;
|
return us<T>() * 1e-3;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<std::is_floating_point<T>::value, T>::type us()
|
constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
||||||
const {
|
us() const {
|
||||||
if (IsInfinite()) {
|
return IsInfinite() ? std::numeric_limits<T>::infinity() : microseconds_;
|
||||||
return std::numeric_limits<T>::infinity();
|
|
||||||
} else {
|
|
||||||
return microseconds_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr int64_t seconds_or(int64_t fallback_value) const {
|
||||||
|
return IsFinite() ? UnsafeSeconds() : fallback_value;
|
||||||
|
}
|
||||||
|
constexpr int64_t ms_or(int64_t fallback_value) const {
|
||||||
|
return IsFinite() ? UnsafeMillis() : fallback_value;
|
||||||
|
}
|
||||||
|
constexpr int64_t us_or(int64_t fallback_value) const {
|
||||||
|
return IsFinite() ? microseconds_ : fallback_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool IsInfinite() const {
|
constexpr bool IsInfinite() const {
|
||||||
@ -145,27 +171,33 @@ class Timestamp {
|
|||||||
microseconds_ += other.us();
|
microseconds_ += other.us();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
bool operator==(const Timestamp& other) const {
|
constexpr bool operator==(const Timestamp& other) const {
|
||||||
return microseconds_ == other.microseconds_;
|
return microseconds_ == other.microseconds_;
|
||||||
}
|
}
|
||||||
bool operator!=(const Timestamp& other) const {
|
constexpr bool operator!=(const Timestamp& other) const {
|
||||||
return microseconds_ != other.microseconds_;
|
return microseconds_ != other.microseconds_;
|
||||||
}
|
}
|
||||||
bool operator<=(const Timestamp& other) const {
|
constexpr bool operator<=(const Timestamp& other) const {
|
||||||
return microseconds_ <= other.microseconds_;
|
return microseconds_ <= other.microseconds_;
|
||||||
}
|
}
|
||||||
bool operator>=(const Timestamp& other) const {
|
constexpr bool operator>=(const Timestamp& other) const {
|
||||||
return microseconds_ >= other.microseconds_;
|
return microseconds_ >= other.microseconds_;
|
||||||
}
|
}
|
||||||
bool operator>(const Timestamp& other) const {
|
constexpr bool operator>(const Timestamp& other) const {
|
||||||
return microseconds_ > other.microseconds_;
|
return microseconds_ > other.microseconds_;
|
||||||
}
|
}
|
||||||
bool operator<(const Timestamp& other) const {
|
constexpr bool operator<(const Timestamp& other) const {
|
||||||
return microseconds_ < other.microseconds_;
|
return microseconds_ < other.microseconds_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit constexpr Timestamp(int64_t us) : microseconds_(us) {}
|
explicit constexpr Timestamp(int64_t us) : microseconds_(us) {}
|
||||||
|
constexpr int64_t UnsafeSeconds() const {
|
||||||
|
return (microseconds_ + 500000) / 1000000;
|
||||||
|
}
|
||||||
|
constexpr int64_t UnsafeMillis() const {
|
||||||
|
return (microseconds_ + 500) / 1000;
|
||||||
|
}
|
||||||
int64_t microseconds_;
|
int64_t microseconds_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,8 +14,24 @@
|
|||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace test {
|
namespace test {
|
||||||
TEST(TimestampTest, ConstExpr) {
|
TEST(TimestampTest, ConstExpr) {
|
||||||
|
constexpr int64_t kValue = 12345;
|
||||||
constexpr Timestamp kTimestampInf = Timestamp::Infinity();
|
constexpr Timestamp kTimestampInf = Timestamp::Infinity();
|
||||||
static_assert(kTimestampInf.IsInfinite(), "");
|
static_assert(kTimestampInf.IsInfinite(), "");
|
||||||
|
static_assert(kTimestampInf.ms_or(-1) == -1, "");
|
||||||
|
|
||||||
|
constexpr Timestamp kTimestampSeconds = Timestamp::Seconds<kValue>();
|
||||||
|
constexpr Timestamp kTimestampMs = Timestamp::Millis<kValue>();
|
||||||
|
constexpr Timestamp kTimestampUs = Timestamp::Micros<kValue>();
|
||||||
|
|
||||||
|
static_assert(kTimestampSeconds.seconds_or(0) == kValue, "");
|
||||||
|
static_assert(kTimestampMs.ms_or(0) == kValue, "");
|
||||||
|
static_assert(kTimestampUs.us_or(0) == kValue, "");
|
||||||
|
|
||||||
|
static_assert(kTimestampMs > kTimestampUs, "");
|
||||||
|
|
||||||
|
EXPECT_EQ(kTimestampSeconds.seconds(), kValue);
|
||||||
|
EXPECT_EQ(kTimestampMs.ms(), kValue);
|
||||||
|
EXPECT_EQ(kTimestampUs.us(), kValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TimestampTest, GetBackSameValues) {
|
TEST(TimestampTest, GetBackSameValues) {
|
||||||
|
Reference in New Issue
Block a user