1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2025-09-19 20:16:10 +08:00

Add KeyValues3 & CUtlLeanVector (#177)

This commit is contained in:
vanz666
2023-11-18 22:19:28 +03:00
committed by GitHub
parent 9d90a82cfd
commit bf82ba994d
14 changed files with 3511 additions and 112 deletions

View File

@ -32,6 +32,7 @@ public:
int GetEntryIndex() const;
int GetSerialNumber() const;
int ToInt() const;
bool operator !=(const CEntityHandle& other) const;
bool operator ==(const CEntityHandle& other) const;
bool operator ==(const CEntityInstance* pEnt) const;
@ -110,6 +111,11 @@ inline int CEntityHandle::GetSerialNumber() const
return m_Parts.m_Serial;
}
inline int CEntityHandle::ToInt() const
{
return m_Index;
}
inline bool CEntityHandle::operator !=(const CEntityHandle& other) const
{
return m_Index != other.m_Index;

View File

@ -18,7 +18,7 @@
#include "interfaces/interfaces.h"
#include "tier1/bitbuf.h"
#include "tier1/generichash.h"
#include "tier1/keyvalues3.h"
#include "tier1/utlstring.h"
#include "entity2/entityinstance.h"
@ -62,28 +62,7 @@ Valid data types are string, float, long, short, byte & bool. If a
data field should not be broadcasted to clients, use the type "local".
*/
struct GameEventKeySymbol_t
{
inline GameEventKeySymbol_t(const char* keyName): m_nHashCode(0), m_pszKeyName(NULL)
{
if (!keyName || !keyName[0])
return;
m_nHashCode = MurmurHash2LowerCase(keyName, strlen(keyName), 0x31415926);
m_pszKeyName = keyName;
#if 0
if (g_bUpdateStringTokenDatabase)
{
RegisterStringToken(m_nHashCode, keyName, 0, true);
}
#endif
}
private:
unsigned int m_nHashCode;
const char* m_pszKeyName;
};
typedef CKV3MemberName GameEventKeySymbol_t;
#define MAX_EVENT_NAME_LENGTH 32 // max game event name length
@ -158,8 +137,7 @@ public:
// Something script vm related
virtual void unk001() = 0;
// Not based on keyvalues anymore as it seems like
virtual void* GetDataKeys() const = 0;
virtual KeyValues3* GetDataKeys() const = 0;
};
abstract_class IGameEventListener2

View File

