Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 5229 was 5229, checked in by patrick, 19 years ago

orxonox/trunk: remastered the tList class, some speed improvements and some security features. more documentation

File size: 11.0 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) const;
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>
63    inline tList<T>::tList ()
64{
65  this->currentEl = NULL;
66  this->first = NULL;
67  this->last = NULL;
68  this->size = 0;
69}
70
71
72/**
73 *  the deconstructor
74
75   this will delete only the list. ATTENTION: the list is deleted, but the objects in the list will remain
76 */
77template<class T>
78    inline tList<T>::~tList ()
79{
80  this->currentEl = this->first;
81  listElement<T>* le;
82  while(this->currentEl != NULL)
83  {
84    le = this->currentEl->next;
85    delete this->currentEl;
86    this->currentEl = le;
87  }
88  this->first = NULL;
89  this->last = NULL;
90  this->currentEl = NULL;
91  this->size = 0;
92}
93
94
95/**
96 *  add an entity to the list
97 * @param entity: the entity to add
98 */
99template<class T>
100    inline void tList<T>::add(T* entity)
101{
102  if( unlikely(entity == NULL)) return;
103  listElement<T>* el = new listElement<T>;
104  el->prev = this->last;
105  el->curr = entity;
106  el->next = NULL;
107
108  this->last = el;
109
110  if( unlikely(el->prev == NULL)) this->first = el; /* if first element */
111  else el->prev->next = el;
112  this->size++;
113}
114
115/**
116 *  add an entity to the list
117 * @param entity: the entity to add
118 */
119template<class T>
120    inline void tList<T>::addAtBeginning(T* entity)
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;
127
128  this->first = el;
129
130  if( unlikely(el->next == NULL)) this->last = el; /* if first element */
131  else el->next->prev = el;
132  this->size++;
133}
134
135
136/**
137 *  remove an entity from the list
138 * @param entity: the entity to be removed
139 */
140template<class T>
141    inline void tList<T>::remove(const T* entity)
142{
143  this->currentEl = this->first;
144  while( this->currentEl != NULL)
145  {
146    if( unlikely(this->currentEl->curr == entity))
147    {
148      // erstes element?
149      if( unlikely(this->currentEl->prev == NULL)) this->first = this->currentEl->next;
150      else this->currentEl->prev->next = this->currentEl->next;
151
152      // letztes element?
153      if( unlikely(this->currentEl->next == NULL)) this->last = this->currentEl->prev;
154      else this->currentEl->next->prev = this->currentEl->prev;
155
156      delete this->currentEl;
157      this->size--;
158      return;
159    }
160    this->currentEl = this->currentEl->next;
161  }
162}
163
164
165/**
166 * removes the Last Element of the List
167 */
168 template<class T>
169     inline void tList<T>::removeLast()
170{
171  if( unlikely(this->last == NULL))
172    return;
173
174  // only one element in the list (and its not NULL :D )
175  if( unlikely(this->last == this->first))
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}
190
191
192/**
193 *  this will delete all objects from the list, this can be very dangerous if there are ghost objects in the list.
194 */
195template<class T>
196    inline void tList<T>::flush()
197{
198  this->currentEl = this->first;
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  }
208  this->first = NULL;
209  this->last = NULL;
210  this->size = 0;
211}
212
213
214/**
215 *  returns the first element of the list
216 * @returns first element
217 */
218template<class T>
219    inline T* tList<T>::firstElement() const
220{
221  return this->first->curr;
222}
223
224
225/**
226 *  function returns the last element of the list
227 * @returns the last element
228 */
229template<class T>
230    inline T* tList<T>::lastElement() const
231{
232  return this->last->curr;
233}
234
235
236/**
237 *  returns true if the list is empty
238 * @returns true if the list is empty
239 */
240template<class T>
241    inline bool tList<T>::isEmpty() const
242{
243  return (this->size == 0)?true:false;
244}
245
246
247/**
248 *  checks if an entity is in the List.
249 * @param entity The entity to check for in the entire List.
250 * @returns true if it is, false otherwise
251 */
252template<class T>
253    inline bool tList<T>::inList(T* entity) const
254{
255  // pre checks
256  if( unlikely(entity == NULL)) return false;
257
258  // search in the List
259  listElement<T>* el = this->first;
260  while( this->currentEl != NULL)
261  {
262    if( this->currentEl->curr == entity)
263      return true;
264
265    el = this->currentEl->next;
266  }
267}
268
269
270/**
271 *  this returns the number of elements in the list
272 * @returns number of elements
273 */
274template<class T>
275    inline unsigned int tList<T>::getSize() const
276{
277  return this->size;
278}
279
280
281/**
282 *  creates an itereator object and returns it
283 * @returns the iterator object to this list
284
285   You will use this, if you want to iterate through the list
286 */
287template<class T>
288    inline tIterator<T>* tList<T>::getIterator() const
289{
290  return new tIterator<T>(this);
291}
292
293
294
295/**
296 *  this returns the next element after toEntity or the first if toEntity is last
297 * @param toEntity: the entity after which is an entity, that has to be returned, sorry, terrible phrase
298 * @returns the element after toEntity
299 */
300template<class T>
301    inline T* tList<T>::nextElement(T* toEntity)
302{
303  //if( this->last == this->first == NULL) return NULL;
304  if(this->size == 0) return NULL;
305  if( toEntity == NULL) return this->first->curr;
306  if( toEntity == this->last->curr ) return this->first->curr;
307  this->currentEl = this->first;
308  while(this->currentEl->curr != toEntity && this->currentEl->next != NULL)
309  {
310    this->currentEl = this->currentEl->next;
311  }
312  if(this->currentEl == NULL) return NULL;
313  return this->currentEl->next->curr;
314}
315
316
317/**
318 *  creates an array out of the list (ATTENTION: not implemented)
319 * @returns pointer to the array beginning
320
321   ATTENTION: function is not implemented and wont do anything
322 */
323template<class T>
324    T* tList<T>::toArray()
325{
326  return NULL;
327}
328
329
330
331
332/**
333    *  an iterator class
334
335   this enables the user to iterate through a list very easely
336 */
337template<class T> class tIterator
338{
339  public:
340    tIterator(const tList<T>* list);
341    ~tIterator();
342
343    T* firstElement();
344    T* lastElement();
345    T* nextElement();
346    T* prevElement();
347    T* seekElement(const T* element);
348    T* iteratorElement(const tIterator<T>* iterator);
349
350  private:
351    listElement<T>*    currentEl;                      //!< pointer to the current list element in the iterator
352    listElement<T>*    tmpEl;                          //!< temp listElemnt pointer
353    const tList<T>*    list;                           //!< The List, that we want to iterate through
354};
355
356
357/**
358 *  iterator constructor
359 * @param startElement:  the first list element from the tList
360 *
361 * normaly you will use it like this:
362 **********************************************************
363 * tIterator<char>* nameIterator = nameList->getIterator();
364 * char name* = nameIterator->firstElement();
365 * while( name != NULL)
366 *  {
367 *   PRINTF(3)("found name: %s in list\n", name);
368 *   name = nameIterator->nextElement();
369 *  }
370 * delete nameIterator;
371 * ********************************************************
372 */
373template<class T>
374  inline tIterator<T>::tIterator (const tList<T>* list)
375{
376  this->currentEl = NULL;
377  this->tmpEl = NULL;
378  this->list = list;
379}
380
381
382/**
383 *  the destructor
384 */
385template<class T>
386    inline tIterator<T>::~tIterator ()
387{}
388
389/**
390 * this returns the first element of the iterator list
391 * @returns first element
392 */
393template<class T>
394    inline T* tIterator<T>::firstElement ()
395{
396  this->tmpEl = this->list->first;
397  if( likely(this->tmpEl != NULL))
398  {
399    this->currentEl = this->tmpEl->next;
400    return this->tmpEl->curr;
401  }
402  else
403    return NULL;
404}
405
406/**
407 * this returns the last element of the iterator list
408 * @returns last element
409 */
410template<class T>
411    inline T* tIterator<T>::lastElement ()
412{
413  this->tmpEl = this->list->last;
414  if( likely(this->tmpEl != NULL))
415  {
416    this->currentEl = tmpEl->prev;
417    return this->tmpEl->curr;
418  }
419  else
420    return NULL;
421}
422
423
424/**
425 *  use it to iterate through the list
426 * @returns next list element
427 */
428template<class T>
429    inline T* tIterator<T>::nextElement ()
430{
431  if( unlikely(this->currentEl == NULL))
432    return NULL;
433
434  this->tmpEl = this->currentEl;
435  this->currentEl = this->currentEl->next;
436
437  return this->tmpEl->curr;
438}
439
440
441/**
442 *  use it to iterate backwards through the list
443 * @returns next list element
444 */
445template<class T>
446    inline T* tIterator<T>::prevElement ()
447{
448  if( unlikely(this->currentEl == NULL))
449    return NULL;
450
451  this->tmpEl = this->currentEl;
452  this->currentEl = this->currentEl->prev;
453
454  return this->tmpEl->curr;
455}
456
457
458/**
459 *  gets the element after the selected one, sets the iterator to this point in the list
460 * @param element the element to seek
461 * @returns current list element
462 */
463template<class T>
464    inline T* tIterator<T>::seekElement (const T* element)
465{
466  if( unlikely(element == NULL))
467  {
468    this->currentEl = NULL;
469    return NULL;
470  }
471  this->tmpEl = this->list->first;
472  while( this->tmpEl != NULL)
473  {
474    if( unlikely(this->tmpEl->curr == element))
475    {
476      this->currentEl = this->tmpEl;
477      return this->currentEl->curr;
478    }
479    this->tmpEl = this->tmpEl->next;
480  }
481  this->currentEl = NULL;
482  return NULL;
483}
484
485/**
486 * grabs the iterator entity from another iterator
487 * @param iterator the iterator to grab the local currentEl from
488 * @returns the grabbed element (current). NULL if not found, or not defined
489 *
490 * Both iterators must be from the same List!
491 */
492template<class T>
493    T* tIterator<T>::iteratorElement(const tIterator<T>* iterator)
494{
495  if( unlikely(iterator != NULL && iterator->list == this->list))
496  {
497    this->currentEl = iterator->currentEl;
498    if (this->currentEl != NULL)
499      return this->currentEl->curr;
500    else
501      return NULL;
502  }
503  else
504  {
505    this->currentEl = NULL;
506    return NULL;
507  }
508}
509
510
511#endif /* _LIST_H */
Note: See TracBrowser for help on using the repository browser.