Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: a new Function to List.
This gives the ability to remove entities from the end of the List.
This is good, if you have an entity just added, and then deleted right afterwards

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