mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-12-09 03:28:24 +00:00
Update CUtlLeanVector*
This commit is contained in:
parent
11e97c7d54
commit
4438dc5774
@ -15,22 +15,30 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "commonmacros.h"
|
||||||
|
#include "rawallocator.h"
|
||||||
#include "tier0/platform.h"
|
#include "tier0/platform.h"
|
||||||
#include "tier0/dbg.h"
|
#include "tier0/dbg.h"
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#include "tier0/memdbgon.h"
|
|
||||||
|
|
||||||
#define FOR_EACH_LEANVEC( vecName, iteratorName ) \
|
#define FOR_EACH_LEANVEC( vecName, iteratorName ) \
|
||||||
for ( auto iteratorName = vecName.First(); vecName.IsValidIterator( iteratorName ); iteratorName = vecName.Next( iteratorName ) )
|
for ( auto iteratorName = vecName.First(); vecName.IsValidIterator( iteratorName ); iteratorName = vecName.Next( iteratorName ) )
|
||||||
|
|
||||||
template< class T, class I >
|
template< class T, class I, class A >
|
||||||
class CUtlLeanVectorBase
|
class CUtlLeanVectorBase
|
||||||
{
|
{
|
||||||
|
typedef A CAllocator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum : I
|
||||||
|
{
|
||||||
|
EXTERNAL_BUFFER_MARKER = (I { 1 } << (std::numeric_limits<I>::digits - 1))
|
||||||
|
};
|
||||||
|
|
||||||
// constructor, destructor
|
// constructor, destructor
|
||||||
CUtlLeanVectorBase();
|
CUtlLeanVectorBase( I growSize = 0, I initSize = 0 );
|
||||||
|
CUtlLeanVectorBase( T *pMemory, I allocationCount, I numElements = 0 );
|
||||||
~CUtlLeanVectorBase();
|
~CUtlLeanVectorBase();
|
||||||
|
|
||||||
// Gets the base address (can change when adding elements!)
|
// Gets the base address (can change when adding elements!)
|
||||||
@ -40,12 +48,24 @@ public:
|
|||||||
// Makes sure we have enough memory allocated to store a requested # of elements
|
// Makes sure we have enough memory allocated to store a requested # of elements
|
||||||
void EnsureCapacity( int num, bool force = false );
|
void EnsureCapacity( int num, bool force = false );
|
||||||
|
|
||||||
|
bool IsExternallyAllocated() const { return (m_nAllocated & EXTERNAL_BUFFER_MARKER) != 0; }
|
||||||
|
|
||||||
|
// Attaches the buffer to external memory....
|
||||||
|
void SetExternalBuffer( T *pMemory, int allocationCount, int numElements = 0 );
|
||||||
|
void SetExternalBuffer( const T *pMemory, int allocationCount, int numElements = 0 );
|
||||||
|
void AssumeMemory( T *pMemory, int allocationCount, int numElements = 0 );
|
||||||
|
T *Detach();
|
||||||
|
void *DetachMemory();
|
||||||
|
|
||||||
|
int NumAllocated() const { return (m_nAllocated & (~EXTERNAL_BUFFER_MARKER)); }
|
||||||
|
|
||||||
// Element removal
|
// Element removal
|
||||||
void RemoveAll(); // doesn't deallocate memory
|
void RemoveAll(); // doesn't deallocate memory
|
||||||
|
|
||||||
|
bool IsIdxValid( I i ) const { return (i >= 0) && (i < NumAllocated()); }
|
||||||
|
|
||||||
// Memory deallocation
|
// Memory deallocation
|
||||||
void Purge();
|
void Purge();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
struct
|
struct
|
||||||
@ -59,14 +79,21 @@ protected:
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// constructor, destructor
|
// constructor, destructor
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template< class T, class I >
|
template< class T, class I, class A >
|
||||||
inline CUtlLeanVectorBase<T, I>::CUtlLeanVectorBase() : m_nCount(0),
|
inline CUtlLeanVectorBase<T, I, A>::CUtlLeanVectorBase( I growSize, I initSize ) :
|
||||||
m_nAllocated(0), m_pElements(NULL)
|
m_nCount( 0 ), m_nAllocated( 0 ), m_pElements( nullptr )
|
||||||
|
{
|
||||||
|
EnsureCapacity( initSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class I, class A >
|
||||||
|
inline CUtlLeanVectorBase<T, I, A>::CUtlLeanVectorBase( T *pMemory, I allocationCount, I numElements ) :
|
||||||
|
m_nCount( numElements ), m_nAllocated( allocationCount | EXTERNAL_BUFFER_MARKER ), m_pElements( pMemory )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template< class T, class I >
|
template< class T, class I, class A >
|
||||||
inline CUtlLeanVectorBase<T, I>::~CUtlLeanVectorBase()
|
inline CUtlLeanVectorBase<T, I, A>::~CUtlLeanVectorBase()
|
||||||
{
|
{
|
||||||
Purge();
|
Purge();
|
||||||
}
|
}
|
||||||
@ -74,38 +101,87 @@ inline CUtlLeanVectorBase<T, I>::~CUtlLeanVectorBase()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Gets the base address (can change when adding elements!)
|
// Gets the base address (can change when adding elements!)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template< class T, class I >
|
template< class T, class I, class A >
|
||||||
inline T* CUtlLeanVectorBase<T, I>::Base()
|
inline T* CUtlLeanVectorBase<T, I, A>::Base()
|
||||||
{
|
{
|
||||||
return m_nAllocated ? m_pElements : NULL;
|
return NumAllocated() ? m_pElements : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template< class T, class I >
|
template< class T, class I, class A >
|
||||||
inline const T* CUtlLeanVectorBase<T, I>::Base() const
|
inline const T* CUtlLeanVectorBase<T, I, A>::Base() const
|
||||||
{
|
{
|
||||||
return m_nAllocated ? m_pElements : NULL;
|
return NumAllocated() ? m_pElements : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Attaches the buffer to external memory....
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template< class T, class I, class A >
|
||||||
|
inline void CUtlLeanVectorBase<T, I, A>::SetExternalBuffer( T *pMemory, int allocationCount, int numElements )
|
||||||
|
{
|
||||||
|
// Blow away any existing allocated memory
|
||||||
|
Purge();
|
||||||
|
|
||||||
|
m_nCount = numElements;
|
||||||
|
m_nAllocated = allocationCount | EXTERNAL_BUFFER_MARKER;
|
||||||
|
m_pElements = pMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class I, class A >
|
||||||
|
inline void CUtlLeanVectorBase<T, I, A>::SetExternalBuffer( const T *pMemory, int allocationCount, int numElements )
|
||||||
|
{
|
||||||
|
// Blow away any existing allocated memory
|
||||||
|
Purge();
|
||||||
|
|
||||||
|
m_nCount = numElements;
|
||||||
|
m_nAllocated = allocationCount | EXTERNAL_BUFFER_MARKER;
|
||||||
|
m_pElements = const_cast<T *>(pMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class I, class A >
|
||||||
|
inline void CUtlLeanVectorBase<T, I, A>::AssumeMemory( T *pMemory, int allocationCount, int numElements )
|
||||||
|
{
|
||||||
|
// Blow away any existing allocated memory
|
||||||
|
Purge();
|
||||||
|
|
||||||
|
m_nCount = numElements;
|
||||||
|
m_nAllocated = allocationCount;
|
||||||
|
|
||||||
|
// Simply take the pointer but don't mark us as external
|
||||||
|
m_pElements = pMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class I, class A >
|
||||||
|
inline T *CUtlLeanVectorBase<T, I, A>::Detach()
|
||||||
|
{
|
||||||
|
return (T *)DetachMemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class I, class A >
|
||||||
|
inline void *CUtlLeanVectorBase<T, I, A>::DetachMemory()
|
||||||
|
{
|
||||||
|
if(IsExternallyAllocated())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
void *pMemory = m_pElements;
|
||||||
|
m_nCount = 0;
|
||||||
|
m_nAllocated = 0;
|
||||||
|
|
||||||
|
m_pElements = 0;
|
||||||
|
return pMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Makes sure we have enough memory allocated to store a requested # of elements
|
// Makes sure we have enough memory allocated to store a requested # of elements
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template< class T, class I >
|
template< class T, class I, class A >
|
||||||
void CUtlLeanVectorBase<T, I>::EnsureCapacity( int num, bool force )
|
void CUtlLeanVectorBase<T, I, A>::EnsureCapacity( int num, bool force )
|
||||||
{
|
{
|
||||||
|
if(num <= NumAllocated())
|
||||||
|
return;
|
||||||
|
|
||||||
I nMinAllocated = (31 + sizeof( T )) / sizeof( T );
|
I nMinAllocated = (31 + sizeof( T )) / sizeof( T );
|
||||||
I nMaxAllocated = (std::numeric_limits<I>::max)();
|
I nMaxAllocated = (std::numeric_limits<I>::max)();
|
||||||
I nNewAllocated = m_nAllocated;
|
|
||||||
|
|
||||||
if ( force )
|
|
||||||
{
|
|
||||||
if ( num == m_nAllocated )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( num <= m_nAllocated )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( num > nMaxAllocated )
|
if ( num > nMaxAllocated )
|
||||||
{
|
{
|
||||||
@ -114,30 +190,30 @@ void CUtlLeanVectorBase<T, I>::EnsureCapacity( int num, bool force )
|
|||||||
DebuggerBreak();
|
DebuggerBreak();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( force )
|
I nNewAllocated = num;
|
||||||
|
if ( !force )
|
||||||
|
nNewAllocated = CalcNewDoublingCount( NumAllocated(), num, nMinAllocated, nMaxAllocated );
|
||||||
|
|
||||||
|
T *pNew = nullptr;
|
||||||
|
if(IsExternallyAllocated())
|
||||||
{
|
{
|
||||||
nNewAllocated = num;
|
CAllocator::template Alloc<T>( nNewAllocated, nNewAllocated );
|
||||||
|
V_memmove( pNew, Base(), m_nCount * sizeof( T ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while ( nNewAllocated < num )
|
pNew = CAllocator::Realloc( m_pElements, nNewAllocated, nNewAllocated );
|
||||||
{
|
|
||||||
if ( nNewAllocated < nMaxAllocated/2 )
|
|
||||||
nNewAllocated = MAX( nNewAllocated*2, nMinAllocated );
|
|
||||||
else
|
|
||||||
nNewAllocated = nMaxAllocated;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pElements = (T*)realloc( m_pElements, nNewAllocated * sizeof(T) );
|
m_pElements = pNew;
|
||||||
m_nAllocated = nNewAllocated;
|
m_nAllocated = nNewAllocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Element removal
|
// Element removal
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template< class T, class I >
|
template< class T, class I, class A >
|
||||||
void CUtlLeanVectorBase<T, I>::RemoveAll()
|
void CUtlLeanVectorBase<T, I, A>::RemoveAll()
|
||||||
{
|
{
|
||||||
T* pElement = Base();
|
T* pElement = Base();
|
||||||
const T* pEnd = &pElement[ m_nCount ];
|
const T* pEnd = &pElement[ m_nCount ];
|
||||||
@ -150,26 +226,37 @@ void CUtlLeanVectorBase<T, I>::RemoveAll()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Memory deallocation
|
// Memory deallocation
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template< class T, class I >
|
template< class T, class I, class A >
|
||||||
inline void CUtlLeanVectorBase<T, I>::Purge()
|
inline void CUtlLeanVectorBase<T, I, A>::Purge()
|
||||||
{
|
{
|
||||||
RemoveAll();
|
RemoveAll();
|
||||||
|
|
||||||
if ( m_nAllocated > 0 )
|
if(!IsExternallyAllocated())
|
||||||
{
|
{
|
||||||
free( (void*)m_pElements );
|
if(NumAllocated() > 0)
|
||||||
m_pElements = NULL;
|
{
|
||||||
|
CAllocator::Free( m_pElements );
|
||||||
|
m_pElements = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_nAllocated = 0;
|
m_nAllocated = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template< class T, size_t N, class I >
|
template< class T, size_t N, class I, class A >
|
||||||
class CUtlLeanVectorFixedGrowableBase
|
class CUtlLeanVectorFixedGrowableBase
|
||||||
{
|
{
|
||||||
|
typedef A CAllocator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum : I
|
||||||
|
{
|
||||||
|
EXTERNAL_BUFFER_MARKER = (I { 1 } << (std::numeric_limits<I>::digits - 1))
|
||||||
|
};
|
||||||
|
|
||||||
// constructor, destructor
|
// constructor, destructor
|
||||||
CUtlLeanVectorFixedGrowableBase();
|
CUtlLeanVectorFixedGrowableBase( I growSize = 0, I initSize = 0 );
|
||||||
|
CUtlLeanVectorFixedGrowableBase( T *pMemory, I allocationCount, I numElements = 0 );
|
||||||
~CUtlLeanVectorFixedGrowableBase();
|
~CUtlLeanVectorFixedGrowableBase();
|
||||||
|
|
||||||
// Gets the base address (can change when adding elements!)
|
// Gets the base address (can change when adding elements!)
|
||||||
@ -179,9 +266,15 @@ public:
|
|||||||
// Makes sure we have enough memory allocated to store a requested # of elements
|
// Makes sure we have enough memory allocated to store a requested # of elements
|
||||||
void EnsureCapacity( int num, bool force = false );
|
void EnsureCapacity( int num, bool force = false );
|
||||||
|
|
||||||
|
bool IsExternallyAllocated() const { return (m_nAllocated & EXTERNAL_BUFFER_MARKER) != 0; }
|
||||||
|
|
||||||
|
int NumAllocated() const { return (m_nAllocated & (~EXTERNAL_BUFFER_MARKER)); }
|
||||||
|
|
||||||
// Element removal
|
// Element removal
|
||||||
void RemoveAll(); // doesn't deallocate memory
|
void RemoveAll(); // doesn't deallocate memory
|
||||||
|
|
||||||
|
bool IsIdxValid( I i ) const { return (i >= 0) && (i < NumAllocated()); }
|
||||||
|
|
||||||
// Memory deallocation
|
// Memory deallocation
|
||||||
void Purge();
|
void Purge();
|
||||||
|
|
||||||
@ -214,14 +307,21 @@ protected:
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// constructor, destructor
|
// constructor, destructor
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template< class T, size_t N, class I >
|
template< class T, size_t N, class I, class A >
|
||||||
inline CUtlLeanVectorFixedGrowableBase<T, N, I>::CUtlLeanVectorFixedGrowableBase() : m_nCount(0),
|
inline CUtlLeanVectorFixedGrowableBase<T, N, I, A>::CUtlLeanVectorFixedGrowableBase( I growSize, I initSize ) :
|
||||||
m_nAllocated(N)
|
m_nCount( 0 ), m_nAllocated( N )
|
||||||
|
{
|
||||||
|
EnsureCapacity( initSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, size_t N, class I, class A >
|
||||||
|
inline CUtlLeanVectorFixedGrowableBase<T, N, I, A>::CUtlLeanVectorFixedGrowableBase( T *pMemory, I allocationCount, I numElements ) :
|
||||||
|
m_nCount( numElements ), m_nAllocated( allocationCount | EXTERNAL_BUFFER_MARKER ), m_pElements( pMemory )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template< class T, size_t N, class I >
|
template< class T, size_t N, class I, class A >
|
||||||
inline CUtlLeanVectorFixedGrowableBase<T, N, I>::~CUtlLeanVectorFixedGrowableBase()
|
inline CUtlLeanVectorFixedGrowableBase<T, N, I, A>::~CUtlLeanVectorFixedGrowableBase()
|
||||||
{
|
{
|
||||||
Purge();
|
Purge();
|
||||||
}
|
}
|
||||||
@ -229,46 +329,46 @@ inline CUtlLeanVectorFixedGrowableBase<T, N, I>::~CUtlLeanVectorFixedGrowableBas
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Gets the base address (can change when adding elements!)
|
// Gets the base address (can change when adding elements!)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template< class T, size_t N, class I >
|
template< class T, size_t N, class I, class A >
|
||||||
inline T* CUtlLeanVectorFixedGrowableBase<T, N, I>::Base()
|
inline T* CUtlLeanVectorFixedGrowableBase<T, N, I, A>::Base()
|
||||||
{
|
{
|
||||||
if ( m_nAllocated )
|
if ( NumAllocated() )
|
||||||
{
|
{
|
||||||
if ( ( size_t )m_nAllocated > N )
|
if ( IsExternallyAllocated() || ( size_t )NumAllocated() > N )
|
||||||
return m_pElements;
|
return m_pElements;
|
||||||
else
|
else
|
||||||
return &m_FixedAlloc[ 0 ];
|
return &m_FixedAlloc[ 0 ];
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template< class T, size_t N, class I >
|
template< class T, size_t N, class I, class A >
|
||||||
inline const T* CUtlLeanVectorFixedGrowableBase<T, N, I>::Base() const
|
inline const T* CUtlLeanVectorFixedGrowableBase<T, N, I, A>::Base() const
|
||||||
{
|
{
|
||||||
if ( m_nAllocated )
|
if ( NumAllocated() )
|
||||||
{
|
{
|
||||||
if ( ( size_t )m_nAllocated > N )
|
if ( IsExternallyAllocated() || ( size_t )NumAllocated() > N )
|
||||||
return m_pElements;
|
return m_pElements;
|
||||||
else
|
else
|
||||||
return &m_FixedAlloc[ 0 ];
|
return &m_FixedAlloc[ 0 ];
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Makes sure we have enough memory allocated to store a requested # of elements
|
// Makes sure we have enough memory allocated to store a requested # of elements
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template< class T, size_t N, class I >
|
template< class T, size_t N, class I, class A >
|
||||||
void CUtlLeanVectorFixedGrowableBase<T, N, I>::EnsureCapacity( int num, bool force )
|
void CUtlLeanVectorFixedGrowableBase<T, N, I, A>::EnsureCapacity( int num, bool force )
|
||||||
{
|
{
|
||||||
|
if ( num <= NumAllocated() )
|
||||||
|
return;
|
||||||
|
|
||||||
I nMinAllocated = (31 + sizeof( T )) / sizeof( T );
|
I nMinAllocated = (31 + sizeof( T )) / sizeof( T );
|
||||||
I nMaxAllocated = (std::numeric_limits<I>::max)();
|
I nMaxAllocated = (std::numeric_limits<I>::max)();
|
||||||
I nNewAllocated = m_nAllocated;
|
I nNewAllocated = num;
|
||||||
|
|
||||||
if ( num <= m_nAllocated )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( ( size_t )num > N )
|
if ( ( size_t )num > N )
|
||||||
{
|
{
|
||||||
@ -278,46 +378,31 @@ void CUtlLeanVectorFixedGrowableBase<T, N, I>::EnsureCapacity( int num, bool for
|
|||||||
Plat_FatalErrorFunc( "%s allocation count overflow", __FUNCTION__ );
|
Plat_FatalErrorFunc( "%s allocation count overflow", __FUNCTION__ );
|
||||||
DebuggerBreak();
|
DebuggerBreak();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( force )
|
|
||||||
{
|
|
||||||
nNewAllocated = num;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while ( nNewAllocated < num )
|
|
||||||
{
|
|
||||||
if ( nNewAllocated < nMaxAllocated/2 )
|
|
||||||
nNewAllocated = MAX( nNewAllocated*2, nMinAllocated );
|
|
||||||
else
|
|
||||||
nNewAllocated = nMaxAllocated;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nNewAllocated = num;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ( size_t )m_nAllocated > N )
|
if(!force)
|
||||||
|
nNewAllocated = CalcNewDoublingCount( NumAllocated(), num, nMinAllocated, nMaxAllocated );
|
||||||
|
|
||||||
|
T *pNew = nullptr;
|
||||||
|
if(!IsExternallyAllocated() && (size_t)NumAllocated() > N)
|
||||||
{
|
{
|
||||||
m_pElements = (T*)realloc( m_pElements, nNewAllocated * sizeof(T) );
|
pNew = CAllocator::Realloc( m_pElements, nNewAllocated, nNewAllocated );
|
||||||
}
|
}
|
||||||
else if ( ( size_t )nNewAllocated > N )
|
else
|
||||||
{
|
{
|
||||||
T* pNew = (T*)malloc( nNewAllocated * sizeof(T) );
|
pNew = CAllocator::template Alloc<T>( nNewAllocated, nNewAllocated );
|
||||||
memcpy( pNew, Base(), m_nCount * sizeof(T) );
|
V_memmove( pNew, Base(), m_nCount * sizeof( T ) );
|
||||||
|
}
|
||||||
|
|
||||||
m_pElements = pNew;
|
m_pElements = pNew;
|
||||||
}
|
|
||||||
|
|
||||||
m_nAllocated = nNewAllocated;
|
m_nAllocated = nNewAllocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Element removal
|
// Element removal
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template< class T, size_t N, class I >
|
template< class T, size_t N, class I, class A >
|
||||||
void CUtlLeanVectorFixedGrowableBase<T, N, I>::RemoveAll()
|
void CUtlLeanVectorFixedGrowableBase<T, N, I, A>::RemoveAll()
|
||||||
{
|
{
|
||||||
T* pElement = Base();
|
T* pElement = Base();
|
||||||
const T* pEnd = &pElement[ m_nCount ];
|
const T* pEnd = &pElement[ m_nCount ];
|
||||||
@ -330,23 +415,29 @@ void CUtlLeanVectorFixedGrowableBase<T, N, I>::RemoveAll()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Memory deallocation
|
// Memory deallocation
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template< class T, size_t N, class I >
|
template< class T, size_t N, class I, class A >
|
||||||
inline void CUtlLeanVectorFixedGrowableBase<T, N, I>::Purge()
|
inline void CUtlLeanVectorFixedGrowableBase<T, N, I, A>::Purge()
|
||||||
{
|
{
|
||||||
RemoveAll();
|
RemoveAll();
|
||||||
|
|
||||||
if ( ( size_t )m_nAllocated > N )
|
if(!IsExternallyAllocated())
|
||||||
free( (void*)m_pElements );
|
{
|
||||||
|
if((size_t)NumAllocated() > N)
|
||||||
|
CAllocator::Free( m_pElements );
|
||||||
|
|
||||||
m_nAllocated = N;
|
m_nAllocated = N;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template< class B, class T, class I >
|
template< class B, class T, class I >
|
||||||
class CUtlLeanVectorImpl : public B
|
class CUtlLeanVectorImpl : public B
|
||||||
{
|
{
|
||||||
|
typedef B BaseClass;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// constructor, destructor
|
// constructor, destructor
|
||||||
CUtlLeanVectorImpl() {};
|
CUtlLeanVectorImpl( I growSize = 0, I initSize = 0 ) : BaseClass( growSize, initSize ) {};
|
||||||
|
CUtlLeanVectorImpl( T *pMemory, I allocationCount, I numElements = 0 ) : BaseClass( pMemory, allocationCount, numElements ) {};
|
||||||
~CUtlLeanVectorImpl() {};
|
~CUtlLeanVectorImpl() {};
|
||||||
|
|
||||||
// Copy the array.
|
// Copy the array.
|
||||||
@ -355,17 +446,18 @@ public:
|
|||||||
class Iterator_t
|
class Iterator_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Iterator_t( const T* _elem, const T* _end ) : elem( _elem ), end( _end ) {}
|
Iterator_t( I i ) : index( i ) {}
|
||||||
const T* elem;
|
I index;
|
||||||
const T* end;
|
|
||||||
bool operator==( const Iterator_t it ) const { return elem == it.elem && end == it.end; }
|
bool operator==( const Iterator_t it ) const { return index == it.index; }
|
||||||
bool operator!=( const Iterator_t it ) const { return elem != it.elem || end != it.end; }
|
bool operator!=( const Iterator_t it ) const { return index != it.index; }
|
||||||
};
|
};
|
||||||
Iterator_t First() const { const T* base = this->Base(); return Iterator_t( base, &base[ this->m_nCount ] ); }
|
Iterator_t First() const { return Iterator_t( this->IsIdxValid( 0 ) ? 0 : InvalidIndex() ); }
|
||||||
Iterator_t Next( const Iterator_t &it ) const { return Iterator_t( it.elem + 1, it.end ); }
|
Iterator_t Next( const Iterator_t &it ) const { return Iterator_t( this->IsIdxValid( it.index + 1 ) ? it.index + 1 : InvalidIndex() ); }
|
||||||
bool IsValidIterator( const Iterator_t &it ) const { return it.elem && it.elem != it.end; }
|
I GetIndex( const Iterator_t &it ) const { return it.index; }
|
||||||
T& operator[]( const Iterator_t &it ) { return *const_cast<T*>(it.elem); }
|
bool IsIdxAfter( I i, const Iterator_t &it ) const { return i > it.index; }
|
||||||
const T& operator[]( const Iterator_t &it ) const { return *it.elem; }
|
bool IsValidIterator( const Iterator_t &it ) const { return this->IsIdxValid( it.index ); }
|
||||||
|
Iterator_t InvalidIterator() const { return Iterator_t( InvalidIndex() ); }
|
||||||
|
|
||||||
// element access
|
// element access
|
||||||
T& operator[]( int i );
|
T& operator[]( int i );
|
||||||
@ -388,6 +480,7 @@ public:
|
|||||||
T* AddToTailGetPtr();
|
T* AddToTailGetPtr();
|
||||||
|
|
||||||
// Adds an element, uses copy constructor
|
// Adds an element, uses copy constructor
|
||||||
|
int AddToTail();
|
||||||
int AddToTail( const T& src );
|
int AddToTail( const T& src );
|
||||||
|
|
||||||
// Adds multiple elements, uses default constructor
|
// Adds multiple elements, uses default constructor
|
||||||
@ -399,6 +492,8 @@ public:
|
|||||||
void SetSize( int size );
|
void SetSize( int size );
|
||||||
void SetCount( int count );
|
void SetCount( int count );
|
||||||
|
|
||||||
|
void EnsureCount( int num );
|
||||||
|
|
||||||
// Finds an element (element needs operator== defined)
|
// Finds an element (element needs operator== defined)
|
||||||
int Find( const T& src ) const;
|
int Find( const T& src ) const;
|
||||||
|
|
||||||
@ -408,6 +503,8 @@ public:
|
|||||||
bool FindAndRemove( const T& src ); // removes first occurrence of src, preserves order, shifts elements
|
bool FindAndRemove( const T& src ); // removes first occurrence of src, preserves order, shifts elements
|
||||||
bool FindAndFastRemove( const T& src ); // removes first occurrence of src, doesn't preserve order
|
bool FindAndFastRemove( const T& src ); // removes first occurrence of src, doesn't preserve order
|
||||||
void RemoveMultiple( int elem, int num ); // preserves order, shifts elements
|
void RemoveMultiple( int elem, int num ); // preserves order, shifts elements
|
||||||
|
void RemoveMultipleFromHead( int num ); // preserves order, shifts elements
|
||||||
|
void RemoveMultipleFromTail( int num ); // preserves order, shifts elements
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Can't copy this unless we explicitly do it!
|
// Can't copy this unless we explicitly do it!
|
||||||
@ -538,6 +635,15 @@ T* CUtlLeanVectorImpl<B, T, I>::AddToTailGetPtr()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Adds an element, uses copy constructor
|
// Adds an element, uses copy constructor
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
template< class B, class T, class I >
|
||||||
|
int CUtlLeanVectorImpl<B, T, I>::AddToTail()
|
||||||
|
{
|
||||||
|
this->EnsureCapacity( this->m_nCount + 1 );
|
||||||
|
T* pBase = this->Base();
|
||||||
|
Construct( &pBase[ this->m_nCount ] );
|
||||||
|
return this->m_nCount++;
|
||||||
|
}
|
||||||
|
|
||||||
template< class B, class T, class I >
|
template< class B, class T, class I >
|
||||||
int CUtlLeanVectorImpl<B, T, I>::AddToTail( const T& src )
|
int CUtlLeanVectorImpl<B, T, I>::AddToTail( const T& src )
|
||||||
{
|
{
|
||||||
@ -644,6 +750,15 @@ inline void CUtlLeanVectorImpl<B, T, I>::SetSize( int size )
|
|||||||
SetCount( size );
|
SetCount( size );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< class B, class T, class I >
|
||||||
|
void CUtlLeanVectorImpl<B, T, I>::EnsureCount( int num )
|
||||||
|
{
|
||||||
|
if(Count() < num)
|
||||||
|
{
|
||||||
|
AddMultipleToTail( num - Count() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Finds an element (element needs operator== defined)
|
// Finds an element (element needs operator== defined)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -672,7 +787,7 @@ void CUtlLeanVectorImpl<B, T, I>::FastRemove( int elem )
|
|||||||
if ( this->m_nCount > 0 )
|
if ( this->m_nCount > 0 )
|
||||||
{
|
{
|
||||||
if ( elem != this->m_nCount - 1 )
|
if ( elem != this->m_nCount - 1 )
|
||||||
memcpy( &pBase[ elem ], &pBase[ this->m_nCount - 1 ], sizeof( T ) );
|
V_memmove( &pBase[ elem ], &pBase[ this->m_nCount - 1 ], sizeof( T ) );
|
||||||
--this->m_nCount;
|
--this->m_nCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -722,6 +837,20 @@ void CUtlLeanVectorImpl<B, T, I>::RemoveMultiple( int elem, int num )
|
|||||||
this->m_nCount -= num;
|
this->m_nCount -= num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< class B, class T, class I >
|
||||||
|
void CUtlLeanVectorImpl<B, T, I>::RemoveMultipleFromHead( int num )
|
||||||
|
{
|
||||||
|
Assert( num <= Count() );
|
||||||
|
RemoveMultiple( 0, num );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class B, class T, class I >
|
||||||
|
void CUtlLeanVectorImpl<B, T, I>::RemoveMultipleFromTail( int num )
|
||||||
|
{
|
||||||
|
Assert( num <= Count() );
|
||||||
|
RemoveMultiple( Count() - num, num );
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Shifts elements
|
// Shifts elements
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -750,12 +879,10 @@ void CUtlLeanVectorImpl<B, T, I>::DestructElements( T* pElement, const T* pEnd )
|
|||||||
Destruct( pElement++ );
|
Destruct( pElement++ );
|
||||||
}
|
}
|
||||||
|
|
||||||
template < class T, class I = short >
|
template < class T, class I = short, class A = CMemAllocAllocator >
|
||||||
using CUtlLeanVector = CUtlLeanVectorImpl< CUtlLeanVectorBase< T, I >, T, I >;
|
using CUtlLeanVector = CUtlLeanVectorImpl< CUtlLeanVectorBase< T, I, A >, T, I >;
|
||||||
|
|
||||||
template < class T, size_t N = 3, class I = int >
|
template < class T, size_t N = 3, class I = int, class A = CMemAllocAllocator >
|
||||||
using CUtlLeanVectorFixedGrowable = CUtlLeanVectorImpl< CUtlLeanVectorFixedGrowableBase< T, N, I >, T, I >;
|
using CUtlLeanVectorFixedGrowable = CUtlLeanVectorImpl< CUtlLeanVectorFixedGrowableBase< T, N, I, A >, T, I >;
|
||||||
|
|
||||||
#include "tier0/memdbgoff.h"
|
|
||||||
|
|
||||||
#endif // UTLLEANVECTOR_H
|
#endif // UTLLEANVECTOR_H
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user