Implement CUtlMemory, CUtlBlockMemory and CUtlVector

CUtlMemory has been modified to fit the size of the in-engine structure.
The new types seem to be either int64 or unsigned (size_t?).
This commit is contained in:
Kawe Mazidjatari 2022-08-04 01:28:07 +02:00
parent 0fe554b3d1
commit 20d1fabd0c
13 changed files with 3317 additions and 11 deletions

8
r5dev/tier0/memalloc.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef TIER0_MEMALLOC_H
#define TIER0_MEMALLOC_H
#define MEM_ALLOC_CREDIT_CLASS()
#define MEM_ALLOC_CLASSNAME(type) NULL
#define MEM_ALLOC_CREDIT_FUNCTION()
#endif /* TIER0_MEMALLOC_H */

View File

@ -149,6 +149,30 @@
#endif // CROSS_PLATFORM_VERSION < 2
//-----------------------------------------------------------------------------
// Set up build configuration defines.
//-----------------------------------------------------------------------------
#ifdef _CERT
#define IsCert() 1
#else
#define IsCert() 0
#endif
#ifdef _DEBUG
#define IsRelease() 0
#define IsDebug() 1
#else
#define IsRelease() 1
#define IsDebug() 0
#endif
#ifdef _RETAIL
#define IsRetail() 1
#else
#define IsRetail() 0
#endif
#if defined( GNUC ) && !defined( COMPILER_PS3 ) // use pre-align on PS3
// gnuc has the align decoration at the end
#define ALIGN4
@ -156,6 +180,7 @@
#define ALIGN16
#define ALIGN32
#define ALIGN128
#define ALIGN_N( _align_ )
#undef ALIGN16_POST
#define ALIGN4_POST DECL_ALIGN(4)
@ -163,6 +188,7 @@
#define ALIGN16_POST DECL_ALIGN(16)
#define ALIGN32_POST DECL_ALIGN(32)
#define ALIGN128_POST DECL_ALIGN(128)
#define ALIGN_N_POST( _align_ ) DECL_ALIGN( _align_ )
#else
// MSVC has the align at the start of the struct
// PS3 SNC supports both
@ -171,14 +197,110 @@
#define ALIGN16 DECL_ALIGN(16)
#define ALIGN32 DECL_ALIGN(32)
#define ALIGN128 DECL_ALIGN(128)
#define ALIGN_N( _align_ ) DECL_ALIGN( _align_ )
#define ALIGN4_POST
#define ALIGN8_POST
#define ALIGN16_POST
#define ALIGN32_POST
#define ALIGN128_POST
#define ALIGN_N_POST( _align_ )
#endif
// !!! NOTE: if you get a compile error here, you are using VALIGNOF on an abstract type :NOTE !!!
#define VALIGNOF_PORTABLE( type ) ( sizeof( AlignOf_t<type> ) - sizeof( type ) )
#if defined( COMPILER_GCC ) || defined( COMPILER_MSVC )
#define VALIGNOF( type ) __alignof( type )
#define VALIGNOF_TEMPLATE_SAFE( type ) VALIGNOF_PORTABLE( type )
#else
#error "PORT: Code only tested with MSVC! Must validate with new compiler, and use built-in keyword if available."
#endif
// Use ValidateAlignment to sanity-check alignment usage when allocating arrays of an aligned type
#define ALIGN_ASSERT( pred ) { COMPILE_TIME_ASSERT( pred ); }
template< class T, int ALIGN >
inline void ValidateAlignmentExplicit(void)
{
// Alignment must be a power of two
ALIGN_ASSERT((ALIGN & (ALIGN - 1)) == 0);
// Alignment must not imply gaps in the array (which the CUtlMemory pattern does not allow for)
ALIGN_ASSERT(ALIGN <= sizeof(T));
// Alignment must be a multiple of the size of the object type, or elements will *NOT* be aligned!
ALIGN_ASSERT((sizeof(T) % ALIGN) == 0);
// Alignment should be a multiple of the base alignment of T
// ALIGN_ASSERT((ALIGN % VALIGNOF(T)) == 0);
}
template< class T > inline void ValidateAlignment(void) { ValidateAlignmentExplicit<T, VALIGNOF(T)>(); }
// Portable alternative to __alignof
template<class T> struct AlignOf_t { AlignOf_t() {} AlignOf_t& operator=(const AlignOf_t&) { return *this; } byte b; T t; };
template < size_t NUM, class T, int ALIGN > struct AlignedByteArrayExplicit_t {};
template < size_t NUM, class T > struct AlignedByteArray_t : public AlignedByteArrayExplicit_t< NUM, T, VALIGNOF_TEMPLATE_SAFE(T) > {};
#if defined(MSVC) && ( defined(_DEBUG) || defined(USE_MEM_DEBUG) )
#pragma warning(disable:4290)
#pragma warning(push)
#include <typeinfo.h>
// MEM_DEBUG_CLASSNAME is opt-in.
// Note: typeid().name() is not threadsafe, so if the project needs to access it in multiple threads
// simultaneously, it'll need a mutex.
#if defined(_CPPRTTI) && defined(MEM_DEBUG_CLASSNAME)
template <typename T> const char* MemAllocClassName(T* p)
{
static const char* pszName = typeid(*p).name(); // @TODO: support having debug heap ignore certain allocations, and ignore memory allocated here [5/7/2009 tom]
return pszName;
}
#define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( MemAllocClassName( this ) )
#define MEM_ALLOC_CLASSNAME(type) (typeid((type*)(0)).name())
#else
#define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( __FILE__ )
#define MEM_ALLOC_CLASSNAME(type) (__FILE__)
#endif
// MEM_ALLOC_CREDIT_FUNCTION is used when no this pointer is available ( inside 'new' overloads, for example )
#ifdef _MSC_VER
#define MEM_ALLOC_CREDIT_FUNCTION() MEM_ALLOC_CREDIT_( __FUNCTION__ )
#else
#define MEM_ALLOC_CREDIT_FUNCTION() (__FILE__)
#endif
#pragma warning(pop)
#else
#define MEM_ALLOC_CREDIT_CLASS()
#define MEM_ALLOC_CLASSNAME(type) NULL
#define MEM_ALLOC_CREDIT_FUNCTION()
#endif
//-----------------------------------------------------------------------------
// Macro to assist in asserting constant invariants during compilation
// This implementation of compile time assert has zero cost (so it can safely be
// included in release builds) and can be used at file scope or function scope.
#ifdef __GNUC__
#define COMPILE_TIME_ASSERT( pred ) typedef int UNIQUE_ID[ (pred) ? 1 : -1 ]
#else
#if _MSC_VER >= 1600
// If available use static_assert instead of weird language tricks. This
// leads to much more readable messages when compile time assert constraints
// are violated.
#define COMPILE_TIME_ASSERT( pred ) static_assert( pred, "Compile time assert constraint is not true: " #pred )
#else
// Due to gcc bugs this can in rare cases (some template functions) cause redeclaration
// errors when used multiple times in one scope. Fix by adding extra scoping.
#define COMPILE_TIME_ASSERT( pred ) typedef char compile_time_assert_type[(pred) ? 1 : -1];
#endif
#endif
// ASSERT_INVARIANT used to be needed in order to allow COMPILE_TIME_ASSERTs at global
// scope. However the new COMPILE_TIME_ASSERT macro supports that by default.
#define ASSERT_INVARIANT( pred ) COMPILE_TIME_ASSERT( pred )
// This can be used to declare an abstract (interface only) class.
// Classes marked abstract should not be instantiated. If they are, and access violation will occur.
//
@ -474,6 +596,123 @@ inline int64 CastPtrToInt64(const void* p)
#endif // BUILD_AS_DLL
//-----------------------------------------------------------------------------
// C++11 helpers
//-----------------------------------------------------------------------------
#define VALVE_CPP11 1
#if VALVE_CPP11
template <class T> struct C11RemoveReference { typedef T Type; };
template <class T> struct C11RemoveReference<T&> { typedef T Type; };
template <class T> struct C11RemoveReference<T&&> { typedef T Type; };
template <class T>
inline typename C11RemoveReference<T>::Type&& Move(T&& obj)
{
return static_cast<typename C11RemoveReference<T>::Type&&>(obj);
}
template <class T>
inline T&& Forward(typename C11RemoveReference<T>::Type& obj)
{
return static_cast<T&&>(obj);
}
template <class T>
inline T&& Forward(typename C11RemoveReference<T>::Type&& obj)
{
return static_cast<T&&>(obj);
}
#endif
//-----------------------------------------------------------------------------
// Methods to invoke the constructor, copy constructor, and destructor
//-----------------------------------------------------------------------------
template <class T>
inline T* Construct(T* pMemory)
{
return ::new(pMemory) T;
}
template <class T, typename ARG1>
inline T* Construct(T* pMemory, ARG1 a1)
{
return ::new(pMemory) T(a1);
}
template <class T, typename ARG1, typename ARG2>
inline T* Construct(T* pMemory, ARG1 a1, ARG2 a2)
{
return ::new(pMemory) T(a1, a2);
}
template <class T, typename ARG1, typename ARG2, typename ARG3>
inline T* Construct(T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3)
{
return ::new(pMemory) T(a1, a2, a3);
}
template <class T, typename ARG1, typename ARG2, typename ARG3, typename ARG4>
inline T* Construct(T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3, ARG4 a4)
{
return ::new(pMemory) T(a1, a2, a3, a4);
}
template <class T, typename ARG1, typename ARG2, typename ARG3, typename ARG4, typename ARG5>
inline T* Construct(T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3, ARG4 a4, ARG5 a5)
{
return ::new(pMemory) T(a1, a2, a3, a4, a5);
}
template <class T>
inline T* CopyConstruct(T* pMemory, T const& src)
{
return ::new(pMemory) T(src);
}
template <class T>
inline T* MoveConstruct(T* pMemory, T&& src)
{
return ::new(pMemory) T(Move(src));
}
// [will] - Fixing a clang compile: unable to create a pseudo-destructor (aka a destructor that does nothing) for float __attribute__((__vector_size__(16)))
// Fixed by specializing the Destroy function to not call destructor for that type.
#if defined( __clang__ ) || defined (LINUX)
template <class T>
inline void Destruct(T* pMemory);
template <>
inline void Destruct(float __attribute__((__vector_size__(16)))* pMemory);
#endif // __clang__
template <class T>
inline void Destruct(T* pMemory)
{
pMemory->~T();
#ifdef _DEBUG
memset(pMemory, 0xDD, sizeof(T));
#endif
}
// [will] - Fixing a clang compile: unable to create a pseudo-destructor (aka a destructor that does nothing) for float __attribute__((__vector_size__(16)))
// Fixed by specializing the Destroy function to not call destructor for that type.
#if defined( __clang__ ) || defined (LINUX)
template <>
inline void Destruct(float __attribute__((__vector_size__(16)))* pMemory)
{
#ifdef _DEBUG
memset(pMemory, 0xDD, sizeof(float __attribute__((__vector_size__(16)))));
#endif
}
#endif // __clang__
//-----------------------------------------------------------------------------
// Processor Information:
//-----------------------------------------------------------------------------

