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