dictionary.h

Go to the documentation of this file.
00001 /****************************************************************************/
00002 /*                                                                          */
00003 /*  Copyright (c) 1994-2002                                                 */
00004 /*  Jeremy Levitt                                                           */
00005 /*                                                                          */
00006 /****************************************************************************/
00007 
00008 #ifndef _dict_h_
00009 #define _dict_h_
00010 
00011 #include <assert.h>
00012 //#include <iostream.h>
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 /*  class Dict_Entry                                                        */
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 /*  class Dict                                                              */
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);     // return (k1<k2) ? -1 : ((k1==k2) 0 : 1)
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 /*  class Dict_Ptr                                                          */
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 /*    Dict::Destroy()                                                       */
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 /*    Dict::Copy()                                                          */
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 /*   Dict::operator=                                                        */
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 /*    Dict::Find_Insert_Point()                                             */
00153 /*                                                                          */
00154 /*    Return a pointer-pointer to where the element should be inserted.     */
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 /*    Dict::Insert()                                                        */
00169 /*                                                                          */
00170 /*    Return 0 if the element was successfully inserted                     */
00171 /*    Return 1 if insertion fails becuase an entry with the same key        */
00172 /*    is already present                                                    */
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 /*    Dict::Delete()                                                        */
00194 /*                                                                          */
00195 /*    Return 0 if the element was successfully deleted and 1                */
00196 /*    if the deletion failed because the entry could not be found.          */
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 /*    Dict::Fetch()                                                         */
00217 /*                                                                          */
00218 /*    Return a pointer to the element if it was found, otherwise return     */
00219 /*    a NULL pointer.                                                       */
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 /*    Dict::operator[]                                                      */
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 /*    Dict_Entry::operator<<                                                */
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 /*    Dict::operator<<                                                      */
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 } // end of namespace CVCL
00268 
00269 #endif /* _dict_h_ */
00270 

Generated on Thu Apr 13 16:57:31 2006 for CVC Lite by  doxygen 1.4.4