home *** CD-ROM | disk | FTP | other *** search
- #ifndef __RWTVHDICT_H__
- #define __RWTVHDICT_H__
- pragma push_align_members(64);
-
- /*
- * RWTValHashDictionary: A parameterized hashing dictionary of keys K and values V.
- *
- * $Header: E:/vcs/rw/tvhdict.h_v 1.1 04 Mar 1992 10:16:46 KEFFER $
- *
- ****************************************************************************
- *
- * Rogue Wave Software, Inc.
- * P.O. Box 2328
- * Corvallis, OR 97339
- *
- * Copyright (C) 1992. This software is subject to copyright
- * protection under the laws of the United States and other countries.
- *
- ***************************************************************************
- *
- * $Log: E:/vcs/rw/tvhdict.h_v $
- *
- * Rev 1.1 04 Mar 1992 10:16:46 KEFFER
- *
- *
- * Rev 1.0 02 Mar 1992 16:10:54 KEFFER
- * Initial revision.
- */
-
- //$DECLARE_TEMPLATE
-
- #include "rw/tvsldict.h"
- #include "rw/tvvector.h"
-
- template <class K, class V> class RWTValHashDictionary {
-
- typedef RWTValSlistDictionary<K,V> CHAINDICT;
- typedef RWTValSlistDictionaryIterator<K,V> CHAINDICTITERATOR;
- typedef RWTValVector<CHAINDICT*> CHAINVEC;
- friend class RWTValHashDictionaryIterator<K,V>;
-
- protected:
-
- CHAINVEC _table;
- unsigned _nitems;
- unsigned (*_hashFun)(const K&); // User-supplied hashing function
-
- int hashIndex(const K& val) const {return (int)((*_hashFun)(val) % _table.length());}
-
- public:
-
- // Constructors:
- RWTValHashDictionary(unsigned (*hashKey)(const K&), unsigned size = RWDEFAULT_CAPACITY);
- RWTValHashDictionary(const RWTValHashDictionary<K,V>&);
- ~RWTValHashDictionary() {clear();}
-
- // Operators:
- RWTValHashDictionary& operator=(const RWTValHashDictionary<K,V>&);
- // Look up key, add if not there:
- V& operator[](K key);
-
- // Member functions:
- void applyToKeyAndValue(void (*applyFun)(K,V&,void*), void*);
- void clear();
- RWBoolean contains(K) const; // Contain key?
- unsigned entries() const {return _nitems;}
- RWBoolean isEmpty() const {return _nitems==0;}
- RWBoolean find(K key, K& retKey) const; // Returns key in "retKey" if found
- RWBoolean findValue(K key, V& retVal) const; // Returns value in "retVal" if found
- RWBoolean findKeyAndValue(K key, K& retKey, V& retVal) const;
- void insertKeyAndValue(K key, V value)
- {(*this)[key] = value;}
- RWBoolean remove(K);
- void resize(unsigned);
- };
-
-
-
- /****************************************************************
- * *
- * Declarations for RWTValHashDictionaryIterator<K,V> *
- * *
- ****************************************************************/
-
- template <class K, class V>
- class RWTValHashDictionaryIterator {
-
- // For convenience in what follows:
- typedef RWTValHashDictionary<K,V> HASHDICT;
- typedef RWTValSlistDictionary<K,V> CHAINDICT;
- typedef RWTValSlistDictionaryIterator<K,V> CHAINDICTITERATOR;
-
- HASHDICT* _myHash;
- int _idx;
- CHAINDICTITERATOR* _iterator;
-
- void nextChain(); // Advance to the next chain
-
- // Disallow postfix increment. Unless we hide it, some compilers will
- // substitute the prefix increment operator in its place.
- RWBoolean operator++(int);
-
- public:
-
- RWTValHashDictionaryIterator(HASHDICT& s);
-
- RWBoolean operator++(); // Advance and test
- HASHDICT* container() const {return _myHash;}
- K key() const {return _iterator->key();}
- void reset();
- void reset(HASHDICT& s);
- V value() const {return _iterator->value();}
- };
-
- //$IMPLEMENT_TEMPLATE
-
- /****************************************************************
- * *
- * Definitions for RWTValHashDictionary<T> *
- * *
- ****************************************************************/
-
- template <class K, class V>
- RWTValHashDictionary<K,V>::RWTValHashDictionary(unsigned (*hashFun)(const K&), unsigned size) :
- _table(size, rwnil),
- _nitems(0),
- _hashFun(hashFun)
- {
- }
-
- template <class K, class V>
- RWTValHashDictionary<K,V>::RWTValHashDictionary(const RWTValHashDictionary<K,V>& v) :
- _table(v._table.length(), rwnil),
- _nitems(v._nitems),
- _hashFun(v._hashFun)
- {
- int N = _table.length();
- for (int i=0; i<N; i++){
- if (v._table(i)) _table(i) = new CHAINDICT(*v._table(i));
- }
- }
-
- template <class K, class V> RWTValHashDictionary<K,V>&
- RWTValHashDictionary<K,V>::operator=(const RWTValHashDictionary<K,V>& v)
- {
- int N;
- clear();
- _table.reshape(N=v._table.length());
- _hashFun = v._hashFun;
- for (int i=0; i<N; i++){
- if (v._table(i)) _table(i) = new CHAINDICT(*v._table(i));
- }
- _nitems = v._nitems;
- return *this;
- }
-
- template <class K, class V> V&
- RWTValHashDictionary<K,V>::operator[](K key)
- {
- int idx = hashIndex(key);
- CHAINDICT* chain = _table(idx);
- if (chain==rwnil) _table(idx) = chain = new CHAINDICT;
- unsigned N = chain->entries();
- V& val = chain->operator[](key);
- if (N!=chain->entries()) _nitems++; // Ugly, I know.
- return val;
- }
-
- template <class K, class V> void
- RWTValHashDictionary<K,V>::applyToKeyAndValue(void (*applyFun)(K,V&,void*), void* a)
- {
- int N = (int)_table.length();
- for (int i=0; i<N; i++) {
- if (_table(i)) _table(i)->applyToKeyAndValue(applyFun, a);
- }
- }
-
- template <class K, class V> void
- RWTValHashDictionary<K,V>::clear()
- {
- int i = _table.length();
- while (i--) { delete _table(i); _table(i) = rwnil; }
-
- _nitems = 0;
- }
-
- template <class K, class V> RWBoolean
- RWTValHashDictionary<K,V>::contains(K key) const
- {
- CHAINDICT* chain = _table(hashIndex(key));
- return chain ? chain->contains(key) : FALSE;
- }
-
- // Returns TRUE if the key is in the collection. Puts the found
- // key in retKey.
- template <class K, class V> RWBoolean
- RWTValHashDictionary<K,V>::find(K key, K& retKey) const
- {
- CHAINDICT* chain = _table(hashIndex(key));
- return chain ? chain->find(key, retKey) : FALSE;
- }
-
- template <class K, class V> RWBoolean
- RWTValHashDictionary<K,V>::findValue(K key, V& retVal) const
- {
- CHAINDICT* chain = _table(hashIndex(key));
- return chain ? chain->findValue(key, retVal) : FALSE;
- }
-
- template <class K, class V> RWBoolean
- RWTValHashDictionary<K,V>::findKeyAndValue(K key, K& retKey, V& retVal) const
- {
- CHAINDICT* chain = _table(hashIndex(key));
- return chain ? chain->findKeyAndValue(key, retKey, retVal) : FALSE;
- }
-
- template <class K, class V> RWBoolean
- RWTValHashDictionary<K,V>::remove(K key)
- {
- CHAINDICT* chain = _table(hashIndex(key));
- if (chain) {
- if (chain->remove(key)) {_nitems--; return TRUE;}
- }
- return FALSE;
- }
-
- template <class K, class V> void
- RWTValHashDictionary<K,V>::resize(unsigned N)
- {
- #ifdef RWDEBUG
- unsigned oldNitems = _nitems;
- #endif
- CHAINVEC tempTable =_table; // Save old values
- _table.reshape(N); // Resize internal table
- _table = rwnil; // Zero it
- _nitems = 0;
-
- // Now iterate through the old collection, inserting each item
- for (int i=0; i<tempTable.length(); i++){
- if (tempTable(i)) {
- CHAINDICTITERATOR next(*tempTable(i));
- while ( ++next ) insertKeyAndValue(next.key(), next.value());
- delete tempTable(i);
- }
- }
- #ifdef RWDEBUG
- assert(_nitems==oldNitems); // Make sure we got 'em all.
- #endif
- }
-
-
-
- /****************************************************************
- * *
- * Definitions for RWTValHashDictionaryIterator<T> *
- * *
- ****************************************************************/
-
- template <class K, class V>
- RWTValHashDictionaryIterator<K,V>::RWTValHashDictionaryIterator(RWTValHashDictionary<K,V>& d) :
- _myHash(&d),
- _idx(-1),
- _iterator(rwnil)
- {
- nextChain(); // Advance to the first chain
- }
-
- template <class K, class V> RWBoolean
- RWTValHashDictionaryIterator<K,V>::operator++()
- {
- while (_iterator && ++(*_iterator)==FALSE){
- nextChain();
- }
- return _iterator!=rwnil;
- }
-
- template <class K, class V> void
- RWTValHashDictionaryIterator<K,V>::reset()
- {
- _idx = -1;
- nextChain();
- }
-
- template <class K, class V> void
- RWTValHashDictionaryIterator<K,V>::reset(RWTValHashDictionary<K,V>& t)
- {
- _myHash = &t;
- _idx = -1;
- nextChain();
- }
-
- // Advance the iterator to work on the next chain.
- template <class K, class V> void
- RWTValHashDictionaryIterator<K,V>::nextChain()
- {
- while (++_idx < _myHash->_table.length()) {
- if (_myHash->_table(_idx)) {
- if (_iterator) _iterator->reset(*_myHash->_table(_idx));
- else _iterator = new CHAINDICTITERATOR(*_myHash->_table(_idx));
- return;
- }
- }
- delete _iterator;
- _iterator = rwnil;
- }
-
- pragma pop_align_members();
- #endif /* __RWTVDICT_H__ */
-