Add conversions to and from double for units.

Bug: webrtc:8415
Change-Id: I6b1f7afb163daa327e45c51f1a3fb7cafbb1444e
Reviewed-on: https://webrtc-review.googlesource.com/78183
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23451}
This commit is contained in:
Sebastian Jansson
2018-05-30 15:47:44 +02:00
committed by Commit Bot
parent f859e55d9b
commit 942b360d82
9 changed files with 424 additions and 87 deletions

View File

@ -16,6 +16,7 @@
#include <string>
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "api/units/data_size.h"
#include "api/units/time_delta.h"
@ -43,28 +44,78 @@ class DataRate {
static DataRate Infinity() {
return DataRate(data_rate_impl::kPlusInfinityVal);
}
static DataRate bits_per_second(int64_t bits_per_sec) {
RTC_DCHECK_GE(bits_per_sec, 0);
return DataRate(bits_per_sec);
template <
typename T,
typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
static DataRate bps(T bits_per_second) {
RTC_DCHECK_GE(bits_per_second, 0);
RTC_DCHECK_LT(bits_per_second, data_rate_impl::kPlusInfinityVal);
return DataRate(rtc::dchecked_cast<int64_t>(bits_per_second));
}
static DataRate bps(int64_t bits_per_sec) {
return DataRate::bits_per_second(bits_per_sec);
template <
typename T,
typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
static DataRate kbps(T kilobits_per_sec) {
RTC_DCHECK_GE(kilobits_per_sec, 0);
RTC_DCHECK_LT(kilobits_per_sec, data_rate_impl::kPlusInfinityVal / 1000);
return DataRate::bps(rtc::dchecked_cast<int64_t>(kilobits_per_sec) * 1000);
}
static DataRate kbps(int64_t kilobits_per_sec) {
return DataRate::bits_per_second(kilobits_per_sec * 1000);
template <typename T,
typename std::enable_if<std::is_floating_point<T>::value>::type* =
nullptr>
static DataRate bps(T bits_per_second) {
if (bits_per_second == std::numeric_limits<T>::infinity()) {
return Infinity();
} else {
RTC_DCHECK(!std::isnan(bits_per_second));
RTC_DCHECK_GE(bits_per_second, 0);
RTC_DCHECK_LT(bits_per_second, data_rate_impl::kPlusInfinityVal);
return DataRate(rtc::dchecked_cast<int64_t>(bits_per_second));
}
}
int64_t bits_per_second() const {
template <typename T,
typename std::enable_if<std::is_floating_point<T>::value>::type* =
nullptr>
static DataRate kbps(T kilobits_per_sec) {
return DataRate::bps(kilobits_per_sec * 1e3);
}
template <typename T = int64_t>
typename std::enable_if<std::is_integral<T>::value, T>::type bps() const {
RTC_DCHECK(IsFinite());
return bits_per_sec_;
return rtc::dchecked_cast<T>(bits_per_sec_);
}
int64_t bps() const { return bits_per_second(); }
int64_t kbps() const { return (bps() + 500) / 1000; }
template <typename T = int64_t>
typename std::enable_if<std::is_integral<T>::value, T>::type kbps() const {
return rtc::dchecked_cast<T>((bps() + 500) / 1000);
}
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type bps()
const {
if (IsInfinite()) {
return std::numeric_limits<T>::infinity();
} else {
return bits_per_sec_;
}
}
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type kbps()
const {
return bps<T>() * 1e-3;
}
bool IsZero() const { return bits_per_sec_ == 0; }
bool IsInfinite() const {
return bits_per_sec_ == data_rate_impl::kPlusInfinityVal;
}
bool IsFinite() const { return !IsInfinite(); }
double operator/(const DataRate& other) const {
return bps<double>() / other.bps<double>();
}
bool operator==(const DataRate& other) const {
return bits_per_sec_ == other.bits_per_sec_;
}
@ -92,34 +143,32 @@ class DataRate {
};
inline DataRate operator*(const DataRate& rate, const double& scalar) {
return DataRate::bits_per_second(std::round(rate.bits_per_second() * scalar));
return DataRate::bps(std::round(rate.bps() * scalar));
}
inline DataRate operator*(const double& scalar, const DataRate& rate) {
return rate * scalar;
}
inline DataRate operator*(const DataRate& rate, const int64_t& scalar) {
return DataRate::bits_per_second(rate.bits_per_second() * scalar);
return DataRate::bps(rate.bps() * scalar);
}
inline DataRate operator*(const int64_t& scalar, const DataRate& rate) {
return rate * scalar;
}
inline DataRate operator*(const DataRate& rate, const int32_t& scalar) {
return DataRate::bits_per_second(rate.bits_per_second() * scalar);
return DataRate::bps(rate.bps() * scalar);
}
inline DataRate operator*(const int32_t& scalar, const DataRate& rate) {
return rate * scalar;
}
inline DataRate operator/(const DataSize& size, const TimeDelta& duration) {
return DataRate::bits_per_second(data_rate_impl::Microbits(size) /
duration.us());
return DataRate::bps(data_rate_impl::Microbits(size) / duration.us());
}
inline TimeDelta operator/(const DataSize& size, const DataRate& rate) {
return TimeDelta::us(data_rate_impl::Microbits(size) /
rate.bits_per_second());
return TimeDelta::us(data_rate_impl::Microbits(size) / rate.bps());
}
inline DataSize operator*(const DataRate& rate, const TimeDelta& duration) {
int64_t microbits = rate.bits_per_second() * duration.us();
int64_t microbits = rate.bps() * duration.us();
return DataSize::bytes((microbits + 4000000) / 8000000);
}
inline DataSize operator*(const TimeDelta& duration, const DataRate& rate) {