Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Macros
SkTInternalLList.h File Reference
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkTo.h"

Go to the source code of this file.

Classes

class  SkTInternalLList< T >
 
class  SkTInternalLList< T >::Iter
 

Macros

#define SK_DECLARE_INTERNAL_LLIST_INTERFACE(ClassName)
 

Macro Definition Documentation

◆ SK_DECLARE_INTERNAL_LLIST_INTERFACE

#define SK_DECLARE_INTERNAL_LLIST_INTERFACE (   ClassName)
Value:
friend class SkTInternalLList<ClassName>; \
/* back pointer to the owning list - for debugging */ \
SkDEBUGCODE(SkTInternalLList<ClassName>* fList = nullptr;) \
ClassName* fPrev = nullptr; \
ClassName* fNext = nullptr
Instance * fNext

This macro creates the member variables required by the SkTInternalLList class. It should be placed in the private section of any class that will be stored in a double linked list.

Definition at line 19 of file SkTInternalLList.h.

28 {
29public:
31
32 void reset() {
33 fHead = nullptr;
34 fTail = nullptr;
35 }
36
37 void remove(T* entry) {
38 SkASSERT(fHead && fTail);
39 SkASSERT(this->isInList(entry));
40
41 T* prev = entry->fPrev;
42 T* next = entry->fNext;
43
44 if (prev) {
45 prev->fNext = next;
46 } else {
47 fHead = next;
48 }
49 if (next) {
50 next->fPrev = prev;
51 } else {
52 fTail = prev;
53 }
54
55 entry->fPrev = nullptr;
56 entry->fNext = nullptr;
57
58#ifdef SK_DEBUG
59 entry->fList = nullptr;
60#endif
61 }
62
63 void addToHead(T* entry) {
64 SkASSERT(nullptr == entry->fPrev && nullptr == entry->fNext);
65 SkASSERT(nullptr == entry->fList);
66
67 entry->fPrev = nullptr;
68 entry->fNext = fHead;
69 if (fHead) {
70 fHead->fPrev = entry;
71 }
72 fHead = entry;
73 if (nullptr == fTail) {
74 fTail = entry;
75 }
76
77#ifdef SK_DEBUG
78 entry->fList = this;
79#endif
80 }
81
82 void addToTail(T* entry) {
83 SkASSERT(nullptr == entry->fPrev && nullptr == entry->fNext);
84 SkASSERT(nullptr == entry->fList);
85
86 entry->fPrev = fTail;
87 entry->fNext = nullptr;
88 if (fTail) {
89 fTail->fNext = entry;
90 }
91 fTail = entry;
92 if (nullptr == fHead) {
93 fHead = entry;
94 }
95
96#ifdef SK_DEBUG
97 entry->fList = this;
98#endif
99 }
100
101 /**
102 * Inserts a new list entry before an existing list entry. The new entry must not already be
103 * a member of this or any other list. If existingEntry is NULL then the new entry is added
104 * at the tail.
105 */
106 void addBefore(T* newEntry, T* existingEntry) {
107 SkASSERT(newEntry);
108
109 if (nullptr == existingEntry) {
110 this->addToTail(newEntry);
111 return;
112 }
113
114 SkASSERT(this->isInList(existingEntry));
115 newEntry->fNext = existingEntry;
116 T* prev = existingEntry->fPrev;
117 existingEntry->fPrev = newEntry;
118 newEntry->fPrev = prev;
119 if (nullptr == prev) {
120 SkASSERT(fHead == existingEntry);
121 fHead = newEntry;
122 } else {
123 prev->fNext = newEntry;
124 }
125#ifdef SK_DEBUG
126 newEntry->fList = this;
127#endif
128 }
129
130 /**
131 * Inserts a new list entry after an existing list entry. The new entry must not already be
132 * a member of this or any other list. If existingEntry is NULL then the new entry is added
133 * at the head.
134 */
135 void addAfter(T* newEntry, T* existingEntry) {
136 SkASSERT(newEntry);
137
138 if (nullptr == existingEntry) {
139 this->addToHead(newEntry);
140 return;
141 }
142
143 SkASSERT(this->isInList(existingEntry));
144 newEntry->fPrev = existingEntry;
145 T* next = existingEntry->fNext;
146 existingEntry->fNext = newEntry;
147 newEntry->fNext = next;
148 if (nullptr == next) {
149 SkASSERT(fTail == existingEntry);
150 fTail = newEntry;
151 } else {
152 next->fPrev = newEntry;
153 }
154#ifdef SK_DEBUG
155 newEntry->fList = this;
156#endif
157 }
158
159 void concat(SkTInternalLList&& list) {
160 if (list.isEmpty()) {
161 return;
162 }
163
164 list.fHead->fPrev = fTail;
165 if (!fHead) {
166 SkASSERT(!list.fHead->fPrev);
167 fHead = list.fHead;
168 } else {
169 SkASSERT(fTail);
170 fTail->fNext = list.fHead;
171 }
172 fTail = list.fTail;
173
174#ifdef SK_DEBUG
175 for (T* node = list.fHead; node; node = node->fNext) {
176 SkASSERT(node->fList == &list);
177 node->fList = this;
178 }
179#endif
180
181 list.fHead = list.fTail = nullptr;
182 }
183
184 bool isEmpty() const {
185 SkASSERT(SkToBool(fHead) == SkToBool(fTail));
186 return !fHead;
187 }
188
189 T* head() const { return fHead; }
190 T* tail() const { return fTail; }
191
192 class Iter {
193 public:
194 enum IterStart {
195 kHead_IterStart,
196 kTail_IterStart
197 };
198
199 Iter() : fCurr(nullptr) {}
200 Iter(const Iter& iter) : fCurr(iter.fCurr) {}
201 Iter& operator= (const Iter& iter) { fCurr = iter.fCurr; return *this; }
202
203 T* init(const SkTInternalLList& list, IterStart startLoc) {
204 if (kHead_IterStart == startLoc) {
205 fCurr = list.fHead;
206 } else {
207 SkASSERT(kTail_IterStart == startLoc);
208 fCurr = list.fTail;
209 }
210
211 return fCurr;
212 }
213
214 T* get() { return fCurr; }
215
216 /**
217 * Return the next/previous element in the list or NULL if at the end.
218 */
219 T* next() {
220 if (nullptr == fCurr) {
221 return nullptr;
222 }
223
224 fCurr = fCurr->fNext;
225 return fCurr;
226 }
227
228 T* prev() {
229 if (nullptr == fCurr) {
230 return nullptr;
231 }
232
233 fCurr = fCurr->fPrev;
234 return fCurr;
235 }
236
237 /**
238 * C++11 range-for interface.
239 */
240 bool operator!=(const Iter& that) { return fCurr != that.fCurr; }
241 T* operator*() { return this->get(); }
242 void operator++() { this->next(); }
243
244 private:
245 T* fCurr;
246 };
247
248 Iter begin() const {
249 Iter iter;
250 iter.init(*this, Iter::kHead_IterStart);
251 return iter;
252 }
253
254 Iter end() const { return Iter(); }
255
256#ifdef SK_DEBUG
257 void validate() const {
258 SkASSERT(!fHead == !fTail);
259 Iter iter;
260 for (T* item = iter.init(*this, Iter::kHead_IterStart); item; item = iter.next()) {
261 SkASSERT(this->isInList(item));
262 if (nullptr == item->fPrev) {
263 SkASSERT(fHead == item);
264 } else {
265 SkASSERT(item->fPrev->fNext == item);
266 }
267 if (nullptr == item->fNext) {
268 SkASSERT(fTail == item);
269 } else {
270 SkASSERT(item->fNext->fPrev == item);
271 }
272 }
273 }
274
275 /**
276 * Debugging-only method that uses the list back pointer to check if 'entry' is indeed in 'this'
277 * list.
278 */
279 bool isInList(const T* entry) const {
280 return entry->fList == this;
281 }
282
283 /**
284 * Debugging-only method that laboriously counts the list entries.
285 */
286 int countEntries() const {
287 int count = 0;
288 for (T* entry = fHead; entry; entry = entry->fNext) {
289 ++count;
290 }
291 return count;
292 }
293#endif // SK_DEBUG
294
295private:
296 T* fHead = nullptr;
297 T* fTail = nullptr;
298
299 SkTInternalLList(const SkTInternalLList&) = delete;
300 SkTInternalLList& operator=(const SkTInternalLList&) = delete;
301};
302
303#endif
m reset()
int count
static float next(float f)
static float prev(float f)
#define SkASSERT(cond)
Definition SkAssert.h:116
static SkSize operator*(SkISize u, SkScalar s)
bool operator!=(const sk_sp< T > &a, const sk_sp< U > &b)
Definition SkRefCnt.h:355
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
static const char * begin(const StringSlice &s)
Definition editor.cpp:252
glong glong end
init(device_serial, adb_binary)
Definition _adb_path.py:12
#define T