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 */