Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / core / SkTInternalSList.h
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