2 * Copyright 2014 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef SkTInternalSList_DEFINED
9 #define SkTInternalSList_DEFINED
11 #include "SkTInternalLList.h" // for SkPtrWrapper
14 * This macro creates the methods required by the SkTInternalSList class.
15 * It should be instantiated in the private block of the class you want to put
16 * into an SkTInternalSList.
17 * For most use cases you should use SK_DECLARE_INTERNAL_SLIST_INTERFACE and not
18 * this macro. If you care about the field name, or want to re-use an existing
19 * field, then you can use this macro to declare the methods pointing to a
21 * Unlike SK_DECLARE_INTERNAL_SLIST_INTERFACE this does not declare the field
23 * It also makes SkTInternalSList<ClassName> a friend to give it access to the
26 #define SK_DECLARE_INTERNAL_SLIST_ADAPTER(ClassName, field) \
27 ClassName* getSListNext() { \
30 void setSListNext(ClassName* next) { \
33 friend class SkTInternalSList<ClassName>
36 * This macro declares an fSListNext that auto initializes to NULL and then
37 * uses SK_DECLARE_INTERNAL_SLIST_ADAPTER to add the methods needed by
39 * It should be instantiated in the private block of the class you want to put
40 * into an SkTInternalSList.
42 #define SK_DECLARE_INTERNAL_SLIST_INTERFACE(ClassName) \
43 SK_DECLARE_INTERNAL_SLIST_ADAPTER(ClassName, fSListNext); \
44 SkPtrWrapper<ClassName> fSListNext
47 * An implementation of an intrusive singly linked list.
48 * The type T must have a methods getSListNext and setSListNext that are visible
49 * to the list. The easiest way to do this is with
50 * SK_DECLARE_INTERNAL_SLIST_INTERFACE.
51 * The list does not maintain ownership of any of its elements, or ever delete
54 template<typename T> class SkTInternalSList {
56 SkTInternalSList() : fHead(NULL), fCount(0) {}
59 * Push an item onto the head of the list.
60 * This method is *not* thread safe.
63 SkASSERT(entry->getSListNext() == NULL);
64 entry->setSListNext(fHead);
70 * Takes all the items from another list and pushes them into this list.
71 * No ordering guarantees are made, the other list will be emptied.
72 * This method is *not* thread safe.
74 void pushAll(SkTInternalSList<T>* other) {
75 if (this->isEmpty()) {
79 while (!other->isEmpty()) {
80 this->push(other->pop());
85 * Pop an item from the head of the list.
86 * Returns NULL if the list is empty.
87 * This method is *not* thread safe.
94 fHead = result->getSListNext();
95 result->setSListNext(NULL);
105 * Returns true if the list has no elements.
107 bool isEmpty() const {
108 return NULL == fHead;
112 * Swaps the contents of this list with another one.
113 * This method is *not* thread safe.
115 void swap(SkTInternalSList<T>* other) {
116 SkTSwap(fHead, other->fHead);
117 SkTSwap(fCount, other->fCount);
121 * Returns the count of elements in the list.
123 int getCount() const {