Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Tools/List.h

Go to the documentation of this file.
00001 /**
00002  * @file List.h
00003  * 
00004  * Declaration of template class List.
00005  * 
00006  * @author <A href=mailto:roefer@tzi.de>Thomas Röfer</A>
00007  */
00008 
00009 #ifndef __LIST_H__
00010 #define __LIST_H__
00011 
00012 #include "Tools/Streams/InOut.h"
00013 
00014 template <class T> class List;
00015 
00016 template <class T> Out& operator<<(Out&,const List<T>&);
00017 template <class T> In& operator>>(In&,List<T>&);
00018 
00019 /**
00020  * The class implements double linked lists for arbitrary data types.
00021  */
00022 template <class T> class List
00023 {
00024   private:
00025     /**
00026      * A struct for list nodes.
00027      */
00028     struct Data
00029     {
00030       T* data; /**< A pointer to a list entry. */
00031       Data* next; /**< A pointer to the next list node. */
00032       Data* prev; /**< A pointer to the previous list node. */
00033     };
00034 
00035     Data* first; /**< A pointer to the first list node. */
00036     Data* last; /**< A pointer to the last list node. */
00037     int size; /**< The number of entries in the list. */
00038 
00039   public:
00040     /**
00041      * The local class implements a list iterator.
00042      */
00043     class Pos
00044     {
00045       private:
00046         Data* entry; /**< A pointer to the current list entry. */
00047 
00048       public:
00049         /**
00050          * Empty constructor.
00051          * The iterator points nowhere.
00052          */
00053         Pos() {entry = 0;}
00054 
00055         /**
00056          * Constructor.
00057          * The iterator points to the given list node.
00058          * @param p The list node.
00059          */
00060         Pos(Data* p) {entry = p;}
00061 
00062         /**
00063          * The pre-increment operator moves the iterator to the successor in the list.
00064          * If the iterator is moved behind the end of the list, it will point nowhere.
00065          * Note that the iterator must point to a list element before
00066          * this operation.
00067          * @return A reference to the new state of the iterator.
00068          */
00069         Pos& operator++() {entry = entry->next; return *this;}
00070 
00071         /**
00072          * The pre-decrement operator moves the iterator to the predecessor in the list.
00073          * If the iterator is moved before the beginning of the list, it will point nowhere.
00074          * Note that the iterator must point to a list element before
00075          * this operation.
00076          * @return A reference to the new state of the iterator.
00077          */
00078         Pos& operator--() {entry = entry->prev; return *this;}
00079 
00080         /**
00081          * The post-increment operator moves the iterator to the successor in the list.
00082          * If the iterator is moved behind the end of the list, it will point nowhere.
00083          * Note that the iterator must point to a list element before
00084          * this operation.
00085          * @return The state of the iterator before the operation.
00086          */
00087         Pos operator++(int) {Pos old(entry); entry = entry->next; return old;}
00088 
00089         /**
00090          * The post-decrement operator moves the iterator to the predecessor in the list.
00091          * If the iterator is moved before the beginning of the list, it will point nowhere.
00092          * Note that the iterator must point to a list element before
00093          * this operation.
00094          * @return The state of the iterator before the operation.
00095          */
00096         Pos operator--(int) {Pos old(entry); entry = entry->prev; return old;}
00097 
00098         /**
00099          * The operator returns whether the iterator points to a list entry.
00100          * If it does not point to a list entry, it points "nowhere".
00101          * @return Does it point to a list entry?
00102          */
00103         operator bool() const {return entry != 0;}
00104 
00105         /**
00106          * The operator determines whether two iterators point to the same list element.
00107          * @param pos The other iterator.
00108          * @return Are they equal?
00109          */
00110         bool operator==(const Pos& pos) const {return entry == pos.entry;}
00111 
00112         /**
00113          * The operator determines whether two iterators point to different list elements.
00114          * @param pos The other iterator.
00115          * @return Are they unequal?
00116          */
00117         bool operator!=(const Pos& pos) const {return entry != pos.entry;}
00118 
00119       friend class List<T>;
00120     };
00121 
00122     /**
00123      * The functions empties the list. 
00124      * All list elements are destructed.
00125      */
00126     void clear()
00127     {
00128       Pos p = getFirst();
00129       while(p)
00130         remove(p);
00131     }
00132 
00133     /**
00134      * Constructor of an empty list.
00135      */
00136     List() {first = 0; last = 0; size = 0;}
00137 
00138     /**
00139      * The operator copies another list into this list.
00140      * The previous entries in this list are destroyed.
00141      * @param l The other list.
00142      * @return A reference to this list after the operation took place.
00143      */
00144     List& operator=(const List& l)
00145     {
00146       clear();
00147       Pos p = l.getFirst();
00148       while(p)
00149       {
00150         insert(new T(l[p]));
00151         ++p;
00152       }
00153       return *this;
00154     }
00155 
00156     /**
00157      * Copy constuctor.
00158      * @param l The list from which this list will be copied.
00159      */
00160     List(const List& l) {first = 0; last = 0; size = 0; *this = l;}
00161 
00162     /**
00163      * Destructor.
00164      * All list elements are destructed.
00165      */
00166     ~List() {clear();}
00167 
00168     /**
00169      * The function returns an iterator pointing to the first element of the list.
00170      * @return The iterator.
00171      */
00172     Pos getFirst() const {return Pos(first);}
00173 
00174     /**
00175      * The function returns an iterator pointing to the last element of the list.
00176      * @return The iterator.
00177      */
00178     Pos getLast() const {return Pos(last);}
00179 
00180     /**
00181      * The operator implements read-only access to individual elements of the list.
00182      * @param p The iterator pointing to the element to be accessed.
00183      * @return A reference to the selected list element.
00184      */
00185     const T& operator[](Pos p) const {return *p.entry->data;}
00186 
00187     /**
00188      * The operator implements read/write access to individual elements of the list.
00189      * @param p The iterator pointing to the element to be accessed.
00190      * @return A reference to the selected list element.
00191      */
00192     T& operator[](Pos p) {return *p.entry->data;}
00193 
00194     /**
00195      * The operator concatenates another list to this list.
00196      * @param l The other list.
00197      * @return A reference to this list after the operation took place.
00198      */
00199     List<T>& operator+=(const List<T>& l)
00200     {
00201       for(List<T>::Pos pos = l.getFirst(); pos; ++pos)
00202         insert(l[pos]);
00203       return *this;
00204     }
00205 
00206     /**
00207      * The operator concatenates two lists.
00208      * @param l The other list.
00209      * @return The concatenation of this list and the other list.
00210      */
00211     List<T> operator+(const List<T>& l) const {List<T> temp(*this); return temp += l;}
00212 
00213     /**
00214      * The function returns the number of elements in the list.
00215      * @return The length of the list.
00216      */
00217     int getSize() const {return size;}
00218 
00219     /**
00220      * The function inserts a new element into the list.
00221      * @param t The new element. It will not be copied, and it will be destructed
00222      *          when it is removed from the list.
00223      * @param p An iterator pointing to the element after which the new one is
00224      *          inserted. If the operator points nowhere, the element will be
00225      *          appended to the list. This is also the default case.
00226      * @return An iterator pointing to the new list element.
00227      */
00228     Pos insert(T* t,Pos p = Pos())
00229     {
00230       Data* data = new Data;
00231       data->data = t;
00232       if(p.entry)
00233       {
00234         data->prev = p.entry->prev;
00235         p.entry->prev = data;
00236         if(data->prev)
00237         {
00238           data->next = data->prev->next;
00239           data->prev->next = data;
00240         }
00241         else
00242         {
00243           data->next = first;
00244           first = data;
00245         }
00246       }
00247       else
00248       {
00249         data->prev = last;
00250         last = data;
00251         data->next = 0;
00252         if(data->prev)
00253           data->prev->next = data;
00254         else
00255           first = data;
00256       }
00257       ++size;
00258       return Pos(data);
00259     }
00260 
00261     /**
00262      * The function inserts a new element into the list.
00263      * @param t The new element. A copy will be inserted into the list. Therefore,
00264      *          the class of the element must provide a copy constuctor.
00265      * @param p An iterator pointing to the element after which the new one is
00266      *          inserted. If the operator points nowhere, the element will be
00267      *          appended to the list. This is also the default case.
00268      * @return An iterator pointing to the new list element.
00269      */
00270     Pos insert(const T& t,Pos p = Pos()) {T* t2 = new T(t); return insert(t2,p);}
00271 
00272     /**
00273      * The function removes an element from the list.
00274      * The element will be destructed.
00275      * @param p An iterator pointing to the element that shall be removed.
00276      */
00277     void remove(Pos& p)
00278     {
00279       Data* data = p.entry;
00280       if(!data)
00281         return;
00282       if(data->prev)
00283         data->prev->next = data->next;
00284       else
00285         first = data->next;
00286       if(data->next)
00287         data->next->prev = data->prev;
00288       else
00289         last = data->prev;
00290       p.entry = data->next;
00291 //without if (data->data): HEAP[RobotControl.exe]: HEAP: Free Heap block 9807e38 modified at 9807e64 after it was freed
00292       if (data->data)
00293         delete data->data;
00294       delete data;
00295       --size;
00296     }
00297 };
00298 
00299 /**
00300  * The operator writes a list into a stream.
00301  * @param stream The stream.
00302  * @param list The list that is written.
00303  * @return The stream.
00304  */
00305 template <class T> Out& operator<<(Out& stream,const List<T>& list)
00306 {
00307   stream << list.getSize();
00308   for(typename List<T>::Pos pos = list.getFirst(); pos; ++pos)
00309     stream << list[pos];
00310   return stream;
00311 }
00312 
00313 /**
00314  * The operator reads a list from a stream.
00315  * The original list elements are removed from the list.
00316  * @param stream The stream.
00317  * @param list The list that is read.
00318  * @return The stream.
00319  */
00320 template <class T> In& operator>>(In& stream,List<T>& list)
00321 {
00322   list.clear();
00323   int size;
00324   for(stream >> size; size; size--)
00325   {
00326     T* p = new T;
00327     stream >> *p;
00328     list.insert(p);
00329   }
00330   return stream;
00331 }
00332 
00333 #endif
00334 
00335 /*
00336  * Changelog:
00337  * 
00338  * $Log: List.h,v $
00339  * Revision 1.1.1.1  2004/05/22 17:35:53  cvsadm
00340  * created new repository GT2004_WM
00341  *
00342  * Revision 1.1  2003/10/07 10:13:21  cvsadm
00343  * Created GT2004 (M.J.)
00344  *
00345  * Revision 1.3  2003/09/28 09:28:48  juengel
00346  * Comments corrected.
00347  *
00348  * Revision 1.2  2003/09/26 15:28:10  juengel
00349  * Renamed DataTypes to representations.
00350  *
00351  * Revision 1.1  2003/09/26 11:40:39  juengel
00352  * - sorted tools
00353  * - clean-up in DataTypes
00354  *
00355  * Revision 1.1.1.1  2003/07/02 09:40:22  cvsadm
00356  * created new repository for the competitions in Padova from the 
00357  * tamara CVS (Tuesday 2:00 pm)
00358  *
00359  * removed unused solutions
00360  *
00361  * Revision 1.5  2003/03/05 15:45:52  dueffert
00362  * warning removed
00363  *
00364  * Revision 1.4  2002/12/17 13:37:02  dueffert
00365  * bug fixed ?!
00366  *
00367  * Revision 1.3  2002/12/16 14:53:53  dueffert
00368  * changelog added
00369  *
00370  */

Generated on Thu Sep 23 19:57:38 2004 for GT2004 by doxygen 1.3.6