#ifndef UTLMAP_H #define UTLMAP_H #ifdef _WIN32 #pragma once #endif #include "dbg.h" #include "utlrbtree.h" #define FOR_EACH_MAP( mapName, iteratorName ) \ for ( int iteratorName = (mapName).FirstInorder(); (mapName).IsUtlMap && iteratorName != (mapName).InvalidIndex(); iteratorName = (mapName).NextInorder( iteratorName ) ) #define FOR_EACH_MAP_FAST( mapName, iteratorName ) \ for ( int iteratorName = 0; (mapName).IsUtlMap && iteratorName < (mapName).MaxElement(); ++iteratorName ) if ( !(mapName).IsValidIndex( iteratorName ) ) continue; else struct base_utlmap_t { public: enum { IsUtlMap = true }; }; template class CUtlMap : public base_utlmap_t { public: typedef K KeyType_t; typedef T ElemType_t; typedef I IndexType_t; CUtlMap(int growSize = 0, int initSize = 0, const LessFunc_t& lessfunc = 0) : m_Tree(growSize, initSize, CKeyLess(lessfunc)) { } CUtlMap(LessFunc_t lessfunc) : m_Tree(CKeyLess(lessfunc)) { } void EnsureCapacity(int num) { m_Tree.EnsureCapacity(num); } ElemType_t& Element(IndexType_t i) { return m_Tree.Element(i).elem; } const ElemType_t& Element(IndexType_t i) const { return m_Tree.Element(i).elem; } ElemType_t& operator[](IndexType_t i) { return m_Tree.Element(i).elem; } const ElemType_t& operator[](IndexType_t i) const { return m_Tree.Element(i).elem; } KeyType_t& Key(IndexType_t i) { return m_Tree.Element(i).key; } const KeyType_t& Key(IndexType_t i) const { return m_Tree.Element(i).key; } unsigned int Count() const { return m_Tree.Count(); } IndexType_t MaxElement() const { return m_Tree.MaxElement(); } bool IsValidIndex(IndexType_t i) const { return m_Tree.IsValidIndex(i); } bool IsValid() const { return m_Tree.IsValid(); } static IndexType_t InvalidIndex() { return CTree::InvalidIndex(); } void SetLessFunc(LessFunc_t func) { m_Tree.SetLessFunc(CKeyLess(func)); } IndexType_t Insert(const KeyType_t& key, const ElemType_t& insert) { Node_t node; node.key = key; node.elem = insert; return m_Tree.Insert(node); } IndexType_t Insert(const KeyType_t& key) { Node_t node; node.key = key; return m_Tree.Insert(node); } IndexType_t InsertWithDupes(const KeyType_t& key, const ElemType_t& insert) { Node_t node; node.key = key; node.elem = insert; return m_Tree.Insert(node); } IndexType_t InsertWithDupes(const KeyType_t& key) { Node_t node; node.key = key; return m_Tree.Insert(node); } bool HasElement(const KeyType_t& key) const { Node_t dummyNode; dummyNode.key = key; return m_Tree.HasElement(dummyNode); } IndexType_t Find(const KeyType_t& key) const { Node_t dummyNode; dummyNode.key = key; return m_Tree.Find(dummyNode); } IndexType_t FindFirst(const KeyType_t& key) const { Node_t dummyNode; dummyNode.key = key; return m_Tree.FindFirst(dummyNode); } const ElemType_t& FindElement(const KeyType_t& key, const ElemType_t& defaultValue) const { IndexType_t i = Find(key); if (i == InvalidIndex()) return defaultValue; return Element(i); } IndexType_t FindClosest(const KeyType_t& key, CompareOperands_t eFindCriteria) const { Node_t dummyNode; dummyNode.key = key; return m_Tree.FindClosest(dummyNode, eFindCriteria); } void RemoveAt(IndexType_t i) { m_Tree.RemoveAt(i); } bool Remove(const KeyType_t& key) { Node_t dummyNode; dummyNode.key = key; return m_Tree.Remove(dummyNode); } void RemoveAll() { m_Tree.RemoveAll(); } void Purge() { m_Tree.Purge(); } void PurgeAndDeleteElements(); IndexType_t FirstInorder() const { return m_Tree.FirstInorder(); } IndexType_t NextInorder(IndexType_t i) const { return m_Tree.NextInorder(i); } IndexType_t PrevInorder(IndexType_t i) const { return m_Tree.PrevInorder(i); } IndexType_t LastInorder() const { return m_Tree.LastInorder(); } IndexType_t NextInorderSameKey(IndexType_t i) const { IndexType_t iNext = NextInorder(i); if (!IsValidIndex(iNext)) return InvalidIndex(); if (Key(iNext) != Key(i)) return InvalidIndex(); return iNext; } void Reinsert(const KeyType_t& key, IndexType_t i) { m_Tree[i].key = key; m_Tree.Reinsert(i); } IndexType_t InsertOrReplace(const KeyType_t& key, const ElemType_t& insert) { IndexType_t i = Find(key); if (i != InvalidIndex()) { Element(i) = insert; return i; } return Insert(key, insert); } void Swap(CUtlMap< K, T, I >& that) { m_Tree.Swap(that.m_Tree); } struct Node_t { Node_t() { } Node_t(const Node_t& from) : key(from.key), elem(from.elem) { } KeyType_t key; ElemType_t elem; }; class CKeyLess { public: CKeyLess(const LessFunc_t& lessFunc) : m_LessFunc(lessFunc) {} bool operator!() const { return !m_LessFunc; } bool operator()(const Node_t& left, const Node_t& right) const { return m_LessFunc(left.key, right.key); } LessFunc_t m_LessFunc; }; typedef CUtlRBTree CTree; CTree* AccessTree() { return &m_Tree; } protected: CTree m_Tree; }; template< typename K, typename T, typename I, typename LessFunc_t > inline void CUtlMap::PurgeAndDeleteElements() { for (I i = 0; i < MaxElement(); ++i) { if (!IsValidIndex(i)) continue; delete Element(i); } Purge(); } #endif