Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: scrolling back through the Shell's History works

File size: 12.2 KB
RevLine 
[4486]1/*!
[5068]2 * @file list.h
3 * a File that includes a List-template
4 */
[2636]5
[3224]6#ifndef _LIST_H
7#define _LIST_H
[2036]8
[3860]9#include "compiler.h"
10#ifndef NULL
[4499]11#define NULL 0                                       //!< this will define NULL
[3860]12#endif
[2036]13
[5115]14template<class T> class tIterator;
[2036]15
[4574]16//! a list element of the tList,
[3652]17template<class T> struct listElement
[2077]18{
[4488]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
[3652]22};
[2077]23
[4488]24/**
[4836]25 *  the list template class
[4497]26
27   you will use this as a generic list for all type of objects
[5229]28 */
[4574]29template<class T> class tList
[2822]30{
[5115]31  friend class tIterator<T>;
32
[5229]33  public:
34    tList ();
35    ~tList ();
[2822]36
[5229]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) const;
47    tIterator<T>* getIterator() const;
48    T* nextElement(T* toEntity);
49    T* toArray();
[3652]50
[5229]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
[2822]56};
57
58
[4497]59/**
[4836]60 *  the constructor
[5229]61 */
[2822]62template<class T>
[5229]63    inline tList<T>::tList ()
[2822]64{
[5229]65  this->currentEl = NULL;
[2822]66  this->first = NULL;
67  this->last = NULL;
68  this->size = 0;
69}
70
[4497]71
72/**
[4836]73 *  the deconstructor
[4497]74
[5229]75   this will delete only the list. ATTENTION: the list is deleted, but the objects in the list will remain
76 */
[2822]77template<class T>
[5229]78    inline tList<T>::~tList ()
[3553]79{
80  this->currentEl = this->first;
[5229]81  listElement<T>* le;
[3553]82  while(this->currentEl != NULL)
[5229]83  {
84    le = this->currentEl->next;
85    delete this->currentEl;
86    this->currentEl = le;
87  }
[3553]88  this->first = NULL;
89  this->last = NULL;
[5229]90  this->currentEl = NULL;
[3553]91  this->size = 0;
92}
[2822]93
[3553]94
[4497]95/**
[4836]96 *  add an entity to the list
97 * @param entity: the entity to add
[5229]98 */
[2822]99template<class T>
[5229]100    inline void tList<T>::add(T* entity)
[2822]101{
[3860]102  if( unlikely(entity == NULL)) return;
[3652]103  listElement<T>* el = new listElement<T>;
[2822]104  el->prev = this->last;
105  el->curr = entity;
106  el->next = NULL;
107
108  this->last = el;
109
[3860]110  if( unlikely(el->prev == NULL)) this->first = el; /* if first element */
[2822]111  else el->prev->next = el;
112  this->size++;
113}
114
[5073]115/**
116 *  add an entity to the list
117 * @param entity: the entity to add
118 */
119template<class T>
[5074]120    inline void tList<T>::addAtBeginning(T* entity)
[5073]121{
122  if( unlikely(entity == NULL)) return;
123  listElement<T>* el = new listElement<T>;
124  el->next = this->first;
125  el->curr = entity;
126  el->prev = NULL;
[2822]127
[5073]128  this->first = el;
129
[5229]130  if( unlikely(el->next == NULL)) this->last = el; /* if first element */
[5073]131  else el->next->prev = el;
132  this->size++;
133}
134
135
[4497]136/**
[4836]137 *  remove an entity from the list
138 * @param entity: the entity to be removed
[5229]139 */
[2822]140template<class T>
[5229]141    inline void tList<T>::remove(const T* entity)
[2822]142{
143  this->currentEl = this->first;
144  while( this->currentEl != NULL)
[5229]145  {
146    if( unlikely(this->currentEl->curr == entity))
[2822]147    {
[5229]148      // erstes element?
149      if( unlikely(this->currentEl->prev == NULL)) this->first = this->currentEl->next;
150      else this->currentEl->prev->next = this->currentEl->next;
[2822]151
[5229]152      // letztes element?
153      if( unlikely(this->currentEl->next == NULL)) this->last = this->currentEl->prev;
154      else this->currentEl->next->prev = this->currentEl->prev;
[2822]155
[5229]156      delete this->currentEl;
157      this->size--;
158      return;
[2822]159    }
[5229]160    this->currentEl = this->currentEl->next;
161  }
[2822]162}
163
[5229]164
[5068]165/**
166 * removes the Last Element of the List
167 */
168 template<class T>
169     inline void tList<T>::removeLast()
170{
[5229]171  if( unlikely(this->last == NULL))
[5068]172    return;
[5229]173
174  // only one element in the list (and its not NULL :D )
175  if( unlikely(this->last == this->first))
[5068]176  {
177    delete this->first;
178    this->first = NULL;
179    this->last = NULL;
180    this->size--;
181  }
182  else
183  {
184    listElement<T>* delLast = this->last;
185    this->last->prev->next = NULL;
186    this->last = this->last->prev;
187    delete delLast;
188  }
189}
[2822]190
[5229]191
[4497]192/**
[5229]193 *  this will delete all objects from the list, this can be very dangerous if there are ghost objects in the list.
194 */
[2822]195template<class T>
[5229]196    inline void tList<T>::flush()
[2822]197{
198  this->currentEl = this->first;
[5229]199
200  listElement<T>* le;
201  while( this->currentEl != NULL)
202  {
203    le = this->currentEl->next;
204    delete this->currentEl->curr;
205    delete this->currentEl;
206    this->currentEl = le;
207  }
[2822]208  this->first = NULL;
209  this->last = NULL;
[5230]210  this->currentEl = NULL;
[2822]211  this->size = 0;
212}
213
214
[4497]215/**
[4836]216 *  returns the first element of the list
217 * @returns first element
[5229]218 */
[2822]219template<class T>
[5229]220    inline T* tList<T>::firstElement() const
[2822]221{
222  return this->first->curr;
223}
224
[3832]225
[4497]226/**
[4836]227 *  function returns the last element of the list
228 * @returns the last element
[5229]229 */
[3790]230template<class T>
[5229]231    inline T* tList<T>::lastElement() const
[3790]232{
233  return this->last->curr;
234}
[2822]235
[3790]236
[4497]237/**
[4836]238 *  returns true if the list is empty
239 * @returns true if the list is empty
[5229]240 */
[2822]241template<class T>
[5229]242    inline bool tList<T>::isEmpty() const
[2822]243{
[5229]244  return (this->size == 0)?true:false;
[2822]245}
246
[5229]247
[4508]248/**
[5229]249 *  checks if an entity is in the List.
[4836]250 * @param entity The entity to check for in the entire List.
251 * @returns true if it is, false otherwise
[5229]252 */
[4508]253template<class T>
[5229]254    inline bool tList<T>::inList(T* entity) const
[4574]255{
[4508]256  // pre checks
[5229]257  if( unlikely(entity == NULL)) return false;
[2822]258
[4508]259  // search in the List
[5229]260  listElement<T>* el = this->first;
261  while( this->currentEl != NULL)
262  {
263    if( this->currentEl->curr == entity)
264      return true;
[4508]265
[5229]266    el = this->currentEl->next;
267  }
[4508]268}
269
[5229]270
[4497]271/**
[4836]272 *  this returns the number of elements in the list
273 * @returns number of elements
[5229]274 */
[2822]275template<class T>
[5229]276    inline unsigned int tList<T>::getSize() const
[2822]277{
278  return this->size;
279}
280
281
[4497]282/**
[4836]283 *  creates an itereator object and returns it
284 * @returns the iterator object to this list
[4497]285
286   You will use this, if you want to iterate through the list
[5229]287 */
[2822]288template<class T>
[5229]289    inline tIterator<T>* tList<T>::getIterator() const
[3652]290{
[5115]291  return new tIterator<T>(this);
[3652]292}
293
294
[2822]295
[3585]296/**
[4836]297 *  this returns the next element after toEntity or the first if toEntity is last
298 * @param toEntity: the entity after which is an entity, that has to be returned, sorry, terrible phrase
299 * @returns the element after toEntity
[5229]300 */
[2822]301template<class T>
[5229]302    inline T* tList<T>::nextElement(T* toEntity)
[3585]303{
[3586]304  //if( this->last == this->first == NULL) return NULL;
305  if(this->size == 0) return NULL;
[3585]306  if( toEntity == NULL) return this->first->curr;
307  if( toEntity == this->last->curr ) return this->first->curr;
308  this->currentEl = this->first;
309  while(this->currentEl->curr != toEntity && this->currentEl->next != NULL)
[5229]310  {
311    this->currentEl = this->currentEl->next;
312  }
[3585]313  if(this->currentEl == NULL) return NULL;
314  return this->currentEl->next->curr;
315}
316
317
[4497]318/**
[4836]319 *  creates an array out of the list (ATTENTION: not implemented)
320 * @returns pointer to the array beginning
[4497]321
322   ATTENTION: function is not implemented and wont do anything
[5229]323 */
[3585]324template<class T>
[5229]325    T* tList<T>::toArray()
[4497]326{
327  return NULL;
328}
[2822]329
[5115]330
331
332
333/**
[5229]334    *  an iterator class
[5115]335
336   this enables the user to iterate through a list very easely
337 */
338template<class T> class tIterator
339{
340  public:
341    tIterator(const tList<T>* list);
342    ~tIterator();
343
344    T* firstElement();
[5118]345    T* lastElement();
[5115]346    T* nextElement();
[5118]347    T* prevElement();
[5229]348    T* seekElement(const T* element);
[5115]349    T* iteratorElement(const tIterator<T>* iterator);
350
[5243]351    /** another way to iterate through the list
352     * !! THIS IS NOT MEANT FOR DELETION
353     */
354    T* prevStep();
355    T* nextStep();
356    T* getCurrent();
357
[5115]358  private:
359    listElement<T>*    currentEl;                      //!< pointer to the current list element in the iterator
360    listElement<T>*    tmpEl;                          //!< temp listElemnt pointer
361    const tList<T>*    list;                           //!< The List, that we want to iterate through
362};
363
364
365/**
366 *  iterator constructor
367 * @param startElement:  the first list element from the tList
368 *
369 * normaly you will use it like this:
370 **********************************************************
371 * tIterator<char>* nameIterator = nameList->getIterator();
372 * char name* = nameIterator->firstElement();
373 * while( name != NULL)
374 *  {
375 *   PRINTF(3)("found name: %s in list\n", name);
376 *   name = nameIterator->nextElement();
377 *  }
378 * delete nameIterator;
379 * ********************************************************
380 */
381template<class T>
382  inline tIterator<T>::tIterator (const tList<T>* list)
383{
[5209]384  this->currentEl = NULL;
[5115]385  this->tmpEl = NULL;
386  this->list = list;
387}
388
389
390/**
391 *  the destructor
392 */
393template<class T>
394    inline tIterator<T>::~tIterator ()
[5230]395{
396  this->currentEl = NULL;
397  this->tmpEl = NULL;
398  this->list = NULL;
399}
[5115]400
[5229]401/**
402 * this returns the first element of the iterator list
403 * @returns first element
404 */
[5115]405template<class T>
406    inline T* tIterator<T>::firstElement ()
407{
[5131]408  this->tmpEl = this->list->first;
[5229]409  if( likely(this->tmpEl != NULL))
[5131]410  {
411    this->currentEl = this->tmpEl->next;
412    return this->tmpEl->curr;
413  }
[5118]414  else
[5115]415    return NULL;
[5118]416}
417
[5229]418/**
419 * this returns the last element of the iterator list
420 * @returns last element
421 */
[5118]422template<class T>
423    inline T* tIterator<T>::lastElement ()
424{
[5131]425  this->tmpEl = this->list->last;
[5229]426  if( likely(this->tmpEl != NULL))
[5131]427  {
428    this->currentEl = tmpEl->prev;
429    return this->tmpEl->curr;
430  }
[5115]431  else
[5118]432    return NULL;
[5115]433}
434
435
436/**
437 *  use it to iterate through the list
438 * @returns next list element
439 */
440template<class T>
441    inline T* tIterator<T>::nextElement ()
442{
[5229]443  if( unlikely(this->currentEl == NULL))
[5115]444    return NULL;
445
[5131]446  this->tmpEl = this->currentEl;
[5115]447  this->currentEl = this->currentEl->next;
[5131]448
449  return this->tmpEl->curr;
[5115]450}
451
[5229]452
[5115]453/**
[5118]454 *  use it to iterate backwards through the list
455 * @returns next list element
456 */
457template<class T>
458    inline T* tIterator<T>::prevElement ()
459{
[5229]460  if( unlikely(this->currentEl == NULL))
[5118]461    return NULL;
462
[5131]463  this->tmpEl = this->currentEl;
[5118]464  this->currentEl = this->currentEl->prev;
[5131]465
466  return this->tmpEl->curr;
[5118]467}
468
469
470/**
[5115]471 *  gets the element after the selected one, sets the iterator to this point in the list
472 * @param element the element to seek
473 * @returns current list element
474 */
475template<class T>
[5229]476    inline T* tIterator<T>::seekElement (const T* element)
[5115]477{
[5229]478  if( unlikely(element == NULL))
[5115]479  {
480    this->currentEl = NULL;
481    return NULL;
482  }
483  this->tmpEl = this->list->first;
484  while( this->tmpEl != NULL)
485  {
486    if( unlikely(this->tmpEl->curr == element))
487    {
488      this->currentEl = this->tmpEl;
489      return this->currentEl->curr;
490    }
491    this->tmpEl = this->tmpEl->next;
492  }
493  this->currentEl = NULL;
494  return NULL;
495}
496
497/**
498 * grabs the iterator entity from another iterator
499 * @param iterator the iterator to grab the local currentEl from
[5120]500 * @returns the grabbed element (current). NULL if not found, or not defined
501 *
502 * Both iterators must be from the same List!
[5115]503 */
504template<class T>
505    T* tIterator<T>::iteratorElement(const tIterator<T>* iterator)
506{
[5229]507  if( unlikely(iterator != NULL && iterator->list == this->list))
[5115]508  {
509    this->currentEl = iterator->currentEl;
510    if (this->currentEl != NULL)
511      return this->currentEl->curr;
512    else
513      return NULL;
514  }
515  else
516  {
517    this->currentEl = NULL;
518    return NULL;
519  }
520}
521
[5243]522/**
523 *  use it to move through the list without interfering with the iteration
[5244]524 * @returns previous list element
525 *
526 * this stepping mode will !not! step beyond the boundraries of the List!
[5243]527 */
528template<class T>
529    inline T* tIterator<T>::nextStep ()
530{
531  if( unlikely(this->tmpEl == NULL || this->tmpEl->next == NULL))
532    return NULL;
533  else
534  {
535    this->tmpEl = this->tmpEl->next;
536    return tmpEl->curr;
537  }
538}
539
540
541/**
542 *  use it to move backwards through the list without interfering with the itereation
543 * @returns next list element
[5244]544 *
545 * this stepping mode will !not! step beyond the boundraries of the List!
[5243]546 */
547template<class T>
548    inline T* tIterator<T>::prevStep ()
549{
550  if( unlikely(this->tmpEl == NULL || this->tmpEl->prev == NULL))
551    return NULL;
552  else
553  {
554    this->tmpEl = this->tmpEl->prev;
555    return tmpEl->curr;
556  }
557}
558
[5244]559/**
560 * @returns the current Element
561 */
[5243]562template<class T>
563    inline T* tIterator<T>::getCurrent()
564{
565  if (likeley(this->tmpEl))
566    return this->tmpEl->curr;
567  else
568    return NULL;
569}
570
[3224]571#endif /* _LIST_H */
Note: See TracBrowser for help on using the repository browser.