#ifndef UTLSTACK_H #define UTLSTACK_H #include #include #include "utlmemory.h" template< class T, class M = CUtlMemory< T > > class CUtlStack { public: CUtlStack(int growSize = 0, int initSize = 0); ~CUtlStack(); void CopyFrom(const CUtlStack& from); T& operator[](int i); T const& operator[](int i) const; T& Element(int i); T const& Element(int i) const; T* Base(); T const* Base() const; T& Top(); T const& Top() const; int Count() const; bool IsIdxValid(int i) const; int Push(); int Push(T const& src); void Pop(); void Pop(T& oldTop); void PopMultiple(int num); void EnsureCapacity(int num); void Clear(); void Purge(); private: void GrowStack(); void ResetDbgInfo(); M m_Memory; int m_Size; T* m_pElements; }; template< class T, class M > inline void CUtlStack::ResetDbgInfo() { m_pElements = m_Memory.Base(); } template< class T, class M > CUtlStack::CUtlStack(int growSize, int initSize) : m_Memory(growSize, initSize), m_Size(0) { ResetDbgInfo(); } template< class T, class M > CUtlStack::~CUtlStack() { Purge(); } template< class T, class M > void CUtlStack::CopyFrom(const CUtlStack& from) { Purge(); EnsureCapacity(from.Count()); for (int i = 0; i < from.Count(); i++) { Push(from[i]); } } template< class T, class M > inline T& CUtlStack::operator[](int i) { assert(IsIdxValid(i)); return m_Memory[i]; } template< class T, class M > inline T const& CUtlStack::operator[](int i) const { assert(IsIdxValid(i)); return m_Memory[i]; } template< class T, class M > inline T& CUtlStack::Element(int i) { assert(IsIdxValid(i)); return m_Memory[i]; } template< class T, class M > inline T const& CUtlStack::Element(int i) const { assert(IsIdxValid(i)); return m_Memory[i]; } template< class T, class M > inline T* CUtlStack::Base() { return m_Memory.Base(); } template< class T, class M > inline T const* CUtlStack::Base() const { return m_Memory.Base(); } template< class T, class M > inline T& CUtlStack::Top() { assert(m_Size > 0); return Element(m_Size - 1); } template< class T, class M > inline T const& CUtlStack::Top() const { assert(m_Size > 0); return Element(m_Size - 1); } template< class T, class M > inline int CUtlStack::Count() const { return m_Size; } template< class T, class M > inline bool CUtlStack::IsIdxValid(int i) const { return (i >= 0) && (i < m_Size); } template< class T, class M > void CUtlStack::GrowStack() { if (m_Size >= m_Memory.NumAllocated()) m_Memory.Grow(); ++m_Size; ResetDbgInfo(); } template< class T, class M > void CUtlStack::EnsureCapacity(int num) { m_Memory.EnsureCapacity(num); ResetDbgInfo(); } template< class T, class M > int CUtlStack::Push() { GrowStack(); Construct(&Element(m_Size - 1)); return m_Size - 1; } template< class T, class M > int CUtlStack::Push(T const& src) { GrowStack(); CopyConstruct(&Element(m_Size - 1), src); return m_Size - 1; } template< class T, class M > void CUtlStack::Pop() { assert(m_Size > 0); Destruct(&Element(m_Size - 1)); --m_Size; } template< class T, class M > void CUtlStack::Pop(T& oldTop) { assert(m_Size > 0); oldTop = Top(); Pop(); } template< class T, class M > void CUtlStack::PopMultiple(int num) { assert(m_Size >= num); for (int i = 0; i < num; ++i) Destruct(&Element(m_Size - i - 1)); m_Size -= num; } template< class T, class M > void CUtlStack::Clear() { for (int i = m_Size; --i >= 0; ) Destruct(&Element(i)); m_Size = 0; } template< class T, class M > void CUtlStack::Purge() { Clear(); m_Memory.Purge(); ResetDbgInfo(); } #endif