aboutsummaryrefslogtreecommitdiff
path: root/mp/src/public/tier1
diff options
context:
space:
mode:
authorJoe Ludwig <[email protected]>2014-05-15 13:59:18 -0700
committerJoe Ludwig <[email protected]>2014-05-15 13:59:18 -0700
commit53e78c503e6e9c7d15e2eefc480755fe37dd7077 (patch)
treec8cc106eb4c0a2b2b5d79f534f2facb0514f5f55 /mp/src/public/tier1
parentAdded many shader source files (diff)
downloadsource-sdk-2013-53e78c503e6e9c7d15e2eefc480755fe37dd7077.tar.xz
source-sdk-2013-53e78c503e6e9c7d15e2eefc480755fe37dd7077.zip
General:
* Upgraded Steamworks SDK to v1.29 * Fixed mod compatibility problem with Multiplayer Base that was introduced in September. * In Hammer, while using the Vertex Tool, pressing CTRL+B will snap selected vertices to the grid. Virtual Reality: * Mods that support virtual reality now need to have a line in gameinfo.txt that says “supportsvr 1”. This indicates to gameui and engine that certain UI should be enabled. * VR-enabled mods will now start up in VR mode when launched from Steam’s VR mode. Windows: * Upgraded to Visual Studio 2013. If you need to build projects for VS 2010, add /2010 to your VPC command line. OSX: * Upgraded to XCode 5.
Diffstat (limited to 'mp/src/public/tier1')
-rw-r--r--mp/src/public/tier1/UtlSortVector.h126
-rw-r--r--mp/src/public/tier1/convar.h6
-rw-r--r--mp/src/public/tier1/fmtstr.h95
-rw-r--r--mp/src/public/tier1/mempool.h22
-rw-r--r--mp/src/public/tier1/strtools.h23
-rw-r--r--mp/src/public/tier1/utlblockmemory.h15
-rw-r--r--mp/src/public/tier1/utlpair.h52
-rw-r--r--mp/src/public/tier1/utlstring.h1
-rw-r--r--mp/src/public/tier1/utlvector.h6
9 files changed, 291 insertions, 55 deletions
diff --git a/mp/src/public/tier1/UtlSortVector.h b/mp/src/public/tier1/UtlSortVector.h
index 76026925..b5bfef53 100644
--- a/mp/src/public/tier1/UtlSortVector.h
+++ b/mp/src/public/tier1/UtlSortVector.h
@@ -1,4 +1,4 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
+//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
//
// $Header: $
// $NoKeywords: $
@@ -45,31 +45,49 @@ public:
template <class T, class LessFunc = CUtlSortVectorDefaultLess<T>, class BaseVector = CUtlVector<T> >
class CUtlSortVector : public BaseVector
{
+ typedef BaseVector BaseClass;
public:
-
- // constructor
+ /// constructor
CUtlSortVector( int nGrowSize = 0, int initSize = 0 );
CUtlSortVector( T* pMemory, int numElements );
- // inserts (copy constructs) an element in sorted order into the list
+ /// inserts (copy constructs) an element in sorted order into the list
int Insert( const T& src );
- // Finds an element within the list using a binary search
- int Find( const T& search ) const;
- int FindLessOrEqual( const T& search ) const;
- int FindLess( const T& search ) const;
+ /// inserts (copy constructs) an element in sorted order into the list if it isn't already in the list
+ int InsertIfNotFound( const T& src );
+
+ /// Finds an element within the list using a binary search. These are templatized based upon the key
+ /// in which case the less function must handle the Less function for key, T and T, key
+ template< typename TKey >
+ int Find( const TKey& search ) const;
+ template< typename TKey >
+ int FindLessOrEqual( const TKey& search ) const;
+ template< typename TKey >
+ int FindLess( const TKey& search ) const;
- // Removes a particular element
+ /// Removes a particular element
void Remove( const T& search );
void Remove( int i );
- // Allows methods to set a context to be used with the less function..
+ /// Allows methods to set a context to be used with the less function..
void SetLessContext( void *pCtx );
- // Note that you can only use this index until sorting is redone!!!
+ /// A version of insertion that will produce an un-ordered list.
+ /// Note that you can only use this index until sorting is redone with RedoSort!!!
int InsertNoSort( const T& src );
void RedoSort( bool bForceSort = false );
+ /// Use this to insert at a specific insertion point; using FindLessOrEqual
+ /// is required for use this this. This will test that what you've inserted
+ /// produces a correctly ordered list.
+ int InsertAfter( int nElemIndex, const T &src );
+
+ /// finds a particular element using a linear search. Useful when used
+ /// in between calls to InsertNoSort and RedoSort
+ template< typename TKey >
+ int FindUnsorted( const TKey &src ) const;
+
protected:
// No copy constructor
CUtlSortVector( const CUtlSortVector<T, LessFunc> & );
@@ -79,10 +97,9 @@ protected:
int AddToTail();
int InsertBefore( int elem );
int InsertAfter( int elem );
+ int InsertBefore( int elem, const T& src );
int AddToHead( const T& src );
int AddToTail( const T& src );
- int InsertBefore( int elem, const T& src );
- int InsertAfter( int elem, const T& src );
int AddMultipleToHead( int num );
int AddMultipleToTail( int num, const T *pToCopy=NULL );
int InsertMultipleBefore( int elem, int num, const T *pToCopy=NULL );
@@ -121,6 +138,10 @@ protected:
bool m_bNeedsSort;
private:
+private:
+ template< typename TKey >
+ int FindLessOrEqual( const TKey& search, bool *pFound ) const;
+
void QuickSort( LessFunc& less, int X, int I );
};
@@ -176,6 +197,43 @@ int CUtlSortVector<T, LessFunc, BaseVector>::InsertNoSort( const T& src )
return lastElement;
}
+/// inserts (copy constructs) an element in sorted order into the list if it isn't already in the list
+template <class T, class LessFunc, class BaseVector>
+int CUtlSortVector<T, LessFunc, BaseVector>::InsertIfNotFound( const T& src )
+{
+ AssertFatal( !m_bNeedsSort );
+ bool bFound;
+ int pos = FindLessOrEqual( src, &bFound );
+ if ( bFound )
+ return pos;
+
+ ++pos;
+ this->GrowVector();
+ this->ShiftElementsRight(pos);
+ CopyConstruct<T>( &this->Element(pos), src );
+ return pos;
+}
+
+template <class T, class LessFunc, class BaseVector>
+int CUtlSortVector<T, LessFunc, BaseVector>::InsertAfter( int nIndex, const T &src )
+{
+ int nInsertedIndex = this->BaseClass::InsertAfter( nIndex, src );
+
+#ifdef DEBUG
+ LessFunc less;
+ if ( nInsertedIndex > 0 )
+ {
+ Assert( less.Less( this->Element(nInsertedIndex-1), src, m_pLessContext ) );
+ }
+ if ( nInsertedIndex < BaseClass::Count()-1 )
+ {
+ Assert( less.Less( src, this->Element(nInsertedIndex+1), m_pLessContext ) );
+ }
+#endif
+ return nInsertedIndex;
+}
+
+
template <class T, class LessFunc, class BaseVector>
void CUtlSortVector<T, LessFunc, BaseVector>::QuickSort( LessFunc& less, int nLower, int nUpper )
{
@@ -218,7 +276,8 @@ void CUtlSortVector<T, LessFunc, BaseVector>::RedoSort( bool bForceSort /*= fals
// finds a particular element
//-----------------------------------------------------------------------------
template <class T, class LessFunc, class BaseVector>
-int CUtlSortVector<T, LessFunc, BaseVector>::Find( const T& src ) const
+template < typename TKey >
+int CUtlSortVector<T, LessFunc, BaseVector>::Find( const TKey& src ) const
{
AssertFatal( !m_bNeedsSort );
@@ -246,10 +305,33 @@ int CUtlSortVector<T, LessFunc, BaseVector>::Find( const T& src ) const
//-----------------------------------------------------------------------------
+// finds a particular element using a linear search. Useful when used
+// in between calls to InsertNoSort and RedoSort
+//-----------------------------------------------------------------------------
+template< class T, class LessFunc, class BaseVector >
+template < typename TKey >
+int CUtlSortVector<T, LessFunc, BaseVector>::FindUnsorted( const TKey &src ) const
+{
+ LessFunc less;
+ int nCount = this->Count();
+ for ( int i = 0; i < nCount; ++i )
+ {
+ if ( less.Less( this->Element(i), src, m_pLessContext ) )
+ continue;
+ if ( less.Less( src, this->Element(i), m_pLessContext ) )
+ continue;
+ return i;
+ }
+ return -1;
+}
+
+
+//-----------------------------------------------------------------------------
// finds a particular element
//-----------------------------------------------------------------------------
template <class T, class LessFunc, class BaseVector>
-int CUtlSortVector<T, LessFunc, BaseVector>::FindLessOrEqual( const T& src ) const
+template < typename TKey >
+int CUtlSortVector<T, LessFunc, BaseVector>::FindLessOrEqual( const TKey& src, bool *pFound ) const
{
AssertFatal( !m_bNeedsSort );
@@ -268,14 +350,26 @@ int CUtlSortVector<T, LessFunc, BaseVector>::FindLessOrEqual( const T& src ) con
}
else
{
+ *pFound = true;
return mid;
}
}
+
+ *pFound = false;
return end;
}
template <class T, class LessFunc, class BaseVector>
-int CUtlSortVector<T, LessFunc, BaseVector>::FindLess( const T& src ) const
+template < typename TKey >
+int CUtlSortVector<T, LessFunc, BaseVector>::FindLessOrEqual( const TKey& src ) const
+{
+ bool bFound;
+ return FindLessOrEqual( src, &bFound );
+}
+
+template <class T, class LessFunc, class BaseVector>
+template < typename TKey >
+int CUtlSortVector<T, LessFunc, BaseVector>::FindLess( const TKey& src ) const
{
AssertFatal( !m_bNeedsSort );
diff --git a/mp/src/public/tier1/convar.h b/mp/src/public/tier1/convar.h
index 2174e1f9..4bff787e 100644
--- a/mp/src/public/tier1/convar.h
+++ b/mp/src/public/tier1/convar.h
@@ -66,7 +66,7 @@ void ConVar_PublishToVXConsole();
//-----------------------------------------------------------------------------
// Called when a ConCommand needs to execute
//-----------------------------------------------------------------------------
-typedef void ( *FnCommandCallbackV1_t )( void );
+typedef void ( *FnCommandCallbackVoid_t )( void );
typedef void ( *FnCommandCallback_t )( const CCommand &command );
#define COMMAND_COMPLETION_MAXITEMS 64
@@ -265,7 +265,7 @@ friend class CCvar;
public:
typedef ConCommandBase BaseClass;
- ConCommand( const char *pName, FnCommandCallbackV1_t callback,
+ ConCommand( const char *pName, FnCommandCallbackVoid_t callback,
const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
ConCommand( const char *pName, FnCommandCallback_t callback,
const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
@@ -295,7 +295,7 @@ private:
// Call this function when executing the command
union
{
- FnCommandCallbackV1_t m_fnCommandCallbackV1;
+ FnCommandCallbackVoid_t m_fnCommandCallbackV1;
FnCommandCallback_t m_fnCommandCallback;
ICommandCallback *m_pCommandCallback;
};
diff --git a/mp/src/public/tier1/fmtstr.h b/mp/src/public/tier1/fmtstr.h
index 31ee23c7..556fc130 100644
--- a/mp/src/public/tier1/fmtstr.h
+++ b/mp/src/public/tier1/fmtstr.h
@@ -31,28 +31,52 @@
int result; \
va_list arg_ptr; \
bool bTruncated = false; \
- static unsigned int scAsserted = 0; \
+ static int scAsserted = 0; \
\
va_start(arg_ptr, lastArg); \
- result = Q_vsnprintfRet( (szBuf), nBufSize, (*(ppszFormat)), arg_ptr, &bTruncated ); \
+ result = V_vsnprintfRet( (szBuf), (nBufSize)-1, (*(ppszFormat)), arg_ptr, &bTruncated ); \
va_end(arg_ptr); \
\
+ (szBuf)[(nBufSize)-1] = 0; \
if ( bTruncated && !(bQuietTruncation) && scAsserted < 5 ) \
{ \
- Assert( !bTruncated ); \
+ Warning( "FmtStrVSNPrintf truncated to %d without QUIET_TRUNCATION specified!\n", ( int )( nBufSize ) ); \
+ AssertMsg( 0, "FmtStrVSNPrintf truncated without QUIET_TRUNCATION specified!\n" ); \
scAsserted++; \
} \
m_nLength = nPrevLen + result; \
} \
while (0)
+// using macro to be compatable with GCC
+#define FmtStrVSNPrintfNoLengthFixup( szBuf, nBufSize, bQuietTruncation, ppszFormat, nPrevLen, lastArg ) \
+ do \
+ { \
+ int result; \
+ va_list arg_ptr; \
+ bool bTruncated = false; \
+ static int scAsserted = 0; \
+ \
+ va_start(arg_ptr, lastArg); \
+ result = V_vsnprintfRet( (szBuf), (nBufSize)-1, (*(ppszFormat)), arg_ptr, &bTruncated ); \
+ va_end(arg_ptr); \
+ \
+ (szBuf)[(nBufSize)-1] = 0; \
+ if ( bTruncated && !(bQuietTruncation) && scAsserted < 5 ) \
+ { \
+ Warning( "FmtStrVSNPrintf truncated to %d without QUIET_TRUNCATION specified!\n", ( int )( nBufSize ) ); \
+ AssertMsg( 0, "FmtStrVSNPrintf truncated without QUIET_TRUNCATION specified!\n" ); \
+ scAsserted++; \
+ } \
+ } \
+ while (0)
//-----------------------------------------------------------------------------
//
// Purpose: String formatter with specified size
//
-template <int SIZE_BUF>
+template <int SIZE_BUF, bool QUIET_TRUNCATION = false >
class CFmtStrN
{
public:
@@ -80,14 +104,36 @@ public:
// Explicit reformat
const char *sprintf(PRINTF_FORMAT_STRING const char *pszFormat, ...) FMTFUNCTION( 2, 3 )
{
- FmtStrVSNPrintf( m_szBuf, SIZE_BUF, m_bQuietTruncation, &pszFormat, 0, pszFormat );
+ InitQuietTruncation();
+ FmtStrVSNPrintf(m_szBuf, SIZE_BUF, m_bQuietTruncation, &pszFormat, 0, pszFormat );
+ return m_szBuf;
+ }
+
+ // Use this for va_list formatting
+ const char *sprintf_argv(const char *pszFormat, va_list arg_ptr)
+ {
+ int result;
+ bool bTruncated = false;
+ static int s_nWarned = 0;
+
+ InitQuietTruncation();
+ result = V_vsnprintfRet( m_szBuf, SIZE_BUF - 1, pszFormat, arg_ptr, &bTruncated );
+ m_szBuf[SIZE_BUF - 1] = 0;
+ if ( bTruncated && !m_bQuietTruncation && ( s_nWarned < 5 ) )
+ {
+ Warning( "CFmtStr truncated to %d without QUIET_TRUNCATION specified!\n", SIZE_BUF );
+ AssertMsg( 0, "CFmtStr truncated without QUIET_TRUNCATION specified!\n" );
+ s_nWarned++;
+ }
+ m_nLength = V_strlen( m_szBuf );
return m_szBuf;
}
// Use this for pass-through formatting
void VSprintf(const char **ppszFormat, ...)
{
- FmtStrVSNPrintf( m_szBuf, SIZE_BUF, m_bQuietTruncation, ppszFormat, 0, ppszFormat);
+ InitQuietTruncation();
+ FmtStrVSNPrintf( m_szBuf, SIZE_BUF, m_bQuietTruncation, ppszFormat, 0, ppszFormat );
}
// Compatible API with CUtlString for converting to const char*
@@ -97,14 +143,17 @@ public:
operator const char *() const { return m_szBuf; }
char *Access() { return m_szBuf; }
- CFmtStrN<SIZE_BUF> & operator=( const char *pchValue )
+ // Access template argument
+ static inline int GetMaxLength() { return SIZE_BUF-1; }
+
+ CFmtStrN<SIZE_BUF,QUIET_TRUNCATION> & operator=( const char *pchValue )
{
V_strncpy( m_szBuf, pchValue, SIZE_BUF );
m_nLength = V_strlen( m_szBuf );
return *this;
}
- CFmtStrN<SIZE_BUF> & operator+=( const char *pchValue )
+ CFmtStrN<SIZE_BUF,QUIET_TRUNCATION> & operator+=( const char *pchValue )
{
Append( pchValue );
return *this;
@@ -112,13 +161,19 @@ public:
int Length() const { return m_nLength; }
+ void SetLength( int nLength )
+ {
+ m_nLength = Min( nLength, SIZE_BUF - 1 );
+ m_szBuf[m_nLength] = '\0';
+ }
+
void Clear()
{
m_szBuf[0] = 0;
m_nLength = 0;
}
- void AppendFormat(PRINTF_FORMAT_STRING const char *pchFormat, ... ) FMTFUNCTION( 2, 3 )
+ void AppendFormat( PRINTF_FORMAT_STRING const char *pchFormat, ... )
{
char *pchEnd = m_szBuf + m_nLength;
FmtStrVSNPrintf( pchEnd, SIZE_BUF - m_nLength, m_bQuietTruncation, &pchFormat, m_nLength, pchFormat );
@@ -163,14 +218,12 @@ public:
void AppendIndent( uint32 unCount, char chIndent = '\t' );
+ void SetQuietTruncation( bool bQuiet ) { m_bQuietTruncation = bQuiet; }
+
protected:
virtual void InitQuietTruncation()
{
-#ifdef _DEBUG
- m_bQuietTruncation = false;
-#else
- m_bQuietTruncation = true; // Force quiet for release builds
-#endif
+ m_bQuietTruncation = QUIET_TRUNCATION;
}
bool m_bQuietTruncation;
@@ -183,16 +236,14 @@ private:
// Version which will not assert if strings are truncated
-template <int SIZE_BUF>
-class CFmtStrQuietTruncationN : public CFmtStrN<SIZE_BUF>
+template < int SIZE_BUF >
+class CFmtStrQuietTruncationN : public CFmtStrN<SIZE_BUF, true >
{
-protected:
- virtual void InitQuietTruncation() { this->m_bQuietTruncation = true; }
};
-template< int SIZE_BUF >
-void CFmtStrN<SIZE_BUF>::AppendIndent( uint32 unCount, char chIndent )
+template< int SIZE_BUF, bool QUIET_TRUNCATION >
+void CFmtStrN< SIZE_BUF, QUIET_TRUNCATION >::AppendIndent( uint32 unCount, char chIndent )
{
Assert( Length() + unCount < SIZE_BUF );
if( Length() + unCount >= SIZE_BUF )
@@ -204,8 +255,8 @@ void CFmtStrN<SIZE_BUF>::AppendIndent( uint32 unCount, char chIndent )
m_szBuf[ m_nLength ] = '\0';
}
-template< int SIZE_BUF >
-void CFmtStrN<SIZE_BUF>::AppendFormatV( const char *pchFormat, va_list args )
+template< int SIZE_BUF, bool QUIET_TRUNCATION >
+void CFmtStrN< SIZE_BUF, QUIET_TRUNCATION >::AppendFormatV( const char *pchFormat, va_list args )
{
int cubPrinted = V_vsnprintf( m_szBuf+Length(), SIZE_BUF - Length(), pchFormat, args );
m_nLength += cubPrinted;
diff --git a/mp/src/public/tier1/mempool.h b/mp/src/public/tier1/mempool.h
index 88406fbf..01d3a33f 100644
--- a/mp/src/public/tier1/mempool.h
+++ b/mp/src/public/tier1/mempool.h
@@ -30,19 +30,27 @@
typedef void (*MemoryPoolReportFunc_t)( PRINTF_FORMAT_STRING char const* pMsg, ... );
+// Ways a memory pool can grow when it needs to make a new blob:
+enum MemoryPoolGrowType_t
+{
+ UTLMEMORYPOOL_GROW_NONE=0, // Don't allow new blobs.
+ UTLMEMORYPOOL_GROW_FAST=1, // New blob size is numElements * (i+1) (ie: the blocks it allocates
+ // get larger and larger each time it allocates one).
+ UTLMEMORYPOOL_GROW_SLOW=2 // New blob size is numElements.
+};
+
class CUtlMemoryPool
{
public:
- // Ways the memory pool can grow when it needs to make a new blob.
+ // !KLUDGE! For legacy code support, import the global enum into this scope
enum MemoryPoolGrowType_t
{
- GROW_NONE=0, // Don't allow new blobs.
- GROW_FAST=1, // New blob size is numElements * (i+1) (ie: the blocks it allocates
- // get larger and larger each time it allocates one).
- GROW_SLOW=2 // New blob size is numElements.
+ GROW_NONE=UTLMEMORYPOOL_GROW_NONE,
+ GROW_FAST=UTLMEMORYPOOL_GROW_FAST,
+ GROW_SLOW=UTLMEMORYPOOL_GROW_SLOW
};
- CUtlMemoryPool( int blockSize, int numElements, int growMode = GROW_FAST, const char *pszAllocOwner = NULL, int nAlignment = 0 );
+ CUtlMemoryPool( int blockSize, int numElements, int growMode = UTLMEMORYPOOL_GROW_FAST, const char *pszAllocOwner = NULL, int nAlignment = 0 );
~CUtlMemoryPool();
void* Alloc(); // Allocate the element size you specified in the constructor.
@@ -103,7 +111,7 @@ protected:
class CMemoryPoolMT : public CUtlMemoryPool
{
public:
- CMemoryPoolMT(int blockSize, int numElements, int growMode = GROW_FAST, const char *pszAllocOwner = NULL) : CUtlMemoryPool( blockSize, numElements, growMode, pszAllocOwner) {}
+ CMemoryPoolMT(int blockSize, int numElements, int growMode = UTLMEMORYPOOL_GROW_FAST, const char *pszAllocOwner = NULL) : CUtlMemoryPool( blockSize, numElements, growMode, pszAllocOwner) {}
void* Alloc() { AUTO_LOCK( m_mutex ); return CUtlMemoryPool::Alloc(); }
diff --git a/mp/src/public/tier1/strtools.h b/mp/src/public/tier1/strtools.h
index 93d0af6d..d3f1c65b 100644
--- a/mp/src/public/tier1/strtools.h
+++ b/mp/src/public/tier1/strtools.h
@@ -765,6 +765,29 @@ private:
};
+// Encodes a string (or binary data) in URL encoding format, see rfc1738 section 2.2.
+// Dest buffer should be 3 times the size of source buffer to guarantee it has room to encode.
+void Q_URLEncodeRaw( OUT_Z_CAP(nDestLen) char *pchDest, int nDestLen, const char *pchSource, int nSourceLen );
+
+// Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2.
+// Dest buffer should be at least as large as source buffer to gurantee room for decode.
+// Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed.
+//
+// Returns the amount of space actually used in the output buffer.
+size_t Q_URLDecodeRaw( OUT_CAP(nDecodeDestLen) char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen );
+
+// Encodes a string (or binary data) in URL encoding format, this isn't the strict rfc1738 format, but instead uses + for spaces.
+// This is for historical reasons and HTML spec foolishness that lead to + becoming a de facto standard for spaces when encoding form data.
+// Dest buffer should be 3 times the size of source buffer to guarantee it has room to encode.
+void Q_URLEncode( OUT_Z_CAP(nDestLen) char *pchDest, int nDestLen, const char *pchSource, int nSourceLen );
+
+// Decodes a string (or binary data) in URL encoding format, this isn't the strict rfc1738 format, but instead uses + for spaces.
+// This is for historical reasons and HTML spec foolishness that lead to + becoming a de facto standard for spaces when encoding form data.
+// Dest buffer should be at least as large as source buffer to gurantee room for decode.
+// Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed.
+//
+// Returns the amount of space actually used in the output buffer.
+size_t Q_URLDecode( OUT_CAP(nDecodeDestLen) char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen );
// NOTE: This is for backward compatability!
diff --git a/mp/src/public/tier1/utlblockmemory.h b/mp/src/public/tier1/utlblockmemory.h
index 69885060..b4a254ff 100644
--- a/mp/src/public/tier1/utlblockmemory.h
+++ b/mp/src/public/tier1/utlblockmemory.h
@@ -247,15 +247,16 @@ void CUtlBlockMemory<T,I>::ChangeSize( int 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 )
{
+ // free old blocks if shrinking
+ // Only possible if m_pMemory is non-NULL (and avoids PVS-Studio warning)
+ for ( int i = m_nBlocks; i < nBlocksOld; ++i )
+ {
+ UTLBLOCKMEMORY_TRACK_FREE();
+ free( (void*)m_pMemory[ i ] );
+ }
+
MEM_ALLOC_CREDIT_CLASS();
m_pMemory = (T**)realloc( m_pMemory, m_nBlocks * sizeof(T*) );
Assert( m_pMemory );
diff --git a/mp/src/public/tier1/utlpair.h b/mp/src/public/tier1/utlpair.h
new file mode 100644
index 00000000..d306f324
--- /dev/null
+++ b/mp/src/public/tier1/utlpair.h
@@ -0,0 +1,52 @@
+//========= Copyright, Valve Corporation, All rights reserved. ================//
+//
+// std::pair style container; exists to work easily in our CUtlMap/CUtlHashMap classes
+//
+//=============================================================================//
+
+#ifndef UTLPAIR_H
+#define UTLPAIR_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+// std::pair style container; exists to work easily in our CUtlMap/CUtlHashMap classes
+template<typename T1, typename T2>
+class CUtlPair
+{
+public:
+ CUtlPair() {}
+ CUtlPair( T1 t1, T2 t2 ) : first( t1 ), second( t2 ) {}
+
+ bool operator<( const CUtlPair<T1,T2> &rhs ) const {
+ if ( first != rhs.first )
+ return first < rhs.first;
+ return second < rhs.second;
+ }
+
+ bool operator==( const CUtlPair<T1,T2> &rhs ) const {
+ return first == rhs.first && second == rhs.second;
+ }
+
+ T1 first;
+ T2 second;
+};
+
+// utility to make a CUtlPair without having to specify template parameters
+template<typename T1, typename T2>
+inline CUtlPair<T1,T2> MakeUtlPair( T1 t1, T2 t2 )
+{
+ return CUtlPair<T1,T2>(t1, t2);
+}
+
+//// HashItem() overload that works automatically with our hash containers
+//template<typename T1, typename T2>
+//inline uint32 HashItem( const CUtlPair<T1,T2> &item )
+//{
+// return HashItem( (uint64)HashItem( item.first ) + ((uint64)HashItem( item.second ) << 32) );
+//}
+
+
+#endif // UTLPAIR_H
diff --git a/mp/src/public/tier1/utlstring.h b/mp/src/public/tier1/utlstring.h
index f425b271..c50765fa 100644
--- a/mp/src/public/tier1/utlstring.h
+++ b/mp/src/public/tier1/utlstring.h
@@ -332,6 +332,7 @@ public:
void Clear() { Set( NULL ); }
const T *Get() const { return m_pString ? m_pString : StringFuncs<T>::EmptyString(); }
+ operator const T*() const { return m_pString ? m_pString : StringFuncs<T>::EmptyString(); }
bool IsEmpty() const { return m_pString == NULL; } // Note: empty strings are never stored by Set
diff --git a/mp/src/public/tier1/utlvector.h b/mp/src/public/tier1/utlvector.h
index 1f2fe6e1..180b51e4 100644
--- a/mp/src/public/tier1/utlvector.h
+++ b/mp/src/public/tier1/utlvector.h
@@ -80,6 +80,12 @@ public:
int Count() const;
int Size() const; // don't use me!
+ /// are there no elements? For compatibility with lists.
+ inline bool IsEmpty( void ) const
+ {
+ return ( Count() == 0 );
+ }
+
// Is element index valid?
bool IsValidIndex( int i ) const;
static int InvalidIndex();