| Flutter Impeller |

allocation_size.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef FLUTTER_IMPELLER_BASE_ALLOCATION_SIZE_H_
6 #define FLUTTER_IMPELLER_BASE_ALLOCATION_SIZE_H_
7
8 #include <cmath>
9 #include <cstddef>
10 #include <cstdint>
11 #include <type_traits>
12
13 namespace impeller {
14
15 enum class FromBytesTag { kFromBytes };
16
17 //------------------------------------------------------------------------------
18 /// @brief Represents the size of an allocation in different units.
19 ///
20 /// Refer to the typedefs for Bytes, KiloBytes, MegaBytes,
21 /// Gigabytes, KibiBytes, MebiBytes, and GibiBytes below when using.
22 ///
23 /// Storage and all operations are always on unsigned units of
24 /// bytes.
25 ///
26 /// @tparam Period The number of bytes in 1 unit of the allocation size.
27 ///
28 template <size_t Period>
29 class AllocationSize {
30 public:
31 //----------------------------------------------------------------------------
32 /// @brief Create a zero allocation size.
33 ///
34 constexpr AllocationSize() = default;
35
36 //----------------------------------------------------------------------------
37 /// @brief Create an allocation size with the amount in the `Period`
38 /// number of bytes.
39 ///
40 /// @param[in] size The size in `Period` number of bytes.
41 ///
42 template <class T, class = std::enable_if_t<std::is_arithmetic_v<T>>>
43 explicit constexpr AllocationSize(T size)
44 : bytes_(std::ceil(size) * Period) {}
45
46 //----------------------------------------------------------------------------
47 /// @brief Create an allocation size from another instance with a
48 /// different period.
49 ///
50 /// @param[in] other The other allocation size.
51 ///
52 /// @tparam OtherPeriod The period of the other allocation.
53 ///
54 template <size_t OtherPeriod>
55 explicit constexpr AllocationSize(const AllocationSize<OtherPeriod>& other)
56 : bytes_(other.GetByteSize()) {}
57
58 //----------------------------------------------------------------------------
59 /// @brief Create an allocation size with the amount directly specified
60 /// in bytes.
61 ///
62 /// @param[in] byte_size The byte size.
63 /// @param[in] tag A tag for this constructor.
64 ///
65 constexpr AllocationSize(uint64_t byte_size, FromBytesTag)
66 : bytes_(byte_size) {}
67
68 //----------------------------------------------------------------------------
69 /// @return The byte size.
70 ///
71 constexpr uint64_t GetByteSize() const { return bytes_; }
72
73 //----------------------------------------------------------------------------
74 /// @return The number of `Periods` of bytes.
75 ///
76 constexpr double GetSize() const {
77 return GetByteSize() / static_cast<double>(Period);
78 }
79
80 //----------------------------------------------------------------------------
81 /// @brief Convert the allocation size from one unit to another.
82 ///
83 /// Conversions are non-truncating.
84 ///
85 /// @tparam AllocationSize The allocation size to convert to.
86 ///
87 /// @return The new allocation size.
88 ///
89 template <class AllocationSize>
90 constexpr AllocationSize ConvertTo() {
91 return AllocationSize{GetByteSize(), FromBytesTag::kFromBytes};
92 }
93
94 // The following relational operators can be replaced with a defaulted
95 // spaceship operator post C++20.
96
97 constexpr bool operator<(const AllocationSize& other) const {
98 return bytes_ < other.bytes_;
99 }
100
101 constexpr bool operator>(const AllocationSize& other) const {
102 return bytes_ > other.bytes_;
103 }
104
105 constexpr bool operator>=(const AllocationSize& other) const {
106 return bytes_ >= other.bytes_;
107 }
108
109 constexpr bool operator<=(const AllocationSize& other) const {
110 return bytes_ <= other.bytes_;
111 }
112
113 constexpr bool operator==(const AllocationSize& other) const {
114 return bytes_ == other.bytes_;
115 }
116
117 constexpr bool operator!=(const AllocationSize& other) const {
118 return bytes_ != other.bytes_;
119 }
120
121 // Explicit casts.
122
123 explicit constexpr operator bool() const { return bytes_ != 0u; }
124
125 // Arithmetic operators (overflows are caller error).
126
127 constexpr AllocationSize operator+(const AllocationSize& other) const {
128 return AllocationSize(bytes_ + other.GetByteSize(),
129 FromBytesTag::kFromBytes);
130 }
131
132 constexpr AllocationSize operator-(const AllocationSize& other) const {
133 return AllocationSize(bytes_ - other.GetByteSize(),
134 FromBytesTag::kFromBytes);
135 }
136
137 constexpr AllocationSize& operator+=(const AllocationSize& other) {
138 bytes_ += other.GetByteSize();
139 return *this;
140 }
141
142 constexpr AllocationSize& operator-=(const AllocationSize& other) {
143 bytes_ -= other.GetByteSize();
144 return *this;
145 }
146
147 private:
148 uint64_t bytes_ = {};
149 };
150
151 using Bytes = AllocationSize<1u>;
152
153 using KiloBytes = AllocationSize<1'000u>;
154 using MegaBytes = AllocationSize<1'000u * 1'000u>;
155 using GigaBytes = AllocationSize<1'000u * 1'000u * 1'000u>;
156
157 using KibiBytes = AllocationSize<1'024u>;
158 using MebiBytes = AllocationSize<1'024u * 1'024u>;
159 using GibiBytes = AllocationSize<1'024u * 1'024u * 1'024u>;
160
161 inline namespace allocation_size_literals {
162
163 // NOLINTNEXTLINE
164 constexpr Bytes operator"" _bytes(unsigned long long int size) {
165 return Bytes{size};
166 }
167
168 // NOLINTNEXTLINE
169 constexpr KiloBytes operator"" _kb(unsigned long long int size) {
170 return KiloBytes{size};
171 }
172
173 // NOLINTNEXTLINE
174 constexpr MegaBytes operator"" _mb(unsigned long long int size) {
175 return MegaBytes{size};
176 }
177
178 // NOLINTNEXTLINE
179 constexpr GigaBytes operator"" _gb(unsigned long long int size) {
180 return GigaBytes{size};
181 }
182
183 // NOLINTNEXTLINE
184 constexpr KibiBytes operator"" _kib(unsigned long long int size) {
185 return KibiBytes{size};
186 }
187
188 // NOLINTNEXTLINE
189 constexpr MebiBytes operator"" _mib(unsigned long long int size) {
190 return MebiBytes{size};
191 }
192
193 // NOLINTNEXTLINE
194 constexpr GibiBytes operator"" _gib(unsigned long long int size) {
195 return GibiBytes{size};
196 }
197
198 } // namespace allocation_size_literals
199
200 } // namespace impeller
201
202 #endif // FLUTTER_IMPELLER_BASE_ALLOCATION_SIZE_H_
impeller::AllocationSize
Represents the size of an allocation in different units.
Definition: allocation_size.h:29
impeller::AllocationSize::AllocationSize
constexpr AllocationSize(uint64_t byte_size, FromBytesTag)
Create an allocation size with the amount directly specified in bytes.
Definition: allocation_size.h:65
impeller::AllocationSize::operator<=
constexpr bool operator<=(const AllocationSize &other) const
Definition: allocation_size.h:109
impeller::AllocationSize::GetSize
constexpr double GetSize() const
Definition: allocation_size.h:76
impeller::AllocationSize::ConvertTo
constexpr AllocationSize ConvertTo()
Convert the allocation size from one unit to another.
Definition: allocation_size.h:90
impeller::AllocationSize::operator==
constexpr bool operator==(const AllocationSize &other) const
Definition: allocation_size.h:113
impeller::AllocationSize::operator-
constexpr AllocationSize operator-(const AllocationSize &other) const
Definition: allocation_size.h:132
impeller::AllocationSize::GetByteSize
constexpr uint64_t GetByteSize() const
Definition: allocation_size.h:71
impeller::AllocationSize::operator+
constexpr AllocationSize operator+(const AllocationSize &other) const
Definition: allocation_size.h:127
impeller::AllocationSize::operator<
constexpr bool operator<(const AllocationSize &other) const
Definition: allocation_size.h:97
impeller::AllocationSize::operator-=
constexpr AllocationSize & operator-=(const AllocationSize &other)
Definition: allocation_size.h:142
impeller::AllocationSize::AllocationSize
constexpr AllocationSize(T size)
Create an allocation size with the amount in the Period number of bytes.
Definition: allocation_size.h:43
impeller::AllocationSize::AllocationSize
constexpr AllocationSize()=default
Create a zero allocation size.
impeller::AllocationSize::operator+=
constexpr AllocationSize & operator+=(const AllocationSize &other)
Definition: allocation_size.h:137
impeller::AllocationSize::operator>
constexpr bool operator>(const AllocationSize &other) const
Definition: allocation_size.h:101
impeller::AllocationSize::AllocationSize
constexpr AllocationSize(const AllocationSize< OtherPeriod > &other)
Create an allocation size from another instance with a different period.
Definition: allocation_size.h:55
impeller::AllocationSize::operator>=
constexpr bool operator>=(const AllocationSize &other) const
Definition: allocation_size.h:105
impeller::AllocationSize::operator!=
constexpr bool operator!=(const AllocationSize &other) const
Definition: allocation_size.h:117
impeller
Definition: allocation.cc:12
impeller::FromBytesTag
FromBytesTag
Definition: allocation_size.h:15
impeller::FromBytesTag::kFromBytes
@ kFromBytes
std
Definition: comparable.h:95