Tier1: use correct index types for template classes

This ensures that we can never allocate more memory than the maximum value that type could hold, without triggering a compile warning. There was a mention about shorts being slow on PowerPC platforms for utllinkedlist, but the index local type could be overridden (defaults to index storage type). In case it gets used for PowerPC, use 32bit ints as index local types; as the local type gets used for arithmetic operations while storage type is what's getting cached off in memory. This patch had no effect on generated output code, it was mostly implemented to avoid future problems.
This commit is contained in:
Kawe Mazidjatari 2024-02-10 01:34:03 +01:00
parent b27769fdb5
commit c42ebe2cfc
4 changed files with 28 additions and 27 deletions

View File

@ -31,11 +31,11 @@ enum EDictCompareType
// This is a useful macro to iterate from start to end in order in a map // This is a useful macro to iterate from start to end in order in a map
#define FOR_EACH_DICT( dictName, iteratorName ) \ #define FOR_EACH_DICT( dictName, iteratorName ) \
for( int iteratorName=dictName.First(); iteratorName != dictName.InvalidIndex(); iteratorName = dictName.Next( iteratorName ) ) for( decltype(dictName)::IndexType_t iteratorName=dictName.First(); iteratorName != dictName.InvalidIndex(); iteratorName = dictName.Next( iteratorName ) )
// faster iteration, but in an unspecified order // faster iteration, but in an unspecified order
#define FOR_EACH_DICT_FAST( dictName, iteratorName ) \ #define FOR_EACH_DICT_FAST( dictName, iteratorName ) \
for ( int iteratorName = 0; iteratorName < dictName.MaxElement(); ++iteratorName ) if ( !dictName.IsValidIndex( iteratorName ) ) continue; else for ( decltype(dictName)::IndexType_t iteratorName = 0; iteratorName < dictName.MaxElement(); ++iteratorName ) if ( !dictName.IsValidIndex( iteratorName ) ) continue; else
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// A dictionary mapping from symbol to structure // A dictionary mapping from symbol to structure
@ -46,14 +46,15 @@ class CUtlDict
public: public:
typedef const char* KeyType_t; typedef const char* KeyType_t;
typedef T ElemType_t; typedef T ElemType_t;
typedef I IndexType_t;
// constructor, destructor // constructor, destructor
// Left at growSize = 0, the memory will first allocate 1 element and double in size // Left at growSize = 0, the memory will first allocate 1 element and double in size
// at each increment. // at each increment.
CUtlDict( int compareType = k_eDictCompareTypeCaseInsensitive, int growSize = 0, int initSize = 0 ); CUtlDict( EDictCompareType compareType = k_eDictCompareTypeCaseInsensitive, I growSize = 0, I initSize = 0 );
~CUtlDict( ); ~CUtlDict( );
void EnsureCapacity( int ); void EnsureCapacity( I );
// gets particular elements // gets particular elements
T& Element( I i ); T& Element( I i );
@ -68,7 +69,7 @@ public:
void SetElementName( I i, char const *pName ); void SetElementName( I i, char const *pName );
// Number of elements // Number of elements
unsigned int Count() const; I Count() const;
// Number of allocated slots // Number of allocated slots
I MaxElement() const; I MaxElement() const;
@ -114,7 +115,7 @@ protected:
// constructor, destructor // constructor, destructor
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <class T, class I> template <class T, class I>
CUtlDict<T, I>::CUtlDict( int compareType, int growSize, int initSize ) : m_Elements( growSize, initSize ) CUtlDict<T, I>::CUtlDict( EDictCompareType compareType, I growSize, I initSize ) : m_Elements( growSize, initSize )
{ {
if ( compareType == k_eDictCompareTypeFilenames ) if ( compareType == k_eDictCompareTypeFilenames )
{ {
@ -137,7 +138,7 @@ CUtlDict<T, I>::~CUtlDict()
} }
template <class T, class I> template <class T, class I>
inline void CUtlDict<T, I>::EnsureCapacity( int num ) inline void CUtlDict<T, I>::EnsureCapacity( I num )
{ {
return m_Elements.EnsureCapacity( num ); return m_Elements.EnsureCapacity( num );
} }
@ -199,7 +200,7 @@ inline void CUtlDict<T, I>::SetElementName( I i, char const *pName )
// Num elements // Num elements
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <class T, class I> template <class T, class I>
inline unsigned int CUtlDict<T, I>::Count() const inline I CUtlDict<T, I>::Count() const
{ {
return m_Elements.Count(); return m_Elements.Count();
} }

View File

@ -24,7 +24,7 @@
// This is a useful macro to iterate from head to tail in a linked list. // This is a useful macro to iterate from head to tail in a linked list.
#define FOR_EACH_LL( listName, iteratorName ) \ #define FOR_EACH_LL( listName, iteratorName ) \
for( int iteratorName=listName.Head(); iteratorName != listName.InvalidIndex(); iteratorName = listName.Next( iteratorName ) ) for( decltype(listName)::IndexLocalType_t iteratorName=listName.Head(); iteratorName != listName.InvalidIndex(); iteratorName = listName.Next( iteratorName ) )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// class CUtlLinkedList: // class CUtlLinkedList:
@ -62,12 +62,12 @@ class CUtlLinkedList
{ {
public: public:
typedef T ElemType_t; typedef T ElemType_t;
typedef S IndexType_t; // should really be called IndexStorageType_t, but that would be a huge change typedef S IndexStorageType_t;
typedef I IndexLocalType_t; typedef I IndexLocalType_t;
typedef M MemoryAllocator_t; typedef M MemoryAllocator_t;
// constructor, destructor // constructor, destructor
CUtlLinkedList(ssize_t growSize = 0, ssize_t initSize = 0); CUtlLinkedList(IndexStorageType_t growSize = 0, IndexStorageType_t initSize = 0);
~CUtlLinkedList(); ~CUtlLinkedList();
// gets particular elements // gets particular elements
@ -77,9 +77,9 @@ public:
T const& operator[](I i) const; T const& operator[](I i) const;
// Make sure we have a particular amount of memory // Make sure we have a particular amount of memory
void EnsureCapacity(int num); void EnsureCapacity(IndexStorageType_t num);
void SetGrowSize(int growSize); void SetGrowSize(IndexStorageType_t growSize);
// Memory deallocation // Memory deallocation
void Purge(); void Purge();
@ -221,7 +221,7 @@ template < class T, class I = unsigned short >
class CUtlBlockLinkedList : public CUtlLinkedList< T, I, true, I, CUtlBlockMemory< UtlLinkedListElem_t< T, I >, I > > class CUtlBlockLinkedList : public CUtlLinkedList< T, I, true, I, CUtlBlockMemory< UtlLinkedListElem_t< T, I >, I > >
{ {
public: public:
CUtlBlockLinkedList(int growSize = 0, int initSize = 0) CUtlBlockLinkedList(I growSize = 0, I initSize = 0)
: CUtlLinkedList< T, I, true, I, CUtlBlockMemory< UtlLinkedListElem_t< T, I >, I > >(growSize, initSize) {} : CUtlLinkedList< T, I, true, I, CUtlBlockMemory< UtlLinkedListElem_t< T, I >, I > >(growSize, initSize) {}
protected: protected:
void ResetDbgInfo() {} void ResetDbgInfo() {}
@ -233,7 +233,7 @@ protected:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <class T, class S, bool ML, class I, class M> template <class T, class S, bool ML, class I, class M>
CUtlLinkedList<T, S, ML, I, M>::CUtlLinkedList(ssize_t growSize, ssize_t initSize) : CUtlLinkedList<T, S, ML, I, M>::CUtlLinkedList(S growSize, S initSize) :
m_Memory(growSize, initSize), m_LastAlloc(m_Memory.InvalidIterator()) m_Memory(growSize, initSize), m_LastAlloc(m_Memory.InvalidIterator())
{ {
// Prevent signed non-int datatypes // Prevent signed non-int datatypes
@ -398,7 +398,7 @@ inline bool CUtlFixedLinkedList<T>::IsInList( int i ) const
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template< class T, class S, bool ML, class I, class M > template< class T, class S, bool ML, class I, class M >
void CUtlLinkedList<T, S, ML, I, M>::EnsureCapacity(int num) void CUtlLinkedList<T, S, ML, I, M>::EnsureCapacity(S num)
{ {
MEM_ALLOC_CREDIT_CLASS(); MEM_ALLOC_CREDIT_CLASS();
m_Memory.EnsureCapacity(num); m_Memory.EnsureCapacity(num);
@ -406,7 +406,7 @@ void CUtlLinkedList<T, S, ML, I, M>::EnsureCapacity(int num)
} }
template< class T, class S, bool ML, class I, class M > template< class T, class S, bool ML, class I, class M >
void CUtlLinkedList<T, S, ML, I, M>::SetGrowSize(int growSize) void CUtlLinkedList<T, S, ML, I, M>::SetGrowSize(S growSize)
{ {
RemoveAll(); RemoveAll();
m_Memory.Init(growSize); m_Memory.Init(growSize);
@ -998,7 +998,7 @@ public:
m_nElems = 0; m_nElems = 0;
} }
int Count() const size_t Count() const
{ {
return m_nElems; return m_nElems;
} }
@ -1078,7 +1078,7 @@ private:
} }
Node_t* m_pFirst; Node_t* m_pFirst;
unsigned m_nElems; size_t m_nElems;
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -24,11 +24,11 @@
// This is a useful macro to iterate from start to end in order in a map // This is a useful macro to iterate from start to end in order in a map
#define FOR_EACH_MAP( mapName, iteratorName ) \ #define FOR_EACH_MAP( mapName, iteratorName ) \
for ( unsigned short iteratorName = (mapName).FirstInorder(); (mapName).IsUtlMap && iteratorName != (mapName).InvalidIndex(); iteratorName = (mapName).NextInorder( iteratorName ) ) for ( decltype(mapName)::IndexType_t iteratorName = (mapName).FirstInorder(); (mapName).IsUtlMap && iteratorName != (mapName).InvalidIndex(); iteratorName = (mapName).NextInorder( iteratorName ) )
// faster iteration, but in an unspecified order // faster iteration, but in an unspecified order
#define FOR_EACH_MAP_FAST( mapName, iteratorName ) \ #define FOR_EACH_MAP_FAST( mapName, iteratorName ) \
for ( unsigned short iteratorName = 0; (mapName).IsUtlMap && iteratorName < (mapName).MaxElement(); ++iteratorName ) if ( !(mapName).IsValidIndex( iteratorName ) ) continue; else for ( decltype(mapName)::IndexType_t iteratorName = 0; (mapName).IsUtlMap && iteratorName < (mapName).MaxElement(); ++iteratorName ) if ( !(mapName).IsValidIndex( iteratorName ) ) continue; else
struct base_utlmap_t struct base_utlmap_t
@ -54,7 +54,7 @@ public:
// Left at growSize = 0, the memory will first allocate 1 element and double in size // Left at growSize = 0, the memory will first allocate 1 element and double in size
// at each increment. // at each increment.
// LessFunc_t is required, but may be set after the constructor using SetLessFunc() below // LessFunc_t is required, but may be set after the constructor using SetLessFunc() below
CUtlMap( int growSize = 0, int initSize = 0, const LessFunc_t &lessfunc = 0 ) CUtlMap( IndexType_t growSize = 0, IndexType_t initSize = 0, const LessFunc_t &lessfunc = 0 )
: m_Tree( growSize, initSize, CKeyLess( lessfunc ) ) : m_Tree( growSize, initSize, CKeyLess( lessfunc ) )
{ {
} }
@ -64,7 +64,7 @@ public:
{ {
} }
void EnsureCapacity( int num ) { m_Tree.EnsureCapacity( num ); } void EnsureCapacity( IndexType_t num ) { m_Tree.EnsureCapacity( num ); }
// gets particular elements // gets particular elements
ElemType_t & Element( IndexType_t i ) { return m_Tree.Element( i ).elem; } ElemType_t & Element( IndexType_t i ) { return m_Tree.Element( i ).elem; }
@ -76,7 +76,7 @@ public:
// Num elements // Num elements
unsigned int Count() const { return m_Tree.Count(); } IndexType_t Count() const { return m_Tree.Count(); }
// Max "size" of the vector // Max "size" of the vector
IndexType_t MaxElement() const { return m_Tree.MaxElement(); } IndexType_t MaxElement() const { return m_Tree.MaxElement(); }

View File

@ -171,7 +171,7 @@ public:
I Root() const; I Root() const;
// Num elements // Num elements
unsigned int Count() const; I Count() const;
// Max "size" of the vector // Max "size" of the vector
// it's not generally safe to iterate from index 0 to MaxElement()-1 (you could do this as a potential // it's not generally safe to iterate from index 0 to MaxElement()-1 (you could do this as a potential
@ -482,9 +482,9 @@ inline I CUtlRBTree<T, I, L, M>::Root() const
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template < class T, class I, typename L, class M > template < class T, class I, typename L, class M >
inline unsigned int CUtlRBTree<T, I, L, M>::Count() const inline I CUtlRBTree<T, I, L, M>::Count() const
{ {
return (unsigned int)m_NumElements; return m_NumElements;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------