28 {
29public:
31
33 fHead = nullptr;
34 fTail = nullptr;
35 }
36
37 void remove(
T* entry) {
40
41 T*
prev = entry->fPrev;
42 T*
next = entry->fNext;
43
46 } else {
48 }
51 } else {
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);
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);
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
103
104
105
106 void addBefore(
T* newEntry,
T* existingEntry) {
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) {
121 fHead = newEntry;
122 } else {
123 prev->fNext = newEntry;
124 }
125#ifdef SK_DEBUG
126 newEntry->fList = this;
127#endif
128 }
129
130
131
132
133
134
135 void addAfter(
T* newEntry,
T* existingEntry) {
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) {
150 fTail = newEntry;
151 } else {
152 next->fPrev = newEntry;
153 }
154#ifdef SK_DEBUG
155 newEntry->fList = this;
156#endif
157 }
158
160 if (list.isEmpty()) {
161 return;
162 }
163
164 list.fHead->fPrev = fTail;
165 if (!fHead) {
167 fHead = list.fHead;
168 } else {
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) {
177 node->fList = this;
178 }
179#endif
180
181 list.fHead = list.fTail = nullptr;
182 }
183
184 bool isEmpty() const {
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
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
218
220 if (nullptr == fCurr) {
221 return nullptr;
222 }
223
224 fCurr = fCurr->fNext;
225 return fCurr;
226 }
227
229 if (nullptr == fCurr) {
230 return nullptr;
231 }
232
233 fCurr = fCurr->fPrev;
234 return fCurr;
235 }
236
237
238
239
240 bool operator!=(
const Iter& that) {
return fCurr != that.fCurr; }
242 void operator++() { this->
next(); }
243
244 private:
246 };
247
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 {
259 Iter iter;
260 for (
T* item = iter.init(*
this, Iter::kHead_IterStart); item; item = iter.next()) {
262 if (nullptr == item->fPrev) {
264 } else {
265 SkASSERT(item->fPrev->fNext == item);
266 }
267 if (nullptr == item->fNext) {
269 } else {
270 SkASSERT(item->fNext->fPrev == item);
271 }
272 }
273 }
274
275
276
277
278
279 bool isInList(
const T* entry)
const {
280 return entry->fList == this;
281 }
282
283
284
285
286 int countEntries() const {
288 for (
T* entry = fHead; entry; entry = entry->fNext) {
290 }
292 }
293#endif
294
295private:
298
301};
302
303#endif
static float next(float f)
static float prev(float f)
static SkSize operator*(SkISize u, SkScalar s)
bool operator!=(const sk_sp< T > &a, const sk_sp< U > &b)
static constexpr bool SkToBool(const T &x)
static const char * begin(const StringSlice &s)