#ifndef TIER1_UTL_VECTOR_H #define TIER1_UTL_VECTOR_H #include "tier1/utlbuffer.h" #include "tier0/lib.h" //----------------------------------------------------------------------------- // Basic vector implementation. There isn't much in them. //----------------------------------------------------------------------------- template class CUtlVector { public: CUtlVector( void ); CUtlVector( size_t nSize ); void AppendHead( const T &data ); void AppendHead( const T *pData, size_t n ); void AppendTail( const T &data ); void AppendTail( const T *data, size_t n ); void AppendAt( size_t nIndex, const T &data ); void AppendAt( size_t nIndex, const T *data, size_t n ); void RemoveHead(); void RemoveTail(); void RemoveAt( size_t nIndex ); T *GetData( void ); size_t GetSize( void ); void Resize( size_t nSize ); void Reserve( size_t nSize ); T &operator[]( size_t nIndex ); T &operator[]( size_t nIndex ) const; // Iterator stuff struct Iterator { T *m_pCurrent; Iterator( T *pCurrent ) : m_pCurrent(pCurrent) {} T& operator*( void ) const { return *m_pCurrent;} Iterator& operator++( void ) { ++m_pCurrent; return *this; } bool operator!=( const Iterator& other ) const { return m_pCurrent != other.m_pCurrent; } }; Iterator begin( void ) const { return Iterator((T*)m_data.GetMemory()); } Iterator end( void ) const { return Iterator((T*)m_data.GetMemory()+m_nSize); } private: size_t m_nSize = 0; CUtlResizableBuffer m_data; }; //---------------------------------------------------------------------------- // Constructor //---------------------------------------------------------------------------- template CUtlVector::CUtlVector( void ) { m_data.Resize(0); }; //---------------------------------------------------------------------------- // Constructor //---------------------------------------------------------------------------- template CUtlVector::CUtlVector( size_t nSize ) { m_data.Resize(nSize); m_nSize = nSize; }; template void CUtlVector::AppendHead( const T &data ) { AppendHead(&data,1); } template void CUtlVector::AppendHead( const T *pData, size_t n ) { } template void CUtlVector::AppendTail( const T &data ) { AppendTail(&data,1); } template void CUtlVector::AppendTail( const T *pData, size_t n ) { m_data.Resize(m_data.GetSize()+n); V_memcpy(m_data+m_nSize,pData,sizeof(T)*n); m_nSize+=n; } template void CUtlVector::AppendAt( size_t nIndex, const T &data ) { AppendAt(nIndex, &data, 1); } template void CUtlVector::AppendAt( size_t nIndex, const T *pData, size_t n ) { } template void CUtlVector::RemoveHead() { m_nSize--; } template void CUtlVector::RemoveTail() { m_nSize--; } template void CUtlVector::RemoveAt( size_t nIndex ) { m_nSize--; } template T *CUtlVector::GetData( void ) { return (T*)m_data.GetMemory(); } template size_t CUtlVector::GetSize( void ) { return m_nSize; } template void CUtlVector::Resize( size_t nSize ) { m_nSize = nSize; } template void CUtlVector::Reserve( size_t nSize ) { m_data.Resize(nSize); } template T &CUtlVector::operator[]( size_t nIndex ) { return m_data[nIndex]; } template T &CUtlVector::operator[]( size_t nIndex ) const { return m_data[nIndex]; } //----------------------------------------------------------------------------- // Self referencing arrays are quite cool. // They allow to append stuff in head and tail of the array and use less memory // copying. Downside is their indexing is O(n/2) // // Implements the same stuff as CUtlVector does. //----------------------------------------------------------------------------- template class CUtlSelfReferencingVector { private: template struct SelfData_t; public: CUtlSelfReferencingVector(); ~CUtlSelfReferencingVector(); void AppendHead( const T& data ); void AppendTail( const T& data ); void AppendAt( size_t nIndex, const T& data ); void RemoveHead( void ); void RemoveTail( void ); void RemoveAt( size_t nIndex ); size_t GetSize(); T operator[]( size_t nIndex ); T& operator[]( size_t nIndex ) const; // Iterator stuff struct Iterator { SelfData_t *m_pCurrent; Iterator( SelfData_t *pCurrent ) : m_pCurrent(pCurrent) {} T& operator*( void ) const { return m_pCurrent->data;} Iterator& operator++( void ) { if (m_pCurrent) m_pCurrent = m_pCurrent->pNext; return *this; } bool operator!=( const Iterator& other ) const { return m_pCurrent != other.m_pCurrent; } }; Iterator begin( void ) const { return Iterator(m_pHead); } Iterator end( void ) const { return Iterator(NULL); } private: size_t m_nSize = 0; template struct SelfData_t { SelfData_t *pNext = NULL; SelfData_t *pPrev = NULL; A data; }; SelfData_t *m_pTail = NULL; SelfData_t *m_pHead = NULL; }; //---------------------------------------------------------------------------- // Constructor //---------------------------------------------------------------------------- template CUtlSelfReferencingVector::CUtlSelfReferencingVector() { }; //---------------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------------- template CUtlSelfReferencingVector::~CUtlSelfReferencingVector() { SelfData_t *pNext = NULL; for (SelfData_t *pCurrent = m_pHead; pCurrent; pCurrent=pNext) { pNext = pCurrent->pNext; delete pCurrent; } }; //---------------------------------------------------------------------------- // Inserts new element in the start of the vector. //---------------------------------------------------------------------------- template void CUtlSelfReferencingVector::AppendHead( const T& data ) { SelfData_t* pData = new SelfData_t; pData->data = data; pData->pNext = m_pHead; if (m_pHead) m_pHead->pPrev = pData; pData->pPrev = 0; m_pHead = pData; if (m_pTail == 0) m_pTail = m_pHead; m_nSize++; }; //---------------------------------------------------------------------------- // Inserts new element in the end of the vector. //---------------------------------------------------------------------------- template void CUtlSelfReferencingVector::AppendTail( const T& data ) { SelfData_t* pData = new SelfData_t; pData->data = data; if (m_pTail) m_pTail->pNext = pData; pData->pPrev = m_pTail; m_pTail = pData; if (m_pHead == 0) m_pHead = m_pTail; m_nSize++; }; //---------------------------------------------------------------------------- // Removes element in the start of the vector. //---------------------------------------------------------------------------- template void CUtlSelfReferencingVector::RemoveHead( void ) { if (m_pHead == m_pTail) m_pHead = 0; }; //---------------------------------------------------------------------------- // Removes element in the end of the vector. //---------------------------------------------------------------------------- template void CUtlSelfReferencingVector::RemoveTail( void ) { } #endif