// #ifndef _HASHTBL_H #define _HASHTBL_H #include //------------------------------ IHashable ------------------------- // An ABC for objects which can be linked into a hash table typedef unsigned int HashIndex; template class _ICLASS IHashable : public IUnknown { public: virtual HashIndex Hash(HashIndex modulo) const = 0; virtual BOOL operator==(const T *) const =0; virtual BOOL operator!=(const T *) const =0; virtual IHashable *&Next() = 0; }; template class _ICLASS HashTable { protected: IHashable * aBuckets[SIZE]; IHashable *& Insert(IHashable *&rpFound, IHashable *pKey); IHashable *& Delete(IHashable *&rpFound); IHashable *& Find(IHashable *hashKey); public: ~HashTable(); // Add returns existing instance or adds BOOL Add(IHashable **pPat); // Remove takes key out of HashTable void Remove(IHashable *pKey); }; template IHashable *& HashTable:: Insert(IHashable *&rpFound, IHashable *pKey) { pKey->Next()=rpFound, pKey->AddRef(), rpFound=pKey; return rpFound; } template IHashable *& HashTable:: Delete(IHashable *&rpFound) { assert(rpFound != 0L); IHashable **ppFoundNext = &rpFound->Next(); IHashable *pFoundNext = *ppFoundNext; *ppFoundNext=0L; rpFound->Release(); return rpFound = pFoundNext; } template BOOL HashTable::Add(IHashable **ppPat) { IHashable *&pSrc = Find(*ppPat); if (pSrc) { (*ppPat)->Release(); *ppPat = pSrc; } else Insert(pSrc, *ppPat) ; (*ppPat) ->AddRef(); return TRUE; } // (pSrc) ? // pPat->Release(), // pPat = pSrc : // Insert(pSrc, pPat) ; template void HashTable::Remove(IHashable *pKey) { IHashable *&pFound =Find(pKey); pFound ? Delete(pFound) : 0L; } #endif