Polaris: Map.h Source File

Map.h

Go to the documentation of this file.
00001 ///
00002 ///
00003 #ifndef _MAP_H
00004 #define _MAP_H
00005 ///
00006 /// \class Map 
00007 /// \brief 
00008 ///
00009 /// \endcode
00010 /// \section DESCRIPTION DESCRIPTION  
00011 /// Map<key,data> owns(data), address(key)
00012 /// 
00013 /// A template for a map for keys of type S
00014 /// to owned objects of type T where:
00015 ///
00016 /// \code
00017 /// 1.  'S' is a class with:
00018 /// a) <, == and << operators taking S& arguments.
00019 /// b) a copy constructor S(S &) to clone the
00020 /// input object or simple enough structure
00021 /// for the default copy constructor to work.
00022 ///
00023 /// 2.  'T' is a class derived from Listable.
00024 /// \endcode
00025 ///
00026 /// The map is implemented as a tree of pointers to
00027 /// whatever type is specified.  Thus, all methods to
00028 /// insert elements into a map take a reference to the
00029 /// key and a pointer to the data and do not allocate space. 
00030 /// (i.e., the map aliases whatever is in the list).  However,
00031 /// the map takes over ownership of the data on insert
00032 /// and will delete both a map element.
00033 ///
00034 #include "ProtoMap.h"
00035 #include "../p-assert.h"
00036 ///
00037 template <class S, class T> class Map : public ProtoMap<S, T> {
00038  protected:
00039     virtual INLINE void    _kill_key(BMKey &key);
00040     ///< kill key
00041 
00042  public:
00043     INLINE Map();
00044     INLINE Map(const Map<S, T> &m);
00045 
00046     virtual INLINE ~Map();
00047 
00048     INLINE T        &ins(const S &key, T *data);
00049     ///< Insert element with (key, data) into the map, and
00050     ///< return a reference to '*data' (for purposes
00051     ///< of programming convenience).
00052     ///< If a node with an equivalent key already exists,
00053     ///< delete the old one and replace it with the new one.
00054 
00055     INLINE void     del(S &del_key);
00056     ///< delete element with key del_key (run-time error if none exists)
00057 
00058     INLINE T       *grab(S &del_key);
00059     ///< remove and return an element with key del_key
00060 
00061     INLINE void     print(ostream & out, char *sep1, char *sep2) const;
00062     ///< print map to out with sep1 between key and data and sep2 between each
00063     ///< element of the map
00064 
00065     INLINE          Map<S, T > & operator = (const Map<S, T> &l);
00066     ///< Copy operator completely copies the Map
00067 
00068     INLINE Listable *listable_clone() const;
00069     ///< Needed for Listable class.
00070 
00071     INLINE void      print(ostream &o) const;
00072     ///< Needed for Listable class.
00073 };
00074 
00075 #include "KeyIterator.h"
00076 
00077 
00078 ///< implementation
00079 
00080 
00081 template <class S, class T>
00082 INLINE void  
00083 Map<S, T>::_kill_key(BMKey & NOTUSED(key))
00084 {
00085     ///< Map doesn't own key... so do nothing.
00086 }
00087 
00088 
00089 template <class S, class T>
00090 INLINE
00091 Map<S, T>::Map()
00092 {
00093     #ifdef MEMORY_LEAK_PRINT
00094     cout << "Map ctor: " << this << " : size=" << sizeof(Map) << endl;
00095     #endif
00096 
00097 }
00098 
00099 template <class S, class T>
00100 INLINE
00101 Map<S, T>::Map(const Map<S, T> &m)
00102 {
00103     #ifdef MEMORY_LEAK_PRINT
00104     cout << "Map ctor: " << this << " : size=" << sizeof(Map) << endl;
00105     #endif
00106 
00107     ///< Invoke copy constructor
00108     (*this) = m;
00109 }
00110 
00111 template <class S, class T>
00112 INLINE
00113 Map<S, T>::~Map()
00114 {
00115     #ifdef MEMORY_LEAK_PRINT
00116     cout << "Map dtor: " << this << " : size=" << sizeof(Map) << endl;
00117     #endif
00118 
00119     ///< Delete the information before the class disappears.
00120     clear();
00121 }
00122 
00123 template <class S, class T>
00124 INLINE T &
00125 Map<S, T>::ins(const S &key, T *data)
00126 {
00127     BMKey           inskey;
00128 
00129     inskey._keyptr = (void *) &key;
00130     
00131     T * exists = (T *) remove(inskey);
00132 
00133     ///< Remove any preexisting node with same key
00134     if (exists) 
00135       delete exists;
00136     
00137     BaseMap::ins(inskey, data);
00138 
00139     return *data;
00140 }
00141 
00142 template <class S, class T>
00143 INLINE void 
00144 Map<S, T>::del(S &key)
00145 {
00146     BMKey           delkey;
00147     T              *el;
00148 
00149     delkey._keyptr = (void *) &key;
00150 
00151     el = (T *) remove(delkey);
00152 
00153     p_assert(el, "Map<S,T>::del(S &key): No node found with specified key");
00154     
00155     delete el;
00156 }
00157 
00158 template <class S, class T>
00159 INLINE T *  
00160 Map<S, T>::grab(S &key)
00161 {
00162     BMKey           delkey;
00163 
00164     delkey._keyptr = (void *) &key;
00165 
00166     return (T *) remove(delkey);
00167 }
00168 
00169 template <class S, class T>
00170 INLINE void
00171 Map<S,T>::print(ostream & out, char *sep1, char *sep2) const
00172 {
00173     out << "{";
00174 
00175     for (KeyIterator<S,T> map_iter = *this; map_iter.valid(); ++map_iter) {
00176         BMKey printkey;
00177         printkey._keyptr = (void *) &map_iter.current_key();
00178         _print(out, printkey);
00179         out << sep1 << map_iter.current_data() << sep2;
00180     }
00181 
00182     out << "}";
00183 }
00184 
00185 template <class S, class T>
00186 INLINE Map<S, T> &
00187 Map<S, T>::operator = (const Map<S, T> &m) 
00188 {
00189     ///< Clear out current map
00190     clear();
00191 
00192     ///< Copy all the items one by one
00193     for (KeyIterator<S, T> map_iter = m; map_iter.valid(); ++map_iter) 
00194         ins( map_iter.current_key(), 
00195             (T *) map_iter.current_data().listable_clone());
00196 
00197     return *this;
00198 }
00199 
00200 template <class S, class T>
00201 INLINE Listable *
00202 Map<S, T>::listable_clone() const
00203 {
00204     return (Listable *) new Map<S,T>( *this );
00205 }
00206 
00207 template <class S, class T>
00208 INLINE void
00209 Map<S, T>::print(ostream &o) const
00210 {
00211     print( o, ": ", ", " );
00212 }
00213 
00214 
00215 ///< This interface is for testing purposes only.  It invokes a non-virtual
00216 ///< member function to print a representation of the data structure at this
00217 ///< level of the Collection hierarchy, and, since it is not a class member
00218 ///< function, it must be explicitly instantiated before use.
00219 
00220 template <class S, class T>
00221 ostream &
00222 operator << (ostream & o, const Map<S, T> &m)
00223 {
00224   m.print(o, ": ", ", ");
00225   return o;
00226 }
00227 
00228 #endif
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:58 2005