Polaris: Dictionary.h Source File

Dictionary.h

Go to the documentation of this file.
00001 ///
00002 ///
00003 #ifndef _DICTIONARY_H
00004 #define _DICTIONARY_H
00005 ///
00006 /// file Dictionary.h
00007 ///
00008 /// \class Dictionary 
00009 /// \brief A hashtable based on strings
00010 /// \defgroup C
00011 /// \ingroup C++ CVDL
00012 ///  Polaris
00013 /// \see Dictionary/Data.h
00014 /// \see Dictionary.cc
00015 /// \see Dictionary.h
00016 ///
00017 /// \endcode
00018 /// \section Description Description
00019 /// The Dictionary is used to store objects which can be retrieved
00020 /// based upon a string tag.  In order to guarnatee that the
00021 /// objects in the Dictionary have the appropriate fields, the
00022 /// the class used in the Dictionary template (T) must be
00023 /// derived from Definition.
00024 ///
00025 #include "ClassNames.h"
00026 #include "Definition.h"
00027 #include "Collection/Database.h"
00028 #include "String.h"
00029 ///
00030 #include "macros.h"
00031 ///
00032 void dict_abort(const char *tag);
00033 ///
00034 template <class T>
00035 class Dictionary : public Database<String,T> {
00036     friend class Definition;
00037 
00038  public:
00039     INLINE Dictionary();
00040     INLINE Dictionary(const Dictionary<T> &dict);
00041     INLINE Dictionary<T> & operator = (const Dictionary<T> &dict);
00042 
00043     virtual INLINE ~Dictionary();
00044 
00045     ///< virtual Dictionary<T> *clone() const;
00046 
00047     virtual INLINE void     del(const char *tag);
00048 
00049     virtual INLINE void     ins(T *elem);
00050     virtual INLINE void     ins(T *elem, int replace_if_already_exists);
00051     ///< Insert item into the dictionary.
00052     ///< The meaning of the replace_if_already_exists is:
00053     ///< replace_if_already_exists != 0 :
00054     ///<     If an item already exists in the dictionary with
00055     ///<     the same tag as item, the old item is deleted
00056     ///<     and is replaced by item.
00057     ///< replace_if_already_exists == 0 :
00058     ///<     If an item already exists in the dictionary with
00059     ///<     the same tag as item, an error message is
00060     ///<     displayed and the program is aborted.
00061 
00062     virtual INLINE const T *find_ref(const char *tag) const;
00063     virtual INLINE T       *find_ref(const char *tag);
00064 
00065     virtual INLINE const T *find(const char *tag) const;
00066     virtual INLINE T       *find(const char *tag);
00067 
00068     virtual INLINE const T &operator[] (const char *tag) const;
00069     virtual INLINE T       &operator[] (const char *tag);
00070 
00071     virtual INLINE T       *grab(const char *tag);
00072     ///< Remove and return (does NOT delete) the item in the dictionary
00073     ///< which has this tag.  Returns 0 if none was found
00074 
00075     virtual INLINE const T *arb_ref() const;
00076     virtual INLINE T       *arb_ref();
00077     ///< Returns pointer to arbitrary element (or 0 if dictionary is empty)
00078 
00079     virtual INLINE T       *grab_arb();
00080     ///< Removes and returns pointer to arbitrary element (or returns 0 if
00081     ///< dictionary is empty)
00082 
00083     virtual INLINE void     print(ostream &o) const;
00084     ///< Print the elements of the dictionary.
00085 
00086     virtual INLINE void     rename(const char *tag, const char *new_tag);
00087     ///< Rename the member of this class whose tag is 'tag' to the
00088     ///< new tag 'new_tag' (and automatically reindex it).
00089     ///< An error occurs if there is not item in the dictionary
00090     ///< with the tag 'tag' OR if there is already an item in
00091     ///< the dictionary with the tag 'new_tag'.
00092 };
00093 
00094 template <class T>
00095 INLINE
00096 Dictionary<T>::Dictionary()
00097 {
00098     #ifdef CLASS_INSTANCE_REGISTRY
00099     register_instance(DICTIONARY, sizeof(Dictionary), this);
00100     #endif
00101 }
00102 
00103 template <class T>
00104 INLINE
00105 Dictionary<T>::Dictionary(const Dictionary<T> &other)
00106 {
00107     #ifdef CLASS_INSTANCE_REGISTRY
00108     register_instance(DICTIONARY, sizeof(Dictionary), this);
00109     #endif
00110 
00111     *this = other;
00112 }
00113 
00114 template <class T>
00115 INLINE Dictionary<T> &
00116 Dictionary<T>::operator = (const Dictionary<T> &other) 
00117 {
00118     Database<String,T>::operator = (other);
00119 
00120     return *this;
00121 }
00122 
00123 template <class T>
00124 INLINE
00125 Dictionary<T>::~Dictionary()
00126 {
00127     #ifdef CLASS_INSTANCE_REGISTRY
00128     unregister_instance(DICTIONARY, this);
00129     #endif
00130 }
00131 
00132 template <class T>
00133 INLINE void 
00134 Dictionary<T>::ins(T *elem)
00135 {
00136     Dictionary<T>::ins(elem,0);
00137 }
00138 
00139 template <class T>
00140 INLINE void 
00141 Dictionary<T>::ins(T *elem, int replace_if_already_exists)
00142 {
00143     if (member(elem->tag_ref())) {
00144         if (! replace_if_already_exists) 
00145             p_abort( "inserting an element that already exists" );
00146         del(elem->tag_ref());
00147     }
00148 
00149     String s = elem->tag_ref();
00150 
00151     Database<String,T>::ins( s, elem ); 
00152 }
00153 
00154 template <class T>
00155 INLINE void
00156 Dictionary<T>::del(const char *tag)
00157 {
00158     String    s = tag;
00159 
00160     Database<String,T>::del(s);
00161 }
00162 
00163 template <class T>
00164 INLINE const T *
00165 Dictionary<T>::find_ref(const char *tag) const
00166 {
00167   const String & tag_str = tag;
00168   return Database<String,T>::find_ref(tag_str);
00169 }
00170 
00171 template <class T>
00172 INLINE T *
00173 Dictionary<T>::find_ref(const char *tag)
00174 {
00175   String tag_str(tag);
00176   return Database<String,T>::find_ref(tag_str);
00177 }
00178 
00179 template <class T>
00180 INLINE const T *
00181 Dictionary<T>::find(const char *tag) const
00182 {
00183     return find_ref(tag);
00184 }
00185 
00186 template <class T>
00187 INLINE T *
00188 Dictionary<T>::find(const char *tag)
00189 {
00190     return find_ref(tag);
00191 }
00192 
00193 template <class T>
00194 INLINE const T &
00195 Dictionary<T>::operator[] (const char *tag) const 
00196 {
00197     const T *found = find_ref(tag);
00198     if (!found)
00199       dict_abort(tag);
00200     return *found;
00201 }
00202 
00203 template <class T>
00204 INLINE T &
00205 Dictionary<T>::operator[] (const char *tag)
00206 {
00207     T *found = find_ref(tag);
00208     if (!found)
00209       dict_abort(tag);
00210     return *found;
00211 }
00212 
00213 template <class T>
00214 INLINE T *
00215 Dictionary<T>::grab(const char *tag)
00216 {
00217     String    key = tag;
00218 
00219     return (T *) Database<String,T>::grab(key);
00220 }
00221 
00222 template <class T>
00223 INLINE const T *
00224 Dictionary<T>::arb_ref() const
00225 {
00226     const String    *key = arb_key_ref();
00227 
00228     if (key == 0)
00229         return 0;
00230 
00231     return find_ref( *key );
00232 }
00233 
00234 template <class T>
00235 INLINE T *
00236 Dictionary<T>::arb_ref()
00237 {
00238     const String    *key = arb_key_ref();
00239 
00240     if (key == 0)
00241         return 0;
00242 
00243     return find_ref( *key );
00244 }
00245 
00246 template <class T>
00247 INLINE T *
00248 Dictionary<T>::grab_arb()
00249 {
00250     T *el = arb_ref();
00251  
00252     if (el != 0) 
00253         return grab( el->tag_ref() );
00254 
00255     return 0;
00256 }
00257 
00258 template <class T>
00259 INLINE void
00260 Dictionary<T>::rename(const char *tag, const char *new_tag)
00261 {
00262     String    key = tag;
00263 
00264     T *el = grab( key );
00265 
00266     el->rename( new_tag );
00267 
00268     ins( el );
00269 }
00270 
00271 template <class T>
00272 INLINE void
00273 Dictionary<T>::print(ostream &o) const
00274 {
00275     Database<String,T>::print(o, ": ", ", ");
00276 }
00277 
00278 ///< This interface is for testing purposes only.  It invokes a non-virtual
00279 ///< member function to print a representation of the data structure at this
00280 ///< level of the Collection hierarchy, and, since it is not a class member
00281 ///< function, it must be explicitly instantiated before use.
00282 
00283 template <class T>
00284 ostream &
00285 operator << (ostream & o, const Dictionary<T> &dict)
00286 {
00287   dict.print(o);
00288   return o;
00289 }
00290 
00291 #include "DictionaryIter.h"
00292 
00293 #endif
00294 
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:44 2005