/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef SkTDStack_DEFINED #define SkTDStack_DEFINED #include "SkTypes.h" template <typename T> class SkTDStack : SkNoncopyable { public: SkTDStack() : fCount(0), fTotalCount(0) { fInitialRec.fNext = NULL; fRec = &fInitialRec; // fCount = kSlotCount; } ~SkTDStack() { Rec* rec = fRec; while (rec != &fInitialRec) { Rec* next = rec->fNext; sk_free(rec); rec = next; } } int count() const { return fTotalCount; } T* push() { SkASSERT(fCount <= kSlotCount); if (fCount == kSlotCount) { Rec* rec = (Rec*)sk_malloc_throw(sizeof(Rec)); rec->fNext = fRec; fRec = rec; fCount = 0; } ++fTotalCount; return &fRec->fSlots[fCount++]; } void push(const T& elem) { *this->push() = elem; } const T& index(int idx) const { SkASSERT(fRec && fCount > idx); return fRec->fSlots[fCount - idx - 1]; } T& index(int idx) { SkASSERT(fRec && fCount > idx); return fRec->fSlots[fCount - idx - 1]; } const T& top() const { SkASSERT(fRec && fCount > 0); return fRec->fSlots[fCount - 1]; } T& top() { SkASSERT(fRec && fCount > 0); return fRec->fSlots[fCount - 1]; } void pop(T* elem) { if (elem) *elem = fRec->fSlots[fCount - 1]; this->pop(); } void pop() { SkASSERT(fCount > 0 && fRec); --fTotalCount; if (--fCount == 0) { if (fRec != &fInitialRec) { Rec* rec = fRec->fNext; sk_free(fRec); fCount = kSlotCount; fRec = rec; } else SkASSERT(fTotalCount == 0); } } private: enum { kSlotCount = 8 }; struct Rec; friend struct Rec; struct Rec { Rec* fNext; T fSlots[kSlotCount]; }; Rec fInitialRec; Rec* fRec; int fCount, fTotalCount; }; #endif