30 |
|
|
31 |
template <class T> |
template <class T> |
32 |
class Dict { |
class Dict { |
|
|
|
|
/* |
|
|
** Types |
|
|
*/ |
|
33 |
public: |
public: |
34 |
typedef std::pair<const std::string, T> value_type; |
typedef std::pair<const std::string, T> value_type; |
35 |
typedef std::string key_type; |
typedef std::string key_type; |
36 |
typedef int size_type; |
typedef size_t size_type; |
37 |
|
|
38 |
private: |
private: |
39 |
struct Entry { |
struct Entry { |
42 |
Entry *next; |
Entry *next; |
43 |
}; |
}; |
44 |
|
|
45 |
/* |
/* |
46 |
** Iterator |
** Iterator |
47 |
*/ |
*/ |
48 |
template <class U> |
template <class U> |
49 |
class Iter { |
class Iter { |
50 |
public: |
public: |
56 |
|
|
57 |
Iter() : dict(0), idx(0), cur(0) {} |
Iter() : dict(0), idx(0), cur(0) {} |
58 |
Iter(const Dict<T> *d, size_type i, Entry *c) |
Iter(const Dict<T> *d, size_type i, Entry *c) |
59 |
: dict(d),idx(i),cur(c) |
: dict(d),idx(i),cur(c) |
60 |
{} |
{} |
61 |
Iter(const Dict<T> *d) :dict(d) |
Iter(const Dict<T> *d) :dict(d) |
62 |
{ |
{ |
75 |
|
|
76 |
reference operator*() {return cur->pair;} |
reference operator*() {return cur->pair;} |
77 |
pointer operator->() {return &cur->pair;} |
pointer operator->() {return &cur->pair;} |
78 |
Iter &operator++() |
Iter &operator++() { |
79 |
{ |
if ((cur=cur->next) == 0) { |
|
if ((cur=cur->next) == 0) |
|
|
{ |
|
80 |
for (++idx; idx<dict->nbuckets; ++idx) |
for (++idx; idx<dict->nbuckets; ++idx) |
81 |
if ((cur=dict->hashtab[idx]) != 0) |
if ((cur=dict->hashtab[idx]) != 0) |
82 |
return *this; |
return *this; |
98 |
Entry *cur; |
Entry *cur; |
99 |
}; |
}; |
100 |
|
|
|
/* |
|
|
** Iterator access |
|
|
*/ |
|
101 |
public: |
public: |
102 |
typedef Iter<value_type> iterator; |
typedef Iter<value_type> iterator; |
103 |
typedef Iter<const value_type> const_iterator; |
typedef Iter<const value_type> const_iterator; |
104 |
friend class iterator; |
friend class iterator; |
105 |
friend class const_iterator; |
friend class const_iterator; |
106 |
|
|
107 |
|
Dict(size_type table_size = 257); |
108 |
|
~Dict(); |
109 |
|
|
110 |
|
size_type size() const { return nentries; } |
111 |
|
|
112 |
iterator begin() { return iterator(this); } |
iterator begin() { return iterator(this); } |
113 |
iterator end() { return iterator(); } |
iterator end() { return iterator(); } |
114 |
const_iterator begin() const { return const_iterator(this); } |
const_iterator begin() const { return const_iterator(this); } |
115 |
const_iterator end() const { return const_iterator(); } |
const_iterator end() const { return const_iterator(); } |
116 |
|
|
|
/* |
|
|
** Construction / destruction |
|
|
*/ |
|
|
Dict(size_type table_size = 257); |
|
|
|
|
|
private: |
|
|
Dict (const Dict<T> &d) |
|
|
: nentries(d.nentries), |
|
|
nbuckets(d.nbuckets), |
|
|
hashtab(new Entry*[nbuckets]) |
|
|
{ |
|
|
for (size_type i=0; i<nbuckets; ++i) { |
|
|
Entry *e = d.hashtab[i]; |
|
|
hashtab[i] = 0; // XXX Fix |
|
|
} |
|
|
} |
|
|
Dict &operator==(const Dict<T> &d); |
|
|
public: |
|
|
|
|
|
~Dict() { |
|
|
clear(); |
|
|
delete [] hashtab; |
|
|
} |
|
|
|
|
|
size_type size() const { return nentries; } |
|
|
|
|
|
/* |
|
|
** Lookup of keys |
|
|
*/ |
|
117 |
iterator find (const std::string &key); |
iterator find (const std::string &key); |
118 |
const_iterator find (const std::string &key) const; |
const_iterator find (const std::string &key) const; |
119 |
|
|
135 |
|
|
136 |
bool has_key(const std::string &key) const; |
bool has_key(const std::string &key) const; |
137 |
|
|
138 |
/* |
/*! Insert a new element into the table. */ |
139 |
** Insertion of new elements. |
void insert(const std::string &key, const T &val); |
|
*/ |
|
|
void insert(const std::string &key, const T &val) { |
|
|
unsigned h = hash(key) % nbuckets; |
|
|
Entry *e = new Entry(key, val); |
|
|
e->next = hashtab[h]; |
|
|
hashtab[h] = e; |
|
|
nentries += 1; |
|
|
} |
|
|
|
|
|
/* |
|
|
** Removal of all or specific elements |
|
|
*/ |
|
140 |
|
|
141 |
/*! Remove all entries from the hash table. */ |
/*! Remove all entries from the hash table. */ |
142 |
void clear(); |
void clear(); |
145 |
void remove(const std::string &key); |
void remove(const std::string &key); |
146 |
|
|
147 |
private: |
private: |
148 |
Entry *find_entry(const std::string &key) const { |
Entry *find_entry(const std::string &key) const; |
|
unsigned h = hash(key) % nbuckets; |
|
|
for (Entry *e = hashtab[h]; e != 0; e=e->next) |
|
|
if (e->pair.first == key) |
|
|
return e; |
|
|
return 0; |
|
|
} |
|
149 |
|
|
150 |
|
/* |
151 |
|
** Variables |
152 |
|
*/ |
153 |
size_type nentries; // Number of entries |
size_type nentries; // Number of entries |
154 |
size_type nbuckets; // Number of buckets in `hashtab' |
size_type nbuckets; // Number of buckets in `hashtab' |
155 |
Entry **hashtab; |
Entry **hashtab; |
156 |
|
private: |
157 |
|
// Copying not implemented yet |
158 |
|
Dict (const Dict<T> &d) |
159 |
|
: nentries(d.nentries), |
160 |
|
nbuckets(d.nbuckets), |
161 |
|
hashtab(new Entry*[nbuckets]) |
162 |
|
{ |
163 |
|
for (size_type i=0; i<nbuckets; ++i) { |
164 |
|
Entry *e = d.hashtab[i]; |
165 |
|
hashtab[i] = 0; // XXX Fix |
166 |
|
} |
167 |
|
} |
168 |
|
Dict &operator=(const Dict<T> &d); |
169 |
}; |
}; |
170 |
|
|
171 |
|
|
172 |
|
//---------------------------------------- |
173 |
|
// Dict implementation |
174 |
|
//---------------------------------------- |
175 |
|
|
176 |
template <class T> |
template <class T> |
177 |
Dict<T>::Dict(size_type table_size) |
Dict<T>::Dict(size_type table_size) |
178 |
: nentries(0), nbuckets (table_size), hashtab (new Entry*[nbuckets]) |
: nentries(0), nbuckets (table_size), hashtab (new Entry*[nbuckets]) |
181 |
hashtab[i] = 0; |
hashtab[i] = 0; |
182 |
} |
} |
183 |
|
|
184 |
|
template <class T> |
185 |
|
Dict<T>::~Dict() { |
186 |
|
clear(); |
187 |
|
delete [] hashtab; |
188 |
|
} |
189 |
|
|
190 |
template <class T> |
template <class T> |
191 |
typename Dict<T>::iterator |
typename Dict<T>::iterator |
210 |
} |
} |
211 |
|
|
212 |
template <class T> |
template <class T> |
213 |
void |
void Dict<T>::clear() |
|
Dict<T>::clear() |
|
214 |
{ |
{ |
215 |
for (int i=0; i<nbuckets; ++i) { |
for (size_type i=0; i<nbuckets; ++i) { |
216 |
Entry *cur, *next; |
Entry *cur, *next; |
217 |
for (cur = hashtab[i]; cur != 0; cur=next) { |
for (cur = hashtab[i]; cur != 0; cur=next) { |
218 |
next = cur->next; |
next = cur->next; |
224 |
} |
} |
225 |
|
|
226 |
template <class T> |
template <class T> |
227 |
void |
void Dict<T>::insert (const std::string &key, const T &val) |
228 |
Dict<T>::remove(const std::string &key) |
{ |
229 |
|
unsigned h = hash(key) % nbuckets; |
230 |
|
Entry *e = new Entry(key, val); |
231 |
|
e->next = hashtab[h]; |
232 |
|
hashtab[h] = e; |
233 |
|
nentries += 1; |
234 |
|
} |
235 |
|
|
236 |
|
|
237 |
|
template <class T> |
238 |
|
void Dict<T>::remove(const std::string &key) |
239 |
{ |
{ |
240 |
unsigned h = hash(key) % nbuckets; |
unsigned h = hash(key) % nbuckets; |
241 |
Entry *e = hashtab[h]; |
Entry *e = hashtab[h]; |
254 |
} |
} |
255 |
|
|
256 |
template <class T> |
template <class T> |
257 |
bool |
bool Dict<T>::has_key(const std::string &key) const { |
|
Dict<T>::has_key(const std::string &key) const |
|
|
{ |
|
258 |
return find_entry(key) != 0; |
return find_entry(key) != 0; |
259 |
} |
} |
260 |
|
|
261 |
|
template <class T> |
262 |
|
typename Dict<T>::Entry * |
263 |
|
Dict<T>::find_entry(const std::string &key) const { |
264 |
|
unsigned h = hash(key) % nbuckets; |
265 |
|
for (Entry *e = hashtab[h]; e != 0; e=e->next) |
266 |
|
if (e->pair.first == key) |
267 |
|
return e; |
268 |
|
return 0; |
269 |
|
} |
270 |
|
|
271 |
|
|
272 |
} |
} |
273 |
#endif |
#endif |