Flutter Engine
The Flutter Engine
SkFixedArray.h
Go to the documentation of this file.
1/*
2 * Copyright 2024 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkTFixedArray_DEFINED
9#define SkTFixedArray_DEFINED
10
12
13#include <cstdint>
14#include <cstring>
15#include <initializer_list>
16#include <type_traits> // IWYU pragma: keep for std::is_trivial_v
17
18namespace skia_private {
19
20/**
21 * Represents an array of `T` (must be a trivial type) that cannot grow past a fixed size `N`.
22 * The fixed-size restriction allows for tighter codegen and a smaller memory footprint.
23 * Missing methods from TArray (e.g. `push_back_n`) can be added on demand.
24 *
25 * The trivial-type restriction is only to simplify implementation; if there is a need, we can
26 * adopt proper move/copy semantics in this class as well.
27 */
28template <int N, typename T>
30public:
31 using value_type = T;
32
33 FixedArray() = default;
34
35 FixedArray(std::initializer_list<T> values) {
36 SkASSERT(values.size() <= N);
37 for (T value : values) {
38 fData[fSize++] = value;
39 }
40 }
41
42 FixedArray(int reserveCount) {
43 // This is here to satisfy the TArray interface. Setting a reserve count on a fixed array
44 // isn't useful.
45 SkASSERT(reserveCount >= 0);
46 SkASSERT(reserveCount <= N);
47 }
48
49 FixedArray(const T* array, int count) {
50 this->reset(array, count);
51 }
52
54 this->reset(that.data(), that.size());
55 }
56
58 if (this != &that) {
59 this->reset(that.data(), that.size());
60 }
61 return *this;
62 }
63
64 T& operator[](size_t index) {
65 SkASSERT(index < fSize);
66 return fData[index];
67 }
68
69 const T& operator[](size_t index) const {
70 SkASSERT(index < fSize);
71 return fData[index];
72 }
73
74 bool operator==(const FixedArray<N, T>& that) const {
75 return fSize == that.fSize && (0 == memcmp(fData, that.fData, fSize * sizeof(T)));
76 }
77
78 bool operator!=(const FixedArray<N, T>& that) const {
79 return !this->operator==(that);
80 }
81
82 int size() const {
83 return fSize;
84 }
85
86 bool empty() const {
87 return fSize == 0;
88 }
89
90 void clear() {
91 fSize = 0;
92 }
93
94 void reset(const T* array, int count) {
95 SkASSERT(count >= 0);
96 SkASSERT(count <= N);
97 fSize = count;
98 std::memcpy(fData, array, count * sizeof(T));
99 }
100
101 void resize(int newSize) {
102 SkASSERT(newSize >= 0);
103 SkASSERT(newSize <= N);
104
105 if (fSize > newSize) {
106 fSize = newSize;
107 } else {
108 while (fSize < newSize) {
109 fData[fSize++] = T();
110 }
111 }
112 }
113
115 SkASSERT(fSize < N);
116 T& ref = fData[fSize++];
117 ref = T();
118 return ref;
119 }
120
121 void push_back(T x) {
122 SkASSERT(fSize < N);
123 fData[fSize++] = x;
124 }
125
126 void pop_back() {
127 SkASSERT(fSize > 0);
128 --fSize;
129 }
130
131 void removeShuffle(int n) {
132 SkASSERT(n < fSize);
133 int last = fSize - 1;
134 if (n != last) {
135 fData[n] = fData[last];
136 }
137 fSize = last;
138 }
139
140 T* data() {
141 return fData;
142 }
143
144 const T* data() const {
145 return fData;
146 }
147
148 T* begin() {
149 return fData;
150 }
151
152 const T* begin() const {
153 return fData;
154 }
155
156 T* end() {
157 return fData + fSize;
158 }
159
160 const T* end() const {
161 return fData + fSize;
162 }
163
164 T& front() {
165 SkASSERT(fSize > 0);
166 return fData[0];
167 }
168
169 const T& front() const {
170 SkASSERT(fSize > 0);
171 return fData[0];
172 }
173
174 T& back() {
175 SkASSERT(fSize > 0);
176 return fData[fSize - 1];
177 }
178
179 const T& back() const {
180 SkASSERT(fSize > 0);
181 return fData[fSize - 1];
182 }
183
184 void reserve(int size) {
185 // This is here to satisfy the TArray interface.
186 SkASSERT(size >= 0);
187 SkASSERT(size <= N);
188 }
189
190 constexpr int capacity() const {
191 return N;
192 }
193
194private:
195 static_assert(std::is_trivial_v<T>);
196 static_assert(N > 0);
197 static_assert(N < 256); // limited by `uint8_t fSize`
198
199 T fData[N];
200 uint8_t fSize = 0;
201};
202
203} // namespace skia_private
204
205#endif
int count
Definition: FontMgrTest.cpp:50
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define N
Definition: beziers.cpp:19
const T * data() const
Definition: SkFixedArray.h:144
const T * begin() const
Definition: SkFixedArray.h:152
T & operator[](size_t index)
Definition: SkFixedArray.h:64
const T * end() const
Definition: SkFixedArray.h:160
FixedArray(const T *array, int count)
Definition: SkFixedArray.h:49
bool operator==(const FixedArray< N, T > &that) const
Definition: SkFixedArray.h:74
FixedArray(int reserveCount)
Definition: SkFixedArray.h:42
const T & operator[](size_t index) const
Definition: SkFixedArray.h:69
const T & back() const
Definition: SkFixedArray.h:179
FixedArray(const FixedArray< N, T > &that)
Definition: SkFixedArray.h:53
void reserve(int size)
Definition: SkFixedArray.h:184
void resize(int newSize)
Definition: SkFixedArray.h:101
FixedArray(std::initializer_list< T > values)
Definition: SkFixedArray.h:35
constexpr int capacity() const
Definition: SkFixedArray.h:190
bool operator!=(const FixedArray< N, T > &that) const
Definition: SkFixedArray.h:78
const T & front() const
Definition: SkFixedArray.h:169
void reset(const T *array, int count)
Definition: SkFixedArray.h:94
FixedArray< N, T > & operator=(const FixedArray< N, T > &that)
Definition: SkFixedArray.h:57
uint8_t value
double x
#define T
Definition: precompiler.cc:65