blob: 5bc10ee9cb16f7ad88b1056e56257871ddf8a682 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SkTDStack_DEFINED
18#define SkTDStack_DEFINED
19
20#include "SkTypes.h"
21
22template <typename T> class SkTDStack : SkNoncopyable {
23public:
24 SkTDStack() : fCount(0), fTotalCount(0)
25 {
26 fInitialRec.fNext = NULL;
27 fRec = &fInitialRec;
28
29 // fCount = kSlotCount;
30 }
31 ~SkTDStack()
32 {
33 Rec* rec = fRec;
34 while (rec != &fInitialRec)
35 {
36 Rec* next = rec->fNext;
37 sk_free(rec);
38 rec = next;
39 }
40 }
41
42 int count() const { return fTotalCount; }
43
44 T* push()
45 {
46 SkASSERT(fCount <= kSlotCount);
47 if (fCount == kSlotCount)
48 {
49 Rec* rec = (Rec*)sk_malloc_throw(sizeof(Rec));
50 rec->fNext = fRec;
51 fRec = rec;
52 fCount = 0;
53 }
54 ++fTotalCount;
55 return &fRec->fSlots[fCount++];
56 }
57 void push(const T& elem) { *this->push() = elem; }
58 const T& index(int idx) const
59 {
60 SkASSERT(fRec && fCount > idx);
61 return fRec->fSlots[fCount - idx - 1];
62 }
63 T& index(int idx)
64 {
65 SkASSERT(fRec && fCount > idx);
66 return fRec->fSlots[fCount - idx - 1];
67 }
68 const T& top() const
69 {
70 SkASSERT(fRec && fCount > 0);
71 return fRec->fSlots[fCount - 1];
72 }
73 T& top()
74 {
75 SkASSERT(fRec && fCount > 0);
76 return fRec->fSlots[fCount - 1];
77 }
78 void pop(T* elem)
79 {
80 if (elem)
81 *elem = fRec->fSlots[fCount - 1];
82 this->pop();
83 }
84 void pop()
85 {
86 SkASSERT(fCount > 0 && fRec);
87 --fTotalCount;
88 if (--fCount == 0)
89 {
90 if (fRec != &fInitialRec)
91 {
92 Rec* rec = fRec->fNext;
93 sk_free(fRec);
94 fCount = kSlotCount;
95 fRec = rec;
96 }
97 else
98 SkASSERT(fTotalCount == 0);
99 }
100 }
101
102private:
103 enum {
104 kSlotCount = 8
105 };
106
107 struct Rec;
108 friend struct Rec;
109
110 struct Rec {
111 Rec* fNext;
112 T fSlots[kSlotCount];
113 };
114 Rec fInitialRec;
115 Rec* fRec;
116 int fCount, fTotalCount;
117};
118
119#endif
120