View File

@ -13,6 +13,7 @@
#include "vstdlib/callback.h"
#include "public/include/iconvar.h"
#include "public/include/iconcommand.h"
#include <tier1/utlvector.h>
//-----------------------------------------------------------------------------
// Purpose: construct/allocate

103
r5dev/tier1/splitstring.cpp Normal file
View File

@ -0,0 +1,103 @@
//================ Copyright (c) 1996-2009 Valve Corporation. All Rights Reserved. =================
//
//
//
//==================================================================================================
#include "core/stdafx.h"
#include "strtools.h"
#include "utlvector.h"
CSplitString::CSplitString()
{
m_szBuffer = nullptr;
}
CSplitString::CSplitString(const char* pString, const char** pSeparators, int nSeparators)
{
Construct(pString, pSeparators, nSeparators);
};
CSplitString::CSplitString(const char* pString, const char* pSeparator)
{
Construct(pString, &pSeparator, 1);
}
CSplitString::~CSplitString()
{
if (m_szBuffer)
delete[] m_szBuffer;
}
void CSplitString::Set(const char* pString, const char** pSeparators, int nSeparators)
{
delete[] m_szBuffer;
Construct(pString, pSeparators, nSeparators);
}
void CSplitString::Construct(const char* pString, const char** pSeparators, int nSeparators)
{
//////////////////////////////////////////////////////////////////////////
// make a duplicate of the original string. We'll use pieces of this duplicate to tokenize the string
// and create NULL-terminated tokens of the original string
//
int nOriginalStringLength = strlen(pString);
m_szBuffer = new char[nOriginalStringLength + 1];
memcpy(m_szBuffer, pString, nOriginalStringLength + 1);
this->Purge();
const char* pCurPos = pString;
while (1)
{
int iFirstSeparator = -1;
const char* pFirstSeparator = 0;
for (int i = 0; i < nSeparators; i++)
{
const char* pTest = strstr(pCurPos, pSeparators[i]);
if (pTest && (!pFirstSeparator || pTest < pFirstSeparator))
{
iFirstSeparator = i;
pFirstSeparator = pTest;
}
}
if (pFirstSeparator)
{
// Split on this separator and continue on.
int separatorLen = strlen(pSeparators[iFirstSeparator]);
if (pFirstSeparator > pCurPos)
{
//////////////////////////////////////////////////////////////////////////
/// Cut the token out of the duplicate string
char* pTokenInDuplicate = m_szBuffer + (pCurPos - pString);
int nTokenLength = pFirstSeparator - pCurPos;
//Assert(nTokenLength > 0 && !memcmp(pTokenInDuplicate, pCurPos, nTokenLength));
pTokenInDuplicate[nTokenLength] = '\0';
this->AddToTail(pTokenInDuplicate /*AllocString( pCurPos, pFirstSeparator-pCurPos )*/);
}
pCurPos = pFirstSeparator + separatorLen;
}
else
{
// Copy the rest of the string
if (int nTokenLength = strlen(pCurPos))
{
//////////////////////////////////////////////////////////////////////////
// There's no need to cut this token, because there's no separator after it.
// just add its copy in the buffer to the tail
char* pTokenInDuplicate = m_szBuffer + (pCurPos - pString);
//Assert(!memcmp(pTokenInDuplicate, pCurPos, nTokenLength));
this->AddToTail(pTokenInDuplicate/*AllocString( pCurPos, -1 )*/);
}
return;
}
}
}
void CSplitString::PurgeAndDeleteElements()
{
Purge();
}

