/*------------------------------------------------------------------------*/ /* */ /* HASHIMP.H */ /* */ /* Copyright (c) 1991, 1994 Borland International */ /* All Rights Reserved */ /* */ /* Note: Hash tables can determine the hash value of an object by */ /* calling a member function or global function named HashValue(). */ /* */ /* For member functions, the following prototype should be used: */ /* */ /* unsigned HashValue() const; */ /* */ /* For global functions, then following prototype should be used: */ /* */ /* unsigned HashValue( const T& t ); */ /* */ /* If the global function is used, the member function does not need to */ /* be defined. */ /* */ /*------------------------------------------------------------------------*/ #if !defined( CLASSLIB_HASHIMP_H ) #define CLASSLIB_HASHIMP_H #if !defined( __CHECKS_H ) #include #endif #if !defined( CLASSLIB_DEFS_H ) #include #endif #if !defined( CLASSLIB_LISTIMP_H ) #include #endif #if !defined( CLASSLIB_VECTIMP_H ) #include #endif #pragma option -Vo- #if defined( BI_CLASSLIB_NO_po ) #pragma option -po- #endif /*------------------------------------------------------------------------*/ /* */ /* template unsigned HashValue( T & t ) */ /* unsigned HashValue( void *& ) */ /* */ /* Template function which calls the HashValue() member function for */ /* an object of type T. The (void *) non-template function is */ /* defined so that indirect container templates will compile. It */ /* should never be called. */ /* */ /*------------------------------------------------------------------------*/ inline unsigned HashValue( void *& t ) { return unsigned(t); } inline unsigned HashValue( const TVoidPointer& t ) { return unsigned(STATIC_CAST(void *,t)); } template unsigned HashValue( const T& t ) { return t.HashValue(); } /*------------------------------------------------------------------------*/ /* */ /* template class TMInternalHashImp */ /* */ /* Used internally. */ /* */ /*------------------------------------------------------------------------*/ template class TMInternalHashTableIteratorImp; template class TMInternalHashImp : public Alloc { public: friend TMInternalHashTableIteratorImp; TMInternalHashImp( unsigned size ) : Table(size), Size(size), ItemsInContainer(0) { } unsigned GetItemsInContainer() const { return ItemsInContainer; } int IsEmpty() const { return ItemsInContainer == 0; } protected: unsigned TableSize() const { return Size; } unsigned ItemsInContainer; TMIVectorImp Table; private: virtual unsigned GetHashValue( const T& t ) const = 0; unsigned Size; }; /*------------------------------------------------------------------------*/ /* */ /* template */ /* class TMInternalHashTableIteratorImp */ /* */ /* Used internally. */ /* */ /*------------------------------------------------------------------------*/ template class TMInternalHashTableIteratorImp : public Alloc { public: TMInternalHashTableIteratorImp( const TMInternalHashImp& h ) : HashIter(h.Table), ListIter(0) { Restart(); } ~TMInternalHashTableIteratorImp() { delete ListIter; } operator int() { return HashIter; } const T& Current() { PRECONDITION( ListIter != 0 ); return ListIter->Current(); } const T& operator ++ ( int ) { PRECONDITION( ListIter != 0 ); const T& t = ListIter->Current(); Scan(); return t; } const T& operator ++ () { PRECONDITION( ListIter != 0 ); Scan(); PRECONDITION( ListIter != 0 ); return ListIter->Current(); } void Restart(); private: TMIVectorIteratorImp HashIter; TMListIteratorImp *ListIter; void Scan(); }; template void TMInternalHashTableIteratorImp::Restart() { HashIter.Restart(); delete ListIter; while( HashIter && HashIter.Current() == 0 ) HashIter++; ListIter = HashIter ? new(*this)TMListIteratorImp( *HashIter.Current() ) : 0; } template void TMInternalHashTableIteratorImp::Scan() { // if not at end of list, then iterate to the next item if( *ListIter ) (*ListIter)++; // if now at end of list, then iterate to the next list (if any) if( ! *ListIter ) { HashIter++; delete ListIter; while( HashIter != 0 && HashIter.Current() == 0 ) HashIter++; if( HashIter == 0 ) ListIter = 0; else ListIter = new(*this)TMListIteratorImp( *HashIter.Current() ); } } /*------------------------------------------------------------------------*/ /* */ /* template class TMHashTableImp */ /* template class TMHashTableIteratorImp */ /* */ /* Implements a managed hash table of objects of type T, using storage */ /* storage allocator A. Assumes that T has meaningful copy and == */ /* semantics as well as a default constructor. */ /* */ /*------------------------------------------------------------------------*/ template class TMHashTableIteratorImp; template class TMHashTableImp : private TMInternalHashImp< T,Alloc,TMListImp > { typedef TMInternalHashImp< T,Alloc,TMListImp > Parent; public: friend TMHashTableIteratorImp; typedef void (*IterFunc)(T&, void *); int Add( const T& t ); int Detach( const T& t ); TMHashTableImp( unsigned size = DEFAULT_HASH_TABLE_SIZE ) : TMInternalHashImp< T,Alloc,TMListImp >(size) { } void ForEach( IterFunc iter, void *args ); T *Find( const T& t ) const; void Flush(); Parent::GetItemsInContainer; Parent::IsEmpty; Parent::operator delete; Parent::operator delete []; private: unsigned GetHashValue( const T& t ) const { return HashValue(t) % TableSize(); } }; template class TMHashTableIteratorImp : public TMInternalHashTableIteratorImp > { public: TMHashTableIteratorImp( const TMHashTableImp& h ) : TMInternalHashTableIteratorImp >(h) {} }; template int TMHashTableImp::Add( const T& t ) { unsigned index = GetHashValue(t); TMListImp *list = Table[index]; if( list == 0 ) { list = Table[index] = new(*this)TMListImp; } if( list == 0 ) return 0; else { list->Add(t); ItemsInContainer++; return 1; } } template int TMHashTableImp::Detach( const T& t ) { unsigned index = GetHashValue(t); TMListImp *list = Table[index]; if( list == 0 || ! list->Detach(t) ) return 0; else { if( list->IsEmpty() ) { delete Table[index]; Table[index] = 0; } ItemsInContainer--; return 1; } } template void TMHashTableImp::ForEach( IterFunc iter, void *args ) { TMIVectorIteratorImp,Alloc> iterator(Table); while( iterator ) { TMListImp *list = iterator++; if( list != 0 ) list->ForEach(iter,args); } } template T *TMHashTableImp::Find( const T& t ) const { TMListImp *list = Table[GetHashValue(t)]; return list ? list->Find(t) : 0; } template void TMHashTableImp::Flush() { for( unsigned i = 0; i < TableSize(); i++ ) { if( Table[i] != 0 ) { Table[i]->Flush(); delete Table[i]; Table[i] = 0; } } ItemsInContainer = 0; } /*------------------------------------------------------------------------*/ /* */ /* template class THashTableImp */ /* template class THashTableIteratorImp */ /* */ /* Implements a hash table of objects of type T. */ /* */ /*------------------------------------------------------------------------*/ template class THashTableIteratorImp; template class THashTableImp : public TMHashTableImp { public: friend THashTableIteratorImp; THashTableImp( unsigned aPrime = DEFAULT_HASH_TABLE_SIZE ) : TMHashTableImp(aPrime) { } }; template class THashTableIteratorImp : public TMHashTableIteratorImp { public: THashTableIteratorImp( const THashTableImp& h ) : TMHashTableIteratorImp(h) { } }; /*------------------------------------------------------------------------*/ /* */ /* template class TMIHashTableImp */ /* template class TMIHashTableIteratorImp */ /* */ /* Implements a managed hash table of pointers to objects of type T, */ /* using the storage storage allocator A. */ /* */ /*------------------------------------------------------------------------*/ template class TMIHashTableIteratorImp; template class TMIHashTableImp : private TMInternalHashImp > { typedef TMInternalHashImp > Parent; public: friend TMIHashTableIteratorImp; typedef void (*IterFunc)(T&, void *); TMIHashTableImp( unsigned size = DEFAULT_HASH_TABLE_SIZE ) : TMInternalHashImp >(size) { } int Add( T *t ); int Detach( T *t, int del = 0 ); void ForEach( IterFunc iter, void *args ); T *Find( const T *t ) const; void Flush( int del = 0 ); Parent::GetItemsInContainer; Parent::IsEmpty; Parent::operator delete; private: unsigned GetHashValue( const TVoidPointer& t ) const { return HashValue(*STATIC_CAST(T *,STATIC_CAST(void *,t)))%TableSize(); } }; template class TMIHashTableIteratorImp : private TMInternalHashTableIteratorImp > { typedef TMInternalHashTableIteratorImp > Parent; public: TMIHashTableIteratorImp( const TMIHashTableImp& h ) : TMInternalHashTableIteratorImp >(h) { } T *Current() { return STATIC_CAST(T *,STATIC_CAST(void *,Parent::Current())); } T *operator ++ (int) { return STATIC_CAST(T *,STATIC_CAST(void *,Parent::operator++(1))); } T *operator ++ () { return STATIC_CAST(T *,STATIC_CAST(void *,Parent::operator++())); } Parent::Restart; Parent::operator int; }; template void TMIHashTableImp::ForEach( IterFunc iter, void *args ) { TMIVectorIteratorImp,Alloc> iterator(Table); while( iterator ) { if( iterator.Current() != 0 ) iterator.Current()->ForEach(iter,args); iterator++; } } template T *TMIHashTableImp::Find( const T *t ) const { TMIListImp *list = Table[GetHashValue(t)]; return list ? list->Find(t) : 0; } template int TMIHashTableImp::Add( T *t ) { unsigned index = GetHashValue(t); TMIListImp *list = Table[GetHashValue(t)]; if( list == 0 ) { list = Table[index] = new(*this)TMIListImp; } if( list == 0 ) return 0; else { list->Add(t); ItemsInContainer++; return 1; } } template int TMIHashTableImp::Detach( T *t, int del ) { unsigned index = GetHashValue(t); TMIListImp *list = Table[GetHashValue(t)]; if( list == 0 || ! list->Detach( t, del ) ) return 0; else { if( list->IsEmpty() ) { delete Table[index]; Table[index] = 0; } ItemsInContainer--; return 1; } } template void TMIHashTableImp::Flush( int del ) { for( unsigned i = 0; i < TableSize(); i++ ) { if( Table[i] != 0 ) { Table[i]->Flush(del); delete Table[i]; Table[i] = 0; } } ItemsInContainer = 0; } /*------------------------------------------------------------------------*/ /* */ /* template class TIHashTableImp */ /* template class TIHashTableIteratorImp */ /* */ /* Implements a hash table of pointers to objects of type T */ /* */ /*------------------------------------------------------------------------*/ template class TIHashTableIteratorImp; template class TIHashTableImp : public TMIHashTableImp { public: friend TIHashTableIteratorImp; TIHashTableImp( unsigned aPrime = DEFAULT_HASH_TABLE_SIZE ) : TMIHashTableImp( aPrime) { } }; template class TIHashTableIteratorImp : public TMIHashTableIteratorImp { public: TIHashTableIteratorImp( const TIHashTableImp& h ) : TMIHashTableIteratorImp(h) { } }; #if defined( BI_CLASSLIB_NO_po ) #pragma option -po. #endif #pragma option -Vo. #endif // CLASSLIB_HASHIMP_H