diff options
Diffstat (limited to 'public/tier1/utlarray.h')
| -rw-r--r-- | public/tier1/utlarray.h | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/public/tier1/utlarray.h b/public/tier1/utlarray.h new file mode 100644 index 0000000..ce5ffe8 --- /dev/null +++ b/public/tier1/utlarray.h @@ -0,0 +1,332 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +// A growable array class that maintains a free list and keeps elements +// in the same location +//=============================================================================// + +#ifndef UTLARRAY_H +#define UTLARRAY_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier0/platform.h" +#include "tier0/dbg.h" +#include "vstdlib/random.h" + +#define FOR_EACH_ARRAY( vecName, iteratorName ) \ + for ( int iteratorName = 0; (vecName).IsUtlArray && iteratorName < (vecName).Count(); iteratorName++ ) +#define FOR_EACH_ARRAY_BACK( vecName, iteratorName ) \ + for ( int iteratorName = (vecName).Count()-1; (vecName).IsUtlArray && iteratorName >= 0; iteratorName-- ) + +// utlarray derives from this so we can do the type check above +struct base_array_t +{ +public: + static const bool IsUtlArray = true; // Used to match this at compiletime +}; + +#if defined( GNUC ) && defined( DEBUG ) +// gcc in debug doesn't optimize away the need for the storage of IsUtlArray so make one here +// as this is in a shared header use SELECTANY to make it throw away the dupe symbols +const bool base_array_t::IsUtlArray SELECTANY; +#endif + +//----------------------------------------------------------------------------- +template< class T, size_t MAX_SIZE > +class CUtlArray : public base_array_t +{ +public: + typedef T ElemType_t; + typedef T* iterator; + typedef const T* const_iterator; + + CUtlArray(); + CUtlArray( T* pMemory, size_t count ); + ~CUtlArray(); + + CUtlArray<T, MAX_SIZE>& operator=( const CUtlArray<T, MAX_SIZE> &other ); + CUtlArray( CUtlArray const& vec ); + + // element access + T& operator[]( int i ); + const T& operator[]( int i ) const; + T& Element( int i ); + const T& Element( int i ) const; + T& Random(); + const T& Random() const; + + // STL compatible member functions. These allow easier use of std::sort + // and they are forward compatible with the C++ 11 range-based for loops. + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + + T* Base(); + const T* Base() const; + + // Returns the number of elements in the array, NumAllocated() is included for consistency with UtlVector + int Count() const; + int NumAllocated() const; + + // Is element index valid? + bool IsValidIndex( int i ) const; + static int InvalidIndex(); + + void CopyArray( const T *pArray, size_t count ); + + void Swap( CUtlArray< T, MAX_SIZE > &vec ); + + // Finds an element (element needs operator== defined) + int Find( const T& src ) const; + void FillWithValue( const T& src ); + + bool HasElement( const T& src ) const; + + // calls delete on each element in it. + void DeleteElements(); + + void Sort( int (__cdecl *pfnCompare)(const T *, const T *) ); + +protected: + T m_Memory[ MAX_SIZE ]; +}; + +//----------------------------------------------------------------------------- +// constructor, destructor +//----------------------------------------------------------------------------- +template< typename T, size_t MAX_SIZE > +inline CUtlArray<T, MAX_SIZE>::CUtlArray() +{ +} + +template< typename T, size_t MAX_SIZE > +inline CUtlArray<T, MAX_SIZE>::CUtlArray( T* pMemory, size_t count ) +{ + CopyArray( pMemory, count ); +} + +template< typename T, size_t MAX_SIZE > +inline CUtlArray<T, MAX_SIZE>::~CUtlArray() +{ +} + +template< typename T, size_t MAX_SIZE > +inline CUtlArray<T, MAX_SIZE>& CUtlArray<T, MAX_SIZE>::operator=( const CUtlArray<T, MAX_SIZE> &other ) +{ + if ( this != &other ) + { + for ( size_t n = 0; n < MAX_SIZE; ++n ) + { + m_Memory[n] = other.m_Memory[n]; + } + } + return *this; +} + +template< typename T, size_t MAX_SIZE > +inline CUtlArray<T, MAX_SIZE>::CUtlArray( CUtlArray const& vec ) +{ + for ( size_t n = 0; n < MAX_SIZE; ++n ) + { + m_Memory[n] = vec.m_Memory[n]; + } +} + +template< typename T, size_t MAX_SIZE > +typename CUtlArray<T, MAX_SIZE>::iterator CUtlArray<T, MAX_SIZE>::begin() +{ + return Base(); +} + +template< typename T, size_t MAX_SIZE > +typename CUtlArray<T, MAX_SIZE>::const_iterator CUtlArray<T, MAX_SIZE>::begin() const +{ + return Base(); +} + +template< typename T, size_t MAX_SIZE > +typename CUtlArray<T, MAX_SIZE>::iterator CUtlArray<T, MAX_SIZE>::end() +{ + return Base() + Count(); +} + +template< typename T, size_t MAX_SIZE > +typename CUtlArray<T, MAX_SIZE>::const_iterator CUtlArray<T, MAX_SIZE>::end() const +{ + return Base() + Count(); +} + +template< typename T, size_t MAX_SIZE > +inline T *CUtlArray<T, MAX_SIZE>::Base() +{ + return &m_Memory[0]; +} + +template< typename T, size_t MAX_SIZE > +inline const T *CUtlArray<T, MAX_SIZE>::Base() const +{ + return &m_Memory[0]; +} + +//----------------------------------------------------------------------------- +// element access +//----------------------------------------------------------------------------- +template< typename T, size_t MAX_SIZE > +inline T& CUtlArray<T, MAX_SIZE>::operator[]( int i ) +{ + Assert( IsValidIndex( i ) ); + return m_Memory[ i ]; +} + +template< typename T, size_t MAX_SIZE > +inline const T& CUtlArray<T, MAX_SIZE>::operator[]( int i ) const +{ + Assert( IsValidIndex( i ) ); + return m_Memory[ i ]; +} + +template< typename T, size_t MAX_SIZE > +inline T& CUtlArray<T, MAX_SIZE>::Element( int i ) +{ + Assert( IsValidIndex( i ) ); + return m_Memory[ i ]; +} + +template< typename T, size_t MAX_SIZE > +inline const T& CUtlArray<T, MAX_SIZE>::Element( int i ) const +{ + Assert( IsValidIndex( i ) ); + return m_Memory[ i ]; +} + +template< typename T, size_t MAX_SIZE > +inline T& CUtlArray<T, MAX_SIZE>::Random() +{ + Assert( MAX_SIZE > 0 ); + return m_Memory[ RandomInt( 0, MAX_SIZE - 1 ) ]; +} + +template< typename T, size_t MAX_SIZE > +inline const T& CUtlArray<T, MAX_SIZE>::Random() const +{ + Assert( MAX_SIZE > 0 ); + return m_Memory[ RandomInt( 0, MAX_SIZE - 1 ) ]; +} + + +//----------------------------------------------------------------------------- +// Count +//----------------------------------------------------------------------------- +template< typename T, size_t MAX_SIZE > +inline int CUtlArray<T, MAX_SIZE>::Count() const +{ + return (int)MAX_SIZE; +} + + +//----------------------------------------------------------------------------- +template< typename T, size_t MAX_SIZE > +inline int CUtlArray<T, MAX_SIZE>::NumAllocated() const +{ + return (int)MAX_SIZE; +} + +//----------------------------------------------------------------------------- +// Is element index valid? +//----------------------------------------------------------------------------- +template< typename T, size_t MAX_SIZE > +inline bool CUtlArray<T, MAX_SIZE>::IsValidIndex( int i ) const +{ + return (i >= 0) && (i < MAX_SIZE); +} + + +//----------------------------------------------------------------------------- +// Returns in invalid index +//----------------------------------------------------------------------------- +template< typename T, size_t MAX_SIZE > +inline int CUtlArray<T, MAX_SIZE>::InvalidIndex() +{ + return -1; +} + + +//----------------------------------------------------------------------------- +// Sorts the vector +//----------------------------------------------------------------------------- +template< typename T, size_t MAX_SIZE > +void CUtlArray<T, MAX_SIZE>::Sort( int (__cdecl *pfnCompare)(const T *, const T *) ) +{ + typedef int (__cdecl *QSortCompareFunc_t)(const void *, const void *); + if ( Count() <= 1 ) + return; + + qsort( Base(), Count(), sizeof(T), (QSortCompareFunc_t)(pfnCompare) ); +} + +template< typename T, size_t MAX_SIZE > +void CUtlArray<T, MAX_SIZE>::CopyArray( const T *pArray, size_t count ) +{ + Assert( count < MAX_SIZE ); + + for ( size_t n = 0; n < count; ++n ) + { + m_Memory[n] = pArray[n]; + } +} + +template< typename T, size_t MAX_SIZE > +void CUtlArray<T, MAX_SIZE>::Swap( CUtlArray< T, MAX_SIZE > &vec ) +{ + for ( size_t n = 0; n < MAX_SIZE; ++n ) + { + V_swap( m_Memory[n], vec.m_Memory[n] ); + } +} + +//----------------------------------------------------------------------------- +// Finds an element (element needs operator== defined) +//----------------------------------------------------------------------------- +template< typename T, size_t MAX_SIZE > +int CUtlArray<T, MAX_SIZE>::Find( const T& src ) const +{ + for ( int i = 0; i < Count(); ++i ) + { + if (Element(i) == src) + return i; + } + return -1; +} + +template< typename T, size_t MAX_SIZE > +void CUtlArray<T, MAX_SIZE>::FillWithValue( const T& src ) +{ + for ( int i = 0; i < Count(); i++ ) + { + Element(i) = src; + } +} + +template< typename T, size_t MAX_SIZE > +bool CUtlArray<T, MAX_SIZE>::HasElement( const T& src ) const +{ + return ( Find(src) >= 0 ); +} + +template< typename T, size_t MAX_SIZE > +inline void CUtlArray<T, MAX_SIZE>::DeleteElements() +{ + for( int i=0; i < MAX_SIZE; i++ ) + { + delete Element(i); + } +} + +#endif // UTLARRAY_H |