View File

@ -0,0 +1,349 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
// A growable memory class.
//===========================================================================//
#ifndef UTLBLOCKMEMORY_H
#define UTLBLOCKMEMORY_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/dbg.h"
#include "tier0/platform.h"
#include "mathlib/mathlib.h"
//#include "tier0/memalloc.h"
//#include "tier0/memdbgon.h"
#pragma warning (disable:4100)
#pragma warning (disable:4514)
//-----------------------------------------------------------------------------
#ifdef UTBLOCKLMEMORY_TRACK
#define UTLBLOCKMEMORY_TRACK_ALLOC() MemAlloc_RegisterAllocation( "||Sum of all UtlBlockMemory||", 0, NumAllocated() * sizeof(T), NumAllocated() * sizeof(T), 0 )
#define UTLBLOCKMEMORY_TRACK_FREE() if ( !m_pMemory ) ; else MemAlloc_RegisterDeallocation( "||Sum of all UtlBlockMemory||", 0, NumAllocated() * sizeof(T), NumAllocated() * sizeof(T), 0 )
#else
#define UTLBLOCKMEMORY_TRACK_ALLOC() ((void)0)
#define UTLBLOCKMEMORY_TRACK_FREE() ((void)0)
#endif
//-----------------------------------------------------------------------------
// The CUtlBlockMemory class:
// A growable memory class that allocates non-sequential blocks, but is indexed sequentially
//-----------------------------------------------------------------------------
template< class T, class I >
class CUtlBlockMemory
{
public:
// constructor, destructor
CUtlBlockMemory(int nGrowSize = 0, int nInitSize = 0);
~CUtlBlockMemory();
// Set the size by which the memory grows - round up to the next power of 2
void Init(int nGrowSize = 0, int nInitSize = 0);
// here to match CUtlMemory, but only used by ResetDbgInfo, so it can just return NULL
T* Base() { return NULL; }
const T* Base() const { return NULL; }
class Iterator_t
{
public:
Iterator_t(I i) : index(i) {}
I index;
bool operator==(const Iterator_t it) const { return index == it.index; }
bool operator!=(const Iterator_t it) const { return index != it.index; }
};
Iterator_t First() const { return Iterator_t(IsIdxValid(0) ? 0 : InvalidIndex()); }
Iterator_t Next(const Iterator_t& it) const { return Iterator_t(IsIdxValid(it.index + 1) ? it.index + 1 : InvalidIndex()); }
I GetIndex(const Iterator_t& it) const { return it.index; }
bool IsIdxAfter(I i, const Iterator_t& it) const { return i > it.index; }
bool IsValidIterator(const Iterator_t& it) const { return IsIdxValid(it.index); }
Iterator_t InvalidIterator() const { return Iterator_t(InvalidIndex()); }
// element access
T& operator[](I i);
const T& operator[](I i) const;
T& Element(I i);
const T& Element(I i) const;
// Can we use this index?
bool IsIdxValid(I i) const;
static I InvalidIndex() { return (I)-1; }
void Swap(CUtlBlockMemory< T, I >& mem);
// Size
int NumAllocated() const;
int Count() const { return NumAllocated(); }
// Grows memory by max(num,growsize) rounded up to the next power of 2, and returns the allocation index/ptr
void Grow(int num = 1);
// Makes sure we've got at least this much memory
void EnsureCapacity(int num);
// Memory deallocation
void Purge();
// Purge all but the given number of elements
void Purge(int numElements);
protected:
int Index(int major, int minor) const { return (major << m_nIndexShift) | minor; }
int MajorIndex(int i) const { return i >> m_nIndexShift; }
int MinorIndex(int i) const { return i & m_nIndexMask; }
void ChangeSize(int nBlocks);
int NumElementsInBlock() const { return m_nIndexMask + 1; }
T** m_pMemory;
int m_nBlocks;
int m_nIndexMask : 27;
int m_nIndexShift : 5;
};
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
template< class T, class I >
CUtlBlockMemory<T, I>::CUtlBlockMemory(int nGrowSize, int nInitAllocationCount)
: m_pMemory(0), m_nBlocks(0), m_nIndexMask(0), m_nIndexShift(0)
{
Init(nGrowSize, nInitAllocationCount);
}
template< class T, class I >
CUtlBlockMemory<T, I>::~CUtlBlockMemory()
{
Purge();
}
//-----------------------------------------------------------------------------
// Fast swap
//-----------------------------------------------------------------------------
template< class T, class I >
void CUtlBlockMemory<T, I>::Swap(CUtlBlockMemory< T, I >& mem)
{
V_swap(m_pMemory, mem.m_pMemory);
V_swap(m_nBlocks, mem.m_nBlocks);
V_swap(m_nIndexMask, mem.m_nIndexMask);
V_swap(m_nIndexShift, mem.m_nIndexShift);
}
//-----------------------------------------------------------------------------
// Set the size by which the memory grows - round up to the next power of 2
//-----------------------------------------------------------------------------
template< class T, class I >
void CUtlBlockMemory<T, I>::Init(int nGrowSize /* = 0 */, int nInitSize /* = 0 */)
{
Purge();
if (nGrowSize == 0)
{
// default grow size is smallest size s.t. c++ allocation overhead is ~6% of block size
nGrowSize = (127 + sizeof(T)) / sizeof(T);
}
nGrowSize = SmallestPowerOfTwoGreaterOrEqual(nGrowSize);
m_nIndexMask = nGrowSize - 1;
m_nIndexShift = 0;
while (nGrowSize > 1)
{
nGrowSize >>= 1;
++m_nIndexShift;
}
Assert(m_nIndexMask + 1 == (1 << m_nIndexShift));
Grow(nInitSize);
}
//-----------------------------------------------------------------------------
// element access
//-----------------------------------------------------------------------------
template< class T, class I >
inline T& CUtlBlockMemory<T, I>::operator[](I i)
{
Assert(IsIdxValid(i));
T* pBlock = m_pMemory[MajorIndex(i)];
return pBlock[MinorIndex(i)];
}
template< class T, class I >
inline const T& CUtlBlockMemory<T, I>::operator[](I i) const
{
Assert(IsIdxValid(i));
const T* pBlock = m_pMemory[MajorIndex(i)];
return pBlock[MinorIndex(i)];
}
template< class T, class I >
inline T& CUtlBlockMemory<T, I>::Element(I i)
{
Assert(IsIdxValid(i));
T* pBlock = m_pMemory[MajorIndex(i)];
return pBlock[MinorIndex(i)];
}
template< class T, class I >
inline const T& CUtlBlockMemory<T, I>::Element(I i) const
{
Assert(IsIdxValid(i));
const T* pBlock = m_pMemory[MajorIndex(i)];
return pBlock[MinorIndex(i)];
}
//-----------------------------------------------------------------------------
// Size
//-----------------------------------------------------------------------------
template< class T, class I >
inline int CUtlBlockMemory<T, I>::NumAllocated() const
{
return m_nBlocks * NumElementsInBlock();
}
//-----------------------------------------------------------------------------
// Is element index valid?
//-----------------------------------------------------------------------------
template< class T, class I >
inline bool CUtlBlockMemory<T, I>::IsIdxValid(I i) const
{
return (i >= 0) && (MajorIndex(i) < m_nBlocks);
}
template< class T, class I >
void CUtlBlockMemory<T, I>::Grow(int num)
{
if (num <= 0)
return;
int nBlockSize = NumElementsInBlock();
int nBlocks = (num + nBlockSize - 1) / nBlockSize;
ChangeSize(m_nBlocks + nBlocks);
}
template< class T, class I >
void CUtlBlockMemory<T, I>::ChangeSize(int nBlocks)
{
UTLBLOCKMEMORY_TRACK_FREE(); // this must stay before the recalculation of m_nBlocks, since it implicitly uses the old value
int nBlocksOld = m_nBlocks;
m_nBlocks = nBlocks;
UTLBLOCKMEMORY_TRACK_ALLOC(); // this must stay after the recalculation of m_nBlocks, since it implicitly uses the new value
// free old blocks if shrinking
for (int i = m_nBlocks; i < nBlocksOld; ++i)
{
UTLBLOCKMEMORY_TRACK_FREE();
free((void*)m_pMemory[i]);
}
if (m_pMemory)
{
MEM_ALLOC_CREDIT_CLASS();
m_pMemory = (T**)realloc(m_pMemory, m_nBlocks * sizeof(T*));
Assert(m_pMemory);
}
else
{
MEM_ALLOC_CREDIT_CLASS();
m_pMemory = (T**)malloc(m_nBlocks * sizeof(T*));
Assert(m_pMemory);
}
if (!m_pMemory)
{
Error(eDLL_T::COMMON, "CUtlBlockMemory overflow!\n");
}
// allocate new blocks if growing
int nBlockSize = NumElementsInBlock();
for (int i = nBlocksOld; i < m_nBlocks; ++i)
{
MEM_ALLOC_CREDIT_CLASS();
m_pMemory[i] = (T*)malloc(nBlockSize * sizeof(T));
Assert(m_pMemory[i]);
}
}
//-----------------------------------------------------------------------------
// Makes sure we've got at least this much memory
//-----------------------------------------------------------------------------
template< class T, class I >
inline void CUtlBlockMemory<T, I>::EnsureCapacity(int num)
{
Grow(num - NumAllocated());
}
//-----------------------------------------------------------------------------
// Memory deallocation
//-----------------------------------------------------------------------------
template< class T, class I >
void CUtlBlockMemory<T, I>::Purge()
{
if (!m_pMemory)
return;
for (int i = 0; i < m_nBlocks; ++i)
{
UTLBLOCKMEMORY_TRACK_FREE();
free((void*)m_pMemory[i]);
}
m_nBlocks = 0;
UTLBLOCKMEMORY_TRACK_FREE();
free((void*)m_pMemory);
m_pMemory = 0;
}
template< class T, class I >
void CUtlBlockMemory<T, I>::Purge(int numElements)
{
Assert(numElements >= 0);
int nAllocated = NumAllocated();
if (numElements > nAllocated)
{
// Ensure this isn't a grow request in disguise.
Assert(numElements <= nAllocated);
return;
}
if (numElements <= 0)
{
Purge();
return;
}
int nBlockSize = NumElementsInBlock();
int nBlocksOld = m_nBlocks;
int nBlocks = (numElements + nBlockSize - 1) / nBlockSize;
// If the number of blocks is the same as the allocated number of blocks, we are done.
if (nBlocks == m_nBlocks)
return;
ChangeSize(nBlocks);
}
//#include "tier0/memdbgoff.h"
#endif // UTLBLOCKMEMORY_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -113,6 +113,7 @@
<ClCompile Include="..\tier1\cvar.cpp" />
<ClCompile Include="..\tier1\IConVar.cpp" />
<ClCompile Include="..\tier1\NetAdr2.cpp" />
<ClCompile Include="..\tier1\splitstring.cpp" />
<ClCompile Include="..\tier1\strtools.cpp" />
<ClCompile Include="..\tier2\meshutils.cpp" />
<ClCompile Include="..\tier2\renderutils.cpp" />
@ -462,6 +463,7 @@
<ClInclude Include="..\tier0\fasttimer.h" />
<ClInclude Include="..\tier0\interface.h" />
<ClInclude Include="..\tier0\jobthread.h" />
<ClInclude Include="..\tier0\memalloc.h" />
<ClInclude Include="..\tier0\memstd.h" />
<ClInclude Include="..\tier0\platform.h" />
<ClInclude Include="..\tier0\platform_internal.h" />
@ -478,6 +480,7 @@
<ClInclude Include="..\tier1\mempool.h" />
<ClInclude Include="..\tier1\NetAdr2.h" />
<ClInclude Include="..\tier1\strtools.h" />
<ClInclude Include="..\tier1\utlblockmemory.h" />
<ClInclude Include="..\tier1\utldict.h" />
<ClInclude Include="..\tier1\utlmemory.h" />
<ClInclude Include="..\tier1\utlvector.h" />

