Guiliani  Version 2.6 revision 7293 (documentation build 12)
eC_TList_Iterators.h
1/*
2* Copyright (C) TES Electronic Solutions GmbH,
3* All Rights Reserved.
4* Contact: info@guiliani.de
5*
6* This file is part of the Guiliani HMI framework
7* for the development of graphical user interfaces on embedded systems.
8*/
9
10#if !defined(ECTLISTITERATORS_H)
11#define ECTLISTITERATORS_H
12
13#include "eC_Types.h"
14#include <cassert>
15
16template <class T> class eC_TListDoubleLinked;
17template <class T> class ListNode;
18template <class T> class eC_TSafeIterator;
19
20
22
33template <class T>
34
36{
37 friend class eC_TListDoubleLinked<T>;
38 friend class eC_TSafeIterator<T>;
39
40protected:
41 typedef ListNode<T> Node;
42
45
46public:
47
48 //-------------------------------------
52 eC_TIterator() : m_pNode(NULL) {}
53
58 eC_TIterator(Node* pNode) : m_pNode(pNode) {}
59
61 virtual ~eC_TIterator() {}
62
70
71 //-------------------------------------
79 {
80 m_pNode = kIter.m_pNode;
81 return *this;
82 }
83
84 //-------------------------------------
91 eC_Bool operator==(const eC_TIterator& kIter) const
92 {
93 return m_pNode == kIter.m_pNode;
94 }
95
103 eC_Bool operator==(const Node* const ptrNode) const
104 {
105 return m_pNode == ptrNode;
106 }
107
108 //-------------------------------------
115 eC_Bool operator!=(const eC_TIterator& kIter) const
116 {
117 return m_pNode != kIter.m_pNode;
118 }
119
120 //------------------------------
128 eC_Bool IsValid() const
129 {
130 return m_pNode != NULL;
131 }
132
133 //-------------------------------------
139 virtual eC_Bool IsInsideList() const
140 {
141 return m_pNode != NULL;
142 }
143
144 //-------------------------------------
154 {
155 eC_TIterator tmpIter = *this; // save old iterator
156 if (m_pNode)
157 {
158 m_pNode = m_pNode->m_pkNext; // next may be NULL if at end
159 }
160 return tmpIter; // return old iterator
161 }
162
163 //-------------------------------------
172 {
173 if (m_pNode != NULL)
174 {
175 m_pNode = m_pNode->m_pkNext; // next may be NULL if at end
176 }
177
178 return *this; // return new iterator (uses copy contructor)
179 }
180
181 //-------------------------------------
191 {
192 eC_TIterator tmpIter = *this;
193 if (m_pNode)
194 {
196 }
197 return tmpIter;
198 }
199
200 //-------------------------------------
209 {
210 if (m_pNode)
211 {
213 }
214
215 return *this;
216 }
217
218 //-------------------------------------
226 {
227 if (m_pNode)
228 {
229 return m_pNode->m_tValue;
230 }
231
232#ifdef GUILIANI_USE_EXCEPTIONS
233 throw 0; // referencing deleted node
234#endif
235 }
236
237protected:
242 Node* GetNode() const
243 {
244 return m_pNode;
245 }
246};
247
248//----------------------------------------------------------------------------
249//----------------------safe Iterators----------------------------------------
250//----------------------------------------------------------------------------
251enum Update_t {REMOVED, ADDED, KILL, REVERSE_ORDER};
252
254
310template <class T>
311
313{
314 friend class eC_TListDoubleLinked<T>;
315 eC_TListDoubleLinked<T>* m_pList;
316 typename eC_TIterator<T>::Node* m_pSaveNextNode;
317 typename eC_TIterator<T>::Node* m_pSavePrevNode;
318
319 //------------------------------
320
321 //this function updates a safe iterator, if list was modified.
322 //function is called by list, if iterator has been registered (e.g. while initialized).
323 void Validate(typename eC_TIterator<T>::Node* pkUpdateNode, Update_t eUpdate)
324 {
325 typename eC_TIterator<T>::Node * pkTempNode;
326
327 switch (eUpdate)
328 {
329 case REMOVED :
330 if (eC_TIterator<T>::m_pNode == pkUpdateNode) //current element was removed
331 {
332 eC_TIterator<T>::m_pNode = NULL; //invalidate iterator until next iteration
333 }
334
335 else if (m_pSaveNextNode == pkUpdateNode) //next element was removed
336 {
337 assert(m_pSaveNextNode != NULL);
338 m_pSaveNextNode = m_pSaveNextNode->m_pkNext;
339 }
340
341 else if (m_pSavePrevNode == pkUpdateNode) //previous element was removed
342 {
343 assert(m_pSavePrevNode != NULL);
344 m_pSavePrevNode = m_pSavePrevNode->m_pkPrevious;
345 }
346 break;
347
348 case KILL : // iterator is invalid (after sorting and RemoveAll in list)
350 m_pSavePrevNode = NULL;
351 m_pSaveNextNode = NULL;
352 break;
353
354 case REVERSE_ORDER :
355 pkTempNode = m_pSaveNextNode;
356 m_pSaveNextNode = m_pSavePrevNode;
357 m_pSavePrevNode = pkTempNode;
358 break;
359
360 case ADDED :
361 // The node "pkUpdateNode" was added:
362 // if new element is added before current element that is associated with this iterator
363
364 if (eC_TIterator<T>::m_pNode == pkUpdateNode->m_pkNext // current element is next element of updated node
365 && eC_TIterator<T>::m_pNode != NULL) // current element is not invalid
366 {
367 m_pSavePrevNode = pkUpdateNode; // previous node is the new node
368 }
369
370 // if new element is added after current element that is associated with this iterator
371 else if (eC_TIterator<T>::m_pNode == pkUpdateNode->m_pkPrevious
372 && eC_TIterator<T>::m_pNode != NULL)
373 {
374 m_pSaveNextNode = pkUpdateNode;
375 }
376
377 // if formerly current node was deleted before and other element was added at this position
378 else if (eC_TIterator<T>::m_pNode == NULL)
379 {
380 if (m_pSavePrevNode == pkUpdateNode->m_pkPrevious
381 && m_pSaveNextNode == pkUpdateNode->m_pkNext)
382 {
383 eC_TIterator<T>::m_pNode = pkUpdateNode;
384 }
385 }
386 break;
387 }
388 }
389
390 void SetList(eC_TListDoubleLinked<T>* pList)
391 {
392 if (m_pList != pList)
393 {
394 eC_TListDoubleLinked<T>* pTempList = m_pList;
395 m_pList = pList;
396 if (pTempList)
397 pTempList->UnregisterIterator(this);
398 if (pList)
399 pList->RegisterIterator(this);
400 }
401 }
402
403public:
410 : m_pList(NULL),
411 m_pSaveNextNode(NULL),
412 m_pSavePrevNode(NULL)
413 {}
414
420 : eC_TIterator<T>(kIter),
421 m_pList(NULL)
422 {
423 SetList(kIter.m_pList);
424 m_pSaveNextNode = kIter.m_pSaveNextNode;
425 m_pSavePrevNode = kIter.m_pSavePrevNode;
426 }
427
428 //------------------------------
429 virtual ~eC_TSafeIterator()
430 {
431 SetList(NULL);
432 }
433
440 {
442 SetList(kIter.m_pList);
443 m_pSaveNextNode = kIter.m_pSaveNextNode;
444 m_pSavePrevNode = kIter.m_pSavePrevNode;
445
446 return *this;
447 }
448
449 //-------------------------------------
455 eC_Bool operator==(const eC_TSafeIterator &kIter) const
456 {
458 && (m_pSavePrevNode == kIter.m_pSavePrevNode)
459 && (m_pSaveNextNode == kIter.m_pSaveNextNode));
460 }
461
462 //-------------------------------------
468 eC_Bool operator!=(const eC_TSafeIterator &kIter)
469 {
471 || (m_pSavePrevNode != kIter.m_pSavePrevNode)
472 || (m_pSaveNextNode != kIter.m_pSaveNextNode));
473 }
474
475 //-------------------------------------
484 {
486 eC_TIterator<T>::m_pNode = m_pSaveNextNode;
487
488 if (pOldNode)
489 m_pSavePrevNode = pOldNode;
490
491 if (m_pSaveNextNode != NULL)
492 {
493 m_pSaveNextNode = m_pSaveNextNode->m_pkNext;
494 }
495
496 return *this;
497 }
498
499 //-------------------------------------
508 {
510 eC_TIterator<T>::m_pNode = m_pSavePrevNode;
511
512 if (pOldNode)
513 m_pSaveNextNode = pOldNode;
514
515 if (m_pSavePrevNode != NULL)
516 {
517 m_pSavePrevNode = m_pSavePrevNode->m_pkPrevious;
518 }
519
520 return *this;
521 }
522
523 //-------------------------------------
530 virtual eC_Bool IsInsideList() const
531 {
532 // Note, we may also be inside of list when current element is invalid
533 return !((eC_TIterator<T>::m_pNode == NULL && m_pSaveNextNode == NULL)
534 || (eC_TIterator<T>::m_pNode == NULL && m_pSavePrevNode != NULL));
535 }
536
537
539 eC_Bool IsPreviousValid() const { return m_pSavePrevNode != NULL;}
540
542 eC_Bool IsNextValid() const{ return m_pSaveNextNode != NULL;}
543};
544
545#endif // ECTLISTITERATORS_H
ListNode template class.
Definition: eC_TList_doubleLinked.h:27
ListNode * m_pkPrevious
pointer to previous node
Definition: eC_TList_doubleLinked.h:44
ListNode * m_pkNext
pointer to next node
Definition: eC_TList_doubleLinked.h:41
T m_tValue
value of this node
Definition: eC_TList_doubleLinked.h:47
Classic iterator implementation with operator++, operator–, operator*.
Definition: eC_TList_Iterators.h:36
eC_TIterator(Node *pNode)
Definition: eC_TList_Iterators.h:58
eC_Bool operator==(const Node *const ptrNode) const
Definition: eC_TList_Iterators.h:103
virtual eC_Bool IsInsideList() const
Definition: eC_TList_Iterators.h:139
eC_TIterator operator++(int)
Definition: eC_TList_Iterators.h:153
eC_TIterator operator--(int)
Definition: eC_TList_Iterators.h:190
ListNode< T > Node
typedef for node
Definition: eC_TList_Iterators.h:41
eC_TIterator & operator=(const eC_TIterator &kIter)
Definition: eC_TList_Iterators.h:78
eC_TIterator(const eC_TIterator< T > &x)
Definition: eC_TList_Iterators.h:69
eC_Bool operator==(const eC_TIterator &kIter) const
Definition: eC_TList_Iterators.h:91
Node * m_pNode
this node
Definition: eC_TList_Iterators.h:44
eC_Bool operator!=(const eC_TIterator &kIter) const
Definition: eC_TList_Iterators.h:115
virtual ~eC_TIterator()
Destructor.
Definition: eC_TList_Iterators.h:61
eC_TIterator & operator++()
Definition: eC_TList_Iterators.h:171
eC_TIterator()
Definition: eC_TList_Iterators.h:52
eC_TIterator & operator--()
Definition: eC_TList_Iterators.h:208
Node * GetNode() const
Definition: eC_TList_Iterators.h:242
eC_Bool IsValid() const
Definition: eC_TList_Iterators.h:128
T & operator*()
Definition: eC_TList_Iterators.h:225
Represents a double linked list template with header and tail node.
Definition: eC_TList_doubleLinked.h:67
An iterator that stays valid even if elements are deleted from the list.
Definition: eC_TList_Iterators.h:313
virtual eC_Bool IsInsideList() const
Definition: eC_TList_Iterators.h:530
eC_Bool operator!=(const eC_TSafeIterator &kIter)
Definition: eC_TList_Iterators.h:468
eC_Bool IsNextValid() const
Definition: eC_TList_Iterators.h:542
eC_TSafeIterator & operator--()
Definition: eC_TList_Iterators.h:507
eC_Bool IsPreviousValid() const
Definition: eC_TList_Iterators.h:539
eC_TSafeIterator & operator=(const eC_TSafeIterator &kIter)
Definition: eC_TList_Iterators.h:439
eC_TSafeIterator & operator++()
Definition: eC_TList_Iterators.h:483
eC_Bool operator==(const eC_TSafeIterator &kIter) const
Definition: eC_TList_Iterators.h:455
eC_TSafeIterator()
Definition: eC_TList_Iterators.h:409
eC_TSafeIterator(const eC_TSafeIterator< T > &kIter)
Definition: eC_TList_Iterators.h:419