@ -652,18 +652,6 @@ private:
#endif
};
class CThreadEmptyMutex
{
public:
CThreadEmptyMutex( const char* pDebugName ) { }
~CThreadEmptyMutex() { }
inline void Lock( const char *pFileName, int nLine ) { }
inline void Lock( const char *pFileName, int nLine ) const { }
inline void Unlock( const char *pFileName, int nLine ) { }
inline void Unlock( const char *pFileName, int nLine ) const { }
};
//-----------------------------------------------------------------------------
//
// An alternative mutex that is useful for cases when thread contention is
@ -799,10 +787,12 @@ typedef CThreadMutex CThreadFastMutex;
class CThreadNullMutex
{
public:
static void Lock() {}
static void Unlock() {}
CThreadNullMutex( const char* pDebugName ) {}
static bool TryLock() { return true; }
static void Lock( const char *pFileName, int nLine ) {}
static void Unlock( const char *pFileName, int nLine ) {}
static bool TryLock( const char *pFileName, int nLine ) { return true; }
static bool AssertOwnedByCurrentThread() { return true; }
static void SetTrace( bool b ) {}

View File

@ -88,6 +88,14 @@ typedef char tchar;
#define TCHAR_IS_CHAR
#endif
#if defined( _MSC_VER ) || defined( WIN32 )
typedef wchar_t uchar16;
typedef unsigned int uchar32;
#else
typedef unsigned short uchar16;
typedef wchar_t uchar32;
#endif
#ifdef FORCED_UNICODE
#undef _UNICODE
#endif

View File

@ -216,6 +216,16 @@ public:
}
}
CBufferStringGrowable(const CBufferStringGrowable& other) : m_nTotalCount(0), m_nAllocated(STACK_ALLOCATION_MARKER | (MAX_SIZE & LENGTH_MASK))
{
memset(m_Memory.m_szString, 0, sizeof(m_Memory.m_szString));
if (AllowHeapAllocation)
{
m_nAllocated |= ALLOW_HEAP_ALLOCATION;
}
MoveFrom(const_cast<CBufferStringGrowable&>(other));
}
~CBufferStringGrowable()
{
if (IsHeapAllocated() && m_Memory.m_pString)
@ -228,6 +238,12 @@ public:
}
}
inline CBufferStringGrowable& operator=(const CBufferStringGrowable& src)
{
MoveFrom(const_cast<CBufferStringGrowable&>(src));
return *this;
}
inline int GetAllocatedNumber() const
{
return m_nAllocated & LENGTH_MASK;

1027
public/tier1/keyvalues3.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -286,7 +286,7 @@ void CUtlHashtable<KeyT, ValueT, KeyHashT, KeyIsEqualT, AltKeyT, TableT>::InitTa
template <typename KeyT, typename ValueT, typename KeyHashT, typename KeyIsEqualT, typename AltKeyT, typename TableT>
void CUtlHashtable<KeyT, ValueT, KeyHashT, KeyIsEqualT, AltKeyT, TableT>::SetExternalBuffer( byte* pRawBuffer, unsigned int nBytes, bool bAssumeOwnership, bool bGrowable )
{
Assert( ((uintptr_t)pRawBuffer % __alignof(int)) == 0 );
Assert( ((uintp)pRawBuffer % __alignof(int)) == 0 );
uint32 bestSize = LargestPowerOfTwoLessThanOrEqual( nBytes / sizeof(entry_t) );
Assert( bestSize != 0 && bestSize*sizeof(entry_t) <= nBytes );
@ -747,14 +747,14 @@ void CUtlHashtable<KeyT, ValueT, KeyHashT, KeyIsEqualT, AltKeyT, TableT>::DbgChe
// and also the validity of the user's Hash and Equal function objects.
// NOTE: will fail if function objects require any sort of state!
CUtlHashtable clone;
unsigned int bytes = sizeof(entry_t)*max(16,m_table.Count());
unsigned int bytes = sizeof(entry_t)*max(16,m_nTableSize);
byte* tempbuf = (byte*) malloc(bytes);
clone.SetExternalBuffer( tempbuf, bytes, false, false );
clone = *this;
int count = 0, roots = 0, ends = 0;
int slotmask = m_table.Count() - 1;
for (int i = 0; i < m_table.Count(); ++i)
int slotmask = m_nTableSize - 1;
for (int i = 0; i < m_nTableSize; ++i)
{
if (!(m_table[i].flags_and_hash & FLAG_FREE)) ++count;
if (m_table[i].IdealIndex(slotmask) == (uint)i) ++roots;
@ -897,9 +897,9 @@ protected:
KeyHashT m_hash;
unsigned int operator()( IndirectIndex idx ) const
{
const ptrdiff_t tableoffset = (uintptr_t)(&((Hashtable_t*)1024)->GetHashRef()) - 1024;
const ptrdiff_t tableoffset = (uintp)(&((Hashtable_t*)1024)->GetHashRef()) - 1024;
const ptrdiff_t owneroffset = offsetof(CUtlStableHashtable, m_table) + tableoffset;
CUtlStableHashtable* pOwner = (CUtlStableHashtable*)((uintptr_t)this - owneroffset);
CUtlStableHashtable* pOwner = (CUtlStableHashtable*)((uintp)this - owneroffset);
return m_hash( pOwner->m_data[ idx.m_index ].m_key );
}
unsigned int operator()( KeyArg_t k ) const { return m_hash( k ); }
@ -915,16 +915,16 @@ protected:
}
unsigned int operator()( IndirectIndex lhs, KeyArg_t rhs ) const
{
const ptrdiff_t tableoffset = (uintptr_t)(&((Hashtable_t*)1024)->GetEqualRef()) - 1024;
const ptrdiff_t tableoffset = (uintp)(&((Hashtable_t*)1024)->GetEqualRef()) - 1024;
const ptrdiff_t owneroffset = offsetof(CUtlStableHashtable, m_table) + tableoffset;
CUtlStableHashtable* pOwner = (CUtlStableHashtable*)((uintptr_t)this - owneroffset);
CUtlStableHashtable* pOwner = (CUtlStableHashtable*)((uintp)this - owneroffset);
return m_eq( pOwner->m_data[ lhs.m_index ].m_key, rhs );
}
unsigned int operator()( IndirectIndex lhs, KeyAlt_t rhs ) const
{
const ptrdiff_t tableoffset = (uintptr_t)(&((Hashtable_t*)1024)->GetEqualRef()) - 1024;
const ptrdiff_t tableoffset = (uintp)(&((Hashtable_t*)1024)->GetEqualRef()) - 1024;
const ptrdiff_t owneroffset = offsetof(CUtlStableHashtable, m_table) + tableoffset;
CUtlStableHashtable* pOwner = (CUtlStableHashtable*)((uintptr_t)this - owneroffset);
CUtlStableHashtable* pOwner = (CUtlStableHashtable*)((uintp)this - owneroffset);
return m_eq( pOwner->m_data[ lhs.m_index ].m_key, rhs );
}
};

View File

@ -0,0 +1,731 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======//
//
// Purpose:
//
// $NoKeywords: $
//
// A growable array class that maintains a free list and keeps elements
// in the same location
//=============================================================================//
#ifndef UTLLEANVECTOR_H
#define UTLLEANVECTOR_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/platform.h"
#include "tier0/dbg.h"
#include <limits>
#define FOR_EACH_LEANVEC( vecName, iteratorName ) \
for ( auto iteratorName = vecName.First(); vecName.IsValidIterator( iteratorName ); iteratorName = vecName.Next( iteratorName ) )
template< class T, class I >
class CUtlLeanVectorBase
{
public:
// constructor, destructor
CUtlLeanVectorBase();
~CUtlLeanVectorBase();
// Gets the base address (can change when adding elements!)
T* Base();
const T* Base() const;
// Makes sure we have enough memory allocated to store a requested # of elements
void EnsureCapacity( int num, bool force = false );
// Element removal
void RemoveAll(); // doesn't deallocate memory
// Memory deallocation
void Purge();
protected:
I m_Size;
I m_nAllocationCount;
T* m_pMemory;
};
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
template< class T, class I >
inline CUtlLeanVectorBase<T, I>::CUtlLeanVectorBase() : m_Size(0),
m_nAllocationCount(0), m_pMemory(0)
{
}
template< class T, class I >
inline CUtlLeanVectorBase<T, I>::~CUtlLeanVectorBase()
{
Purge();
}
//-----------------------------------------------------------------------------
// Gets the base address (can change when adding elements!)
//-----------------------------------------------------------------------------
template< class T, class I >
inline T* CUtlLeanVectorBase<T, I>::Base()
{
return m_nAllocationCount ? m_pMemory : NULL;
}
template< class T, class I >
inline const T* CUtlLeanVectorBase<T, I>::Base() const
{
return m_nAllocationCount ? m_pMemory : NULL;
}
//-----------------------------------------------------------------------------
// Makes sure we have enough memory allocated to store a requested # of elements
//-----------------------------------------------------------------------------
template< class T, class I >
void CUtlLeanVectorBase<T, I>::EnsureCapacity( int num, bool force )
{
I nMinAllocationCount = ( 31 + sizeof( T ) ) / sizeof( T );
I nMaxAllocationCount = (std::numeric_limits<I>::max)();
I nNewAllocationCount = m_nAllocationCount;
if ( force )
{
if ( num == m_nAllocationCount )
return;
}
else
{
if ( num <= m_nAllocationCount )
return;
}
if ( num > nMaxAllocationCount )
{
Msg( "%s allocation count overflow( %llu > %llu )\n", __FUNCTION__, num, nMaxAllocationCount );
Plat_FatalErrorFunc( "%s allocation count overflow", __FUNCTION__ );
DebuggerBreak();
}
if ( force )
{
nNewAllocationCount = num;
}
else
{
while ( nNewAllocationCount < num )
{
if ( nNewAllocationCount < nMaxAllocationCount/2 )
nNewAllocationCount = MAX( nNewAllocationCount*2, nMinAllocationCount );
else
nNewAllocationCount = nMaxAllocationCount;
}
}
m_pMemory = (T*)realloc( m_pMemory, nNewAllocationCount * sizeof(T) );
m_nAllocationCount = nNewAllocationCount;
}
//-----------------------------------------------------------------------------
// Element removal
//-----------------------------------------------------------------------------
template< class T, class I >
void CUtlLeanVectorBase<T, I>::RemoveAll()
{
T* pElement = Base();
const T* pEnd = &pElement[ m_Size ];
while ( pElement != pEnd )
Destruct( pElement++ );
m_Size = 0;
}
//-----------------------------------------------------------------------------
// Memory deallocation
//-----------------------------------------------------------------------------
template< class T, class I >
inline void CUtlLeanVectorBase<T, I>::Purge()
{
RemoveAll();
if ( m_nAllocationCount > 0 )
{
free( (void*)m_pMemory );
m_pMemory = 0;
}
m_nAllocationCount = 0;
}
template< class T, size_t N, class I >
class CUtlLeanVectorFixedGrowableBase
{
public:
// constructor, destructor
CUtlLeanVectorFixedGrowableBase();
~CUtlLeanVectorFixedGrowableBase();
// Gets the base address (can change when adding elements!)
T* Base();
const T* Base() const;
// Makes sure we have enough memory allocated to store a requested # of elements
void EnsureCapacity( int num, bool force = false );
// Element removal
void RemoveAll(); // doesn't deallocate memory
// Memory deallocation
void Purge();
protected:
I m_Size;
I m_nAllocationCount;
union
{
T* m_pMemory;
T m_Memory[ N ];
};
};
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
template< class T, size_t N, class I >
inline CUtlLeanVectorFixedGrowableBase<T, N, I>::CUtlLeanVectorFixedGrowableBase() : m_Size(0),
m_nAllocationCount(N)
{
}
template< class T, size_t N, class I >
inline CUtlLeanVectorFixedGrowableBase<T, N, I>::~CUtlLeanVectorFixedGrowableBase()
{
Purge();
}
//-----------------------------------------------------------------------------
// Gets the base address (can change when adding elements!)
//-----------------------------------------------------------------------------
template< class T, size_t N, class I >
inline T* CUtlLeanVectorFixedGrowableBase<T, N, I>::Base()
{
if ( m_nAllocationCount )
{
if ( m_nAllocationCount > N )
return m_pMemory;
else
return &m_Memory[ 0 ];
}
return NULL;
}
template< class T, size_t N, class I >
inline const T* CUtlLeanVectorFixedGrowableBase<T, N, I>::Base() const
{
if ( m_nAllocationCount )
{
if ( m_nAllocationCount > N )
return m_pMemory;
else
return &m_Memory[ 0 ];
}
return NULL;
}
//-----------------------------------------------------------------------------
// Makes sure we have enough memory allocated to store a requested # of elements
//-----------------------------------------------------------------------------
template< class T, size_t N, class I >
void CUtlLeanVectorFixedGrowableBase<T, N, I>::EnsureCapacity( int num, bool force )
{
I nMinAllocationCount = ( 31 + sizeof( T ) ) / sizeof( T );
I nMaxAllocationCount = (std::numeric_limits<I>::max)();
I nNewAllocationCount = m_nAllocationCount;
if ( num <= m_nAllocationCount )
return;
if ( num > N )
{
if ( num > nMaxAllocationCount )
{
Msg( "%s allocation count overflow( %llu > %llu )\n", __FUNCTION__, num, nMaxAllocationCount );
Plat_FatalErrorFunc( "%s allocation count overflow", __FUNCTION__ );
DebuggerBreak();
}
if ( force )
{
nNewAllocationCount = num;
}
else
{
while ( nNewAllocationCount < num )
{
if ( nNewAllocationCount < nMaxAllocationCount/2 )
nNewAllocationCount = MAX( nNewAllocationCount*2, nMinAllocationCount );
else
nNewAllocationCount = nMaxAllocationCount;
}
}
}
else
{
nNewAllocationCount = num;
}
if ( m_nAllocationCount > N )
{
m_pMemory = (T*)realloc( m_pMemory, nNewAllocationCount * sizeof(T) );
}
else if ( nNewAllocationCount > N )
{
T* pNew = (T*)malloc( nNewAllocationCount * sizeof(T) );
memcpy( pNew, Base(), m_Size * sizeof(T) );
m_pMemory = pNew;
}
m_nAllocationCount = nNewAllocationCount;
}
//-----------------------------------------------------------------------------
// Element removal
//-----------------------------------------------------------------------------
template< class T, size_t N, class I >
void CUtlLeanVectorFixedGrowableBase<T, N, I>::RemoveAll()
{
T* pElement = Base();
const T* pEnd = &pElement[ m_Size ];
while ( pElement != pEnd )
Destruct( pElement++ );
m_Size = 0;
}
//-----------------------------------------------------------------------------
// Memory deallocation
//-----------------------------------------------------------------------------
template< class T, size_t N, class I >
inline void CUtlLeanVectorFixedGrowableBase<T, N, I>::Purge()
{
RemoveAll();
if ( m_nAllocationCount > N )
free( (void*)m_pMemory );
m_nAllocationCount = N;
}
template< class B, class T, class I >
class CUtlLeanVectorImpl : public B
{
public:
// constructor, destructor
CUtlLeanVectorImpl() {};
~CUtlLeanVectorImpl() {};
// Copy the array.
CUtlLeanVectorImpl<B, T, I>& operator=( const CUtlLeanVectorImpl<B, T, I> &other );
struct Iterator_t
{
Iterator_t( T* _elem, const T* _end ) : elem( _elem ), end( _end ) {}
T* elem;
const T* end;
};
Iterator_t First() const { T* base = const_cast<T*>( this->Base() ); return Iterator_t( base, &base[ this->m_Size ] ); }
Iterator_t Next( const Iterator_t &it ) const { return Iterator_t( it.elem + 1, it.end ); }
bool IsValidIterator( const Iterator_t &it ) const { return it.elem != it.end; }
T& operator[]( const Iterator_t &it ) { return *it.elem; }
const T& operator[]( const Iterator_t &it ) const { return *it.elem; }
// element access
T& operator[]( int i );
const T& operator[]( int i ) const;
T& Element( int i );
const T& Element( int i ) const;
T& Head();
const T& Head() const;
T& Tail();
const T& Tail() const;
// Returns the number of elements in the vector
int Count() const;
// Is element index valid?
bool IsValidIndex( int i ) const;
static int InvalidIndex();
// Adds an element, uses default constructor
T* AddToTailGetPtr();
// Adds an element, uses copy constructor
int AddToTail( const T& src );
// Adds multiple elements, uses default constructor
int AddMultipleToTail( int nSize );
// Adds multiple elements, uses default constructor
T* InsertBeforeGetPtr( int nBeforeIndex, int nSize = 1 );
void SetSize( int size );
void SetCount( int count );
// Finds an element (element needs operator== defined)
int Find( const T& src ) const;
// Element removal
void FastRemove( int elem ); // doesn't preserve order
void Remove( int elem ); // 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
void RemoveMultiple( int elem, int num ); // preserves order, shifts elements
protected:
// Can't copy this unless we explicitly do it!
CUtlLeanVectorImpl( CUtlLeanVectorImpl const& vec ) { Assert(0); }
// Shifts elements....
void ShiftElements( T* pDest, const T* pSrc, const T* pSrcEnd );
// construct, destruct elements
void ConstructElements( T* pElement, const T* pEnd );
void DestructElements( T* pElement, const T* pEnd );
};
template< class B, class T, class I >
inline CUtlLeanVectorImpl<B, T, I>& CUtlLeanVectorImpl<B, T, I>::operator=( const CUtlLeanVectorImpl<B, T, I> &other )
{
int nCount = other.Count();
SetSize( nCount );
for ( int i = 0; i < nCount; i++ )
{
(*this)[ i ] = other[ i ];
}
return *this;
}
//-----------------------------------------------------------------------------
// element access
//-----------------------------------------------------------------------------
template< class B, class T, class I >
inline T& CUtlLeanVectorImpl<B, T, I>::operator[]( int i )
{
Assert( i < this->m_Size );
return this->Base()[ i ];
}
template< class B, class T, class I >
inline const T& CUtlLeanVectorImpl<B, T, I>::operator[]( int i ) const
{
Assert( i < this->m_Size );
return this->Base()[ i ];
}
template< class B, class T, class I >
inline T& CUtlLeanVectorImpl<B, T, I>::Element( int i )
{
Assert( i < this->m_Size );
return this->Base()[ i ];
}
template< class B, class T, class I >
inline const T& CUtlLeanVectorImpl<B, T, I>::Element( int i ) const
{
Assert( i < this->m_Size );
return this->Base()[ i ];
}
template< class B, class T, class I >
inline T& CUtlLeanVectorImpl<B, T, I>::Head()
{
Assert( this->m_Size > 0 );
return this->Base()[ 0 ];
}
template< class B, class T, class I >
inline const T& CUtlLeanVectorImpl<B, T, I>::Head() const
{
Assert( this->m_Size > 0 );
return this->Base()[ 0 ];
}
template< class B, class T, class I >
inline T& CUtlLeanVectorImpl<B, T, I>::Tail()
{
Assert( this->m_Size > 0 );
return this->Base()[ this->m_Size - 1 ];
}
template< class B, class T, class I >
inline const T& CUtlLeanVectorImpl<B, T, I>::Tail() const
{
Assert( this->m_Size > 0 );
return this->Base()[ this->m_Size - 1 ];
}
//-----------------------------------------------------------------------------
// Count
//-----------------------------------------------------------------------------
template< class B, class T, class I >
inline int CUtlLeanVectorImpl<B, T, I>::Count() const
{
return this->m_Size;
}
//-----------------------------------------------------------------------------
// Is element index valid?
//-----------------------------------------------------------------------------
template< class B, class T, class I >
inline bool CUtlLeanVectorImpl<B, T, I>::IsValidIndex( int i ) const
{
return (i >= 0) && (i < this->m_Size);
}
//-----------------------------------------------------------------------------
// Returns in invalid index
//-----------------------------------------------------------------------------
template< class B, class T, class I >
inline int CUtlLeanVectorImpl<B, T, I>::InvalidIndex()
{
return -1;
}
//-----------------------------------------------------------------------------
// Adds an element, uses default constructor
//-----------------------------------------------------------------------------
template< class B, class T, class I >
T* CUtlLeanVectorImpl<B, T, I>::AddToTailGetPtr()
{
this->EnsureCapacity( this->m_Size + 1 );
T* pBase = this->Base();
Construct( &pBase[ this->m_Size ] );
return &pBase[ this->m_Size++ ];
}
//-----------------------------------------------------------------------------
// Adds an element, uses copy constructor
//-----------------------------------------------------------------------------
template< class B, class T, class I >
int CUtlLeanVectorImpl<B, T, I>::AddToTail( const T& src )
{
this->EnsureCapacity( this->m_Size + 1 );
T* pBase = this->Base();
CopyConstruct( &pBase[ this->m_Size ], src );
return this->m_Size++;
}
//-----------------------------------------------------------------------------
// Adds multiple elements, uses default constructor
//-----------------------------------------------------------------------------
template< class B, class T, class I >
int CUtlLeanVectorImpl<B, T, I>::AddMultipleToTail( int nSize )
{
int nOldSize = this->m_Size;
if ( nSize > 0 )
{
int nMaxSize = (std::numeric_limits<I>::max)();
if ( ( nMaxSize - nOldSize ) < nSize )
{
Msg( "%s allocation count overflow( add %llu + current %llu > max %llu )\n", __FUNCTION__, nSize, nOldSize, nMaxSize );
Plat_FatalErrorFunc( "%s allocation count overflow", __FUNCTION__ );
DebuggerBreak();
}
int nNewSize = nOldSize + nSize;
this->EnsureCapacity( nNewSize );
T* pBase = this->Base();
ConstructElements( &pBase[ nOldSize ], &pBase[ nNewSize ] );
this->m_Size = nNewSize;
}
return nOldSize;
}
//-----------------------------------------------------------------------------
// Adds multiple elements, uses default constructor
//-----------------------------------------------------------------------------
template< class B, class T, class I >
T* CUtlLeanVectorImpl<B, T, I>::InsertBeforeGetPtr( int nBeforeIndex, int nSize )
{
int nOldSize = this->m_Size;
if ( nBeforeIndex < 0 || nBeforeIndex > nOldSize )
{
Plat_FatalErrorFunc( "%s: invalid nBeforeIndex %d\n", __FUNCTION__, nBeforeIndex );
DebuggerBreak();
}
if ( nSize <= 0 )
{
Plat_FatalErrorFunc( "%s: invalid nSize %d\n", __FUNCTION__, nSize );
DebuggerBreak();
}
int nMaxSize = (std::numeric_limits<I>::max)();
if ( ( nMaxSize - nOldSize ) < nSize )
{
Msg( "%s allocation count overflow( add %llu + current %llu > max %llu )\n", __FUNCTION__, nSize, nOldSize, nMaxSize );
Plat_FatalErrorFunc( "%s allocation count overflow", __FUNCTION__ );
DebuggerBreak();
}
int nNewSize = nOldSize + nSize;
this->EnsureCapacity( nNewSize );
T* pBase = this->Base();
ShiftElements( &pBase[ nBeforeIndex + nSize ], &pBase[ nBeforeIndex ], &pBase[ nOldSize ] );
ConstructElements( &pBase[ nBeforeIndex ], &pBase[ nBeforeIndex + nSize ] );
this->m_Size = nNewSize;
return &pBase[ nBeforeIndex ];
}
template< class B, class T, class I >
void CUtlLeanVectorImpl<B, T, I>::SetCount( int count )
{
this->EnsureCapacity( count );
T* pBase = this->Base();
if ( this->m_Size < count )
ConstructElements( &pBase[ this->m_Size ], &pBase[ count ] );
else if ( this->m_Size > count )
DestructElements( &pBase[ count ], &pBase[ this->m_Size ] );
this->m_Size = count;
}
template< class B, class T, class I >
inline void CUtlLeanVectorImpl<B, T, I>::SetSize( int size )
{
SetCount( size );
}
//-----------------------------------------------------------------------------
// Finds an element (element needs operator== defined)
//-----------------------------------------------------------------------------
template< class B, class T, class I >
int CUtlLeanVectorImpl<B, T, I>::Find( const T& src ) const
{
const T* pBase = this->Base();
for ( int i = 0; i < Count(); ++i )
{
if ( pBase[i] == src )
return i;
}
return -1;
}
//-----------------------------------------------------------------------------
// Element removal
//-----------------------------------------------------------------------------
template< class B, class T, class I >
void CUtlLeanVectorImpl<B, T, I>::FastRemove( int elem )
{
Assert( IsValidIndex(elem) );
T* pBase = this->Base();
Destruct( &pBase[ elem ] );
if ( this->m_Size > 0 )
{
if ( elem != this->m_Size - 1 )
memcpy( &pBase[ elem ], &pBase[ this->m_Size - 1 ], sizeof( T ) );
--this->m_Size;
}
}
template< class B, class T, class I >
void CUtlLeanVectorImpl<B, T, I>::Remove( int elem )
{
T* pBase = this->Base();
Destruct( &pBase[ elem ] );
ShiftElements( &pBase[ elem ], &pBase[ elem + 1 ], &pBase[ this->m_Size ] );
--this->m_Size;
}
template< class B, class T, class I >
bool CUtlLeanVectorImpl<B, T, I>::FindAndRemove( const T& src )
{
int elem = Find( src );
if ( elem != -1 )
{
Remove( elem );
return true;
}
return false;
}
template< class B, class T, class I >
bool CUtlLeanVectorImpl<B, T, I>::FindAndFastRemove( const T& src )
{
int elem = Find( src );
if ( elem != -1 )
{
FastRemove( elem );
return true;
}
return false;
}
template< class B, class T, class I >
void CUtlLeanVectorImpl<B, T, I>::RemoveMultiple( int elem, int num )
{
Assert( elem >= 0 );
Assert( elem + num <= Count() );
T* pBase = this->Base();
DestructElements( &pBase[ elem ], &pBase[ elem + num ] );
ShiftElements( &pBase[ elem ], &pBase[ elem + num ], &pBase[ this->m_Size ] );
this->m_Size -= num;
}
//-----------------------------------------------------------------------------
// Shifts elements
//-----------------------------------------------------------------------------
template< class B, class T, class I >
void CUtlLeanVectorImpl<B, T, I>::ShiftElements( T* pDest, const T* pSrc, const T* pSrcEnd )
{
ptrdiff_t numToMove = pSrcEnd - pSrc;
if ( numToMove > 0 )
memmove( pDest, pSrc, numToMove * sizeof( T ) );
}
//-----------------------------------------------------------------------------
// construct, destruct elements
//-----------------------------------------------------------------------------
template< class B, class T, class I >
void CUtlLeanVectorImpl<B, T, I>::ConstructElements( T* pElement, const T* pEnd )
{
while ( pElement < pEnd )
Construct( pElement++ );
}
template< class B, class T, class I >
void CUtlLeanVectorImpl<B, T, I>::DestructElements( T* pElement, const T* pEnd )
{
while ( pElement < pEnd )
Destruct( pElement++ );
}
template < class T, class I = short >
using CUtlLeanVector = CUtlLeanVectorImpl< CUtlLeanVectorBase< T, I >, T, I >;
template < class T, size_t N = 3, class I = short >
using CUtlLeanVectorFixedGrowable = CUtlLeanVectorImpl< CUtlLeanVectorFixedGrowableBase< T, N, I >, T, I >;
#endif // UTLLEANVECTOR_H

View File

@ -16,7 +16,6 @@
#include "tier0/dbg.h"
#include <string.h>
#include <cstdint>
#include "tier0/platform.h"
#include "tier0/memalloc.h"
@ -24,6 +23,10 @@
#include "mathlib/mathlib.h"
#include "tier0/memdbgon.h"
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)-1)
#endif
#ifdef _MSC_VER
#pragma warning (disable:4100)
#pragma warning (disable:4514)

