Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Dictionary.inl
Go to the documentation of this file.
1 /* Project FoundationEx
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: FoundationEx
6  FILE: Dictionary.inl
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Implementation of the Dictionary class
13 */
14 
15 #ifndef NDEBUG
16 #define DICT_CHECK(a, b) if ((a) == 0) throw b;
17 #else
18 #define DICT_CHECK(a, b)
19 #endif
20 
21 const int CHAINS = 256;
22 
23 // +-------------------------------------------------------------------+
24 
25 template <class T> Dictionary<T>::Dictionary()
26  : items(0)
27 { init(); }
28 
29 template <class T> Dictionary<T>::~Dictionary()
30 { clear(); }
31 
32 // +-------------------------------------------------------------------+
33 
34 template <class T>
36 {
37  items = 0;
38  memset(table, 0, CHAINS*sizeof(PTR));
39 }
40 
41 template <class T>
43 {
44  for (int i = 0; i < CHAINS; i++) {
45  DictionaryCell<T>* link = table[i];
46 
47  while (link) {
48  DictionaryCell<T>* n = link->next;
49  delete link;
50  link = n;
51  }
52  }
53 
54  init();
55 }
56 
57 // +-------------------------------------------------------------------+
58 
59 template <class T>
61 {
62  int idx = key.hash() % CHAINS;
63  DictionaryCell<T>* cell = table[idx];
64 
65  if (cell == 0) { // empty chain
66  items++;
67 
68 #ifdef MEM_DEBUG
69  cell = new(__FILE__,__LINE__) DictionaryCell<T>(key);
70 #else
71  cell = new DictionaryCell<T>(key);
72 #endif
73 
74  table[idx] = cell;
75 
76  return cell->value;
77  }
78  else { // search for key
79  while (cell->next && cell->key != key)
80  cell = cell->next;
81 
82  if (cell->key != key) { // not found in chain
83  items++;
84 
85 #ifdef MEM_DEBUG
86  cell->next = new(__FILE__,__LINE__) DictionaryCell<T>(key);
87 #else
88  cell->next = new DictionaryCell<T>(key);
89 #endif
90 
91  return cell->next->value;
92  }
93  else { // found: return it!
94  return cell->value;
95  }
96  }
97 }
98 
99 // +-------------------------------------------------------------------+
100 
101 template <class T>
102 void Dictionary<T>::insert(const Text& key, const T& val)
103 {
104  T& value = operator[](key);
105  value = val;
106 }
107 
108 // +-------------------------------------------------------------------+
109 
110 template <class T>
111 void Dictionary<T>::remove(const Text& key)
112 {
113  int idx = key.hash() % CHAINS;
114  DictionaryCell<T>* cell = table[idx];
115 
116  if (cell == 0) { // empty chain
117  return;
118  }
119  else { // search for key
120  while (cell->next && cell->key != key)
121  cell = cell->next;
122 
123  if (cell->key != key) { // not found in chain
124  return;
125  }
126  else { // found: remove it!
127  if (table[idx] == cell) {
128  table[idx] = cell->next;
129  delete cell;
130  }
131  else {
132  DictionaryCell<T>* p = table[idx];
133  while (p->next != cell)
134  p = p->next;
135  p->next = cell->next;
136  delete cell;
137  }
138  }
139  }
140 }
141 
142 // +-------------------------------------------------------------------+
143 
144 template <class T>
145 int Dictionary<T>::contains(const Text& key) const
146 {
147  int idx = key.hash() % CHAINS;
148  DictionaryCell<T>* cell = table[idx];
149 
150  if (cell != 0) {
151  while (cell->next && cell->key != key)
152  cell = cell->next;
153 
154  if (cell->key == key)
155  return 1;
156  }
157 
158  return 0;
159 }
160 
161 // +-------------------------------------------------------------------+
162 
163 template <class T>
164 T Dictionary<T>::find(const Text& key, T defval) const
165 {
166  int idx = key.hash() % CHAINS;
167  DictionaryCell<T>* cell = table[idx];
168 
169  if (cell != 0) {
170  while (cell->next && cell->key != key)
171  cell = cell->next;
172 
173  if (cell->key == key)
174  return cell->value;
175  }
176 
177  return defval;
178 }
179 
180 // +-------------------------------------------------------------------+
181 
183  : dict(&d), chain(0), here(0)
184 { }
185 
187 { }
188 
189 // +-------------------------------------------------------------------+
190 
191 template <class T>
193 {
194  chain = 0;
195  here = 0;
196 }
197 
198 // +-------------------------------------------------------------------+
199 
200 template <class T>
202 {
203  return here->key;
204 }
205 
206 template <class T>
208 {
209  return here->value;
210 }
211 
212 // +-------------------------------------------------------------------+
213 
214 template <class T>
216 {
217  forth();
218  int more = chain < CHAINS;
219  return more;
220 }
221 
222 // +-------------------------------------------------------------------+
223 
224 template <class T>
226 {
227  if (here) {
228  here = here->next;
229  if (!here) // off the end of this chain
230  chain++;
231  }
232 
233  if (!here) {
234  while (!dict->table[chain] && chain < CHAINS)
235  chain++;
236 
237  if (chain < CHAINS)
238  here = dict->table[chain];
239  else
240  here = 0;
241  }
242 }
243 
244 // +-------------------------------------------------------------------+
245 
246 template <class T>
248 {
249  dict = &d;
250  reset();
251 }
252 
253 // +-------------------------------------------------------------------+
254 
255 template <class T>
257 {
258  return *dict;
259 }
260