00001 #ifndef GSGL_DATA_DICT_H
00002 #define GSGL_DATA_DICT_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "data/data.hpp"
00038 #include "data/exception.hpp"
00039 #include "data/comparable.hpp"
00040 #include "data/indexable.hpp"
00041 #include "data/pointer.hpp"
00042 #include "data/tuple.hpp"
00043 #include "data/list.hpp"
00044 #include "data/stack.hpp"
00045 #include "data/string.hpp"
00046
00047 #include <typeinfo>
00048
00049 namespace gsgl
00050 {
00051
00052 namespace data
00053 {
00054
00055 template <typename T, typename I>
00056 class dictionary_iterator;
00057
00058
00059
00060
00061
00062
00063
00064 template <typename T, typename I>
00065 class dictionary
00066 : public data_object,
00067 public iterable<T, dictionary_iterator<T,I> >,
00068 public indexable<T,I>
00069 {
00070 friend class dictionary_iterator<T,I>;
00071
00072
00073 struct dict_node
00074 {
00075 T item;
00076 I index;
00077
00078 dict_node *left;
00079 dict_node *right;
00080
00081 dict_node(const T & item, const I & index, dict_node *left = 0, dict_node *right = 0);
00082 ~dict_node();
00083
00084 dict_node *copy() const;
00085 };
00086
00087 mutable dict_node *root;
00088 gsgl::index_t count;
00089
00090 public:
00091 dictionary();
00092 dictionary(const dictionary &);
00093 dictionary & operator= (const dictionary &);
00094 virtual ~dictionary();
00095
00096
00097
00098 virtual gsgl::index_t size() { return count; }
00099 virtual void clear();
00100
00101
00102
00103
00104
00105 using iterable<T, dictionary_iterator<T,I> >::append;
00106 virtual void append(const T & item);
00107 virtual void insert(const iterator & i, const T & item);
00108 virtual void remove(const iterator & i);
00109
00110
00111
00112
00113
00114 virtual bool contains_index(const I & index) const;
00115 virtual const T & item(const I & index) const;
00116 virtual T & item(const I & index);
00117
00118
00119
00120
00121
00122 bool operator== (const dictionary<T,I> &) const;
00123 virtual void remove(const I & index);
00124
00125
00126
00127 private:
00128 T & get_item(const I & index, bool create_new = true);
00129
00130 dict_node *find_node(const I & index, dict_node ***link);
00131 void remove_node(dict_node *cur, dict_node **link);
00132 };
00133
00134
00135
00136
00137 template <typename T, typename I>
00138 dictionary<T,I>::dict_node::dict_node(const T & item, const I & index, dict_node *left, dict_node *right)
00139 : item(item), index(index), left(left), right(right)
00140 {
00141 }
00142
00143
00144 template <typename T, typename I>
00145 dictionary<T,I>::dict_node::~dict_node()
00146 {
00147 delete left;
00148 delete right;
00149 }
00150
00151
00152 template <typename T, typename I>
00153 typename dictionary<T,I>::dict_node *dictionary<T,I>::dict_node::copy() const
00154 {
00155 return new dict_node(item, index, left ? left->copy() : 0, right ? right->copy() : 0);
00156 }
00157
00158
00159
00160
00161 template <typename T, typename I>
00162 dictionary<T,I>::dictionary()
00163 : data_object(), iterable<T, dictionary_iterator<T,I> >(), indexable<T,I>(),
00164 root(0), count(0)
00165 {
00166 }
00167
00168
00169 template <typename T, typename I>
00170 dictionary<T,I>::dictionary(const dictionary & d)
00171 : data_object(), iterable<T, dictionary_iterator<T,I> >(), indexable<T,I>(),
00172 root(0), count(d.count)
00173 {
00174 if (d.root)
00175 root = d.root->copy();
00176 }
00177
00178
00179 template <typename T, typename I>
00180 dictionary<T,I> & dictionary<T,I>::operator= (const dictionary & d)
00181 {
00182 this->clear();
00183 if (d.root)
00184 root = d.root->copy();
00185 count = d.count;
00186 return *this;
00187 }
00188
00189
00190 template <typename T, typename I>
00191 dictionary<T,I>::~dictionary()
00192 {
00193 this->clear();
00194 }
00195
00196
00197 template <typename T, typename I>
00198 bool dictionary<T,I>::operator== (const dictionary<T,I> & d) const
00199 {
00200 typename const_iterator a = this->iter(), b = d.iter();
00201
00202 for (; a.is_valid() && b.is_valid(); ++a, ++b)
00203 {
00204 if (!(*a == *b))
00205 return false;
00206 }
00207
00208 if (a.is_valid() || b.is_valid())
00209 return false;
00210
00211 return true;
00212 }
00213
00214
00215 template <typename T, typename I>
00216 void dictionary<T,I>::clear()
00217 {
00218 delete root;
00219 root = 0;
00220 count = 0;
00221 }
00222
00223
00224 template <typename T, typename I>
00225 void dictionary<T,I>::append(const T & item)
00226 {
00227 throw internal_exception(__FILE__, __LINE__, L"It is an error to append a value alone to a dictionary.");
00228 }
00229
00230
00231 template <typename T, typename I>
00232 void dictionary<T,I>::insert(const iterator & i, const T & item)
00233 {
00234 throw internal_exception(__FILE__, __LINE__, L"It is an error to insert a value alone to a dictionary.");
00235 }
00236
00237
00238 template <typename T, typename I>
00239 void dictionary<T,I>::remove(const iterator & i)
00240 {
00241 remove(i.get_index());
00242 }
00243
00244
00245
00246
00247 template <typename T, typename I>
00248 void dictionary<T,I>::remove(const I & index)
00249 {
00250 if (root)
00251 {
00252 dict_node *cur, **link = &root;
00253 cur = find_node(index, &link);
00254
00255
00256 if (cur)
00257 {
00258 remove_node(cur, link);
00259 return;
00260 }
00261 }
00262
00263
00264 throw runtime_exception(L"Attempted to remove an invalid item from a dictionary.");
00265 }
00266
00267
00268
00269
00270 template <typename T, typename I>
00271 bool dictionary<T,I>::contains_index(const I & index) const
00272 {
00273 dict_node *cur, **link = &root;
00274 cur = const_cast<dictionary<T,I> *>(this)->find_node(index, &link);
00275
00276 return cur != 0;
00277 }
00278
00279
00280 template <typename T, typename I>
00281 const T & dictionary<T,I>::item(const I & index) const
00282 {
00283 return const_cast<dictionary<T,I> *>(this)->get_item(index);
00284 }
00285
00286
00287 template <typename T, typename I>
00288 T & dictionary<T,I>::item(const I & index)
00289 {
00290 return get_item(index);
00291 }
00292
00293
00294
00295
00296 template <typename T, typename I>
00297 T & dictionary<T,I>::get_item(const I & index, bool create_new)
00298 {
00299 dict_node *cur, **link = &root;
00300 cur = find_node(index, &link);
00301
00302 if (!cur)
00303 {
00304 if (create_new)
00305 {
00306 *link = cur = new dict_node(T(), index);
00307 ++count;
00308 }
00309 else
00310 {
00311 throw runtime_exception(L"Unable to find item in dictionary!");
00312 }
00313 }
00314
00315 assert(cur);
00316 return cur->item;
00317 }
00318
00319
00320 template <typename T, typename I>
00321 typename dictionary<T,I>::dict_node *dictionary<T,I>::find_node(const I & index, dict_node ***link)
00322 {
00323 dict_node *cur = **link;
00324
00325 while (cur)
00326 {
00327 if (index < cur->index)
00328 {
00329 *link = &cur->left;
00330 cur = cur->left;
00331 }
00332 else if (index == cur->index)
00333 {
00334 break;
00335 }
00336 else
00337 {
00338 *link = &cur->right;
00339 cur = cur->right;
00340 }
00341 }
00342
00343 return cur;
00344 }
00345
00346
00347 template <typename T, typename I>
00348 void dictionary<T,I>::remove_node(dict_node *cur, dict_node **link)
00349 {
00350 assert(cur);
00351 assert(link);
00352
00353 if (cur->left && cur->right)
00354 {
00355
00356 dict_node **pred_link = &cur->left, *pred = cur->left;
00357 while (pred->right)
00358 {
00359 pred_link = &pred;
00360 pred = pred->right;
00361 }
00362
00363
00364 cur->index = pred->index;
00365 cur->item = pred->item;
00366
00367
00368 remove_node(pred, pred_link);
00369 }
00370 else
00371 {
00372 if (cur->left)
00373 {
00374 *link = cur->left;
00375 }
00376 else if (cur->right)
00377 {
00378 *link = cur->right;
00379 }
00380 else
00381 {
00382 *link = 0;
00383 }
00384
00385 cur->left = cur->right = 0;
00386 delete cur;
00387
00388 --count;
00389 }
00390 }
00391
00392
00393
00394
00395
00396 template <typename T, typename I>
00397 class dictionary_iterator
00398 {
00399 const dictionary<T,I> & parent;
00400
00401 typename dictionary<T,I>::dict_node *cur, *prev;
00402 data::simple_stack<typename dictionary<T,I>::dict_node *> nodes_seen;
00403
00404 protected:
00405 dictionary_iterator(const iterable<T, dictionary_iterator> & parent_iterable)
00406 : parent(dynamic_cast<const dictionary<T,I> &>(parent_iterable)),
00407 cur(0), prev(0)
00408 {
00409 for (cur = const_cast<typename dictionary<T,I>::dict_node *>(parent.root); cur && cur->left; cur = cur->left)
00410 nodes_seen.push(cur);
00411 }
00412
00413 dictionary_iterator(const dictionary_iterator & di)
00414 : parent(di.parent), cur(di.cur), prev(di.prev), nodes_seen(di.nodes_seen) {}
00415
00416 dictionary_iterator & operator= (const dictionary_iterator & di)
00417 {
00418 parent = di.parent;
00419 cur = di.cur;
00420 prev = di.prev;
00421 nodes_seen = di.nodes_seen;
00422 return *this;
00423 }
00424
00425 inline bool is_valid() const { return cur != 0; }
00426
00427 inline const T & operator* () const
00428 {
00429 if (cur)
00430 return const_cast<T &>(cur->item);
00431 else
00432 throw memory_exception(__FILE__, __LINE__, L"Iterator overflow in dictionary iterator dereference.");
00433 }
00434
00435 dictionary_iterator & operator++();
00436
00437 public:
00438 inline const I & get_index() const
00439 {
00440 if (cur)
00441 return cur->index;
00442 else
00443 throw memory_exception(__FILE__, __LINE__, L"Iterator overflow in dictionary iterator key reference.");
00444 }
00445 };
00446
00447
00448 template <typename T, typename I>
00449 dictionary_iterator<T,I> & dictionary_iterator<T,I>::operator++()
00450 {
00451 if (cur)
00452 {
00453 if (cur->right && cur->right != prev)
00454 {
00455 prev = cur;
00456 nodes_seen.push(cur);
00457 cur = cur->right;
00458
00459 while (cur->left)
00460 {
00461 nodes_seen.push(cur);
00462 cur = cur->left;
00463 }
00464 }
00465 else if (nodes_seen.size())
00466 {
00467 prev = cur;
00468 cur = nodes_seen.top();
00469 nodes_seen.pop();
00470
00471 while (nodes_seen.size() && prev == cur->right)
00472 {
00473 prev = cur;
00474 cur = nodes_seen.top();
00475 nodes_seen.pop();
00476 }
00477
00478 if (prev == cur->right)
00479 cur = 0;
00480 }
00481 else
00482 {
00483 cur = 0;
00484 }
00485 }
00486 else
00487 {
00488 throw memory_exception(__FILE__, __LINE__, L"Iterator overflow in dictionary iterator preincrement.");
00489 }
00490
00491 return *this;
00492 }
00493
00494
00495 }
00496
00497 }
00498
00499 #endif