View File

@ -33,6 +33,16 @@ public:
#define DefLessFunc( type ) CDefOps< type >::LessFunc
template <typename T>
class CDefLess
{
public:
CDefLess() {}
CDefLess( int i ) {}
inline bool operator()( const T &lhs, const T &rhs ) const { return ( lhs < rhs ); }
inline bool operator!() const { return false; }
};
//-------------------------------------
inline bool StringLessThan( const char * const &lhs, const char * const &rhs) { return ( strcmp( lhs, rhs) < 0 ); }
@ -656,7 +666,8 @@ I CUtlRBTree<T, I, L, M>::NewNode()
Assert( m_Elements.IsValidIterator( it ) );
if ( !m_Elements.IsValidIterator( it ) )
{
Error( "CUtlRBTree overflow!\n" );
Plat_FatalErrorFunc( "CUtlRBTree overflow with %u elements!\n", Count() );
DebuggerBreak();
}
}
m_LastAlloc = it;
@ -1465,7 +1476,7 @@ I CUtlRBTree<T, I, L, M>::Insert( T const &insert )
bool leftchild;
FindInsertionPosition( insert, parent, leftchild );
I newNode = InsertAt( parent, leftchild );
CopyConstruct( &Element( newNode ), insert );
Element( newNode ) = insert;
return newNode;
}
@ -1507,7 +1518,7 @@ I CUtlRBTree<T, I, L, M>::InsertIfNotFound( T const &insert )
}
I newNode = InsertAt( parent, leftchild );
CopyConstruct( &Element( newNode ), insert );
Element( newNode ) = insert;
return newNode;
}

