Polaris: KeyIterator.h Source File

KeyIterator.h

Go to the documentation of this file.
00001 ///
00002 ///
00003 #ifndef _KEY_ITERATOR_H
00004 #define _KEY_ITERATOR_H
00005 ///
00006 /// \class KeyIterator 
00007 /// \brief 
00008 ///
00009 /// \endcode
00010 /// \section DESCRIPTION DESCRIPTION
00011 /// A template for a complex iterator over a map for keys
00012 /// of type S to objects of type T where:
00013 ///
00014 /// \code
00015 /// 1.  'S' is a class with:
00016 ///
00017 ///     a) <, == and << operators taking S& arguments.
00018 ///     b) a copy constructor S(S &) to clone the
00019 ///        input object or simple enough structure
00020 ///        for the default copy constructor to work.
00021 ///
00022 /// 2.  'T' is a class derived from Listable.
00023 /// \endcode
00024 ///
00025 /// These Iterators are designed to work much like the general
00026 /// Collection Iterator:
00027 ///
00028 /// Declare an iterator:
00029 /// \code
00030 /// BaseIter Li = some_map_structure;
00031 /// \endcode
00032 ///
00033 /// --or--
00034 ///
00035 /// \code
00036 /// BaseIter Li(some_map_structure);
00037 /// \endcode
00038 ///
00039 /// This implementation works with the reference counting
00040 /// scheme of Collections.  Thus, it is not possible for an
00041 /// element of a Collection to be deleted out from under
00042 /// an iterator.  It is possible, however, for the current()
00043 /// node to suddenly become invalid--that is for the object
00044 /// suddenly being made inaccessable, turning the current
00045 /// node into a ghost-node. It is illegal to try to access
00046 /// the current node if it is a ghost-node.  This can be
00047 /// checked by calling current_valid().
00048 ///
00049 /// Ghost nodes can only be encountered in live structures by
00050 /// loosing ownership of the current node, but they are more
00051 /// frequent in reference structures.  If an object is
00052 /// deleted from a live structure, references to it will
00053 /// remain.  These, too, become "ghost-nodes".
00054 /// By default, ghost-nodes are skipped over by the iterator.
00055 /// For example, the Iterator forms described above skip
00056 /// over ghost-nodes.  However, if an iterator is declared as
00057 /// the default, it is still possible to check for ghost nodes
00058 /// within the iteration space
00059 /// by calling next() and prev() using the STOP_AT_GHOSTS option:
00060 /// next(STOP_AT_GHOSTS)   --or--  prev(STOP_AT_GHOSTS).
00061 ///
00062 /// Also, it is possible to declare an iterator which will
00063 /// always stop on the ghost nodes.  This is done by passing
00064 /// a positive flag in the constructor after the name of the
00065 /// list.  This can be done as follows:
00066 ///
00067 /// \code
00068 /// BaseIter Li(some_collection, STOP_AT_GHOSTS)
00069 /// (iterate over whole list including ghosts)
00070 /// \endcode
00071 ///
00072 /// In these above forms, the increment and decrement will stop
00073 /// on ghost nodes. next() and prev() will still stop on ghost-
00074 /// nodes only if they have the STOP_AT_GHOSTS flag.  The general rule is
00075 /// that the ++ and -- operators behave according to how the
00076 /// Iterator was declared, while next and prev behave according to
00077 /// whether they have an argument.
00078 ///
00079 ///
00080 #include "../macros.h"
00081 #include "../String.h"
00082 ///
00083 #include "BaseIter.h"
00084 #include "TypedBaseMap.h"
00085 #include "TypedBaseRefMap.h"
00086 ///
00087 #include "ghost_enum.h"
00088 ///
00089 template <class S, class T> class KeyIterator {
00090  private:
00091     BaseIter       _iter;
00092 
00093  public:
00094     INLINE T       &current_data();
00095     ///< Return data of current element.  Cause an error
00096     ///< if valid() == 0
00097 
00098     INLINE const S &current_key() const;
00099     INLINE       S &current_key();
00100     ///< Return key of current element.  Cause an error
00101     ///< if valid() == 0
00102 
00103     INLINE void     reset();
00104     ///< Go back to the beginning of the iteration space
00105     INLINE void     set_to_last();
00106     ///< Set the iterator to the last value
00107     ///< Useful if you need to iterator backwards
00108 
00109     INLINE void     next(iter_option option = STOP_ON_GHOSTS);
00110     ///< go to the next valid element, or if STOP_AT_GHOSTS
00111     ///< to the next element
00112     INLINE void     operator++ ();
00113     ///< go to next element according to how KeyIterator was
00114     ///< defined
00115 
00116     INLINE void     prev(iter_option option = STOP_ON_GHOSTS);
00117     ///< go to the previous valid element, or if STOP_AT_GHOSTS
00118     ///< to the previous element
00119     INLINE void     operator-- ();
00120     ///< go to next element according to how KeyIterator was
00121     ///< defined
00122 
00123     INLINE Boolean  end();
00124     ///< Return true if there no more Nodes to iterate on
00125 
00126     INLINE Boolean  valid();
00127     ///< Equivalent to NOT end()
00128 
00129     INLINE Boolean  current_valid() const;
00130     ///< Return true iff valid() would return 1 AND the current node is
00131     ///< still valid.  This function will return 0 even if valid()
00132     ///< returns 1 if the current node is invalid, which will happen if
00133     ///< the current node has become a ghost node by being deleted from
00134     ///< its Collection.
00135     ///< In the event that the current node is invalid, it is
00136     ///< a checked run-time error to make a call to current().
00137     ///< However, the valid() method still returns 1 since
00138     ///< the end of the iteration space has not yet been reached.
00139     ///< Also, the operator++/--/prev()/next() methods
00140     ///< will all work correctly and properly find the next element in
00141     ///< the iteration space.
00142     ///< If there is any chance that the current element pointed to
00143     ///< by a BaseIter can be deleted, both valid() and
00144     ///< current_valid() must return 1 for a call to current() to be
00145     ///< acceptable.
00146 
00147     INLINE Boolean  current_invalid() const;
00148     ///< Equivalent to ( ! current_valid() )
00149 
00150     INLINE KeyIterator(const KeyIterator<S, T> &other);
00151     ///< This method copies the entire state (including current element)
00152     ///< of the iterator.  If you don't like this, then immediately follow
00153     ///< this constructor with a call to reset()
00154 
00155     INLINE KeyIterator<S, T> & operator = (const KeyIterator<S, T> &other);
00156     ///< This method copies the entire state (including current element)
00157     ///< of the iterator.  If you don't like this, then immediately follow
00158     ///< this constructor with a call to reset()
00159 
00160     
00161 
00162     INLINE KeyIterator(const TypedBaseMap<S, T> &map, 
00163                        iter_option option = STOP_ON_GHOSTS);
00164     ///< Constructor -- note: The iterator does not contain a copy of
00165     ///< the map -- it just contains some pointers into it,
00166     ///< therefore the map may not have items deleted or
00167     ///< inserted during the lifetime of this iterator.
00168   
00169     INLINE KeyIterator<S, T> & operator = (const TypedBaseMap<S, T> &map);
00170     
00171     INLINE KeyIterator(const TypedBaseRefMap<S, T> &map, 
00172                        iter_option option = STOP_ON_GHOSTS);
00173     ///< Constructor -- note: The iterator does not contain a copy of
00174     ///< the map -- it just contains some pointers into it,
00175     ///< therefore the map may not have items deleted or
00176     ///< inserted during the lifetime of this iterator.
00177   
00178     INLINE KeyIterator<S, T> & operator = (const TypedBaseRefMap<S, T> &map);
00179 
00180     INLINE ~KeyIterator();
00181 };
00182 
00183 ///< INLINE functions
00184 
00185 template <class S, class T>
00186 INLINE T &
00187 KeyIterator<S, T>::current_data() 
00188 {
00189     return (T &) _iter.current();
00190 }
00191 
00192 template <class S, class T>
00193 INLINE const S &
00194 KeyIterator<S, T>::current_key() const
00195 {
00196     const S &key = *((S *) _iter.current_key());
00197 
00198     return key;
00199 }
00200 
00201 template <class S, class T>
00202 INLINE S &
00203 KeyIterator<S, T>::current_key()
00204 {
00205     S &key = *((S *) _iter.current_key());
00206 
00207     return key;
00208 }
00209 
00210 template <class S, class T> 
00211 INLINE void     
00212 KeyIterator<S, T>::reset()
00213 {
00214     _iter.reset();
00215 }
00216 
00217 template <class S, class T> 
00218 INLINE void     
00219 KeyIterator<S, T>::set_to_last()
00220 {
00221     _iter.set_to_last();
00222 }
00223 
00224 template <class S, class T> 
00225 INLINE void     
00226 KeyIterator<S, T>::next(iter_option option GIV(STOP_ON_GHOSTS))
00227 {
00228     _iter.next(option);
00229 }
00230 
00231 template <class S, class T> 
00232 INLINE void     
00233 KeyIterator<S, T>::operator++ () 
00234 {
00235     _iter.next(_iter.skip_ghosts() ? SKIP_GHOSTS : STOP_ON_GHOSTS);
00236 }
00237 
00238 template <class S, class T> 
00239 INLINE void     
00240 KeyIterator<S, T>::prev(iter_option option GIV(STOP_ON_GHOSTS))
00241 {
00242     _iter.prev(option);
00243 }
00244 
00245 template <class S, class T> 
00246 INLINE void     
00247 KeyIterator<S, T>::operator-- () 
00248 {
00249     _iter.prev(_iter.skip_ghosts() ? SKIP_GHOSTS : STOP_ON_GHOSTS);
00250 }
00251 
00252 template <class S, class T> 
00253 INLINE Boolean 
00254 KeyIterator<S, T>::end()
00255 {
00256     return _iter.end();
00257 }
00258 
00259 template <class S, class T> 
00260 INLINE Boolean      
00261 KeyIterator<S, T>::valid()
00262 {
00263     return _iter.valid();
00264 }
00265 
00266 template <class S, class T> 
00267 INLINE Boolean      
00268 KeyIterator<S, T>::current_valid() const
00269 {
00270     return _iter.current_valid();
00271 }
00272 
00273 template <class S, class T> 
00274 INLINE Boolean
00275 KeyIterator<S, T>::current_invalid() const
00276 {
00277     return _iter.current_invalid();
00278 }
00279 
00280 template <class S, class T> 
00281 INLINE 
00282 KeyIterator<S, T>::KeyIterator(const KeyIterator<S, T> &other)
00283     : _iter(other._iter)
00284 {
00285     ///< nothing else to do
00286 }
00287 
00288 template <class S, class T> 
00289 INLINE KeyIterator<S, T> &
00290 KeyIterator<S,T>::operator = (const KeyIterator<S, T> &other) 
00291 {
00292     _iter = other._iter;
00293     return *this;
00294 }
00295 
00296 template <class S, class T>
00297 INLINE 
00298 KeyIterator<S, T>::KeyIterator(const TypedBaseMap<S, T> &map, 
00299                                iter_option option GIV(STOP_ON_GHOSTS))
00300     : _iter(map._base_data_list(), option)
00301 {
00302     ///< nothing to do
00303 }
00304 
00305 template <class S, class T>
00306 INLINE KeyIterator<S, T> & 
00307 KeyIterator<S, T>::operator = (const TypedBaseMap<S, T> &map)
00308 {
00309     _iter = map._base_data_list();
00310     return *this;
00311 }
00312 
00313 template <class S, class T> 
00314 INLINE 
00315 KeyIterator<S, T>::KeyIterator(const TypedBaseRefMap<S, T> &map,
00316                                iter_option option GIV(STOP_ON_GHOSTS))
00317     : _iter(map._base_data_list(), option)
00318 {
00319     ///< nothing to do
00320 }
00321 
00322 template <class S, class T>
00323 INLINE KeyIterator<S, T> & 
00324 KeyIterator<S, T>::operator = (const TypedBaseRefMap<S, T> &map)
00325 {
00326     _iter = map._base_data_list();
00327     return *this;
00328 }
00329 
00330 template <class S, class T>
00331 INLINE
00332 KeyIterator<S, T>::~KeyIterator()
00333 {
00334     ///< nothing to do
00335 }
00336 
00337 #endif
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:57 2005