diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /sp/src/public/tier1/utldict.h | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'sp/src/public/tier1/utldict.h')
| -rw-r--r-- | sp/src/public/tier1/utldict.h | 358 |
1 files changed, 358 insertions, 0 deletions
diff --git a/sp/src/public/tier1/utldict.h b/sp/src/public/tier1/utldict.h new file mode 100644 index 00000000..b4268e90 --- /dev/null +++ b/sp/src/public/tier1/utldict.h @@ -0,0 +1,358 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: A dictionary mapping from symbol to structure
+//
+// $Header: $
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef UTLDICT_H
+#define UTLDICT_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "tier0/dbg.h"
+#include "tier1/utlmap.h"
+
+// Include this because tons of code was implicitly getting utlsymbol or utlvector via utldict.h
+#include "tier1/utlsymbol.h"
+
+#include "tier0/memdbgon.h"
+
+enum EDictCompareType
+{
+ k_eDictCompareTypeCaseSensitive=0,
+ k_eDictCompareTypeCaseInsensitive=1,
+ k_eDictCompareTypeFilenames // Slashes and backslashes count as the same character..
+};
+
+//-----------------------------------------------------------------------------
+// A dictionary mapping from symbol to structure
+//-----------------------------------------------------------------------------
+#define FOR_EACH_DICT( dictName, iteratorName ) \
+ for( int iteratorName=dictName.First(); iteratorName != dictName.InvalidIndex(); iteratorName = dictName.Next( iteratorName ) )
+
+// faster iteration, but in an unspecified order
+#define FOR_EACH_DICT_FAST( dictName, iteratorName ) \
+ for ( int iteratorName = 0; iteratorName < dictName.MaxElement(); ++iteratorName ) if ( !dictName.IsValidIndex( iteratorName ) ) continue; else
+
+//-----------------------------------------------------------------------------
+// A dictionary mapping from symbol to structure
+//-----------------------------------------------------------------------------
+template <class T, class I = int >
+class CUtlDict
+{
+public:
+ // constructor, destructor
+ // Left at growSize = 0, the memory will first allocate 1 element and double in size
+ // at each increment.
+ CUtlDict( int compareType = k_eDictCompareTypeCaseInsensitive, int growSize = 0, int initSize = 0 );
+ ~CUtlDict( );
+
+ void EnsureCapacity( int );
+
+ // gets particular elements
+ T& Element( I i );
+ const T& Element( I i ) const;
+ T& operator[]( I i );
+ const T& operator[]( I i ) const;
+
+ // gets element names
+ char *GetElementName( I i );
+ char const *GetElementName( I i ) const;
+
+ void SetElementName( I i, char const *pName );
+
+ // Number of elements
+ unsigned int Count() const;
+
+ // Number of allocated slots
+ I MaxElement() const;
+
+ // Checks if a node is valid and in the tree
+ bool IsValidIndex( I i ) const;
+
+ // Invalid index
+ static I InvalidIndex();
+
+ // Insert method (inserts in order)
+ I Insert( const char *pName, const T &element );
+ I Insert( const char *pName );
+
+ // Find method
+ I Find( const char *pName ) const;
+ bool HasElement( const char *pName ) const;
+
+ // Remove methods
+ void RemoveAt( I i );
+ void Remove( const char *pName );
+ void RemoveAll( );
+
+ // Purge memory
+ void Purge();
+ void PurgeAndDeleteElements(); // Call delete on each element.
+
+ // Iteration methods
+ I First() const;
+ I Next( I i ) const;
+
+ // Nested typedefs, for code that might need
+ // to fish out the index type from a given dict
+ typedef I IndexType_t;
+
+protected:
+ typedef CUtlMap<const char *, T, I> DictElementMap_t;
+ DictElementMap_t m_Elements;
+};
+
+
+//-----------------------------------------------------------------------------
+// constructor, destructor
+//-----------------------------------------------------------------------------
+template <class T, class I>
+CUtlDict<T, I>::CUtlDict( int compareType, int growSize, int initSize ) : m_Elements( growSize, initSize )
+{
+ if ( compareType == k_eDictCompareTypeFilenames )
+ {
+ m_Elements.SetLessFunc( CaselessStringLessThanIgnoreSlashes );
+ }
+ else if ( compareType == k_eDictCompareTypeCaseInsensitive )
+ {
+ m_Elements.SetLessFunc( CaselessStringLessThan );
+ }
+ else
+ {
+ m_Elements.SetLessFunc( StringLessThan );
+ }
+}
+
+template <class T, class I>
+CUtlDict<T, I>::~CUtlDict()
+{
+ Purge();
+}
+
+template <class T, class I>
+inline void CUtlDict<T, I>::EnsureCapacity( int num )
+{
+ return m_Elements.EnsureCapacity( num );
+}
+
+//-----------------------------------------------------------------------------
+// gets particular elements
+//-----------------------------------------------------------------------------
+template <class T, class I>
+inline T& CUtlDict<T, I>::Element( I i )
+{
+ return m_Elements[i];
+}
+
+template <class T, class I>
+inline const T& CUtlDict<T, I>::Element( I i ) const
+{
+ return m_Elements[i];
+}
+
+//-----------------------------------------------------------------------------
+// gets element names
+//-----------------------------------------------------------------------------
+template <class T, class I>
+inline char *CUtlDict<T, I>::GetElementName( I i )
+{
+ return (char *)m_Elements.Key( i );
+}
+
+template <class T, class I>
+inline char const *CUtlDict<T, I>::GetElementName( I i ) const
+{
+ return m_Elements.Key( i );
+}
+
+template <class T, class I>
+inline T& CUtlDict<T, I>::operator[]( I i )
+{
+ return Element(i);
+}
+
+template <class T, class I>
+inline const T & CUtlDict<T, I>::operator[]( I i ) const
+{
+ return Element(i);
+}
+
+template <class T, class I>
+inline void CUtlDict<T, I>::SetElementName( I i, char const *pName )
+{
+ MEM_ALLOC_CREDIT_CLASS();
+ // TODO: This makes a copy of the old element
+ // TODO: This relies on the rb tree putting the most recently
+ // removed element at the head of the insert list
+ free( (void *)m_Elements.Key( i ) );
+ m_Elements.Reinsert( strdup( pName ), i );
+}
+
+//-----------------------------------------------------------------------------
+// Num elements
+//-----------------------------------------------------------------------------
+template <class T, class I>
+inline unsigned int CUtlDict<T, I>::Count() const
+{
+ return m_Elements.Count();
+}
+
+//-----------------------------------------------------------------------------
+// Number of allocated slots
+//-----------------------------------------------------------------------------
+template <class T, class I>
+inline I CUtlDict<T, I>::MaxElement() const
+{
+ return m_Elements.MaxElement();
+}
+
+//-----------------------------------------------------------------------------
+// Checks if a node is valid and in the tree
+//-----------------------------------------------------------------------------
+template <class T, class I>
+inline bool CUtlDict<T, I>::IsValidIndex( I i ) const
+{
+ return m_Elements.IsValidIndex(i);
+}
+
+
+//-----------------------------------------------------------------------------
+// Invalid index
+//-----------------------------------------------------------------------------
+template <class T, class I>
+inline I CUtlDict<T, I>::InvalidIndex()
+{
+ return DictElementMap_t::InvalidIndex();
+}
+
+
+//-----------------------------------------------------------------------------
+// Delete a node from the tree
+//-----------------------------------------------------------------------------
+template <class T, class I>
+void CUtlDict<T, I>::RemoveAt(I elem)
+{
+ free( (void *)m_Elements.Key( elem ) );
+ m_Elements.RemoveAt(elem);
+}
+
+
+//-----------------------------------------------------------------------------
+// remove a node in the tree
+//-----------------------------------------------------------------------------
+template <class T, class I> void CUtlDict<T, I>::Remove( const char *search )
+{
+ I node = Find( search );
+ if (node != InvalidIndex())
+ {
+ RemoveAt(node);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Removes all nodes from the tree
+//-----------------------------------------------------------------------------
+template <class T, class I>
+void CUtlDict<T, I>::RemoveAll()
+{
+ typename DictElementMap_t::IndexType_t index = m_Elements.FirstInorder();
+ while ( index != m_Elements.InvalidIndex() )
+ {
+ free( (void *)m_Elements.Key( index ) );
+ index = m_Elements.NextInorder( index );
+ }
+
+ m_Elements.RemoveAll();
+}
+
+template <class T, class I>
+void CUtlDict<T, I>::Purge()
+{
+ RemoveAll();
+}
+
+
+template <class T, class I>
+void CUtlDict<T, I>::PurgeAndDeleteElements()
+{
+ // Delete all the elements.
+ I index = m_Elements.FirstInorder();
+ while ( index != m_Elements.InvalidIndex() )
+ {
+ free( (void *)m_Elements.Key( index ) );
+ delete m_Elements[index];
+ index = m_Elements.NextInorder( index );
+ }
+
+ m_Elements.RemoveAll();
+}
+
+
+//-----------------------------------------------------------------------------
+// inserts a node into the tree
+//-----------------------------------------------------------------------------
+template <class T, class I>
+I CUtlDict<T, I>::Insert( const char *pName, const T &element )
+{
+ MEM_ALLOC_CREDIT_CLASS();
+ return m_Elements.Insert( strdup( pName ), element );
+}
+
+template <class T, class I>
+I CUtlDict<T, I>::Insert( const char *pName )
+{
+ MEM_ALLOC_CREDIT_CLASS();
+ return m_Elements.Insert( strdup( pName ) );
+}
+
+
+//-----------------------------------------------------------------------------
+// finds a node in the tree
+//-----------------------------------------------------------------------------
+template <class T, class I>
+I CUtlDict<T, I>::Find( const char *pName ) const
+{
+ MEM_ALLOC_CREDIT_CLASS();
+ if ( pName )
+ return m_Elements.Find( pName );
+ else
+ return InvalidIndex();
+}
+
+//-----------------------------------------------------------------------------
+// returns true if we already have this node
+//-----------------------------------------------------------------------------
+template <class T, class I>
+bool CUtlDict<T, I>::HasElement( const char *pName ) const
+{
+ if ( pName )
+ return m_Elements.IsValidIndex( m_Elements.Find( pName ) );
+ else
+ return false;
+}
+
+
+//-----------------------------------------------------------------------------
+// Iteration methods
+//-----------------------------------------------------------------------------
+template <class T, class I>
+I CUtlDict<T, I>::First() const
+{
+ return m_Elements.FirstInorder();
+}
+
+template <class T, class I>
+I CUtlDict<T, I>::Next( I i ) const
+{
+ return m_Elements.NextInorder(i);
+}
+
+#include "tier0/memdbgoff.h"
+
+#endif // UTLDICT_H
|