12ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com/*
22ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com * Copyright 2012 Google Inc.
32ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com *
42ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com * Use of this source code is governed by a BSD-style license that can be
52ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com * found in the LICENSE file.
62ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com */
72ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
842619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com#ifndef SkTInternalLList_DEFINED
942619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com#define SkTInternalLList_DEFINED
102ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
112ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com#include "SkTypes.h"
122ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
13fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com/**
1442619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com * Helper class to automatically initialize the doubly linked list created pointers.
152ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com */
162ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.comtemplate <typename T> class SkPtrWrapper {
172ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com  public:
182ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com      SkPtrWrapper() : fPtr(NULL) {}
192ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com      SkPtrWrapper& operator =(T* ptr) { fPtr = ptr; return *this; }
202ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com      operator T*() const { return fPtr; }
212ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com      T* operator->() { return fPtr; }
222ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com  private:
232ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com      T* fPtr;
242ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com};
252ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
262ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
272ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com/**
2842619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com * This macro creates the member variables required by the SkTInternalLList class. It should be
2942619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com * placed in the private section of any class that will be stored in a double linked list.
302ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com */
3142619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com#define SK_DECLARE_INTERNAL_LLIST_INTERFACE(ClassName)              \
3242619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com    friend class SkTInternalLList<ClassName>;                       \
3342619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com    /* back pointer to the owning list - for debugging */           \
3442619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com    SkDEBUGCODE(SkPtrWrapper<SkTInternalLList<ClassName> > fList;)  \
3542619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com    SkPtrWrapper<ClassName> fPrev;                                  \
3642619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com    SkPtrWrapper<ClassName> fNext
372ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
382ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com/**
392ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com * This class implements a templated internal doubly linked list data structure.
402ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com */
41e3beb6bd7de7fa211681abbb0be58e80b19885e0commit-bot@chromium.orgtemplate <class T> class SkTInternalLList : SkNoncopyable {
422ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.compublic:
4342619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com    SkTInternalLList()
442ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        : fHead(NULL)
452ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        , fTail(NULL) {
462ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    }
472ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
482ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    void remove(T* entry) {
4949f085dddff10473b6ebf832a974288300224e60bsalomon        SkASSERT(fHead && fTail);
502ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        SkASSERT(this->isInList(entry));
512ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
522ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        T* prev = entry->fPrev;
532ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        T* next = entry->fNext;
542ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
5549f085dddff10473b6ebf832a974288300224e60bsalomon        if (prev) {
562ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com            prev->fNext = next;
572ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        } else {
582ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com            fHead = next;
592ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        }
6049f085dddff10473b6ebf832a974288300224e60bsalomon        if (next) {
612ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com            next->fPrev = prev;
622ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        } else {
632ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com            fTail = prev;
642ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        }
652ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
662ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        entry->fPrev = NULL;
672ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        entry->fNext = NULL;
682ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
6939ac1aec0e91f2b481ca5eb6cb1c9483210ed9babsalomon@google.com#ifdef SK_DEBUG
702ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        entry->fList = NULL;
712ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com#endif
722ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    }
732ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
742ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    void addToHead(T* entry) {
752ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        SkASSERT(NULL == entry->fPrev && NULL == entry->fNext);
762ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        SkASSERT(NULL == entry->fList);
772ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
782ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        entry->fPrev = NULL;
792ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        entry->fNext = fHead;
8049f085dddff10473b6ebf832a974288300224e60bsalomon        if (fHead) {
812ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com            fHead->fPrev = entry;
822ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        }
832ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        fHead = entry;
842ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        if (NULL == fTail) {
852ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com            fTail = entry;
862ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        }
872ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
8839ac1aec0e91f2b481ca5eb6cb1c9483210ed9babsalomon@google.com#ifdef SK_DEBUG
892ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        entry->fList = this;
902ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com#endif
912ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    }
922ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
9342619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com    void addToTail(T* entry) {
9442619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com        SkASSERT(NULL == entry->fPrev && NULL == entry->fNext);
9542619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com        SkASSERT(NULL == entry->fList);
9642619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com
9742619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com        entry->fPrev = fTail;
9842619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com        entry->fNext = NULL;
9949f085dddff10473b6ebf832a974288300224e60bsalomon        if (fTail) {
10042619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com            fTail->fNext = entry;
10142619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com        }
10242619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com        fTail = entry;
10342619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com        if (NULL == fHead) {
10442619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com            fHead = entry;
10542619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com        }
10642619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com
10742619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com#ifdef SK_DEBUG
10842619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com        entry->fList = this;
10942619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com#endif
11042619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com    }
11142619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com
112dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com    /**
113dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com     * Inserts a new list entry before an existing list entry. The new entry must not already be
114dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com     * a member of this or any other list. If existingEntry is NULL then the new entry is added
115dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com     * at the tail.
116dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com     */
117dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com    void addBefore(T* newEntry, T* existingEntry) {
11849f085dddff10473b6ebf832a974288300224e60bsalomon        SkASSERT(newEntry);
119dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com
120dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        if (NULL == existingEntry) {
121dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com            this->addToTail(newEntry);
122dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com            return;
123dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        }
124dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com
125dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        SkASSERT(this->isInList(existingEntry));
126dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        newEntry->fNext = existingEntry;
127dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        T* prev = existingEntry->fPrev;
128dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        existingEntry->fPrev = newEntry;
129dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        newEntry->fPrev = prev;
130dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        if (NULL == prev) {
131dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com            SkASSERT(fHead == existingEntry);
132dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com            fHead = newEntry;
133dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        } else {
134dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com            prev->fNext = newEntry;
135dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        }
136b8b8ba01f0d52d598e88798f7f90ed3bcc648e23robertphillips@google.com#ifdef SK_DEBUG
137dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        newEntry->fList = this;
138dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com#endif
139dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com    }
140dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com
141dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com    /**
142dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com     * Inserts a new list entry after an existing list entry. The new entry must not already be
143dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com     * a member of this or any other list. If existingEntry is NULL then the new entry is added
144dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com     * at the head.
145dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com     */
146dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com    void addAfter(T* newEntry, T* existingEntry) {
14749f085dddff10473b6ebf832a974288300224e60bsalomon        SkASSERT(newEntry);
148dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com
149dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        if (NULL == existingEntry) {
150dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com            this->addToHead(newEntry);
151dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com            return;
152dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        }
153dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com
154dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        SkASSERT(this->isInList(existingEntry));
155dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        newEntry->fPrev = existingEntry;
156dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        T* next = existingEntry->fNext;
157dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        existingEntry->fNext = newEntry;
158dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        newEntry->fNext = next;
159dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        if (NULL == next) {
160dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com            SkASSERT(fTail == existingEntry);
161dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com            fTail = newEntry;
162dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        } else {
163dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com            next->fPrev = newEntry;
164dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        }
165b8b8ba01f0d52d598e88798f7f90ed3bcc648e23robertphillips@google.com#ifdef SK_DEBUG
166dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        newEntry->fList = this;
167dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com#endif
168dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com    }
169dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com
170fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    bool isEmpty() const {
171fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        return NULL == fHead && NULL == fTail;
1722ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    }
1732ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
174a292112154f803feb9f5cc002bbfab559f7cb633bsalomon@google.com    T* head() { return fHead; }
175a292112154f803feb9f5cc002bbfab559f7cb633bsalomon@google.com    T* tail() { return fTail; }
176a292112154f803feb9f5cc002bbfab559f7cb633bsalomon@google.com
1772ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    class Iter {
1782ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    public:
1792ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        enum IterStart {
1802ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com            kHead_IterStart,
1812ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com            kTail_IterStart
1822ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        };
1832ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
18442619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com        Iter() : fCurr(NULL) {}
18542619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com        Iter(const Iter& iter) : fCurr(iter.fCurr) {}
18642619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com        Iter& operator= (const Iter& iter) { fCurr = iter.fCurr; return *this; }
1872ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
18842619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com        T* init(const SkTInternalLList& list, IterStart startLoc) {
1892ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com            if (kHead_IterStart == startLoc) {
19042619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com                fCurr = list.fHead;
1912ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com            } else {
1922ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com                SkASSERT(kTail_IterStart == startLoc);
19342619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com                fCurr = list.fTail;
1942ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com            }
1952ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
19642619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com            return fCurr;
1972ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        }
1982ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
19942619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com        T* get() { return fCurr; }
20042619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com
2012ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        /**
2022ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com         * Return the next/previous element in the list or NULL if at the end.
2032ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com         */
2042ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        T* next() {
20542619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com            if (NULL == fCurr) {
2062ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com                return NULL;
2072ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com            }
2082ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
20942619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com            fCurr = fCurr->fNext;
21042619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com            return fCurr;
2112ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        }
2122ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
2132ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        T* prev() {
21442619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com            if (NULL == fCurr) {
2152ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com                return NULL;
2162ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com            }
2172ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
21842619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com            fCurr = fCurr->fPrev;
21942619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com            return fCurr;
2202ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        }
2212ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
2222ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    private:
22342619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com        T* fCurr;
2242ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    };
2252ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
22639ac1aec0e91f2b481ca5eb6cb1c9483210ed9babsalomon@google.com#ifdef SK_DEBUG
2272ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    void validate() const {
22842619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com        SkASSERT(!fHead == !fTail);
229dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        Iter iter;
23049f085dddff10473b6ebf832a974288300224e60bsalomon        for (T* item = iter.init(*this, Iter::kHead_IterStart); item; item = iter.next()) {
231dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com            SkASSERT(this->isInList(item));
232dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com            if (NULL == item->fPrev) {
233dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com                SkASSERT(fHead == item);
234dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com            } else {
235dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com                SkASSERT(item->fPrev->fNext == item);
236dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com            }
237dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com            if (NULL == item->fNext) {
238dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com                SkASSERT(fTail == item);
239dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com            } else {
240dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com                SkASSERT(item->fNext->fPrev == item);
241dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com            }
242dd3f7a9efefc486833d564527367155eb93691d4bsalomon@google.com        }
2432ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    }
2442ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
2452ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    /**
24642619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com     * Debugging-only method that uses the list back pointer to check if 'entry' is indeed in 'this'
24742619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com     * list.
2482ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com     */
2492ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    bool isInList(const T* entry) const {
2502ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        return entry->fList == this;
2512ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    }
2522ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
2532ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    /**
2542ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com     * Debugging-only method that laboriously counts the list entries.
2552ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com     */
2562ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    int countEntries() const {
2572ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        int count = 0;
25849f085dddff10473b6ebf832a974288300224e60bsalomon        for (T* entry = fHead; entry; entry = entry->fNext) {
2592ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com            ++count;
2602ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        }
2612ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com        return count;
2622ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    }
2632ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com#endif // SK_DEBUG
2642ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
2652ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.comprivate:
2662ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    T* fHead;
2672ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    T* fTail;
2682ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
2692ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com    typedef SkNoncopyable INHERITED;
2702ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com};
2712ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com
27242619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com#endif
273