blob: 6fe1259e681ca2875ba9c5828f82d776fa25d912 [file] [log] [blame]
Sebastian Jansson30bd4032018-04-13 13:56:17 +02001/*
2 * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Sebastian Jansson6fae6ec2018-05-08 10:43:18 +020011#ifndef API_UNITS_DATA_SIZE_H_
12#define API_UNITS_DATA_SIZE_H_
Sebastian Jansson30bd4032018-04-13 13:56:17 +020013
14#include <stdint.h>
15#include <cmath>
16#include <limits>
17#include <string>
Sebastian Jansson942b3602018-05-30 15:47:44 +020018#include <type_traits>
Sebastian Jansson30bd4032018-04-13 13:56:17 +020019
20#include "rtc_base/checks.h"
Sebastian Jansson942b3602018-05-30 15:47:44 +020021#include "rtc_base/numerics/safe_conversions.h"
Sebastian Jansson30bd4032018-04-13 13:56:17 +020022
23namespace webrtc {
24namespace data_size_impl {
25constexpr int64_t kPlusInfinityVal = std::numeric_limits<int64_t>::max();
Sebastian Jansson30bd4032018-04-13 13:56:17 +020026} // namespace data_size_impl
27
Sebastian Jansson66fa5352018-04-30 16:54:57 +020028// DataSize is a class represeting a count of bytes.
Sebastian Jansson30bd4032018-04-13 13:56:17 +020029class DataSize {
30 public:
Sebastian Jansson3b69b192018-05-07 13:51:51 +020031 DataSize() = delete;
Sebastian Jansson8e064192018-08-07 12:34:33 +020032 static constexpr DataSize Zero() { return DataSize(0); }
33 static constexpr DataSize Infinity() {
Sebastian Jansson30bd4032018-04-13 13:56:17 +020034 return DataSize(data_size_impl::kPlusInfinityVal);
35 }
Sebastian Jansson942b3602018-05-30 15:47:44 +020036
37 template <
38 typename T,
39 typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
40 static DataSize bytes(T bytes) {
Sebastian Jansson30bd4032018-04-13 13:56:17 +020041 RTC_DCHECK_GE(bytes, 0);
Sebastian Jansson942b3602018-05-30 15:47:44 +020042 RTC_DCHECK_LT(bytes, data_size_impl::kPlusInfinityVal);
43 return DataSize(rtc::dchecked_cast<int64_t>(bytes));
Sebastian Jansson30bd4032018-04-13 13:56:17 +020044 }
Sebastian Jansson942b3602018-05-30 15:47:44 +020045
46 template <typename T,
47 typename std::enable_if<std::is_floating_point<T>::value>::type* =
48 nullptr>
49 static DataSize bytes(T bytes) {
50 if (bytes == std::numeric_limits<T>::infinity()) {
51 return Infinity();
52 } else {
53 RTC_DCHECK(!std::isnan(bytes));
54 RTC_DCHECK_GE(bytes, 0);
55 RTC_DCHECK_LT(bytes, data_size_impl::kPlusInfinityVal);
56 return DataSize(rtc::dchecked_cast<int64_t>(bytes));
57 }
58 }
59
60 template <typename T = int64_t>
61 typename std::enable_if<std::is_integral<T>::value, T>::type bytes() const {
Sebastian Jansson30bd4032018-04-13 13:56:17 +020062 RTC_DCHECK(IsFinite());
Sebastian Jansson942b3602018-05-30 15:47:44 +020063 return rtc::dchecked_cast<T>(bytes_);
Sebastian Jansson30bd4032018-04-13 13:56:17 +020064 }
Sebastian Jansson942b3602018-05-30 15:47:44 +020065
66 template <typename T>
67 typename std::enable_if<std::is_floating_point<T>::value, T>::type bytes()
68 const {
69 if (IsInfinite()) {
70 return std::numeric_limits<T>::infinity();
71 } else {
72 return bytes_;
73 }
74 }
75
Sebastian Jansson8e064192018-08-07 12:34:33 +020076 constexpr bool IsZero() const { return bytes_ == 0; }
77 constexpr bool IsInfinite() const {
78 return bytes_ == data_size_impl::kPlusInfinityVal;
79 }
80 constexpr bool IsFinite() const { return !IsInfinite(); }
Sebastian Jansson30bd4032018-04-13 13:56:17 +020081 DataSize operator-(const DataSize& other) const {
82 return DataSize::bytes(bytes() - other.bytes());
83 }
84 DataSize operator+(const DataSize& other) const {
85 return DataSize::bytes(bytes() + other.bytes());
86 }
Sebastian Jansson30bd4032018-04-13 13:56:17 +020087 DataSize& operator-=(const DataSize& other) {
88 bytes_ -= other.bytes();
89 return *this;
90 }
91 DataSize& operator+=(const DataSize& other) {
92 bytes_ += other.bytes();
93 return *this;
94 }
Sebastian Jansson942b3602018-05-30 15:47:44 +020095 double operator/(const DataSize& other) const {
96 return bytes<double>() / other.bytes<double>();
97 }
Sebastian Jansson30bd4032018-04-13 13:56:17 +020098 bool operator==(const DataSize& other) const {
99 return bytes_ == other.bytes_;
100 }
101 bool operator!=(const DataSize& other) const {
102 return bytes_ != other.bytes_;
103 }
104 bool operator<=(const DataSize& other) const {
105 return bytes_ <= other.bytes_;
106 }
107 bool operator>=(const DataSize& other) const {
108 return bytes_ >= other.bytes_;
109 }
110 bool operator>(const DataSize& other) const { return bytes_ > other.bytes_; }
111 bool operator<(const DataSize& other) const { return bytes_ < other.bytes_; }
112
113 private:
Sebastian Jansson8e064192018-08-07 12:34:33 +0200114 explicit constexpr DataSize(int64_t bytes) : bytes_(bytes) {}
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200115 int64_t bytes_;
116};
Sebastian Jansson942b3602018-05-30 15:47:44 +0200117
Sebastian Jansson66fa5352018-04-30 16:54:57 +0200118inline DataSize operator*(const DataSize& size, const double& scalar) {
119 return DataSize::bytes(std::round(size.bytes() * scalar));
120}
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200121inline DataSize operator*(const double& scalar, const DataSize& size) {
122 return size * scalar;
123}
Sebastian Jansson66fa5352018-04-30 16:54:57 +0200124inline DataSize operator*(const DataSize& size, const int64_t& scalar) {
125 return DataSize::bytes(size.bytes() * scalar);
126}
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200127inline DataSize operator*(const int64_t& scalar, const DataSize& size) {
128 return size * scalar;
129}
Sebastian Jansson66fa5352018-04-30 16:54:57 +0200130inline DataSize operator*(const DataSize& size, const int32_t& scalar) {
131 return DataSize::bytes(size.bytes() * scalar);
132}
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200133inline DataSize operator*(const int32_t& scalar, const DataSize& size) {
134 return size * scalar;
135}
Sebastian Jansson66fa5352018-04-30 16:54:57 +0200136inline DataSize operator/(const DataSize& size, const int64_t& scalar) {
137 return DataSize::bytes(size.bytes() / scalar);
138}
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200139
140std::string ToString(const DataSize& value);
141
142} // namespace webrtc
143
Sebastian Jansson6fae6ec2018-05-08 10:43:18 +0200144#endif // API_UNITS_DATA_SIZE_H_