Serious-Engine/Sources/Engine/Base/ListIterator.inl
Ryan C. Gordon 24cb244d43 First attempt to hand-merge Ryan's Linux and Mac OS X port.
This was a _ton_ of changes, made 15 years ago, so there are probably some
problems to work out still.

Among others: Engine/Base/Stream.* was mostly abandoned and will need to be
re-ported.

Still, this is a pretty good start, and probably holds a world record for
lines of changes or something.  :)
2016-03-28 23:46:13 -04:00

100 lines
3.4 KiB
C++

#ifndef SE_INCL_LISTITERATOR_INL
#define SE_INCL_LISTITERATOR_INL
#ifdef PRAGMA_ONCE
#pragma once
#endif
/* simple list iterator: 4 bytes structure, all functions are inline */
template<class Cbase, int iOffset>
class CListIter {
private:
CListNode *li_CurrentNode;
public:
/* default constructor - no list attached */
CListIter(void) {
li_CurrentNode = NULL;
};
/* constructor with list attaching */
CListIter(const CListHead &lhHead) {
li_CurrentNode = &lhHead.IterationHead();
};
/* constructor to start from given node */
CListIter(CListNode &lnNode) {
ASSERT(lnNode.IsLinked());
li_CurrentNode = &lnNode;
};
/* start iterating */
void Reset(const CListHead &lhHead) {
li_CurrentNode = &lhHead.IterationHead();
};
/* move to next node */
void MoveToNext(void) {
li_CurrentNode = &li_CurrentNode->IterationSucc();
};
/* move to previous node */
void MoveToPrev(void) {
li_CurrentNode = &li_CurrentNode->IterationPred();
};
/* check if finished */
BOOL IsPastEnd(void) {
return li_CurrentNode->IsTailMarker();
};
/* Insert a node after current one. */
inline void InsertAfterCurrent(CListNode &lnNew) {
li_CurrentNode->IterationInsertAfter(lnNew);
};
/* Insert a node before current one. */
inline void InsertBeforeCurrent(CListNode &lnNew) {
li_CurrentNode->IterationInsertBefore(lnNew);
};
/* Get current element. */
Cbase &Current(void) { return *((Cbase*)((UBYTE *)li_CurrentNode - iOffset)); }
Cbase &operator*(void) { return *((Cbase*)((UBYTE *)li_CurrentNode - iOffset)); }
operator Cbase *(void) { return ((Cbase*)((UBYTE *)li_CurrentNode - iOffset)); }
Cbase *operator->(void) { return ((Cbase*)((UBYTE *)li_CurrentNode - iOffset)); }
};
// taken from stddef.h
//#ifndef offsetof
//#define offsetof(s,m) (size_t)&(((s *)0)->m)
//#endif
// declare a list iterator for a class with a CListNode member
#define LISTITER(baseclass, member) CListIter<baseclass, offsetof(baseclass, member)>
// make 'for' construct for walking a list
#define FOREACHINLIST(baseclass, member, head, iter) \
for ( LISTITER(baseclass, member) iter(head); !iter.IsPastEnd(); iter.MoveToNext() )
// make 'for' construct for walking a list, keeping the iterator for later use
#define FOREACHINLISTKEEP(baseclass, member, head, iter) \
LISTITER(baseclass, member) iter(head); \
for (; !iter.IsPastEnd(); iter.MoveToNext() )
// make 'for' construct for deleting a list
#define FORDELETELIST(baseclass, member, head, iter) \
for ( LISTITER(baseclass, member) iter(head), iter##next; \
iter##next=iter, iter##next.IsPastEnd() || (iter##next.MoveToNext(),1), !iter.IsPastEnd(); \
iter = iter##next)
// get the pointer to the first element in the list
#define LIST_HEAD(listhead, baseclass, member) \
( (baseclass *) ( ((UBYTE *)(&(listhead).Head())) - _offsetof(baseclass, member) ) )
// get the pointer to the last element in the list
#define LIST_TAIL(listhead, baseclass, member) \
( (baseclass *) ( ((UBYTE *)(&(listhead).Tail())) - _offsetof(baseclass, member) ) )
// get the pointer to the predecessor of the element
#define LIST_PRED(element, baseclass, member) \
( (baseclass *) ( ((UBYTE *)(&(element).member.Pred())) - _offsetof(baseclass, member) ) )
// get the pointer to the successor of the element
#define LIST_SUCC(element, baseclass, member) \
( (baseclass *) ( ((UBYTE *)(&(element).member.Succ())) - _offsetof(baseclass, member) ) )
#endif /* include-once check. */