#ifndef UTLDICT_H #define UTLDICT_H #ifdef _WIN32 #pragma once #endif #include "dbg.h" #include "utlmap.h" #include "utlsymbol.h" #include "memdbgon.h" enum EDictCompareType { k_eDictCompareTypeCaseSensitive = 0, k_eDictCompareTypeCaseInsensitive = 1, k_eDictCompareTypeFilenames }; #define FOR_EACH_DICT( dictName, iteratorName ) \ for( int iteratorName=dictName.First(); iteratorName != dictName.InvalidIndex(); iteratorName = dictName.Next( iteratorName ) ) #define FOR_EACH_DICT_FAST( dictName, iteratorName ) \ for ( int iteratorName = 0; iteratorName < dictName.MaxElement(); ++iteratorName ) if ( !dictName.IsValidIndex( iteratorName ) ) continue; else template class CUtlDict { public: typedef const char* KeyType_t; typedef T ElemType_t; CUtlDict(int compareType = k_eDictCompareTypeCaseInsensitive, int growSize = 0, int initSize = 0); ~CUtlDict(); void EnsureCapacity(int); T& Element(I i); const T& Element(I i) const; T& operator[](I i); const T& operator[](I i) const; char const* GetElementName(I i) const; void SetElementName(I i, char const* pName); unsigned int Count() const; I MaxElement() const; bool IsValidIndex(I i) const; static I InvalidIndex(); I Insert(const char* pName, const T& element); I Insert(const char* pName); I Find(const char* pName) const; bool HasElement(const char* pName) const; void RemoveAt(I i); void Remove(const char* pName); void RemoveAll(); void Purge(); void PurgeAndDeleteElements(); I First() const; I Next(I i) const; typedef I IndexType_t; protected: typedef CUtlMap DictElementMap_t; DictElementMap_t m_Elements; }; template CUtlDict::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 CUtlDict::~CUtlDict() { Purge(); } template inline void CUtlDict::EnsureCapacity(int num) { return m_Elements.EnsureCapacity(num); } template inline T& CUtlDict::Element(I i) { return m_Elements[i]; } template inline const T& CUtlDict::Element(I i) const { return m_Elements[i]; } template inline char const* CUtlDict::GetElementName(I i) const { return m_Elements.Key(i); } template inline T& CUtlDict::operator[](I i) { return Element(i); } template inline const T& CUtlDict::operator[](I i) const { return Element(i); } template inline void CUtlDict::SetElementName(I i, char const* pName) { MEM_ALLOC_CREDIT_CLASS(); free(const_cast(m_Elements.Key(i))); m_Elements.Reinsert(strdup(pName), i); } template inline unsigned int CUtlDict::Count() const { return m_Elements.Count(); } template inline I CUtlDict::MaxElement() const { return m_Elements.MaxElement(); } template inline bool CUtlDict::IsValidIndex(I i) const { return m_Elements.IsValidIndex(i); } template inline I CUtlDict::InvalidIndex() { return DictElementMap_t::InvalidIndex(); } template void CUtlDict::RemoveAt(I elem) { free(const_cast(m_Elements.Key(elem))); m_Elements.RemoveAt(elem); } template void CUtlDict::Remove(const char* search) { I node = Find(search); if (node != InvalidIndex()) { RemoveAt(node); } } template void CUtlDict::RemoveAll() { typename DictElementMap_t::IndexType_t index = m_Elements.FirstInorder(); while (index != m_Elements.InvalidIndex()) { const char* p = m_Elements.Key(index); free(const_cast(p)); index = m_Elements.NextInorder(index); } m_Elements.RemoveAll(); } template void CUtlDict::Purge() { RemoveAll(); } template void CUtlDict::PurgeAndDeleteElements() { I index = m_Elements.FirstInorder(); while (index != m_Elements.InvalidIndex()) { const char* p = m_Elements.Key(index); free(const_cast(p)); delete m_Elements[index]; index = m_Elements.NextInorder(index); } m_Elements.RemoveAll(); } template I CUtlDict::Insert(const char* pName, const T& element) { MEM_ALLOC_CREDIT_CLASS(); return m_Elements.Insert(strdup(pName), element); } template I CUtlDict::Insert(const char* pName) { MEM_ALLOC_CREDIT_CLASS(); return m_Elements.Insert(strdup(pName)); } template I CUtlDict::Find(const char* pName) const { MEM_ALLOC_CREDIT_CLASS(); if (pName) return m_Elements.Find(pName); else return InvalidIndex(); } template bool CUtlDict::HasElement(const char* pName) const { if (pName) return m_Elements.IsValidIndex(m_Elements.Find(pName)); else return false; } template I CUtlDict::First() const { return m_Elements.FirstInorder(); } template I CUtlDict::Next(I i) const { return m_Elements.NextInorder(i); } #include "memdbgoff.h" #endif