Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

mlist.h

Go to the documentation of this file.
00001 
00025 #ifndef __MAGIC_LIST_H__
00026 #define __MAGIC_LIST_H__
00027 
00028 template <class T>
00029 class ListNode {
00030   public:
00031     T           mData;      // Actual data object
00032     ListNode*   mPrevNext;  // Previous and next nodes, with addresses XORed
00033 
00034                 ListNode    (T data) {mData=data; mPrevNext=NULL;}
00035                 ~ListNode   () {/*delete mData;*/} // Observe that we can't delete the rest of list from here
00036 };
00037 
00038 template <class T> class ListIter;
00039 
00041 template <class T>
00042 class List {
00043   public:
00044                     List        () {mFirst=mLast=NULL;}
00045                     List        (const List<T>& orig) {
00046                         mFirst=mLast=NULL;
00047                         copy (orig);
00048                     }
00049                     ~List       () {empty();}
00050     
00051     void            add         (T object) {
00052         if (mLast) { // Append to tail
00053             ListNode<T>* newNode = new ListNode<T> (object);
00054             mLast->mPrevNext = (ListNode<T>*) (int(mLast->mPrevNext) ^ int(newNode));
00055             newNode->mPrevNext = mLast;
00056             mLast = newNode;
00057         } else // First node
00058             mFirst = mLast = new ListNode<T> (object);
00059     }
00060     //void          add         (const T& obj) {add (new T (obj));}
00061 
00062     ListNode<T>*    getFirst    () {return mFirst;}
00063     ListNode<T>*    getLast     () {return mLast;}
00064 
00065     void            empty       () {
00066         for (ListNode<T>* i=mFirst, *prev=NULL; i; ) {
00067             ListNode<T>* cur = i; // A temporary
00068             // Iterate here, not in for(;;), because we don't want to use a deleted node.
00069             i = (ListNode<T>*) (int(prev) ^ int(i->mPrevNext));
00070             prev = cur;
00071             delete cur; // And now delete
00072         }
00073         mFirst=mLast=NULL;
00074     }
00075 
00076     void            copy        (const List<T>& orig) {
00077         empty ();
00078     }
00079 
00081     void            moveItemsFrom   (List<T>& orig) {
00082         empty ();
00083         mFirst = orig.mFirst;
00084         mLast = orig.mLast;
00085         orig.mFirst = orig.mLast = NULL;
00086     }
00087     
00088   protected:
00089     ListNode<T>     *mFirst, *mLast;
00090 
00091     friend class ListIter<T>;
00092 };
00093 
00094 template <class T>
00095 class ListIter {
00096   public:
00097                     ListIter        (List<T>& list, bool backward=false)
00098                             : mList (list) {backward? last():first();}
00099                     ListIter        (const List<T>& list, bool backward=false)
00100                             : mList (const_cast<List<T>&>(list)) {backward? last() : first();}
00101                     ListIter        (const ListIter<T>& orig)
00102                             : mList(orig.mList), mCurrent(orig.mCurrent), mPrevious (orig.mPrevious) {}
00103     void            first           () {mCurrent=mList.getFirst(); mPrevious=NULL;}
00104     void            last            () {
00105         mCurrent = mList.getLast();
00106         if (mCurrent)
00107             mPrevious = mCurrent->mPrevNext; // Trivial as next is NULL
00108         else
00109             mPrevious = NULL;
00110     }
00111     void            next            () {
00112         if (mCurrent) {
00113             ListNode<T>* cur = mCurrent;
00114             mCurrent = (ListNode<T>*) (int(mPrevious) ^ int(mCurrent->mPrevNext));
00115             mPrevious = cur;
00116         } else
00117             first ();
00118     }
00119     void            previous        () {
00120         ListNode<T>* cur = mCurrent;
00121         mCurrent = mPrevious;
00122         if (mCurrent)
00123             mPrevious = (ListNode<T>*)(int(cur) ^ int(mCurrent->mPrevNext));
00124         else
00125             mPrevious = NULL;
00126     }
00127     bool            exhausted       () const {return !mCurrent;}
00128     T&              get             () {return mCurrent->mData;}
00129     T*              getp            () {return &mCurrent->mData;}
00130     void            deleteCurrent   () {
00131         if (!mCurrent)
00132             return;
00133         
00134         ListNode<T>* nextNode = (ListNode<T>*) (int(mPrevious) ^ int(mCurrent->mPrevNext));
00135         // Adjust links of the surrounding nodes
00136         if (nextNode) {
00137             ListNode<T>* nextnextNode = (ListNode<T>*) (int(mCurrent) ^ int(nextNode->mPrevNext));
00138             nextNode->mPrevNext = (ListNode<T>*) (int(nextnextNode) ^ int(mPrevious));
00139         } else // We are at last node
00140             mList.mLast = mPrevious;
00141             
00142         if (mPrevious) {
00143             ListNode<T>* prevprevNode = (ListNode<T>*) (int(mCurrent) ^ int(mPrevious->mPrevNext));
00144             mPrevious->mPrevNext = (ListNode<T>*) (int(prevprevNode) ^ int(nextNode));
00145         } else // We are at first node
00146             mList.mFirst = nextNode;
00147 
00148         delete mCurrent;
00149         mCurrent = nextNode;
00150     }
00151   protected:
00152     List<T>&        mList;
00153     ListNode<T>*    mCurrent;
00154     ListNode<T>*    mPrevious;
00155 };
00156 
00157 #endif
00158 

Generated on Thu Feb 10 20:06:42 2005 for LibMagiC by doxygen1.2.18