ListIterator.inl 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #ifndef SE_INCL_LISTITERATOR_INL
  2. #define SE_INCL_LISTITERATOR_INL
  3. #ifdef PRAGMA_ONCE
  4. #pragma once
  5. #endif
  6. /* simple list iterator: 4 bytes structure, all functions are inline */
  7. template<class Cbase, int iOffset>
  8. class CListIter {
  9. private:
  10. CListNode *li_CurrentNode;
  11. public:
  12. /* default constructor - no list attached */
  13. CListIter(void) {
  14. li_CurrentNode = NULL;
  15. };
  16. /* constructor with list attaching */
  17. CListIter(const CListHead &lhHead) {
  18. li_CurrentNode = &lhHead.IterationHead();
  19. };
  20. /* constructor to start from given node */
  21. CListIter(CListNode &lnNode) {
  22. ASSERT(lnNode.IsLinked());
  23. li_CurrentNode = &lnNode;
  24. };
  25. /* start iterating */
  26. void Reset(const CListHead &lhHead) {
  27. li_CurrentNode = &lhHead.IterationHead();
  28. };
  29. /* move to next node */
  30. void MoveToNext(void) {
  31. li_CurrentNode = &li_CurrentNode->IterationSucc();
  32. };
  33. /* move to previous node */
  34. void MoveToPrev(void) {
  35. li_CurrentNode = &li_CurrentNode->IterationPred();
  36. };
  37. /* check if finished */
  38. BOOL IsPastEnd(void) {
  39. return li_CurrentNode->IsTailMarker();
  40. };
  41. /* Insert a node after current one. */
  42. inline void InsertAfterCurrent(CListNode &lnNew) {
  43. li_CurrentNode->IterationInsertAfter(lnNew);
  44. };
  45. /* Insert a node before current one. */
  46. inline void InsertBeforeCurrent(CListNode &lnNew) {
  47. li_CurrentNode->IterationInsertBefore(lnNew);
  48. };
  49. /* Get current element. */
  50. Cbase &Current(void) { return *((Cbase*)((UBYTE *)li_CurrentNode - iOffset)); }
  51. Cbase &operator*(void) { return *((Cbase*)((UBYTE *)li_CurrentNode - iOffset)); }
  52. operator Cbase *(void) { return ((Cbase*)((UBYTE *)li_CurrentNode - iOffset)); }
  53. Cbase *operator->(void) { return ((Cbase*)((UBYTE *)li_CurrentNode - iOffset)); }
  54. };
  55. // taken from stddef.h
  56. //#ifndef offsetof
  57. //#define offsetof(s,m) (size_t)&(((s *)0)->m)
  58. //#endif
  59. // declare a list iterator for a class with a CListNode member
  60. #define LISTITER(baseclass, member) CListIter<baseclass, offsetof(baseclass, member)>
  61. // make 'for' construct for walking a list
  62. #define FOREACHINLIST(baseclass, member, head, iter) \
  63. for ( LISTITER(baseclass, member) iter(head); !iter.IsPastEnd(); iter.MoveToNext() )
  64. // make 'for' construct for walking a list, keeping the iterator for later use
  65. #define FOREACHINLISTKEEP(baseclass, member, head, iter) \
  66. LISTITER(baseclass, member) iter(head); \
  67. for (; !iter.IsPastEnd(); iter.MoveToNext() )
  68. // make 'for' construct for deleting a list
  69. #define FORDELETELIST(baseclass, member, head, iter) \
  70. for ( LISTITER(baseclass, member) iter(head), iter##next; \
  71. iter##next=iter, iter##next.IsPastEnd() || (iter##next.MoveToNext(),1), !iter.IsPastEnd(); \
  72. iter = iter##next)
  73. // get the pointer to the first element in the list
  74. #define LIST_HEAD(listhead, baseclass, member) \
  75. ( (baseclass *) ( ((UBYTE *)(&(listhead).Head())) - offsetof(baseclass, member) ) )
  76. // get the pointer to the last element in the list
  77. #define LIST_TAIL(listhead, baseclass, member) \
  78. ( (baseclass *) ( ((UBYTE *)(&(listhead).Tail())) - offsetof(baseclass, member) ) )
  79. // get the pointer to the predecessor of the element
  80. #define LIST_PRED(element, baseclass, member) \
  81. ( (baseclass *) ( ((UBYTE *)(&(element).member.Pred())) - offsetof(baseclass, member) ) )
  82. // get the pointer to the successor of the element
  83. #define LIST_SUCC(element, baseclass, member) \
  84. ( (baseclass *) ( ((UBYTE *)(&(element).member.Succ())) - offsetof(baseclass, member) ) )
  85. #endif /* include-once check. */