blob: 00ab2eccf7398e7b2a0e461ed10e18c2bf173d65 [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 Janssonc1c8b8e2018-08-07 15:29:04 +020036 template <int64_t bytes>
37 static constexpr DataSize Bytes() {
38 static_assert(bytes >= 0, "");
39 static_assert(bytes < data_size_impl::kPlusInfinityVal, "");
40 return DataSize(bytes);
41 }
Sebastian Jansson942b3602018-05-30 15:47:44 +020042
43 template <
44 typename T,
45 typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
46 static DataSize bytes(T bytes) {
Sebastian Jansson30bd4032018-04-13 13:56:17 +020047 RTC_DCHECK_GE(bytes, 0);
Sebastian Jansson942b3602018-05-30 15:47:44 +020048 RTC_DCHECK_LT(bytes, data_size_impl::kPlusInfinityVal);
49 return DataSize(rtc::dchecked_cast<int64_t>(bytes));
Sebastian Jansson30bd4032018-04-13 13:56:17 +020050 }
Sebastian Jansson942b3602018-05-30 15:47:44 +020051
52 template <typename T,
53 typename std::enable_if<std::is_floating_point<T>::value>::type* =
54 nullptr>
55 static DataSize bytes(T bytes) {
56 if (bytes == std::numeric_limits<T>::infinity()) {
57 return Infinity();
58 } else {
59 RTC_DCHECK(!std::isnan(bytes));
60 RTC_DCHECK_GE(bytes, 0);
61 RTC_DCHECK_LT(bytes, data_size_impl::kPlusInfinityVal);
62 return DataSize(rtc::dchecked_cast<int64_t>(bytes));
63 }
64 }
65
66 template <typename T = int64_t>
67 typename std::enable_if<std::is_integral<T>::value, T>::type bytes() const {
Sebastian Jansson30bd4032018-04-13 13:56:17 +020068 RTC_DCHECK(IsFinite());
Sebastian Jansson942b3602018-05-30 15:47:44 +020069 return rtc::dchecked_cast<T>(bytes_);
Sebastian Jansson30bd4032018-04-13 13:56:17 +020070 }
Sebastian Jansson942b3602018-05-30 15:47:44 +020071
72 template <typename T>
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020073 constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
74 bytes() const {
75 return IsInfinite() ? std::numeric_limits<T>::infinity() : bytes_;
76 }
77
78 constexpr int64_t bytes_or(int64_t fallback_value) const {
79 return IsFinite() ? bytes_ : fallback_value;
Sebastian Jansson942b3602018-05-30 15:47:44 +020080 }
81
Sebastian Jansson8e064192018-08-07 12:34:33 +020082 constexpr bool IsZero() const { return bytes_ == 0; }
83 constexpr bool IsInfinite() const {
84 return bytes_ == data_size_impl::kPlusInfinityVal;
85 }
86 constexpr bool IsFinite() const { return !IsInfinite(); }
Sebastian Jansson30bd4032018-04-13 13:56:17 +020087 DataSize operator-(const DataSize& other) const {
88 return DataSize::bytes(bytes() - other.bytes());
89 }
90 DataSize operator+(const DataSize& other) const {
91 return DataSize::bytes(bytes() + other.bytes());
92 }
Sebastian Jansson30bd4032018-04-13 13:56:17 +020093 DataSize& operator-=(const DataSize& other) {
94 bytes_ -= other.bytes();
95 return *this;
96 }
97 DataSize& operator+=(const DataSize& other) {
98 bytes_ += other.bytes();
99 return *this;
100 }
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +0200101 constexpr double operator/(const DataSize& other) const {
Sebastian Jansson942b3602018-05-30 15:47:44 +0200102 return bytes<double>() / other.bytes<double>();
103 }
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +0200104 constexpr bool operator==(const DataSize& other) const {
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200105 return bytes_ == other.bytes_;
106 }
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +0200107 constexpr bool operator!=(const DataSize& other) const {
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200108 return bytes_ != other.bytes_;
109 }
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +0200110 constexpr bool operator<=(const DataSize& other) const {
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200111 return bytes_ <= other.bytes_;
112 }
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +0200113 constexpr bool operator>=(const DataSize& other) const {
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200114 return bytes_ >= other.bytes_;
115 }
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +0200116 constexpr bool operator>(const DataSize& other) const {
117 return bytes_ > other.bytes_;
118 }
119 constexpr bool operator<(const DataSize& other) const {
120 return bytes_ < other.bytes_;
121 }
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200122
123 private:
Sebastian Jansson8e064192018-08-07 12:34:33 +0200124 explicit constexpr DataSize(int64_t bytes) : bytes_(bytes) {}
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200125 int64_t bytes_;
126};
Sebastian Jansson942b3602018-05-30 15:47:44 +0200127
Sebastian Jansson66fa5352018-04-30 16:54:57 +0200128inline DataSize operator*(const DataSize& size, const double& scalar) {
129 return DataSize::bytes(std::round(size.bytes() * scalar));
130}
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200131inline DataSize operator*(const double& 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 +0200137inline DataSize operator*(const int64_t& scalar, const DataSize& size) {
138 return size * scalar;
139}
Sebastian Jansson66fa5352018-04-30 16:54:57 +0200140inline DataSize operator*(const DataSize& size, const int32_t& scalar) {
141 return DataSize::bytes(size.bytes() * scalar);
142}
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200143inline DataSize operator*(const int32_t& scalar, const DataSize& size) {
144 return size * scalar;
145}
Sebastian Jansson66fa5352018-04-30 16:54:57 +0200146inline DataSize operator/(const DataSize& size, const int64_t& scalar) {
147 return DataSize::bytes(size.bytes() / scalar);
148}
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200149
150std::string ToString(const DataSize& value);
151
152} // namespace webrtc
153
Sebastian Jansson6fae6ec2018-05-08 10:43:18 +0200154#endif // API_UNITS_DATA_SIZE_H_