4 // Permission to use, copy, modify, distribute and sell this software
5 // and its documentation for any purpose is hereby granted without
6 // fee, provided that the above copyright notice appear in all copies
7 // and that both that copyright notice and this permission notice
8 // appear in supporting documentation. Kevin Atkinson makes no
9 // representations about the suitability of this software for any
10 // purpose. It is provided "as is" without express or implied
13 #ifndef __aspeller_vector_hash_hh__
14 #define __aspeller_vector_hash_hh__
20 #undef REL_OPS_POLLUTION // FIXME
25 // This hash table is implemnted as a Open Address Hash Table
26 // which uses a Vector like object to store its data. So
27 // it might even be considered an adapter
30 ////////////////////////////////////////////////////////
32 // Vector Hash Table Iterator //
34 ////////////////////////////////////////////////////////
36 // This is an internal object and should not be created
37 // directly. Instead use VectorHashTable::begin() and end()
39 template <class Parms>
40 // Parms is expected to have:
41 // typename HashTable;
42 // typename TableIter;
47 friend bool operator== (VHTIterator<T>, VHTIterator<T>);
48 #ifndef REL_OPS_POLLUTION
50 friend bool operator!= (VHTIterator<T>, VHTIterator<T>);
52 public: //but don't use
53 typedef typename Parms::TableIter TableIter;
54 typedef typename Parms::HashTable HashTable;
56 HashTable * hash_table;
58 //typedef std::bidirectional_iterator_tag iterator_category;
59 typedef typename Parms::Value value_type;
60 // these cause problems for SUNPRO_CC
61 //typedef typename std::iterator_traits<TableIter>::difference_type difference_type;
62 //typedef typename std::iterator_traits<TableIter>::pointer pointer;
63 //typedef typename std::iterator_traits<TableIter>::reference reference;
65 //VHTIterator vector_iterator() const {return pos;}
67 VHTIterator(TableIter p, HashTable *ht) : pos(p), hash_table(ht) {}
68 VHTIterator(TableIter p, HashTable *ht, bool)
69 : pos(p), hash_table(ht)
71 while (pos != hash_table->vector().end()
72 && hash_table->parms().is_nonexistent(*pos) )
76 value_type & operator * () const {return *pos;}
77 value_type * operator -> () const {return &*pos;}
79 bool at_end() const {return pos == hash_table->vector().end();}
81 VHTIterator& operator++ () {
84 if (pos == hash_table->vector().end()) break;
85 if (!hash_table->parms().is_nonexistent(*pos)) break;
90 VHTIterator operator++ (int) {
91 VHTIterator temp = *this;
96 VHTIterator& operator-- () {
99 if (pos < hash_table->vector().begin()) break;
100 if (!hash_table->parms().is_nonexistent_func(*pos)) break;
105 VHTIterator operator-- (int) {
106 VHTIterator temp = *this;
112 template <class Parms>
114 bool operator== (VHTIterator<Parms> rhs, VHTIterator<Parms> lhs)
116 return rhs.pos == lhs.pos;
119 #ifndef REL_OPS_POLLUTION
121 template <class Parms>
123 bool operator!= (VHTIterator<Parms> rhs, VHTIterator<Parms> lhs)
125 return rhs.pos != lhs.pos;
130 ////////////////////////////////////////////////////////
132 // Vector Hash Table //
134 ////////////////////////////////////////////////////////
136 // Parms is expected to have the following methods
138 // typedef Vector::value_type Value
139 // typedef Vector::size_type Size
143 // bool equal(Key, Key)
145 // bool is_nonexistent(Value)
146 // void make_nonexistent(Value &)
148 template <class Parms>
149 class VectorHashTable {
150 typedef typename Parms::Vector Vector;
152 typedef typename Parms::Vector vector_type;
153 typedef typename Vector::value_type value_type;
154 typedef typename Vector::size_type size_type;
155 typedef typename Vector::difference_type difference_type;
157 typedef typename Vector::pointer pointer;
158 typedef typename Vector::reference reference;
159 typedef typename Vector::const_reference const_reference;
161 typedef typename Parms::Key key_type;
162 public: // but don't use
163 typedef VectorHashTable<Parms> HashTable;
168 typedef Parms parms_type;
169 const parms_type & parms() const {return parms_;}
172 // These public functions are very dangerous and should be used with
173 // great care as the modify the internal structure of the object
174 Vector & vector() {return vector_;}
175 const Vector & vector() const {return vector_;}
176 parms_type & parms() {return parms_;}
178 void set_size(size_type s) {size_ = s;}
184 public: // but don't use
185 typedef typename Vector::iterator vector_iterator;
186 typedef typename Vector::const_iterator const_vector_iterator;
189 int hash1(const key_type &d) const {
190 return parms_.hash(d) % bucket_count();
192 int hash2(const key_type &d) const {
193 return 1 + (parms_.hash(d) % (bucket_count() - 2));
196 struct NonConstParms {
197 typedef VectorHashTable HashTable;
198 typedef vector_iterator TableIter;
199 typedef value_type Value;
202 typedef const VectorHashTable HashTable;
203 typedef const_vector_iterator TableIter;
204 typedef const value_type Value;
207 typedef VHTIterator<NonConstParms> iterator;
208 typedef VHTIterator<ConstParms> const_iterator;
211 void nonexistent_vector();
214 VectorHashTable(size_type i, const Parms & p = Parms());
216 VectorHashTable(const Parms & p = Parms())
217 : parms_(p), vector_(19), size_(0) {nonexistent_vector();}
219 iterator begin() {return iterator(vector_.begin(), this, 1);}
220 iterator end() {return iterator(vector_.end(), this);}
221 const_iterator begin() const {return const_iterator(vector_.begin(), this, 1);}
222 const_iterator end() const {return const_iterator(vector_.end(), this);}
224 std::pair<iterator, bool> insert(const value_type &);
225 bool have(const key_type &) const;
227 iterator find(const key_type&);
228 const_iterator find(const key_type&) const;
230 size_type erase(const key_type &key);
231 void erase(const iterator &p);
233 size_type size() const {return size_;}
234 bool empty() const {return !size_;}
236 void swap(VectorHashTable &);
237 void resize(size_type);
238 size_type bucket_count() const {return vector_.size();}
239 double load_factor() const {return static_cast<double>(size())/bucket_count();}
244 public: // but don't use
245 const vector_type * vector;
251 FindIterator(const HashTable * ht, const key_type & k);
253 bool at_end() const {return parms->is_nonexistent((*vector)[i]);}
255 FindIterator & operator ++() {adv(); return *this;}
257 friend class FindIterator;
260 class ConstFindIterator : public FindIterator
263 ConstFindIterator() {}
264 ConstFindIterator(const HashTable * ht, const key_type & k)
265 : FindIterator(ht,k) {}
266 const value_type & deref() const {return (*this->vector)[this->i];}
269 class MutableFindIterator : public FindIterator
272 MutableFindIterator() {}
273 MutableFindIterator(HashTable * ht, const key_type & k)
274 : FindIterator(ht,k) {}
275 value_type & deref() const {
276 return (*const_cast<vector_type *>(this->vector))[this->i];
280 ConstFindIterator multi_find(const key_type & k) const {
281 return ConstFindIterator(this, k);
284 MutableFindIterator multi_find(const key_type & k) {
285 return MutableFindIterator(this, k);