/* * Copyright 2006 The Android Open Source Project * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #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; } int depth() const { return fTotalCount; } bool empty() const { return fTotalCount == 0; } 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