View File

@ -42,6 +42,13 @@ inline size_t strnlen(const char *s, size_t n)
class CUtlStringToken
{
public:
inline CUtlStringToken(): m_nHashCode(0) {}
inline CUtlStringToken(unsigned int nHashCode): m_nHashCode(nHashCode) {}
inline CUtlStringToken(const CUtlStringToken& other): m_nHashCode(other.m_nHashCode) {}
inline CUtlStringToken& operator=(const CUtlStringToken& src) { m_nHashCode = src.m_nHashCode; return *this; }
public:
unsigned int m_nHashCode;
};

View File

@ -42,9 +42,9 @@ public:
m_pString = NULL;
}
CUtlSymbolLarge( const char* pStr )
CUtlSymbolLarge( const char* pString )
{
m_pString = pStr;
m_pString = pString;
}
CUtlSymbolLarge( CUtlSymbolLarge const& sym )
@ -73,6 +73,8 @@ public:
inline const char* String() const
{
if ( !m_pString )
return "";
return m_pString;
}
@ -124,7 +126,7 @@ struct CUtlSymbolTableLargeBaseTreeEntry_t
};
// Base Class for threaded and non-threaded types
template < class MutexType, bool CASEINSENSITIVE >
template < bool CASEINSENSITIVE, size_t PAGE_SIZE, class MUTEX_TYPE >
class CUtlSymbolTableLargeBase
{
public:
@ -133,7 +135,7 @@ public:
: m_HashTable( 0, eAllocatorType ),
m_MemBlocks( nGrowSize, nInitSize, eAllocatorType ),
m_Mutex( "CUtlSymbolTableLargeBase" ),
m_MemBlockAllocator( ( nInitSize > 0 ) ? 8 : 0, 2048, eAllocatorType ),
m_MemBlockAllocator( ( nInitSize > 0 ) ? 8 : 0, PAGE_SIZE, eAllocatorType ),
m_nElementLimit( INT_MAX - 1 ),
m_bThrowError( true ) { }
@ -171,7 +173,7 @@ private:
UtlSymTableLargeHashFunctor()
{
m_tableOffset = 1024 - (uintptr_t)(&((Hashtable_t*)1024)->GetHashRef());
m_tableOffset = 1024 - (uintp)(&((Hashtable_t*)1024)->GetHashRef());
}
unsigned int operator()( UtlSymTableLargeAltKey k ) const
@ -181,7 +183,7 @@ private:
unsigned int operator()( UtlSymLargeId_t k ) const
{
CUtlSymbolTableLargeBase* pTable = (CUtlSymbolTableLargeBase*)((uintptr_t)this + m_tableOffset);
CUtlSymbolTableLargeBase* pTable = (CUtlSymbolTableLargeBase*)((uintp)this + m_tableOffset);
return pTable->HashValue( k );
}
@ -193,12 +195,12 @@ private:
UtlSymTableLargeEqualFunctor()
{
m_tableOffset = 1024 - (uintptr_t)(&((Hashtable_t*)1024)->GetEqualRef());
m_tableOffset = 1024 - (uintp)(&((Hashtable_t*)1024)->GetEqualRef());
}
bool operator()( UtlSymLargeId_t a, UtlSymLargeId_t b ) const
{
CUtlSymbolTableLargeBase* pTable = (CUtlSymbolTableLargeBase*)((uintptr_t)this + m_tableOffset);
CUtlSymbolTableLargeBase* pTable = (CUtlSymbolTableLargeBase*)((uintp)this + m_tableOffset);
if ( !CASEINSENSITIVE )
return strcmp( pTable->String( a ), pTable->String( b ) ) == 0;
@ -230,14 +232,14 @@ private:
Hashtable_t m_HashTable;
MemBlocksVec_t m_MemBlocks;
MutexType m_Mutex;
MUTEX_TYPE m_Mutex;
CUtlMemoryBlockAllocator m_MemBlockAllocator;
int m_nElementLimit;
bool m_bThrowError;
};
template < class MutexType, bool CASEINSENSITIVE >
inline CUtlSymbolLarge CUtlSymbolTableLargeBase< MutexType, CASEINSENSITIVE >::Find( unsigned int hash, const char* pString, int nLength ) const
template < bool CASEINSENSITIVE, size_t PAGE_SIZE, class MUTEX_TYPE >
inline CUtlSymbolLarge CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUTEX_TYPE >::Find( unsigned int hash, const char* pString, int nLength ) const
{
UtlSymTableLargeAltKey key;
@ -253,8 +255,8 @@ inline CUtlSymbolLarge CUtlSymbolTableLargeBase< MutexType, CASEINSENSITIVE >::F
return CUtlSymbolLarge( String( m_HashTable[ h ] ) );
}
template < class MutexType, bool CASEINSENSITIVE >
inline CUtlSymbolLarge CUtlSymbolTableLargeBase< MutexType, CASEINSENSITIVE >::AddString( unsigned int hash, const char* pString, int nLength )
template < bool CASEINSENSITIVE, size_t PAGE_SIZE, class MUTEX_TYPE >
inline CUtlSymbolLarge CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUTEX_TYPE >::AddString( unsigned int hash, const char* pString, int nLength )
{
if ( m_MemBlocks.Count() >= m_nElementLimit )
{
@ -284,22 +286,22 @@ inline CUtlSymbolLarge CUtlSymbolTableLargeBase< MutexType, CASEINSENSITIVE >::A
return entry->ToSymbol();
}
template < class MutexType, bool CASEINSENSITIVE >
inline const char* CUtlSymbolTableLargeBase< MutexType, CASEINSENSITIVE >::String( UtlSymLargeId_t id ) const
template < bool CASEINSENSITIVE, size_t PAGE_SIZE, class MUTEX_TYPE >
inline const char* CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUTEX_TYPE >::String( UtlSymLargeId_t id ) const
{
return ( const char* )m_MemBlockAllocator.GetBlock( m_MemBlocks[ id ] );
}
template < class MutexType, bool CASEINSENSITIVE >
inline unsigned int CUtlSymbolTableLargeBase< MutexType, CASEINSENSITIVE >::HashValue( UtlSymLargeId_t id ) const
template < bool CASEINSENSITIVE, size_t PAGE_SIZE, class MUTEX_TYPE >
inline unsigned int CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUTEX_TYPE >::HashValue( UtlSymLargeId_t id ) const
{
CUtlSymbolTableLargeBaseTreeEntry_t *entry = (CUtlSymbolTableLargeBaseTreeEntry_t *)m_MemBlockAllocator.GetBlock( m_MemBlocks[ id ] - sizeof( LargeSymbolTableHashDecoration_t ) );
return entry->HashValue();
}
template < class MutexType, bool CASEINSENSITIVE >
inline CUtlSymbolLarge CUtlSymbolTableLargeBase< MutexType, CASEINSENSITIVE >::Find( const char* pString, int nLength ) const
template < bool CASEINSENSITIVE, size_t PAGE_SIZE, class MUTEX_TYPE >
inline CUtlSymbolLarge CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUTEX_TYPE >::Find( const char* pString, int nLength ) const
{
CUtlSymbolLarge sym;
@ -317,14 +319,14 @@ inline CUtlSymbolLarge CUtlSymbolTableLargeBase< MutexType, CASEINSENSITIVE >::F
return sym;
}
template < class MutexType, bool CASEINSENSITIVE >
inline CUtlSymbolLarge CUtlSymbolTableLargeBase< MutexType, CASEINSENSITIVE >::Find( const char* pString ) const
template < bool CASEINSENSITIVE, size_t PAGE_SIZE, class MUTEX_TYPE >
inline CUtlSymbolLarge CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUTEX_TYPE >::Find( const char* pString ) const
{
return Find( pString, pString ? strlen( pString ) : 0 );
}
template < class MutexType, bool CASEINSENSITIVE >
inline CUtlSymbolLarge CUtlSymbolTableLargeBase< MutexType, CASEINSENSITIVE >::AddString( const char* pString, int nLength )
template < bool CASEINSENSITIVE, size_t PAGE_SIZE, class MUTEX_TYPE >
inline CUtlSymbolLarge CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUTEX_TYPE >::AddString( const char* pString, int nLength )
{
CUtlSymbolLarge sym;
@ -345,14 +347,14 @@ inline CUtlSymbolLarge CUtlSymbolTableLargeBase< MutexType, CASEINSENSITIVE >::A
return sym;
}
template < class MutexType, bool CASEINSENSITIVE >
inline CUtlSymbolLarge CUtlSymbolTableLargeBase< MutexType, CASEINSENSITIVE >::AddString( const char* pString )
template < bool CASEINSENSITIVE, size_t PAGE_SIZE, class MUTEX_TYPE >
inline CUtlSymbolLarge CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUTEX_TYPE >::AddString( const char* pString )
{
return AddString( pString, pString ? strlen( pString ) : 0 );
}
template < class MutexType, bool CASEINSENSITIVE >
inline void CUtlSymbolTableLargeBase< MutexType, CASEINSENSITIVE >::RemoveAll()
template < bool CASEINSENSITIVE, size_t PAGE_SIZE, class MUTEX_TYPE >
inline void CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUTEX_TYPE >::RemoveAll()
{
m_Mutex.Lock( __FILE__, __LINE__ );
@ -363,8 +365,8 @@ inline void CUtlSymbolTableLargeBase< MutexType, CASEINSENSITIVE >::RemoveAll()
m_Mutex.Unlock( __FILE__, __LINE__ );
}
template < class MutexType, bool CASEINSENSITIVE >
inline void CUtlSymbolTableLargeBase< MutexType, CASEINSENSITIVE >::Purge()
template < bool CASEINSENSITIVE, size_t PAGE_SIZE, class MUTEX_TYPE >
inline void CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUTEX_TYPE >::Purge()
{
m_Mutex.Lock( __FILE__, __LINE__ );
@ -376,12 +378,12 @@ inline void CUtlSymbolTableLargeBase< MutexType, CASEINSENSITIVE >::Purge()
}
// Case-sensitive
typedef CUtlSymbolTableLargeBase< CThreadEmptyMutex, false > CUtlSymbolTableLarge;
typedef CUtlSymbolTableLargeBase< false, 2048, CThreadNullMutex > CUtlSymbolTableLarge;
// Case-insensitive
typedef CUtlSymbolTableLargeBase< CThreadEmptyMutex, true > CUtlSymbolTableLarge_CI;
typedef CUtlSymbolTableLargeBase< true, 2048, CThreadNullMutex > CUtlSymbolTableLarge_CI;
// Multi-threaded case-sensitive
typedef CUtlSymbolTableLargeBase< CThreadMutex, false > CUtlSymbolTableLargeMT;
typedef CUtlSymbolTableLargeBase< false, 2048, CThreadMutex > CUtlSymbolTableLargeMT;
// Multi-threaded case-insensitive
typedef CUtlSymbolTableLargeBase< CThreadMutex, true > CUtlSymbolTableLargeMT_CI;
typedef CUtlSymbolTableLargeBase< true, 2048, CThreadMutex > CUtlSymbolTableLargeMT_CI;
#endif // UTLSYMBOLLARGE_H

View File

@ -225,15 +225,6 @@ public:
CUtlVectorFixedGrowable( int growSize = 0 ) : BaseClass( growSize, MAX_SIZE ) {}
};
template< class T, class B = short >
class CUtlLeanVectorBase
{
private:
B m_nAllocationCount;
B m_nGrowSize;
T* m_pMemory;
};
//-----------------------------------------------------------------------------
// The CUtlVectorConservative class:
// A array class with a conservative allocation scheme
@ -1190,15 +1181,33 @@ public:
class CSplitString: public CUtlVector<char*, CUtlMemory<char*, int> >
{
public:
CSplitString(const char *pString, const char *pSeparator);
CSplitString(const char *pString, const char **pSeparators, int nSeparators);
~CSplitString();
CSplitString(const char *pString, const char *pSeparator, bool bIncludeSeparators = false)
{
Construct( pString, &pSeparator, 1, bIncludeSeparators);
}
CSplitString(const char *pString, const char **pSeparators, int nSeparators, bool bIncludeSeparators = false)
{
Construct(pString, pSeparators, nSeparators, bIncludeSeparators);
}
~CSplitString()
{
if (m_szBuffer)
delete[] m_szBuffer;
}
//
// NOTE: If you want to make Construct() public and implement Purge() here, you'll have to free m_szBuffer there
//
private:
void Construct(const char *pString, const char **pSeparators, int nSeparators);
void PurgeAndDeleteElements();
DLL_CLASS_IMPORT void Construct(const char *pString, const char **pSeparators, int nSeparators, bool bIncludeSeparators);
void PurgeAndDeleteElements()
{
Purge();
}
private:
char *m_szBuffer; // a copy of original string, with '\0' instead of separators
};

1611
tier1/keyvalues3.cpp Normal file

File diff suppressed because it is too large Load Diff