Main Page   Class Hierarchy   Compound List   File List   Compound Members  

mlist.h

00001 #ifndef __LIST_H__
00002 
00003 template <class T>
00004 class ListNode {
00005   public:
00006     T           mData;      // Actual data object
00007     ListNode*   mPrevNext;  // Previous and next nodes, with addresses XORed
00008 
00009                 ListNode    (T data) {mData=data; mPrevNext=NULL;}
00010                 ~ListNode   () {/*delete mData;*/} // Observe that we can't delete the rest of list from here
00011 };
00012 
00013 template <class T> class ListIter;
00014 
00016 template <class T>
00017 class List {
00018   public:
00019                     List        () {mFirst=mLast=NULL;}
00020                     List        (const List<T>& orig) {
00021                         mFirst=mLast=NULL;
00022                         copy (orig);
00023                     }
00024                     ~List       () {empty();}
00025     
00026     void            add         (T object) {
00027         if (mLast) { // Append to tail
00028             ListNode<T>* newNode = new ListNode<T> (object);
00029             mLast->mPrevNext = (ListNode<T>*) (int(mLast->mPrevNext) ^ int(newNode));
00030             newNode->mPrevNext = mLast;
00031             mLast = newNode;
00032         } else // First node
00033             mFirst = mLast = new ListNode<T> (object);
00034     }
00035     //void          add         (const T& obj) {add (new T (obj));}
00036 
00037     ListNode<T>*    getFirst    () {return mFirst;}
00038     ListNode<T>*    getLast     () {return mLast;}
00039 
00040     void            empty       () {
00041         for (ListNode<T>* i=mFirst, *prev=NULL; i; ) {
00042             ListNode<T>* cur = i; // A temporary
00043             // Iterate here, not in for(;;), because we don't want to use a deleted node.
00044             i = (ListNode<T>*) (int(prev) ^ int(i->mPrevNext));
00045             prev = cur;
00046             delete cur; // And now delete
00047         }
00048         mFirst=mLast=NULL;
00049     }
00050 
00051     void            copy        (const List<T>& orig) {
00052         empty ();
00053     }
00054 
00056     void            moveItemsFrom   (List<T>& orig) {
00057         empty ();
00058         mFirst = orig.mFirst;
00059         mLast = orig.mLast;
00060         orig.mFirst = orig.mLast = NULL;
00061     }
00062     
00063   protected:
00064     ListNode<T>     *mFirst, *mLast;
00065 
00066     friend ListIter<T>;
00067 };
00068 
00069 template <class T>
00070 class ListIter {
00071   public:
00072                     ListIter        (List<T>& list, bool backward=false)
00073                             : mList (list) {backward? last():first();}
00074                     ListIter        (const List<T>& list, bool backward=false)
00075                             : mList (const_cast<List<T>&>(list)) {backward? last() : first();}
00076                     ListIter        (const ListIter<T>& orig)
00077                             : mList(orig.mList), mCurrent(orig.mCurrent), mPrevious (orig.mPrevious) {}
00078     void            first           () {mCurrent=mList.getFirst(); mPrevious=NULL;}
00079     void            last            () {
00080         mCurrent = mList.getLast();
00081         if (mCurrent)
00082             mPrevious = mCurrent->mPrevNext; // Trivial as next is NULL
00083         else
00084             mPrevious = NULL;
00085     }
00086     void            next            () {
00087         if (mCurrent) {
00088             ListNode<T>* cur = mCurrent;
00089             mCurrent = (ListNode<T>*) (int(mPrevious) ^ int(mCurrent->mPrevNext));
00090             mPrevious = cur;
00091         } else
00092             first ();
00093     }
00094     void            previous        () {
00095         ListNode<T>* cur = mCurrent;
00096         mCurrent = mPrevious;
00097         if (mCurrent)
00098             mPrevious = (ListNode<T>*)(int(cur) ^ int(mCurrent->mPrevNext));
00099         else
00100             mPrevious = NULL;
00101     }
00102     bool            exhausted       () const {return !mCurrent;}
00103     T&              get             () {return mCurrent->mData;}
00104     T*              getp            () {return &mCurrent->mData;}
00105     void            deleteCurrent   () {
00106         if (!mCurrent)
00107             return;
00108         
00109         ListNode<T>* nextNode = (ListNode<T>*) (int(mPrevious) ^ int(mCurrent->mPrevNext));
00110         // Adjust links of the surrounding nodes
00111         if (nextNode) {
00112             ListNode<T>* nextnextNode = (ListNode<T>*) (int(mCurrent) ^ int(nextNode->mPrevNext));
00113             nextNode->mPrevNext = (ListNode<T>*) (int(nextnextNode) ^ int(mPrevious));
00114         } else // We are at last node
00115             mList.mLast = mPrevious;
00116             
00117         if (mPrevious) {
00118             ListNode<T>* prevprevNode = (ListNode<T>*) (int(mCurrent) ^ int(mPrevious->mPrevNext));
00119             mPrevious->mPrevNext = (ListNode<T>*) (int(prevprevNode) ^ int(nextNode));
00120         } else // We are at first node
00121             mList.mFirst = nextNode;
00122 
00123         delete mCurrent;
00124         mCurrent = nextNode;
00125     }
00126   protected:
00127     List<T>&        mList;
00128     ListNode<T>*    mCurrent;
00129     ListNode<T>*    mPrevious;
00130 };
00131 
00132 #endif

Generated at Tue Dec 4 19:53:26 2001 for MagiC++ by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001