00001
00002
00003
00004
00005
00006
00007
00008 #ifndef _dict_h_
00009 #define _dict_h_
00010
00011 #include <assert.h>
00012
00013 #include <iostream>
00014 #include <sstream>
00015
00016 #ifndef NULL
00017 #define NULL 0
00018 #endif
00019
00020 namespace CVCL {
00021
00022 typedef void *void_ptr;
00023 template <class _Key, class _Data> class Dict;
00024 template <class _Key, class _Data> class Dict_Entry;
00025 template <class _Key, class _Data> class Dict_Ptr;
00026
00027
00028
00029
00030 template <class _Key, class _Data>
00031 class Dict_Entry {
00032 friend class Dict<_Key, _Data>;
00033 friend class Dict_Ptr<_Key, _Data>;
00034
00035 private:
00036 _Key _key;
00037 _Data _data;
00038 Dict_Entry *_next;
00039
00040 ~Dict_Entry() {}
00041
00042 public:
00043 _Key Key() const { return _key; }
00044 _Data& Data() { return _data; }
00045 };
00046
00047
00048
00049
00050
00051 template <class _Key, class _Data>
00052 class Dict {
00053 friend class Dict_Ptr<_Key, _Data>;
00054
00055 private:
00056 Dict_Entry<_Key, _Data> *_list;
00057 int (*_cmpFunc)(_Key, _Key);
00058 int _numEntries;
00059
00060 Dict_Entry<_Key, _Data>** Find_Insert_Point(_Key&);
00061 void Copy(const Dict &rhs);
00062 void Destroy();
00063
00064 public:
00065 Dict(int (*cmpFunc)(_Key, _Key))
00066 : _list(NULL), _cmpFunc(cmpFunc), _numEntries(0) {}
00067 Dict(const Dict &dict) { Copy(dict); }
00068 ~Dict() { Destroy(); }
00069
00070 int NumEntries() { return _numEntries; }
00071 int Insert(_Key key, _Data data);
00072 int Delete(_Key key);
00073 Dict& operator= (const Dict &rhs);
00074 _Data* Fetch(_Key key);
00075 _Data& operator[] (_Key key);
00076 };
00077
00078
00079
00080
00081
00082 template <class _Key, class _Data>
00083 class Dict_Ptr {
00084 private:
00085 Dict_Entry<_Key, _Data> *_link;
00086
00087 public:
00088 Dict_Ptr(Dict<_Key, _Data> *dict) : _link(dict->_list) {}
00089 Dict_Entry<_Key, _Data>* operator-> () { return _link; }
00090 Dict_Entry<_Key, _Data>& operator* () { assert(_link); return *_link; }
00091 operator void_ptr() const { return void_ptr(_link); }
00092 void operator++ () { if (_link!=NULL) _link=_link->_next; }
00093 void Reset(Dict<_Key, _Data> *dict) { _link=dict->_list; }
00094 };
00095
00096
00097
00098
00099
00100 template <class _Key, class _Data>
00101 void Dict<_Key, _Data>::Destroy()
00102 {
00103 Dict_Entry<_Key, _Data> *tmp = _list;
00104 while(tmp != NULL) {
00105 Dict_Entry<_Key, _Data> *next = tmp->_next;
00106 delete tmp;
00107 tmp = next;
00108 }
00109 }
00110
00111
00112
00113
00114
00115 template <class _Key, class _Data>
00116 void Dict<_Key, _Data>::Copy(const Dict<_Key, _Data> &rhs)
00117 {
00118 _cmpFunc = rhs._cmpFunc;
00119 _numEntries = rhs._numEntries;
00120
00121 Dict_Entry<_Key, _Data> *tmp = rhs._list;
00122 Dict_Entry<_Key, _Data> **copy = &(_list = NULL);
00123
00124 while(tmp != NULL) {
00125 *copy = new Dict_Entry<_Key, _Data>();
00126 (*copy)->_key = tmp->_key;
00127 (*copy)->_data = tmp->_data;
00128 (*copy)->_next = NULL;
00129 copy = &(*copy)->_next;
00130 tmp = tmp->_next;
00131 }
00132 }
00133
00134
00135
00136
00137
00138 template <class _Key, class _Data>
00139 Dict<_Key, _Data>& Dict<_Key, _Data>::operator=
00140 (const Dict<_Key, _Data> &rhs)
00141 {
00142 if (this != &rhs) {
00143 Destroy();
00144 Copy(rhs);
00145 }
00146
00147 return *this;
00148 }
00149
00150
00151
00152
00153
00154
00155
00156 template <class _Key, class _Data>
00157 Dict_Entry<_Key, _Data>**
00158 Dict<_Key, _Data>::Find_Insert_Point(_Key &key)
00159 {
00160 Dict_Entry<_Key, _Data>** link = &_list;
00161 while (*link != NULL && ((*_cmpFunc)((*link)->_key, key))>0)
00162 link = &((*link)->_next);
00163 return link;
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 template <class _Key, class _Data>
00175 int Dict<_Key, _Data>::Insert(_Key key, _Data data)
00176 {
00177 Dict_Entry<_Key, _Data>** link = Find_Insert_Point(key);
00178
00179 if (*link && (*_cmpFunc)((*link)->_key, key)==0)
00180 return 1;
00181
00182 _numEntries++;
00183 Dict_Entry<_Key, _Data>* dict_entry = new Dict_Entry<_Key, _Data>();
00184 dict_entry->_key = key;
00185 dict_entry->_data = data;
00186 dict_entry->_next = *link;
00187 *link = dict_entry;
00188 return 0;
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198 template <class _Key, class _Data>
00199 int Dict<_Key, _Data>::Delete(_Key key)
00200 {
00201 Dict_Entry<_Key, _Data>** link = Find_Insert_Point(key);
00202 Dict_Entry<_Key, _Data>* tmp;
00203
00204 if (!*link || (*_cmpFunc)((*link)->_key, key)!=0)
00205 return 1;
00206
00207 _numEntries--;
00208 tmp = (*link);
00209 *link = (*link)->_next;
00210 delete tmp;
00211 return 0;
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221 template <class _Key, class _Data>
00222 _Data* Dict<_Key, _Data>::Fetch(_Key key)
00223 {
00224 Dict_Entry<_Key, _Data>** link = Find_Insert_Point(key);
00225
00226 if (*link && (*_cmpFunc)((*link)->_key, key)==0)
00227 return &(*link)->Data();
00228
00229 return (_Data *)NULL;
00230 }
00231
00232
00233
00234
00235
00236 template <class _Key, class _Data>
00237 _Data& Dict<_Key, _Data>::operator[] (_Key key)
00238 {
00239 _Data* result = Fetch(key);
00240 assert(result != NULL);
00241 return *result;
00242 }
00243
00244
00245
00246
00247
00248 template <class _Key, class _Data>
00249 std::ostream& operator<< (std::ostream &cout, Dict_Entry<_Key, _Data> &element)
00250 {
00251 return cout << "key: \"" << element.Key()
00252 << "\" data: " << element.Data() << '\n';
00253 }
00254
00255
00256
00257
00258
00259 template <class _Key, class _Data>
00260 std::ostream& operator<< (std::ostream &cout, Dict<_Key, _Data> &dict)
00261 {
00262 for (Dict_Ptr<_Key, _Data> ptr(&dict); ptr!=NULL; ++ptr)
00263 cout << *ptr;
00264 return cout;
00265 }
00266
00267 }
00268
00269 #endif
00270