-
Notifications
You must be signed in to change notification settings - Fork 1
/
hashtable.h
108 lines (87 loc) · 3.7 KB
/
hashtable.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/* File: hashtable.h
* -----------------
* This is a simple table for storing values associated with a string
* key, supporting simple operations for Enter and Lookup. It is not
* much more than a thin cover over the STL associative map container,
* but hides the awkward C++ template syntax and provides a more
* familiar interface.
*
* The keys are always strings, but the values can be of any type
* (ok, that's actually kind of a fib, it expects the type to be
* some sort of pointer to conform to using NULL for "not found").
* The typename for a Hashtable includes the value type in angle
* brackets, e.g. if the table is storing char *as values, you
* would use the type name Hashtable<char*>. If storing values
* that are of type Decl*, it would be Hashtable<Decl*>.
* The same notation is used on the matching iterator for the table,
* i.e. a Hashtable<char*> supports an Iterator<char*>.
*
* An iterator is provided for iterating over the entries in a table.
* The iterator walks through the values, one by one, in alphabetical
* order by the key. Sample iteration usage:
*
* void PrintNames(Hashtable<Decl*> *table)
* {
* Iterator<Decl*> iter = table->GetIterator();
* Decl *decl;
* while ((decl = iter.GetNextValue()) != NULL) {
* printf("%s\n", decl->GetName());
* }
* }
*/
#ifndef _H_hashtable
#define _H_hashtable
#include <map>
#include <string.h>
struct ltstr {
bool operator()(const char* s1, const char* s2) const
{ return strcmp(s1, s2) < 0; }
};
template <class Value> class Iterator;
template<class Value> class Hashtable {
private:
std::multimap<const char*, Value, ltstr> mmap;
public:
// ctor creates a new empty hashtable
Hashtable() {}
// Returns number of entries currently in table
int NumEntries() const;
// Associates value with key. If a previous entry for
// key exists, the bool parameter controls whether
// new value overwrites the previous (removing it from
// from the table entirely) or just shadows it (keeps previous
// and adds additional entry). The lastmost entered one for an
// key will be the one returned by Lookup.
void Enter(const char *key, Value value,
bool overwriteInsteadOfShadow = true);
// Removes a given key->value pair. Any other values
// for that key are not affected. If this is the last
// remaining value for that key, the key is removed
// entirely.
void Remove(const char *key, Value value);
// Returns value stored under key or NULL if no match.
// If more than one value for key (ie shadow feature was
// used during Enter), returns the lastmost entered one.
Value Lookup(const char *key);
// Returns an Iterator object (see below) that can be used to
// visit each value in the table in alphabetical order.
Iterator<Value> GetIterator();
};
/* Don't worry too much about how the Iterator is implemented, see
* sample usage above for how to iterate over a hashtable using an
* iterator.
*/
template<class Value> class Iterator {
friend class Hashtable<Value>;
private:
typename std::multimap<const char*, Value , ltstr>::iterator cur, end;
Iterator(std::multimap<const char*, Value, ltstr>& t)
: cur(t.begin()), end(t.end()) {}
public:
// Returns current value and advances iterator to next.
// Returns NULL when there are no more values in table
// Visits every value, even those that are shadowed.
Value GetNextValue();
};
#include "hashtable.cc" // icky, but allows implicit template instantiation
#endif