View File

@ -564,6 +564,9 @@
<ClCompile Include="..\tier1\characterset.cpp">
<Filter>sdk\tier1</Filter>
</ClCompile>
<ClCompile Include="..\tier1\splitstring.cpp">
<Filter>sdk\tier1</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\client\cdll_engine_int.h">
@ -1664,6 +1667,12 @@
<ClInclude Include="..\public\include\icliententitylist.h">
<Filter>sdk\public\include</Filter>
</ClInclude>
<ClInclude Include="..\tier1\utlblockmemory.h">
<Filter>sdk\tier1</Filter>
</ClInclude>
<ClInclude Include="..\tier0\memalloc.h">
<Filter>sdk\tier0</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="..\shared\resource\lockedserver.png">

View File

@ -423,6 +423,7 @@
<ClInclude Include="..\tier0\fasttimer.h" />
<ClInclude Include="..\tier0\interface.h" />
<ClInclude Include="..\tier0\jobthread.h" />
<ClInclude Include="..\tier0\memalloc.h" />
<ClInclude Include="..\tier0\memstd.h" />
<ClInclude Include="..\tier0\platform.h" />
<ClInclude Include="..\tier0\platform_internal.h" />
@ -439,6 +440,7 @@
<ClInclude Include="..\tier1\mempool.h" />
<ClInclude Include="..\tier1\NetAdr2.h" />
<ClInclude Include="..\tier1\strtools.h" />
<ClInclude Include="..\tier1\utlblockmemory.h" />
<ClInclude Include="..\tier1\utldict.h" />
<ClInclude Include="..\tier1\utlmemory.h" />
<ClInclude Include="..\tier1\utlvector.h" />
@ -552,6 +554,7 @@
<ClCompile Include="..\tier1\cvar.cpp" />
<ClCompile Include="..\tier1\IConVar.cpp" />
<ClCompile Include="..\tier1\NetAdr2.cpp" />
<ClCompile Include="..\tier1\splitstring.cpp" />
<ClCompile Include="..\tier1\strtools.cpp" />
<ClCompile Include="..\tier2\socketcreator.cpp" />
<ClCompile Include="..\vpc\IAppSystem.cpp" />

