Seaside/SpyCustom/sdk/utlstack.h
2021-06-16 18:49:07 +03:00

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