Polaris: RefSet.h Source File

RefSet.h

Go to the documentation of this file.
00001 ///
00002 ///
00003 #ifndef _REF_SET_H
00004 #define _REF_SET_H
00005 ///
00006 /// \class RefSet 
00007 /// \brief A very simple set class for references
00008 /// \defgroup Polaris
00009 /// \ingroup Polaris
00010 ///  C++ VDL
00011 /// \see RefSet.h
00012 ///
00013 /// \endcode
00014 /// \section Overview Overview
00015 /// A template for a reference set for type T
00016 /// where 'T' must be derived from Listable.
00017 /// Like other Ref collections, this structure stores only
00018 /// references to the actual live objects, so objects which
00019 /// are put in the RefSet are aliased.  Further, also like
00020 /// other Ref Collections, objects must already be living
00021 /// inside other collections before they can be inserted
00022 /// into a RefSet.
00023 ///
00024 /// If an object is inserted into a RefSet and is then
00025 /// removed or deleted from the live structure in which it
00026 /// truely lives, the reference to it in the RefSet becomes
00027 /// invalid.  An invalid element can still be removed and
00028 /// indexed as before.
00029 ///
00030 /// RefSets work with the standard Iterator package.
00031 ///
00032 /// .BUGS
00033 /// The set is implemented...poorly.  It is simply
00034 /// a RefList. It is not well desguised....a lot of the
00035 /// error messages will not seem appropriate, when it
00036 /// prints the set it still has brackets, etc..
00037 /// Further, the interface seems sort of goofy, (for instance,
00038 /// having _member and member and no index etc..)
00039 /// This should perhaps be reconsidered.
00040 ///
00041 /// \endcode
00042 /// \section Hierarchy Hierarchy Structure
00043 /// RefSet does not directly inherit from Collection. Instead
00044 /// it inherits from TypedCollection (which forms the interface
00045 /// to all Iterator routines) and contains a BaseRefList
00046 /// which inherits from Collection.
00047 /// The hierarchy can be represented by:
00048 ///
00049 /// \code
00050 ///                     --- :    'inherited from' relationship
00051 ///                     -c- :    'contained in' relationship
00052 ///
00053 ///
00054 ///                         Collection
00055 ///                        /          \                                          //
00056 ///                       /            \                                         //
00057 ///               BaseList   Listable   BaseRefList
00058 ///               |  \          |             /  |
00059 ///               |   \         |            /   |
00060 ///               |    c  TypedCollection   c    |
00061 ///               |     \     /     \      /     |
00062 ///               |      \   /       \    /      |
00063 ///               |      LIST        RefList     |
00064 ///               |      Set         RefSet      |
00065 ///               c                              c
00066 ///               |          Listable            |
00067 ///               |             |                |
00068 ///               |             |                |
00069 ///               |        BaseMapRoot           |
00070 ///               |       /           \          |
00071 ///               |      /             \         |
00072 ///               BaseMap               BaseRefMap
00073 ///                  |                       |
00074 ///                  |                       |                            
00075 ///             TypedBaseMap          TypedBaseRefMap
00076 ///               /     \                /         \                             //
00077 ///              /       \              /           \                            //
00078 ///    ProtoDatabase      ProtoMap   ProtoRefMap    ProtoRefDatabase
00079 ///         /  \           |    |      |     |         |         \               //
00080 ///        /    \          |    |      |     |         |          \              //
00081 /// Database KeyDatabase  Map KeyMap  RefMap KeyMap  RefDatabase RefKeyDatabase
00082 /// \endcode
00083 ///
00084 /// \endcode
00085 /// \section See See Also
00086 /// Collection, Listable, RefWrapper, Iterator, TypedCollection, Zombie,
00087 /// BaseRefList
00088 ///
00089 #include <stream.h>
00090 #include "../macros.h"
00091 #include "TypedCollection.h"
00092 #include "BaseRefList.h"
00093 ///
00094 template <class T> class RefSet : public TypedCollection<T> {
00095     friend class Iterator <T>;
00096     friend class Mutator <T>;
00097 
00098  protected:
00099     BaseRefList _list;
00100     virtual INLINE const Collection & _base_collection() const;
00101     virtual INLINE Collection & _base_collection();
00102 
00103  public:
00104     INLINE          RefSet();
00105     INLINE          RefSet(const RefSet<T >&l);
00106     virtual INLINE  ~RefSet();
00107 
00108     INLINE int      _member(const T &el) const;
00109     ///< Check to see if node 'el' is a member of the RefSet.  Return
00110     ///< -1 if the element was not found otherwise return its index.
00111 
00112     INLINE const T &_element(int loc) const;
00113     INLINE T       &_element(int loc);
00114     ///< Used to obtain a specific elelemt of the set.  Use the _member()
00115     ///< function to get the index that is used.  An error is raised if
00116     ///< the locth element is invalid.
00117 
00118     INLINE void     _del(int loc);
00119     ///< Random Access Delete.
00120     ///< Delete the Node in position loc where 0 <= loc <= entries()-1
00121 
00122     INLINE void     _modify(int loc, T &el);
00123     ///< Random Access Modify.
00124     ///< Change the node at position loc to be el.
00125 
00126     INLINE int      entries() const;
00127     ///< Return the number of entries in the Set.
00128 
00129     INLINE Boolean  empty() const;
00130     ///< Return a flag indicating if the RefSet is empty.
00131 
00132     INLINE Boolean  any_valid() const;
00133     ///< Check to see if any valid elements exist in the RefSet.
00134 
00135     INLINE void     print(ostream & out, char *sep) const;
00136     ///< print list to out with 'sep' sepperating each element.
00137 
00138     INLINE T        &ins(const T &new_element);
00139     ///< Insert new_element into the set, and return a reference
00140     ///<   to 'new_element' (for purposes of programming convenience).
00141     ///< If an element with the same key already exists, the old
00142     ///<   object is deleted and replace with 'new_element'.
00143 
00144     INLINE void     del(T &el);
00145     ///< Delete node 'el'.
00146 
00147     INLINE T       &grab();
00148     ///< Remove and return an arbitrary valid element of the set.  This
00149     ///< raises an error if there are no valid elements.
00150 
00151     INLINE Boolean  member(const T &el) const;
00152     ///< Check to see if node 'el' is a member of the RefSet.
00153 
00154     INLINE Boolean  valid(const T &el) const;
00155     ///< Check to see if node 'el' is still valid in the RefSet.
00156 
00157     INLINE Boolean  valid(const int loc) const;
00158     ///< Check to see if the locth element is valid.
00159 
00160     INLINE void     clear();
00161     ///< Delete the entire list.
00162 
00163     INLINE RefSet<T> & operator -= (const RefSet<T>& l);
00164     ///< Remove one set from another.  This operator
00165     ///< finds the members of the arg RefSet which are also
00166     ///< in the *this RefSet, and removes them from the *this
00167     ///< RefSet.  The elements of the arg RefSet need not
00168     ///< all be contained in the *this RefSet.
00169     ///< THIS OPERATOR DECIDES THAT ELEMENTS ARE THE SAME BY
00170     ///< COMPARING THEIR ADDRESSES, NOT THEIR CONTENT.  THEREFORE,
00171     ///< THIS WILL NOT FIND CLONES TO BE THE SAME ELEMENT.
00172     ///< THIS IS MOST USEFUL FOR THINGS THAT LIVE IN ONLY ONE
00173     ///< PLACE IN THE SYSTEM, FOR INSTANCE, SYMBOLS.
00174     
00175     INLINE RefSet<T> & operator += (const RefSet<T>& l);
00176     ///< Append the members of one set onto another.
00177     ///< THIS OPERATOR DECIDES THAT ELEMENTS ARE THE SAME BY
00178     ///< COMPARING THEIR ADDRESSES, NOT THEIR CONTENT.  THEREFORE,
00179     ///< THIS WILL NOT FIND CLONES TO BE THE SAME ELEMENT.
00180     ///< THIS IS MOST USEFUL FOR THINGS THAT LIVE IN ONLY ONE
00181     ///< PLACE IN THE SYSTEM, FOR INSTANCE, SYMBOLS.
00182 
00183     INLINE int         operator == (const RefSet<T > &l) const;
00184     ///< Check for equality between two RefSets:
00185     ///<  1.  check that # entries is the same
00186     ///<  2.  check that all members of one are members of the other
00187     
00188     INLINE          RefSet<T >&operator = (const RefSet<T >&l);
00189     ///< Copy operator copies all valid elements of a RefSet.
00190 
00191     INLINE int      structures_OK() const;
00192     ///< Check the structure of the data for errors or inconsistency.
00193     ///< Return 0 and print error message if problems found, otherwise
00194     ///< return 1 without message.
00195 
00196     INLINE Listable *listable_clone() const;
00197     ///< Needed for Listable class.
00198 
00199     INLINE void      print(ostream &o) const;
00200     ///< Needed for Listable class.
00201 };
00202 
00203 
00204 ///< implementation
00205 
00206 #include "Iterator.h"
00207 #include "Mutator.h"
00208 
00209 template <class T>
00210 INLINE          
00211 RefSet<T>::RefSet()
00212 {
00213     ///< nothing to do
00214 }
00215 
00216 template <class T>
00217 INLINE
00218 RefSet<T>::RefSet(const RefSet<T >&l)
00219 {
00220     _list = l._list;
00221 }
00222 
00223 template <class T>
00224 INLINE
00225 RefSet<T>::~RefSet()
00226 {
00227     ///< nothing to do
00228 }
00229 
00230 template <class T>
00231 INLINE int      
00232 RefSet<T>::entries() const
00233 {
00234     return _list.entries();
00235 }
00236 
00237 template <class T>
00238 INLINE Boolean  
00239 RefSet<T>::empty() const
00240 {
00241     return (_list.entries() == 0);
00242 }
00243 
00244 template <class T>
00245 INLINE void     
00246 RefSet<T>::print(ostream & out, char *sep) const
00247 {
00248     out << "{";
00249 
00250     _list.print(out, sep);
00251 
00252     out << "}";
00253 }
00254 
00255 template <class T>
00256 INLINE T &
00257 RefSet<T>::ins(const T &new_element)
00258 {
00259   int loc = _list.index(new_element);
00260   if (loc >= 0) {
00261     ///< Replace the old with the new
00262     _list.modify(loc, CASTAWAY(T &)new_element);
00263   }
00264   else {
00265     ///< Simply insert at end (is not already in set)
00266     _list.ins(new_element, _list.entries());
00267   }
00268 
00269   return CASTAWAY(T &)new_element;
00270 }
00271 
00272 template <class T>
00273 INLINE void     
00274 RefSet<T>::_del(int loc)
00275 {
00276     _list.del(loc);
00277 }
00278 
00279 template <class T>
00280 INLINE void     
00281 RefSet<T>::_modify(int loc, T &el)
00282 {
00283     int old_loc = this->_member(el);
00284 
00285     if (old_loc != loc) {
00286         _list.modify(loc, el);
00287         if (old_loc != -1) {
00288             _list.del(old_loc);
00289         }
00290     }
00291 }
00292 
00293 template <class T>
00294 INLINE void     
00295 RefSet<T>::del(T &el)
00296 {
00297     int i = _list.index(el);
00298 
00299     if (i >= 0)
00300         _list.del(i);
00301 }
00302 
00303 template <class T>
00304 INLINE T &
00305 RefSet<T>::grab()
00306 {
00307     int num = _list.entries()-1;
00308 
00309     ///< Find a valid element
00310     while (!_list.valid(num)) {
00311         _list.del(num);
00312         num = _list.entries()-1;
00313     }
00314 
00315     ///< p_assert( num < 0, "Attempting to grab() from an empty RefSet" );
00316 
00317     T &el = (T &) _list[num];
00318 
00319     _list.del(num);
00320 
00321     return el;
00322 }
00323 
00324 
00325 template <class T>
00326 INLINE int      
00327 RefSet<T>::_member(const T &el) const
00328 {
00329     return _list.index(el);
00330 }
00331 
00332 template <class T>
00333 INLINE Boolean  
00334 RefSet<T>::member(const T &el) const
00335 {
00336     return (_list.member(el));
00337 }
00338 
00339 template <class T>
00340 INLINE Boolean  
00341 RefSet<T>::valid(const int loc) const
00342 {
00343     return (_list.valid(loc));
00344 }
00345 
00346 template <class T>
00347 INLINE Boolean  
00348 RefSet<T>::valid(const T &el) const
00349 {
00350     return (_list.valid(el));
00351 }
00352 
00353 template <class T>
00354 INLINE Boolean  
00355 RefSet<T>::any_valid() const
00356 {
00357     for (int i = 0; i < _list.entries(); ++i)
00358         if (_list.valid(i))
00359             return 1;
00360 
00361     return 0;
00362 }
00363 
00364 template <class T>
00365 INLINE void     
00366 RefSet<T>::clear()
00367 {
00368     _list.clear();
00369 }
00370 
00371 template <class T>
00372 INLINE
00373 int
00374 RefSet<T>::operator == (const RefSet<T> &l) const
00375 {
00376     if (entries() != l.entries())
00377         return 0;
00378 
00379     for (Iterator<T> iter = l; iter.valid(); ++iter) 
00380         if (!(this->member( iter.current() ))) 
00381             return 0;
00382 
00383     return 1;
00384 }
00385 
00386 template <class T>
00387 INLINE RefSet<T> &
00388 RefSet<T>::operator -= (const RefSet<T> &l)
00389 {
00390     ///< THIS OPERATOR DECIDES THAT ELEMENTS ARE THE SAME BY
00391     ///< COMPARING THEIR ADDRESSES, NOT THEIR CONTENT.  THEREFORE,
00392     ///< THIS WILL NOT FIND CLONES TO BE THE SAME ELEMENT.
00393     ///< THIS IS MOST USEFUL FOR THINGS THAT LIVE IN ONLY ONE
00394     ///< PLACE IN THE SYSTEM, FOR INSTANCE, SYMBOLS.
00395 
00396     for (Iterator<T> iter = l; iter.valid(); ++iter) 
00397         if (this->member( iter.current() )) { 
00398         this->del(iter.current());
00399     }
00400 
00401     return *this;
00402 }
00403 
00404 template <class T>
00405 INLINE RefSet<T> &
00406 RefSet<T>::operator += (const RefSet<T> &l)
00407 {
00408     ///< THIS OPERATOR DECIDES THAT ELEMENTS ARE THE SAME BY
00409     ///< COMPARING THEIR ADDRESSES, NOT THEIR CONTENT.  THEREFORE,
00410     ///< THIS WILL NOT FIND CLONES TO BE THE SAME ELEMENT.
00411     ///< THIS IS MOST USEFUL FOR THINGS THAT LIVE IN ONLY ONE
00412     ///< PLACE IN THE SYSTEM, FOR INSTANCE, SYMBOLS.
00413 
00414     for (Iterator<T> iter = l; iter.valid(); ++iter) 
00415         this->ins( iter.current() );
00416 
00417     return *this;
00418 }
00419 
00420 template <class T>
00421 INLINE RefSet<T> & 
00422 RefSet<T>::operator = (const RefSet<T> &l) 
00423 {
00424     _list = l._list;
00425 
00426     return *this;
00427 }
00428 
00429 template <class T>
00430 INLINE int  
00431 RefSet<T>::structures_OK() const
00432 {
00433     return _list.structures_OK();
00434 }
00435 
00436 template <class T>
00437 INLINE const T &
00438 RefSet<T>::_element(int sub) const
00439 {
00440     return (const T &) _list[sub];
00441 }
00442 
00443 template <class T>
00444 INLINE T &
00445 RefSet<T>::_element(int sub)
00446 {
00447     return (T &) _list[sub];
00448 }
00449 
00450 template <class T>
00451 INLINE const Collection &
00452 RefSet<T>::_base_collection() const
00453 {
00454     return _list;
00455 }
00456 
00457 template <class T>
00458 INLINE Collection &
00459 RefSet<T>::_base_collection()
00460 {
00461     return _list;
00462 }
00463 
00464 template <class T>
00465 INLINE Listable *
00466 RefSet<T>::listable_clone() const
00467 {
00468     return (Listable *) new RefSet<T>(*this);
00469 }
00470 
00471 template <class T>
00472 INLINE void
00473 RefSet<T>::print(ostream &o) const
00474 {
00475     print(o, ", ");
00476 }
00477 
00478 ///< This interface is for testing purposes only.  It invokes a non-virtual
00479 ///< member function to print a representation of the data structure at this
00480 ///< level of the Collection hierarchy, and, since it is not a class member
00481 ///< function, it must be explicitly instantiated before use.
00482 
00483 template <class S>
00484 ostream &
00485 operator << (ostream & o, const RefSet<S> &s)
00486 {
00487   s.print(o, ", ");
00488   return o;
00489 }
00490 
00491 #endif
00492 
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:06:05 2005