View File

@ -1191,6 +1191,12 @@
<ClInclude Include="..\public\include\worldsize.h">
<Filter>sdk\public\include</Filter>
</ClInclude>
<ClInclude Include="..\tier1\utlblockmemory.h">
<Filter>sdk\tier1</Filter>
</ClInclude>
<ClInclude Include="..\tier0\memalloc.h">
<Filter>sdk\tier0</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\common\opcodes.cpp">
@ -1493,6 +1499,9 @@
<ClCompile Include="..\tier1\characterset.cpp">
<Filter>sdk\tier1</Filter>
</ClCompile>
<ClCompile Include="..\tier1\splitstring.cpp">
<Filter>sdk\tier1</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\Dedicated.def" />

View File

@ -123,6 +123,7 @@
<ClCompile Include="..\tier1\cvar.cpp" />
<ClCompile Include="..\tier1\IConVar.cpp" />
<ClCompile Include="..\tier1\NetAdr2.cpp" />
<ClCompile Include="..\tier1\splitstring.cpp" />
<ClCompile Include="..\tier1\strtools.cpp" />
<ClCompile Include="..\tier2\meshutils.cpp" />
<ClCompile Include="..\tier2\renderutils.cpp" />
@ -489,6 +490,7 @@
<ClInclude Include="..\tier0\dbgflag.h" />
<ClInclude Include="..\tier0\fasttimer.h" />
<ClInclude Include="..\tier0\jobthread.h" />
<ClInclude Include="..\tier0\memalloc.h" />
<ClInclude Include="..\tier0\memstd.h" />
<ClInclude Include="..\tier0\platform.h" />
<ClInclude Include="..\tier0\platform_internal.h" />
@ -505,6 +507,7 @@
<ClInclude Include="..\tier1\mempool.h" />
<ClInclude Include="..\tier1\NetAdr2.h" />
<ClInclude Include="..\tier1\strtools.h" />
<ClInclude Include="..\tier1\utlblockmemory.h" />
<ClInclude Include="..\tier1\utldict.h" />
<ClInclude Include="..\tier1\utlmemory.h" />
<ClInclude Include="..\tier1\utlvector.h" />

View File

@ -603,6 +603,9 @@
<ClCompile Include="..\tier1\characterset.cpp">
<Filter>sdk\tier1</Filter>
</ClCompile>
<ClCompile Include="..\tier1\splitstring.cpp">
<Filter>sdk\tier1</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\client\cdll_engine_int.h">
@ -1754,6 +1757,12 @@
<ClInclude Include="..\public\include\worldsize.h">
<Filter>sdk\public\include</Filter>
</ClInclude>
<ClInclude Include="..\tier1\utlblockmemory.h">
<Filter>sdk\tier1</Filter>
</ClInclude>
<ClInclude Include="..\tier0\memalloc.h">
<Filter>sdk\tier0</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="..\shared\resource\lockedserver.png">