mirror of
https://github.com/0TheSpy/Seaside.git
synced 2025-01-10 11:19:38 +08:00
238 lines
3.9 KiB
C
238 lines
3.9 KiB
C
|
#ifndef UTLSTACK_H
|
||
|
#define UTLSTACK_H
|
||
|
|
||
|
#include <assert.h>
|
||
|
#include <string.h>
|
||
|
#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<T, M>& 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<T, M>::ResetDbgInfo()
|
||
|
{
|
||
|
m_pElements = m_Memory.Base();
|
||
|
}
|
||
|
|
||
|
template< class T, class M >
|
||
|
CUtlStack<T, M>::CUtlStack(int growSize, int initSize) :
|
||
|
m_Memory(growSize, initSize), m_Size(0)
|
||
|
{
|
||
|
ResetDbgInfo();
|
||
|
}
|
||
|
|
||
|
template< class T, class M >
|
||
|
CUtlStack<T, M>::~CUtlStack()
|
||
|
{
|
||
|
Purge();
|
||
|
}
|
||
|
|
||
|
|
||
|
template< class T, class M >
|
||
|
void CUtlStack<T, M>::CopyFrom(const CUtlStack<T, M>& from)
|
||
|
{
|
||
|
Purge();
|
||
|
EnsureCapacity(from.Count());
|
||
|
for (int i = 0; i < from.Count(); i++)
|
||
|
{
|
||
|
Push(from[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
template< class T, class M >
|
||
|
inline T& CUtlStack<T, M>::operator[](int i)
|
||
|
{
|
||
|
assert(IsIdxValid(i));
|
||
|
return m_Memory[i];
|
||
|
}
|
||
|
|
||
|
template< class T, class M >
|
||
|
inline T const& CUtlStack<T, M>::operator[](int i) const
|
||
|
{
|
||
|
assert(IsIdxValid(i));
|
||
|
return m_Memory[i];
|
||
|
}
|
||
|
|
||
|
template< class T, class M >
|
||
|
inline T& CUtlStack<T, M>::Element(int i)
|
||
|
{
|
||
|
assert(IsIdxValid(i));
|
||
|
return m_Memory[i];
|
||
|
}
|
||
|
|
||
|
template< class T, class M >
|
||
|
inline T const& CUtlStack<T, M>::Element(int i) const
|
||
|
{
|
||
|
assert(IsIdxValid(i));
|
||
|
return m_Memory[i];
|
||
|
}
|
||
|
|
||
|
|
||
|
template< class T, class M >
|
||
|
inline T* CUtlStack<T, M>::Base()
|
||
|
{
|
||
|
return m_Memory.Base();
|
||
|
}
|
||
|
|
||
|
template< class T, class M >
|
||
|
inline T const* CUtlStack<T, M>::Base() const
|
||
|
{
|
||
|
return m_Memory.Base();
|
||
|
}
|
||
|
|
||
|
template< class T, class M >
|
||
|
inline T& CUtlStack<T, M>::Top()
|
||
|
{
|
||
|
assert(m_Size > 0);
|
||
|
return Element(m_Size - 1);
|
||
|
}
|
||
|
|
||
|
template< class T, class M >
|
||
|
inline T const& CUtlStack<T, M>::Top() const
|
||
|
{
|
||
|
assert(m_Size > 0);
|
||
|
return Element(m_Size - 1);
|
||
|
}
|
||
|
|
||
|
template< class T, class M >
|
||
|
inline int CUtlStack<T, M>::Count() const
|
||
|
{
|
||
|
return m_Size;
|
||
|
}
|
||
|
|
||
|
|
||
|
template< class T, class M >
|
||
|
inline bool CUtlStack<T, M>::IsIdxValid(int i) const
|
||
|
{
|
||
|
return (i >= 0) && (i < m_Size);
|
||
|
}
|
||
|
|
||
|
template< class T, class M >
|
||
|
void CUtlStack<T, M>::GrowStack()
|
||
|
{
|
||
|
if (m_Size >= m_Memory.NumAllocated())
|
||
|
m_Memory.Grow();
|
||
|
|
||
|
++m_Size;
|
||
|
|
||
|
ResetDbgInfo();
|
||
|
}
|
||
|
|
||
|
template< class T, class M >
|
||
|
void CUtlStack<T, M>::EnsureCapacity(int num)
|
||
|
{
|
||
|
m_Memory.EnsureCapacity(num);
|
||
|
ResetDbgInfo();
|
||
|
}
|
||
|
|
||
|
|
||
|
template< class T, class M >
|
||
|
int CUtlStack<T, M>::Push()
|
||
|
{
|
||
|
GrowStack();
|
||
|
Construct(&Element(m_Size - 1));
|
||
|
return m_Size - 1;
|
||
|
}
|
||
|
|
||
|
template< class T, class M >
|
||
|
int CUtlStack<T, M>::Push(T const& src)
|
||
|
{
|
||
|
GrowStack();
|
||
|
CopyConstruct(&Element(m_Size - 1), src);
|
||
|
return m_Size - 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
template< class T, class M >
|
||
|
void CUtlStack<T, M>::Pop()
|
||
|
{
|
||
|
assert(m_Size > 0);
|
||
|
Destruct(&Element(m_Size - 1));
|
||
|
--m_Size;
|
||
|
}
|
||
|
|
||
|
template< class T, class M >
|
||
|
void CUtlStack<T, M>::Pop(T& oldTop)
|
||
|
{
|
||
|
assert(m_Size > 0);
|
||
|
oldTop = Top();
|
||
|
Pop();
|
||
|
}
|
||
|
|
||
|
template< class T, class M >
|
||
|
void CUtlStack<T, M>::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<T, M>::Clear()
|
||
|
{
|
||
|
for (int i = m_Size; --i >= 0; )
|
||
|
Destruct(&Element(i));
|
||
|
|
||
|
m_Size = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
template< class T, class M >
|
||
|
void CUtlStack<T, M>::Purge()
|
||
|
{
|
||
|
Clear();
|
||
|
m_Memory.Purge();
|
||
|
ResetDbgInfo();
|
||
|
}
|
||
|
|
||
|
#endif
|