|  | /* | 
|  | * Copyright 2014 Google Inc. | 
|  | * | 
|  | * Use of this source code is governed by a BSD-style license that can be | 
|  | * found in the LICENSE file. | 
|  | */ | 
|  |  | 
|  | #ifndef SkTInternalSList_DEFINED | 
|  | #define SkTInternalSList_DEFINED | 
|  |  | 
|  | #include "SkTInternalLList.h" // for SkPtrWrapper | 
|  |  | 
|  | /** | 
|  | * This macro creates the methods required by the SkTInternalSList class. | 
|  | * It should be instantiated in the private block of the class you want to put | 
|  | * into an SkTInternalSList. | 
|  | * For most use cases you should use SK_DECLARE_INTERNAL_SLIST_INTERFACE and not | 
|  | * this macro. If you care about the field name, or want to re-use an existing | 
|  | * field, then you can use this macro to declare the methods pointing to a | 
|  | * specific field. | 
|  | * Unlike SK_DECLARE_INTERNAL_SLIST_INTERFACE this does not declare the field | 
|  | * itself. | 
|  | * It also makes SkTInternalSList<ClassName> a friend to give it access to the | 
|  | * methods. | 
|  | */ | 
|  | #define SK_DECLARE_INTERNAL_SLIST_ADAPTER(ClassName, field)     \ | 
|  | ClassName* getSListNext() {                                 \ | 
|  | return this->field;                                     \ | 
|  | }                                                           \ | 
|  | void setSListNext(ClassName* next) {                        \ | 
|  | this->field = next;                                     \ | 
|  | }                                                           \ | 
|  | friend class SkTInternalSList<ClassName> | 
|  |  | 
|  | /** | 
|  | * This macro declares an fSListNext that auto initializes to NULL and then | 
|  | * uses SK_DECLARE_INTERNAL_SLIST_ADAPTER to add the methods needed by | 
|  | * SkTInternalSList. | 
|  | * It should be instantiated in the private block of the class you want to put | 
|  | * into an SkTInternalSList. | 
|  | */ | 
|  | #define SK_DECLARE_INTERNAL_SLIST_INTERFACE(ClassName)          \ | 
|  | SK_DECLARE_INTERNAL_SLIST_ADAPTER(ClassName, fSListNext);   \ | 
|  | SkPtrWrapper<ClassName> fSListNext | 
|  |  | 
|  | /** | 
|  | * An implementation of an intrusive singly linked list. | 
|  | * The type T must have a methods getSListNext and setSListNext that are visible | 
|  | * to the list. The easiest way to do this is with | 
|  | * SK_DECLARE_INTERNAL_SLIST_INTERFACE. | 
|  | * The list does not maintain ownership of any of its elements, or ever delete | 
|  | * them. | 
|  | */ | 
|  | template<typename T> class SkTInternalSList { | 
|  | public: | 
|  | SkTInternalSList() : fHead(NULL), fCount(0) {} | 
|  |  | 
|  | /** | 
|  | * Push an item onto the head of the list. | 
|  | * This method is *not* thread safe. | 
|  | */ | 
|  | void push(T* entry) { | 
|  | SkASSERT(entry->getSListNext() == NULL); | 
|  | entry->setSListNext(fHead); | 
|  | fHead = entry; | 
|  | ++fCount; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Takes all the items from another list and pushes them into this list. | 
|  | * No ordering guarantees are made, the other list will be emptied. | 
|  | * This method is *not* thread safe. | 
|  | */ | 
|  | void pushAll(SkTInternalSList<T>* other) { | 
|  | if (this->isEmpty()) { | 
|  | this->swap(other); | 
|  | return; | 
|  | } | 
|  | while (!other->isEmpty()) { | 
|  | this->push(other->pop()); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Pop an item from the head of the list. | 
|  | * Returns NULL if the list is empty. | 
|  | * This method is *not* thread safe. | 
|  | */ | 
|  | T* pop() { | 
|  | if (NULL == fHead) { | 
|  | return NULL; | 
|  | } | 
|  | T* result = fHead; | 
|  | fHead = result->getSListNext(); | 
|  | result->setSListNext(NULL); | 
|  | --fCount; | 
|  | return result; | 
|  | } | 
|  |  | 
|  | T* head() const { | 
|  | return fHead; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Returns true if the list has no elements. | 
|  | */ | 
|  | bool isEmpty() const { | 
|  | return NULL == fHead; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Swaps the contents of this list with another one. | 
|  | * This method is *not* thread safe. | 
|  | */ | 
|  | void swap(SkTInternalSList<T>* other) { | 
|  | SkTSwap(fHead, other->fHead); | 
|  | SkTSwap(fCount, other->fCount); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Returns the count of elements in the list. | 
|  | */ | 
|  | int getCount() const { | 
|  | return fCount; | 
|  | } | 
|  | private: | 
|  | T* fHead; | 
|  | int fCount; | 
|  | }; | 
|  |  | 
|  |  | 
|  | #endif |