Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/util/list.h @ 5216

Last change on this file since 5216 was 5211, checked in by bensch, 19 years ago

orxonox/trunk: valgrind mem-leak-recovered

File size: 10.7 KB
Line 
1/*!
2 * @file list.h
3 * a File that includes a List-template
4 */
5
6#ifndef _LIST_H
7#define _LIST_H
8
9#include "compiler.h"
10#ifndef NULL
11#define NULL 0                                       //!< this will define NULL
12#endif
13
14template<class T> class tIterator;
15
16//! a list element of the tList,
17template<class T> struct listElement
18{
19  listElement*        prev;                          //!< pointer to the previous listElement in the list
20  T*                  curr;                          //!< pointer to the list payload/container
21  listElement*        next;                          //!< pointer to the next listElement
22};
23
24/**
25 *  the list template class
26
27   you will use this as a generic list for all type of objects
28*/
29template<class T> class tList
30{
31  friend class tIterator<T>;
32
33 public:
34  tList ();
35  ~tList ();
36
37  void add(T* entity);
38  void addAtBeginning(T* entity); //!< @todo This should be made with an ENUM
39  void remove(const T* entity);
40  void removeLast();
41  void flush();
42  T* firstElement() const;
43  T* lastElement() const;
44  bool isEmpty() const;
45  unsigned int getSize() const;
46  bool inList(T* entity);
47  tIterator<T>* getIterator() const;
48  T* nextElement(T* toEntity);
49  T* toArray();
50
51 private:
52  unsigned int       size;             //!< the size (lenght) of the list
53  listElement<T>*    first;            //!< pointer to the first element
54  listElement<T>*    last;             //!< pointer to the last element
55  listElement<T>*    currentEl;        //!< pointer to the current element
56};
57
58
59/**
60 *  the constructor
61*/
62template<class T>
63inline tList<T>::tList ()
64{
65  this->first = NULL;
66  this->last = NULL;
67  this->size = 0;
68}
69
70
71/**
72 *  the deconstructor
73
74   this will delete only the list. ATTENTION: the list is deleted, but the objects in the list will
75   not be deleted
76*/
77template<class T>
78inline tList<T>::~tList ()
79{
80  this->currentEl = this->first;
81  while(this->currentEl != NULL)
82    {
83      listElement<T>* le = this->currentEl->next;
84      //delete this->currentEl->curr;  //! THIS IS EXTREMELY UNSAFE (the list only stores pointers not instances) //
85      delete this->currentEl;
86      this->currentEl = le;
87    }
88  this->first = NULL;
89  this->last = NULL;
90  this->size = 0;
91}
92
93
94/**
95 *  add an entity to the list
96 * @param entity: the entity to add
97*/
98template<class T>
99inline void tList<T>::add(T* entity)
100{
101  if( unlikely(entity == NULL)) return;
102  listElement<T>* el = new listElement<T>;
103  el->prev = this->last;
104  el->curr = entity;
105  el->next = NULL;
106
107  this->last = el;
108
109  if( unlikely(el->prev == NULL)) this->first = el; /* if first element */
110  else el->prev->next = el;
111  this->size++;
112}
113
114/**
115 *  add an entity to the list
116 * @param entity: the entity to add
117 */
118template<class T>
119    inline void tList<T>::addAtBeginning(T* entity)
120{
121  if( unlikely(entity == NULL)) return;
122  listElement<T>* el = new listElement<T>;
123  el->next = this->first;
124  el->curr = entity;
125  el->prev = NULL;
126
127  this->first = el;
128
129  if( unlikely(el->next == NULL)) this->first = el; /* if first element */
130  else el->next->prev = el;
131  this->size++;
132}
133
134
135/**
136 *  remove an entity from the list
137 * @param entity: the entity to be removed
138*/
139template<class T>
140inline void tList<T>::remove(const T* entity)
141{
142  this->currentEl = this->first;
143  while( this->currentEl != NULL)
144    {
145      if( unlikely(this->currentEl->curr == entity))
146        {
147          if( unlikely(this->currentEl->prev  == NULL)) this->first = this->currentEl->next;
148          else this->currentEl->prev->next = this->currentEl->next;
149
150          if( unlikely(this->currentEl->next == NULL)) this->last = this->currentEl->prev;
151          else this->currentEl->next->prev = this->currentEl->prev;
152
153          delete this->currentEl;
154          this->size--;
155          return;
156        }
157      this->currentEl = this->currentEl->next;
158    }
159}
160
161/**
162 * removes the Last Element of the List
163 */
164 template<class T>
165     inline void tList<T>::removeLast()
166{
167  if (this->last == NULL)
168    return;
169  else if (this->last == this->first)
170  {
171    delete this->first;
172    this->first = NULL;
173    this->last = NULL;
174    this->size--;
175  }
176  else
177  {
178    listElement<T>* delLast = this->last;
179    this->last->prev->next = NULL;
180    this->last = this->last->prev;
181    delete delLast;
182  }
183}
184
185/**
186 *  this will deletes the objects from the list
187*/
188template<class T>
189inline void tList<T>::flush()
190{
191  this->currentEl = this->first;
192  while(this->currentEl != NULL)
193    {
194      listElement<T>* le = this->currentEl->next;
195      delete this->currentEl->curr;
196      delete this->currentEl;
197      this->currentEl = le;
198    }
199  this->first = NULL;
200  this->last = NULL;
201  this->size = 0;
202}
203
204
205/**
206 *  returns the first element of the list
207 * @returns first element
208*/
209template<class T>
210inline T* tList<T>::firstElement() const
211{
212  return this->first->curr;
213}
214
215
216/**
217 *  function returns the last element of the list
218 * @returns the last element
219*/
220template<class T>
221inline T* tList<T>::lastElement() const
222{
223  return this->last->curr;
224}
225
226
227/**
228 *  returns true if the list is empty
229 * @returns true if the list is empty
230*/
231template<class T>
232inline bool tList<T>::isEmpty() const
233{
234  return (this->size==0)?true:false;
235}
236
237/**
238 *  checks if an entity is in the List
239 * @param entity The entity to check for in the entire List.
240 * @returns true if it is, false otherwise
241*/
242template<class T>
243inline bool tList<T>::inList(T* entity)
244{
245  // pre checks
246  if(this->size == 0) return false;
247  if( entity == NULL) return false;
248
249  // search in the List
250  this->currentEl = this->first;
251  while(this->currentEl->curr != entity && this->currentEl != NULL)
252    this->currentEl = this->currentEl->next;
253
254  // post checks
255  if(this->currentEl == NULL)
256    return false;
257  else
258    return true;
259}
260
261/**
262 *  this returns the number of elements in the list
263 * @returns number of elements
264*/
265template<class T>
266inline unsigned int tList<T>::getSize() const
267{
268  return this->size;
269}
270
271
272/**
273 *  creates an itereator object and returns it
274 * @returns the iterator object to this list
275
276   You will use this, if you want to iterate through the list
277*/
278template<class T>
279inline tIterator<T>* tList<T>::getIterator() const
280{
281  return new tIterator<T>(this);
282}
283
284
285
286/**
287 *  this returns the next element after toEntity or the first if toEntity is last
288 * @param toEntity: the entity after which is an entity, that has to be returned, sorry, terrible phrase
289 * @returns the element after toEntity
290*/
291template<class T>
292inline T* tList<T>::nextElement(T* toEntity)
293{
294  //if( this->last == this->first == NULL) return NULL;
295  if(this->size == 0) return NULL;
296  if( toEntity == NULL) return this->first->curr;
297  if( toEntity == this->last->curr ) return this->first->curr;
298  this->currentEl = this->first;
299  while(this->currentEl->curr != toEntity && this->currentEl->next != NULL)
300    {
301      this->currentEl = this->currentEl->next;
302    }
303  if(this->currentEl == NULL) return NULL;
304  return this->currentEl->next->curr;
305}
306
307
308/**
309 *  creates an array out of the list (ATTENTION: not implemented)
310 * @returns pointer to the array beginning
311
312   ATTENTION: function is not implemented and wont do anything
313*/
314template<class T>
315T* tList<T>::toArray()
316{
317  return NULL;
318}
319
320
321
322
323/**
324 *  an iterator class
325
326   this enables the user to iterate through a list very easely
327 */
328template<class T> class tIterator
329{
330  public:
331    tIterator(const tList<T>* list);
332    ~tIterator();
333
334    T* firstElement();
335    T* lastElement();
336    T* nextElement();
337    T* prevElement();
338    T* seekElement(T* element);
339    T* iteratorElement(const tIterator<T>* iterator);
340
341  private:
342    listElement<T>*    currentEl;                      //!< pointer to the current list element in the iterator
343    listElement<T>*    tmpEl;                          //!< temp listElemnt pointer
344    const tList<T>*    list;                           //!< The List, that we want to iterate through
345};
346
347
348/**
349 *  iterator constructor
350 * @param startElement:  the first list element from the tList
351 *
352 * normaly you will use it like this:
353 **********************************************************
354 * tIterator<char>* nameIterator = nameList->getIterator();
355 * char name* = nameIterator->firstElement();
356 * while( name != NULL)
357 *  {
358 *   PRINTF(3)("found name: %s in list\n", name);
359 *   name = nameIterator->nextElement();
360 *  }
361 * delete nameIterator;
362 * ********************************************************
363 */
364template<class T>
365  inline tIterator<T>::tIterator (const tList<T>* list)
366{
367  this->currentEl = NULL;
368  this->tmpEl = NULL;
369  this->list = list;
370}
371
372
373/**
374 *  the destructor
375 */
376template<class T>
377    inline tIterator<T>::~tIterator ()
378{
379}
380
381template<class T>
382    inline T* tIterator<T>::firstElement ()
383{
384  this->tmpEl = this->list->first;
385  if (this->tmpEl != NULL)
386  {
387    this->currentEl = this->tmpEl->next;
388    return this->tmpEl->curr;
389  }
390  else
391    return NULL;
392}
393
394template<class T>
395    inline T* tIterator<T>::lastElement ()
396{
397  this->tmpEl = this->list->last;
398  if (this->tmpEl != NULL)
399  {
400    this->currentEl = tmpEl->prev;
401    return this->tmpEl->curr;
402  }
403  else
404    return NULL;
405}
406
407
408/**
409 *  use it to iterate through the list
410 * @returns next list element
411 */
412template<class T>
413    inline T* tIterator<T>::nextElement ()
414{
415  if( this->currentEl == NULL)
416    return NULL;
417
418  this->tmpEl = this->currentEl;
419  this->currentEl = this->currentEl->next;
420
421  return this->tmpEl->curr;
422}
423
424/**
425 *  use it to iterate backwards through the list
426 * @returns next list element
427 */
428template<class T>
429    inline T* tIterator<T>::prevElement ()
430{
431  if( this->currentEl == NULL)
432    return NULL;
433
434  this->tmpEl = this->currentEl;
435  this->currentEl = this->currentEl->prev;
436
437  return this->tmpEl->curr;
438}
439
440
441/**
442 *  gets the element after the selected one, sets the iterator to this point in the list
443 * @param element the element to seek
444 * @returns current list element
445 */
446template<class T>
447    inline T* tIterator<T>::seekElement (T* element)
448{
449  if (element == NULL)
450  {
451    this->currentEl = NULL;
452    return NULL;
453  }
454  this->tmpEl = this->list->first;
455  while( this->tmpEl != NULL)
456  {
457    if( unlikely(this->tmpEl->curr == element))
458    {
459      this->currentEl = this->tmpEl;
460      return this->currentEl->curr;
461    }
462    this->tmpEl = this->tmpEl->next;
463  }
464  this->currentEl = NULL;
465  return NULL;
466}
467
468/**
469 * grabs the iterator entity from another iterator
470 * @param iterator the iterator to grab the local currentEl from
471 * @returns the grabbed element (current). NULL if not found, or not defined
472 *
473 * Both iterators must be from the same List!
474 */
475template<class T>
476    T* tIterator<T>::iteratorElement(const tIterator<T>* iterator)
477{
478  if (iterator != NULL && iterator->list == this->list)
479  {
480    this->currentEl = iterator->currentEl;
481    if (this->currentEl != NULL)
482      return this->currentEl->curr;
483    else
484      return NULL;
485  }
486  else
487  {
488    this->currentEl = NULL;
489    return NULL;
490  }
491}
492
493
494#endif /* _LIST_H */
Note: See TracBrowser for help on using the repository browser.