blob: 8c35766b1e039c06bdab4116d979022a47dfad52 [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 Jansson30bd4032018-04-13 13:56:17 +020032 static DataSize Zero() { return DataSize(0); }
33 static DataSize Infinity() {
34 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 Jansson30bd4032018-04-13 13:56:17 +020076 bool IsZero() const { return bytes_ == 0; }
77 bool IsInfinite() const { return bytes_ == data_size_impl::kPlusInfinityVal; }
Sebastian Jansson3b69b192018-05-07 13:51:51 +020078 bool IsFinite() const { return !IsInfinite(); }
Sebastian Jansson30bd4032018-04-13 13:56:17 +020079 DataSize operator-(const DataSize& other) const {
80 return DataSize::bytes(bytes() - other.bytes());
81 }
82 DataSize operator+(const DataSize& other) const {
83 return DataSize::bytes(bytes() + other.bytes());
84 }
Sebastian Jansson30bd4032018-04-13 13:56:17 +020085 DataSize& operator-=(const DataSize& other) {
86 bytes_ -= other.bytes();
87 return *this;
88 }
89 DataSize& operator+=(const DataSize& other) {
90 bytes_ += other.bytes();
91 return *this;
92 }
Sebastian Jansson942b3602018-05-30 15:47:44 +020093 double operator/(const DataSize& other) const {
94 return bytes<double>() / other.bytes<double>();
95 }
Sebastian Jansson30bd4032018-04-13 13:56:17 +020096 bool operator==(const DataSize& other) const {
97 return bytes_ == other.bytes_;
98 }
99 bool operator!=(const DataSize& other) const {
100 return bytes_ != other.bytes_;
101 }
102 bool operator<=(const DataSize& other) const {
103 return bytes_ <= other.bytes_;
104 }
105 bool operator>=(const DataSize& other) const {
106 return bytes_ >= other.bytes_;
107 }
108 bool operator>(const DataSize& other) const { return bytes_ > other.bytes_; }
109 bool operator<(const DataSize& other) const { return bytes_ < other.bytes_; }
110
111 private:
112 explicit DataSize(int64_t bytes) : bytes_(bytes) {}
113 int64_t bytes_;
114};
Sebastian Jansson942b3602018-05-30 15:47:44 +0200115
Sebastian Jansson66fa5352018-04-30 16:54:57 +0200116inline DataSize operator*(const DataSize& size, const double& scalar) {
117 return DataSize::bytes(std::round(size.bytes() * scalar));
118}
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200119inline DataSize operator*(const double& scalar, const DataSize& size) {
120 return size * scalar;
121}
Sebastian Jansson66fa5352018-04-30 16:54:57 +0200122inline DataSize operator*(const DataSize& size, const int64_t& scalar) {
123 return DataSize::bytes(size.bytes() * scalar);
124}
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200125inline DataSize operator*(const int64_t& scalar, const DataSize& size) {
126 return size * scalar;
127}
Sebastian Jansson66fa5352018-04-30 16:54:57 +0200128inline DataSize operator*(const DataSize& size, const int32_t& scalar) {
129 return DataSize::bytes(size.bytes() * scalar);
130}
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200131inline DataSize operator*(const int32_t& scalar, const DataSize& size) {
132 return size * scalar;
133}
Sebastian Jansson66fa5352018-04-30 16:54:57 +0200134inline DataSize operator/(const DataSize& size, const int64_t& scalar) {
135 return DataSize::bytes(size.bytes() / scalar);
136}
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200137
138std::string ToString(const DataSize& value);
139
140} // namespace webrtc
141
Sebastian Jansson6fae6ec2018-05-08 10:43:18 +0200142#endif // API_UNITS_DATA_SIZE_H_