xref: /aosp_15_r20/external/skia/src/base/SkTInternalLList.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2012 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SkTInternalLList_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define SkTInternalLList_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkDebug.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTo.h"
14*c8dee2aaSAndroid Build Coastguard Worker 
15*c8dee2aaSAndroid Build Coastguard Worker /**
16*c8dee2aaSAndroid Build Coastguard Worker  * This macro creates the member variables required by the SkTInternalLList class. It should be
17*c8dee2aaSAndroid Build Coastguard Worker  * placed in the private section of any class that will be stored in a double linked list.
18*c8dee2aaSAndroid Build Coastguard Worker  */
19*c8dee2aaSAndroid Build Coastguard Worker #define SK_DECLARE_INTERNAL_LLIST_INTERFACE(ClassName)              \
20*c8dee2aaSAndroid Build Coastguard Worker     friend class SkTInternalLList<ClassName>;                       \
21*c8dee2aaSAndroid Build Coastguard Worker     /* back pointer to the owning list - for debugging */           \
22*c8dee2aaSAndroid Build Coastguard Worker     SkDEBUGCODE(SkTInternalLList<ClassName>* fList = nullptr;)      \
23*c8dee2aaSAndroid Build Coastguard Worker     ClassName* fPrev = nullptr;                                     \
24*c8dee2aaSAndroid Build Coastguard Worker     ClassName* fNext = nullptr
25*c8dee2aaSAndroid Build Coastguard Worker 
26*c8dee2aaSAndroid Build Coastguard Worker /**
27*c8dee2aaSAndroid Build Coastguard Worker  * This class implements a templated internal doubly linked list data structure.
28*c8dee2aaSAndroid Build Coastguard Worker  */
29*c8dee2aaSAndroid Build Coastguard Worker template <class T> class SkTInternalLList {
30*c8dee2aaSAndroid Build Coastguard Worker public:
SkTInternalLList()31*c8dee2aaSAndroid Build Coastguard Worker     SkTInternalLList() {}
32*c8dee2aaSAndroid Build Coastguard Worker 
reset()33*c8dee2aaSAndroid Build Coastguard Worker     void reset() {
34*c8dee2aaSAndroid Build Coastguard Worker         fHead = nullptr;
35*c8dee2aaSAndroid Build Coastguard Worker         fTail = nullptr;
36*c8dee2aaSAndroid Build Coastguard Worker     }
37*c8dee2aaSAndroid Build Coastguard Worker 
remove(T * entry)38*c8dee2aaSAndroid Build Coastguard Worker     void remove(T* entry) {
39*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(fHead && fTail);
40*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(this->isInList(entry));
41*c8dee2aaSAndroid Build Coastguard Worker 
42*c8dee2aaSAndroid Build Coastguard Worker         T* prev = entry->fPrev;
43*c8dee2aaSAndroid Build Coastguard Worker         T* next = entry->fNext;
44*c8dee2aaSAndroid Build Coastguard Worker 
45*c8dee2aaSAndroid Build Coastguard Worker         if (prev) {
46*c8dee2aaSAndroid Build Coastguard Worker             prev->fNext = next;
47*c8dee2aaSAndroid Build Coastguard Worker         } else {
48*c8dee2aaSAndroid Build Coastguard Worker             fHead = next;
49*c8dee2aaSAndroid Build Coastguard Worker         }
50*c8dee2aaSAndroid Build Coastguard Worker         if (next) {
51*c8dee2aaSAndroid Build Coastguard Worker             next->fPrev = prev;
52*c8dee2aaSAndroid Build Coastguard Worker         } else {
53*c8dee2aaSAndroid Build Coastguard Worker             fTail = prev;
54*c8dee2aaSAndroid Build Coastguard Worker         }
55*c8dee2aaSAndroid Build Coastguard Worker 
56*c8dee2aaSAndroid Build Coastguard Worker         entry->fPrev = nullptr;
57*c8dee2aaSAndroid Build Coastguard Worker         entry->fNext = nullptr;
58*c8dee2aaSAndroid Build Coastguard Worker 
59*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
60*c8dee2aaSAndroid Build Coastguard Worker         entry->fList = nullptr;
61*c8dee2aaSAndroid Build Coastguard Worker #endif
62*c8dee2aaSAndroid Build Coastguard Worker     }
63*c8dee2aaSAndroid Build Coastguard Worker 
addToHead(T * entry)64*c8dee2aaSAndroid Build Coastguard Worker     void addToHead(T* entry) {
65*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(nullptr == entry->fPrev && nullptr == entry->fNext);
66*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(nullptr == entry->fList);
67*c8dee2aaSAndroid Build Coastguard Worker 
68*c8dee2aaSAndroid Build Coastguard Worker         entry->fPrev = nullptr;
69*c8dee2aaSAndroid Build Coastguard Worker         entry->fNext = fHead;
70*c8dee2aaSAndroid Build Coastguard Worker         if (fHead) {
71*c8dee2aaSAndroid Build Coastguard Worker             fHead->fPrev = entry;
72*c8dee2aaSAndroid Build Coastguard Worker         }
73*c8dee2aaSAndroid Build Coastguard Worker         fHead = entry;
74*c8dee2aaSAndroid Build Coastguard Worker         if (nullptr == fTail) {
75*c8dee2aaSAndroid Build Coastguard Worker             fTail = entry;
76*c8dee2aaSAndroid Build Coastguard Worker         }
77*c8dee2aaSAndroid Build Coastguard Worker 
78*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
79*c8dee2aaSAndroid Build Coastguard Worker         entry->fList = this;
80*c8dee2aaSAndroid Build Coastguard Worker #endif
81*c8dee2aaSAndroid Build Coastguard Worker     }
82*c8dee2aaSAndroid Build Coastguard Worker 
addToTail(T * entry)83*c8dee2aaSAndroid Build Coastguard Worker     void addToTail(T* entry) {
84*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(nullptr == entry->fPrev && nullptr == entry->fNext);
85*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(nullptr == entry->fList);
86*c8dee2aaSAndroid Build Coastguard Worker 
87*c8dee2aaSAndroid Build Coastguard Worker         entry->fPrev = fTail;
88*c8dee2aaSAndroid Build Coastguard Worker         entry->fNext = nullptr;
89*c8dee2aaSAndroid Build Coastguard Worker         if (fTail) {
90*c8dee2aaSAndroid Build Coastguard Worker             fTail->fNext = entry;
91*c8dee2aaSAndroid Build Coastguard Worker         }
92*c8dee2aaSAndroid Build Coastguard Worker         fTail = entry;
93*c8dee2aaSAndroid Build Coastguard Worker         if (nullptr == fHead) {
94*c8dee2aaSAndroid Build Coastguard Worker             fHead = entry;
95*c8dee2aaSAndroid Build Coastguard Worker         }
96*c8dee2aaSAndroid Build Coastguard Worker 
97*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
98*c8dee2aaSAndroid Build Coastguard Worker         entry->fList = this;
99*c8dee2aaSAndroid Build Coastguard Worker #endif
100*c8dee2aaSAndroid Build Coastguard Worker     }
101*c8dee2aaSAndroid Build Coastguard Worker 
102*c8dee2aaSAndroid Build Coastguard Worker     /**
103*c8dee2aaSAndroid Build Coastguard Worker      * Inserts a new list entry before an existing list entry. The new entry must not already be
104*c8dee2aaSAndroid Build Coastguard Worker      * a member of this or any other list. If existingEntry is NULL then the new entry is added
105*c8dee2aaSAndroid Build Coastguard Worker      * at the tail.
106*c8dee2aaSAndroid Build Coastguard Worker      */
addBefore(T * newEntry,T * existingEntry)107*c8dee2aaSAndroid Build Coastguard Worker     void addBefore(T* newEntry, T* existingEntry) {
108*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(newEntry);
109*c8dee2aaSAndroid Build Coastguard Worker 
110*c8dee2aaSAndroid Build Coastguard Worker         if (nullptr == existingEntry) {
111*c8dee2aaSAndroid Build Coastguard Worker             this->addToTail(newEntry);
112*c8dee2aaSAndroid Build Coastguard Worker             return;
113*c8dee2aaSAndroid Build Coastguard Worker         }
114*c8dee2aaSAndroid Build Coastguard Worker 
115*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(this->isInList(existingEntry));
116*c8dee2aaSAndroid Build Coastguard Worker         newEntry->fNext = existingEntry;
117*c8dee2aaSAndroid Build Coastguard Worker         T* prev = existingEntry->fPrev;
118*c8dee2aaSAndroid Build Coastguard Worker         existingEntry->fPrev = newEntry;
119*c8dee2aaSAndroid Build Coastguard Worker         newEntry->fPrev = prev;
120*c8dee2aaSAndroid Build Coastguard Worker         if (nullptr == prev) {
121*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(fHead == existingEntry);
122*c8dee2aaSAndroid Build Coastguard Worker             fHead = newEntry;
123*c8dee2aaSAndroid Build Coastguard Worker         } else {
124*c8dee2aaSAndroid Build Coastguard Worker             prev->fNext = newEntry;
125*c8dee2aaSAndroid Build Coastguard Worker         }
126*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
127*c8dee2aaSAndroid Build Coastguard Worker         newEntry->fList = this;
128*c8dee2aaSAndroid Build Coastguard Worker #endif
129*c8dee2aaSAndroid Build Coastguard Worker     }
130*c8dee2aaSAndroid Build Coastguard Worker 
131*c8dee2aaSAndroid Build Coastguard Worker     /**
132*c8dee2aaSAndroid Build Coastguard Worker      * Inserts a new list entry after an existing list entry. The new entry must not already be
133*c8dee2aaSAndroid Build Coastguard Worker      * a member of this or any other list. If existingEntry is NULL then the new entry is added
134*c8dee2aaSAndroid Build Coastguard Worker      * at the head.
135*c8dee2aaSAndroid Build Coastguard Worker      */
addAfter(T * newEntry,T * existingEntry)136*c8dee2aaSAndroid Build Coastguard Worker     void addAfter(T* newEntry, T* existingEntry) {
137*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(newEntry);
138*c8dee2aaSAndroid Build Coastguard Worker 
139*c8dee2aaSAndroid Build Coastguard Worker         if (nullptr == existingEntry) {
140*c8dee2aaSAndroid Build Coastguard Worker             this->addToHead(newEntry);
141*c8dee2aaSAndroid Build Coastguard Worker             return;
142*c8dee2aaSAndroid Build Coastguard Worker         }
143*c8dee2aaSAndroid Build Coastguard Worker 
144*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(this->isInList(existingEntry));
145*c8dee2aaSAndroid Build Coastguard Worker         newEntry->fPrev = existingEntry;
146*c8dee2aaSAndroid Build Coastguard Worker         T* next = existingEntry->fNext;
147*c8dee2aaSAndroid Build Coastguard Worker         existingEntry->fNext = newEntry;
148*c8dee2aaSAndroid Build Coastguard Worker         newEntry->fNext = next;
149*c8dee2aaSAndroid Build Coastguard Worker         if (nullptr == next) {
150*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(fTail == existingEntry);
151*c8dee2aaSAndroid Build Coastguard Worker             fTail = newEntry;
152*c8dee2aaSAndroid Build Coastguard Worker         } else {
153*c8dee2aaSAndroid Build Coastguard Worker             next->fPrev = newEntry;
154*c8dee2aaSAndroid Build Coastguard Worker         }
155*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
156*c8dee2aaSAndroid Build Coastguard Worker         newEntry->fList = this;
157*c8dee2aaSAndroid Build Coastguard Worker #endif
158*c8dee2aaSAndroid Build Coastguard Worker     }
159*c8dee2aaSAndroid Build Coastguard Worker 
concat(SkTInternalLList && list)160*c8dee2aaSAndroid Build Coastguard Worker     void concat(SkTInternalLList&& list) {
161*c8dee2aaSAndroid Build Coastguard Worker         if (list.isEmpty()) {
162*c8dee2aaSAndroid Build Coastguard Worker             return;
163*c8dee2aaSAndroid Build Coastguard Worker         }
164*c8dee2aaSAndroid Build Coastguard Worker 
165*c8dee2aaSAndroid Build Coastguard Worker         list.fHead->fPrev = fTail;
166*c8dee2aaSAndroid Build Coastguard Worker         if (!fHead) {
167*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(!list.fHead->fPrev);
168*c8dee2aaSAndroid Build Coastguard Worker             fHead = list.fHead;
169*c8dee2aaSAndroid Build Coastguard Worker         } else {
170*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(fTail);
171*c8dee2aaSAndroid Build Coastguard Worker             fTail->fNext = list.fHead;
172*c8dee2aaSAndroid Build Coastguard Worker         }
173*c8dee2aaSAndroid Build Coastguard Worker         fTail = list.fTail;
174*c8dee2aaSAndroid Build Coastguard Worker 
175*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
176*c8dee2aaSAndroid Build Coastguard Worker         for (T* node = list.fHead; node; node = node->fNext) {
177*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(node->fList == &list);
178*c8dee2aaSAndroid Build Coastguard Worker             node->fList = this;
179*c8dee2aaSAndroid Build Coastguard Worker         }
180*c8dee2aaSAndroid Build Coastguard Worker #endif
181*c8dee2aaSAndroid Build Coastguard Worker 
182*c8dee2aaSAndroid Build Coastguard Worker         list.fHead = list.fTail = nullptr;
183*c8dee2aaSAndroid Build Coastguard Worker     }
184*c8dee2aaSAndroid Build Coastguard Worker 
isEmpty()185*c8dee2aaSAndroid Build Coastguard Worker     bool isEmpty() const {
186*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(SkToBool(fHead) == SkToBool(fTail));
187*c8dee2aaSAndroid Build Coastguard Worker         return !fHead;
188*c8dee2aaSAndroid Build Coastguard Worker     }
189*c8dee2aaSAndroid Build Coastguard Worker 
head()190*c8dee2aaSAndroid Build Coastguard Worker     T* head() const { return fHead; }
tail()191*c8dee2aaSAndroid Build Coastguard Worker     T* tail() const { return fTail; }
192*c8dee2aaSAndroid Build Coastguard Worker 
193*c8dee2aaSAndroid Build Coastguard Worker     class Iter {
194*c8dee2aaSAndroid Build Coastguard Worker     public:
195*c8dee2aaSAndroid Build Coastguard Worker         enum IterStart {
196*c8dee2aaSAndroid Build Coastguard Worker             kHead_IterStart,
197*c8dee2aaSAndroid Build Coastguard Worker             kTail_IterStart
198*c8dee2aaSAndroid Build Coastguard Worker         };
199*c8dee2aaSAndroid Build Coastguard Worker 
Iter()200*c8dee2aaSAndroid Build Coastguard Worker         Iter() : fCurr(nullptr) {}
Iter(const Iter & iter)201*c8dee2aaSAndroid Build Coastguard Worker         Iter(const Iter& iter) : fCurr(iter.fCurr) {}
202*c8dee2aaSAndroid Build Coastguard Worker         Iter& operator= (const Iter& iter) { fCurr = iter.fCurr; return *this; }
203*c8dee2aaSAndroid Build Coastguard Worker 
init(const SkTInternalLList & list,IterStart startLoc)204*c8dee2aaSAndroid Build Coastguard Worker         T* init(const SkTInternalLList& list, IterStart startLoc) {
205*c8dee2aaSAndroid Build Coastguard Worker             if (kHead_IterStart == startLoc) {
206*c8dee2aaSAndroid Build Coastguard Worker                 fCurr = list.fHead;
207*c8dee2aaSAndroid Build Coastguard Worker             } else {
208*c8dee2aaSAndroid Build Coastguard Worker                 SkASSERT(kTail_IterStart == startLoc);
209*c8dee2aaSAndroid Build Coastguard Worker                 fCurr = list.fTail;
210*c8dee2aaSAndroid Build Coastguard Worker             }
211*c8dee2aaSAndroid Build Coastguard Worker 
212*c8dee2aaSAndroid Build Coastguard Worker             return fCurr;
213*c8dee2aaSAndroid Build Coastguard Worker         }
214*c8dee2aaSAndroid Build Coastguard Worker 
get()215*c8dee2aaSAndroid Build Coastguard Worker         T* get() { return fCurr; }
216*c8dee2aaSAndroid Build Coastguard Worker 
217*c8dee2aaSAndroid Build Coastguard Worker         /**
218*c8dee2aaSAndroid Build Coastguard Worker          * Return the next/previous element in the list or NULL if at the end.
219*c8dee2aaSAndroid Build Coastguard Worker          */
next()220*c8dee2aaSAndroid Build Coastguard Worker         T* next() {
221*c8dee2aaSAndroid Build Coastguard Worker             if (nullptr == fCurr) {
222*c8dee2aaSAndroid Build Coastguard Worker                 return nullptr;
223*c8dee2aaSAndroid Build Coastguard Worker             }
224*c8dee2aaSAndroid Build Coastguard Worker 
225*c8dee2aaSAndroid Build Coastguard Worker             fCurr = fCurr->fNext;
226*c8dee2aaSAndroid Build Coastguard Worker             return fCurr;
227*c8dee2aaSAndroid Build Coastguard Worker         }
228*c8dee2aaSAndroid Build Coastguard Worker 
prev()229*c8dee2aaSAndroid Build Coastguard Worker         T* prev() {
230*c8dee2aaSAndroid Build Coastguard Worker             if (nullptr == fCurr) {
231*c8dee2aaSAndroid Build Coastguard Worker                 return nullptr;
232*c8dee2aaSAndroid Build Coastguard Worker             }
233*c8dee2aaSAndroid Build Coastguard Worker 
234*c8dee2aaSAndroid Build Coastguard Worker             fCurr = fCurr->fPrev;
235*c8dee2aaSAndroid Build Coastguard Worker             return fCurr;
236*c8dee2aaSAndroid Build Coastguard Worker         }
237*c8dee2aaSAndroid Build Coastguard Worker 
238*c8dee2aaSAndroid Build Coastguard Worker         /**
239*c8dee2aaSAndroid Build Coastguard Worker          * C++11 range-for interface.
240*c8dee2aaSAndroid Build Coastguard Worker          */
241*c8dee2aaSAndroid Build Coastguard Worker         bool operator!=(const Iter& that) { return fCurr != that.fCurr; }
242*c8dee2aaSAndroid Build Coastguard Worker         T* operator*() { return this->get(); }
243*c8dee2aaSAndroid Build Coastguard Worker         void operator++() { this->next(); }
244*c8dee2aaSAndroid Build Coastguard Worker 
245*c8dee2aaSAndroid Build Coastguard Worker     private:
246*c8dee2aaSAndroid Build Coastguard Worker         T* fCurr;
247*c8dee2aaSAndroid Build Coastguard Worker     };
248*c8dee2aaSAndroid Build Coastguard Worker 
begin()249*c8dee2aaSAndroid Build Coastguard Worker     Iter begin() const {
250*c8dee2aaSAndroid Build Coastguard Worker         Iter iter;
251*c8dee2aaSAndroid Build Coastguard Worker         iter.init(*this, Iter::kHead_IterStart);
252*c8dee2aaSAndroid Build Coastguard Worker         return iter;
253*c8dee2aaSAndroid Build Coastguard Worker     }
254*c8dee2aaSAndroid Build Coastguard Worker 
end()255*c8dee2aaSAndroid Build Coastguard Worker     Iter end() const { return Iter(); }
256*c8dee2aaSAndroid Build Coastguard Worker 
257*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
validate()258*c8dee2aaSAndroid Build Coastguard Worker     void validate() const {
259*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!fHead == !fTail);
260*c8dee2aaSAndroid Build Coastguard Worker         Iter iter;
261*c8dee2aaSAndroid Build Coastguard Worker         for (T* item = iter.init(*this, Iter::kHead_IterStart); item; item = iter.next()) {
262*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(this->isInList(item));
263*c8dee2aaSAndroid Build Coastguard Worker             if (nullptr == item->fPrev) {
264*c8dee2aaSAndroid Build Coastguard Worker                 SkASSERT(fHead == item);
265*c8dee2aaSAndroid Build Coastguard Worker             } else {
266*c8dee2aaSAndroid Build Coastguard Worker                 SkASSERT(item->fPrev->fNext == item);
267*c8dee2aaSAndroid Build Coastguard Worker             }
268*c8dee2aaSAndroid Build Coastguard Worker             if (nullptr == item->fNext) {
269*c8dee2aaSAndroid Build Coastguard Worker                 SkASSERT(fTail == item);
270*c8dee2aaSAndroid Build Coastguard Worker             } else {
271*c8dee2aaSAndroid Build Coastguard Worker                 SkASSERT(item->fNext->fPrev == item);
272*c8dee2aaSAndroid Build Coastguard Worker             }
273*c8dee2aaSAndroid Build Coastguard Worker         }
274*c8dee2aaSAndroid Build Coastguard Worker     }
275*c8dee2aaSAndroid Build Coastguard Worker 
276*c8dee2aaSAndroid Build Coastguard Worker     /**
277*c8dee2aaSAndroid Build Coastguard Worker      * Debugging-only method that uses the list back pointer to check if 'entry' is indeed in 'this'
278*c8dee2aaSAndroid Build Coastguard Worker      * list.
279*c8dee2aaSAndroid Build Coastguard Worker      */
isInList(const T * entry)280*c8dee2aaSAndroid Build Coastguard Worker     bool isInList(const T* entry) const {
281*c8dee2aaSAndroid Build Coastguard Worker         return entry->fList == this;
282*c8dee2aaSAndroid Build Coastguard Worker     }
283*c8dee2aaSAndroid Build Coastguard Worker 
284*c8dee2aaSAndroid Build Coastguard Worker     /**
285*c8dee2aaSAndroid Build Coastguard Worker      * Debugging-only method that laboriously counts the list entries.
286*c8dee2aaSAndroid Build Coastguard Worker      */
countEntries()287*c8dee2aaSAndroid Build Coastguard Worker     int countEntries() const {
288*c8dee2aaSAndroid Build Coastguard Worker         int count = 0;
289*c8dee2aaSAndroid Build Coastguard Worker         for (T* entry = fHead; entry; entry = entry->fNext) {
290*c8dee2aaSAndroid Build Coastguard Worker             ++count;
291*c8dee2aaSAndroid Build Coastguard Worker         }
292*c8dee2aaSAndroid Build Coastguard Worker         return count;
293*c8dee2aaSAndroid Build Coastguard Worker     }
294*c8dee2aaSAndroid Build Coastguard Worker #endif // SK_DEBUG
295*c8dee2aaSAndroid Build Coastguard Worker 
296*c8dee2aaSAndroid Build Coastguard Worker private:
297*c8dee2aaSAndroid Build Coastguard Worker     T* fHead = nullptr;
298*c8dee2aaSAndroid Build Coastguard Worker     T* fTail = nullptr;
299*c8dee2aaSAndroid Build Coastguard Worker 
300*c8dee2aaSAndroid Build Coastguard Worker     SkTInternalLList(const SkTInternalLList&) = delete;
301*c8dee2aaSAndroid Build Coastguard Worker     SkTInternalLList& operator=(const SkTInternalLList&) = delete;
302*c8dee2aaSAndroid Build Coastguard Worker };
303*c8dee2aaSAndroid Build Coastguard Worker 
304*c8dee2aaSAndroid Build Coastguard Worker #endif
305