mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Tier1: add utility class 'CUtlStack'
This commit is contained in:
parent
88ef6fdd8b
commit
e10981821b
331
src/public/tier1/utlstack.h
Normal file
331
src/public/tier1/utlstack.h
Normal file
@ -0,0 +1,331 @@
|
||||
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
// A stack based on a growable array
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef UTLSTACK_H
|
||||
#define UTLSTACK_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "utlmemory.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The CUtlStack class:
|
||||
// A growable stack class which doubles in size by default.
|
||||
// It will always keep all elements consecutive in memory, and may move the
|
||||
// elements around in memory (via a realloc) when elements are pushed or
|
||||
// popped. Clients should therefore refer to the elements of the stack
|
||||
// by index (they should *never* maintain pointers to elements in the stack).
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< class T, class M = CUtlMemory< T > >
|
||||
class CUtlStack
|
||||
{
|
||||
public:
|
||||
// constructor, destructor
|
||||
CUtlStack( int growSize = 0, int initSize = 0 );
|
||||
~CUtlStack();
|
||||
|
||||
void CopyFrom( const CUtlStack<T, M> &from );
|
||||
|
||||
// element access
|
||||
T& operator[]( int i );
|
||||
T const& operator[]( int i ) const;
|
||||
T& Element( int i );
|
||||
T const& Element( int i ) const;
|
||||
|
||||
// Gets the base address (can change when adding elements!)
|
||||
T* Base();
|
||||
T const* Base() const;
|
||||
|
||||
// Looks at the stack top
|
||||
T& Top();
|
||||
T const& Top() const;
|
||||
|
||||
// Size
|
||||
int Count() const;
|
||||
|
||||
// Is element index valid?
|
||||
bool IsIdxValid( int i ) const;
|
||||
|
||||
// Adds an element, uses default constructor
|
||||
int Push();
|
||||
|
||||
// Adds an element, uses copy constructor
|
||||
int Push( T const& src );
|
||||
|
||||
// Pops the stack
|
||||
void Pop();
|
||||
void Pop( T& oldTop );
|
||||
void PopMultiple( int num );
|
||||
|
||||
// Makes sure we have enough memory allocated to store a requested # of elements
|
||||
void EnsureCapacity( int num );
|
||||
|
||||
// Clears the stack, no deallocation
|
||||
void Clear();
|
||||
|
||||
// Memory deallocation
|
||||
void Purge();
|
||||
|
||||
private:
|
||||
// Grows the stack allocation
|
||||
void GrowStack();
|
||||
|
||||
// For easier access to the elements through the debugger
|
||||
void ResetDbgInfo();
|
||||
|
||||
M m_Memory;
|
||||
int m_Size;
|
||||
|
||||
// For easier access to the elements through the debugger
|
||||
T* m_pElements;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// For easier access to the elements through the debugger
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< class T, class M >
|
||||
inline void CUtlStack<T,M>::ResetDbgInfo()
|
||||
{
|
||||
m_pElements = m_Memory.Base();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// copy into
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
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] );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// element access
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the base address (can change when adding elements!)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the top of the stack
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Size
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< class T, class M >
|
||||
inline int CUtlStack<T,M>::Count() const
|
||||
{
|
||||
return m_Size;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Is element index valid?
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< class T, class M >
|
||||
inline bool CUtlStack<T,M>::IsIdxValid( int i ) const
|
||||
{
|
||||
return (i >= 0) && (i < m_Size);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Grows the stack
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< class T, class M >
|
||||
void CUtlStack<T,M>::GrowStack()
|
||||
{
|
||||
if (m_Size >= m_Memory.NumAllocated())
|
||||
m_Memory.Grow();
|
||||
|
||||
++m_Size;
|
||||
|
||||
ResetDbgInfo();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Makes sure we have enough memory allocated to store a requested # of elements
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< class T, class M >
|
||||
void CUtlStack<T,M>::EnsureCapacity( int num )
|
||||
{
|
||||
m_Memory.EnsureCapacity(num);
|
||||
ResetDbgInfo();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Adds an element, uses default constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< class T, class M >
|
||||
int CUtlStack<T,M>::Push()
|
||||
{
|
||||
GrowStack();
|
||||
Construct( &Element(m_Size-1) );
|
||||
return m_Size - 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Adds an element, uses copy constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< class T, class M >
|
||||
int CUtlStack<T,M>::Push( T const& src )
|
||||
{
|
||||
GrowStack();
|
||||
CopyConstruct( &Element(m_Size-1), src );
|
||||
return m_Size - 1;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Pops the stack
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Element removal
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< class T, class M >
|
||||
void CUtlStack<T,M>::Clear()
|
||||
{
|
||||
for (int i = m_Size; --i >= 0; )
|
||||
Destruct(&Element(i));
|
||||
|
||||
m_Size = 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Memory deallocation
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< class T, class M >
|
||||
void CUtlStack<T,M>::Purge()
|
||||
{
|
||||
Clear();
|
||||
m_Memory.Purge( );
|
||||
ResetDbgInfo();
|
||||
}
|
||||
|
||||
#endif // UTLSTACK_H
|
Loading…
x
Reference in New Issue
Block a user