OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2014 Google Inc. |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. |
| 6 */ |
| 7 |
| 8 #ifndef SkTInternalSList_DEFINED |
| 9 #define SkTInternalSList_DEFINED |
| 10 |
| 11 #include "SkTInternalLList.h" // for SkPtrWrapper |
| 12 |
| 13 /** |
| 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 |
| 20 * specific field. |
| 21 * Unlike SK_DECLARE_INTERNAL_SLIST_INTERFACE this does not declare the field |
| 22 * itself. |
| 23 * It also makes SkTInternalSList<ClassName> a friend to give it access to the |
| 24 * methods. |
| 25 */ |
| 26 #define SK_DECLARE_INTERNAL_SLIST_ADAPTER(ClassName, field) \ |
| 27 ClassName* getSListNext() { \ |
| 28 return this->field; \ |
| 29 } \ |
| 30 void setSListNext(ClassName* next) { \ |
| 31 this->field = next; \ |
| 32 } \ |
| 33 friend class SkTInternalSList<ClassName> |
| 34 |
| 35 /** |
| 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 |
| 38 * SkTInternalSList. |
| 39 * It should be instantiated in the private block of the class you want to put |
| 40 * into an SkTInternalSList. |
| 41 */ |
| 42 #define SK_DECLARE_INTERNAL_SLIST_INTERFACE(ClassName) \ |
| 43 SK_DECLARE_INTERNAL_SLIST_ADAPTER(ClassName, fSListNext); \ |
| 44 SkPtrWrapper<ClassName> fSListNext |
| 45 |
| 46 /** |
| 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 |
| 52 * them. |
| 53 */ |
| 54 template<typename T> class SkTInternalSList { |
| 55 public: |
| 56 SkTInternalSList() : fHead(NULL), fCount(0) {} |
| 57 |
| 58 /** |
| 59 * Push an item onto the head of the list. |
| 60 * This method is *not* thread safe. |
| 61 */ |
| 62 void push(T* entry) { |
| 63 SkASSERT(entry->getSListNext() == NULL); |
| 64 entry->setSListNext(fHead); |
| 65 fHead = entry; |
| 66 ++fCount; |
| 67 } |
| 68 |
| 69 /** |
| 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. |
| 73 */ |
| 74 void pushAll(SkTInternalSList<T>* other) { |
| 75 if (this->isEmpty()) { |
| 76 this->swap(other); |
| 77 return; |
| 78 } |
| 79 while (!other->isEmpty()) { |
| 80 this->push(other->pop()); |
| 81 } |
| 82 } |
| 83 |
| 84 /** |
| 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. |
| 88 */ |
| 89 T* pop() { |
| 90 if (NULL == fHead) { |
| 91 return NULL; |
| 92 } |
| 93 T* result = fHead; |
| 94 fHead = result->getSListNext(); |
| 95 result->setSListNext(NULL); |
| 96 --fCount; |
| 97 return result; |
| 98 } |
| 99 |
| 100 T* head() const { |
| 101 return fHead; |
| 102 } |
| 103 |
| 104 /** |
| 105 * Returns true if the list has no elements. |
| 106 */ |
| 107 bool isEmpty() const { |
| 108 return NULL == fHead; |
| 109 } |
| 110 |
| 111 /** |
| 112 * Swaps the contents of this list with another one. |
| 113 * This method is *not* thread safe. |
| 114 */ |
| 115 void swap(SkTInternalSList<T>* other) { |
| 116 SkTSwap(fHead, other->fHead); |
| 117 SkTSwap(fCount, other->fCount); |
| 118 } |
| 119 |
| 120 /** |
| 121 * Returns the count of elements in the list. |
| 122 */ |
| 123 int getCount() const { |
| 124 return fCount; |
| 125 } |
| 126 private: |
| 127 T* fHead; |
| 128 int fCount; |
| 129 }; |
| 130 |
| 131 |
| 132 #endif |
OLD | NEW |