lllinkedqueue.h

Go to the documentation of this file.
00001 
00032 #ifndef LL_LLLINKEDQUEUE_H
00033 #define LL_LLLINKEDQUEUE_H
00034 
00035 #include "llerror.h"
00036 
00037 // node that actually contains the data
00038 template <class DATA_TYPE> class LLLinkedQueueNode
00039 {
00040 public:
00041         DATA_TYPE                       mData;
00042         LLLinkedQueueNode       *mNextp;
00043         LLLinkedQueueNode       *mPrevp;
00044 
00045 
00046 public:
00047         LLLinkedQueueNode();
00048         LLLinkedQueueNode(const DATA_TYPE data);
00049 
00050         // destructor does not, by default, destroy associated data
00051         // however, the mDatap must be NULL to ensure that we aren't causing memory leaks
00052         ~LLLinkedQueueNode();
00053 };
00054 
00055 
00056 
00057 template <class DATA_TYPE> class LLLinkedQueue
00058 {
00059 
00060 public:
00061         LLLinkedQueue();
00062 
00063         // destructor destroys list and nodes, but not data in nodes
00064         ~LLLinkedQueue();
00065 
00066         // Puts at end of FIFO
00067         void push(const DATA_TYPE data);
00068 
00069         // Takes off front of FIFO
00070         BOOL pop(DATA_TYPE &data);
00071         BOOL peek(DATA_TYPE &data);
00072 
00073         void reset();
00074 
00075         S32 getLength() const;
00076 
00077         BOOL isEmpty() const;
00078 
00079         BOOL remove(const DATA_TYPE data);
00080 
00081         BOOL checkData(const DATA_TYPE data) const;
00082 
00083 private:
00084         // add node to end of list
00085         // set mCurrentp to mQueuep
00086         void addNodeAtEnd(LLLinkedQueueNode<DATA_TYPE> *nodep);
00087 
00088 private:
00089         LLLinkedQueueNode<DATA_TYPE> mHead;             // head node
00090         LLLinkedQueueNode<DATA_TYPE> mTail;             // tail node
00091         S32 mLength;
00092 };
00093 
00094 
00095 //
00096 // Nodes
00097 //
00098 
00099 template <class DATA_TYPE>
00100 LLLinkedQueueNode<DATA_TYPE>::LLLinkedQueueNode() : 
00101         mData(), mNextp(NULL), mPrevp(NULL)
00102 { }
00103 
00104 template <class DATA_TYPE>
00105 LLLinkedQueueNode<DATA_TYPE>::LLLinkedQueueNode(const DATA_TYPE data) : 
00106         mData(data), mNextp(NULL), mPrevp(NULL)
00107 { }
00108 
00109 template <class DATA_TYPE>
00110 LLLinkedQueueNode<DATA_TYPE>::~LLLinkedQueueNode()
00111 { }
00112 
00113 
00114 //
00115 // Queue itself
00116 //
00117 
00118 template <class DATA_TYPE>
00119 LLLinkedQueue<DATA_TYPE>::LLLinkedQueue()
00120 :       mHead(), 
00121         mTail(), 
00122         mLength(0)
00123 { }
00124 
00125 
00126 // destructor destroys list and nodes, but not data in nodes
00127 template <class DATA_TYPE>
00128 LLLinkedQueue<DATA_TYPE>::~LLLinkedQueue()
00129 {
00130         reset();
00131 }
00132 
00133 
00134 // put data into a node and stick it at the end of the list
00135 template <class DATA_TYPE>
00136 void LLLinkedQueue<DATA_TYPE>::push(const DATA_TYPE data)
00137 {
00138         // make the new node
00139         LLLinkedQueueNode<DATA_TYPE> *nodep = new LLLinkedQueueNode<DATA_TYPE>(data);
00140 
00141         addNodeAtEnd(nodep);
00142 }
00143 
00144 
00145 // search the list starting at mHead.mNextp and remove the link with mDatap == data
00146 // set mCurrentp to mQueuep, or NULL if mQueuep points to node with mDatap == data
00147 // return TRUE if found, FALSE if not found
00148 template <class DATA_TYPE>
00149 BOOL LLLinkedQueue<DATA_TYPE>::remove(const DATA_TYPE data)
00150 {
00151         BOOL b_found = FALSE;
00152 
00153         LLLinkedQueueNode<DATA_TYPE> *currentp = mHead.mNextp;
00154 
00155         while (currentp)
00156         {
00157                 if (currentp->mData == data)
00158                 {
00159                         b_found = TRUE;
00160 
00161                         // if there is a next one, fix it
00162                         if (currentp->mNextp)
00163                         {
00164                                 currentp->mNextp->mPrevp = currentp->mPrevp;
00165                         }
00166                         else // we are at end of list
00167                         {
00168                                 mTail.mPrevp = currentp->mPrevp;
00169                         }
00170 
00171                         // if there is a previous one, fix it
00172                         if (currentp->mPrevp)
00173                         {
00174                                 currentp->mPrevp->mNextp = currentp->mNextp;
00175                         }
00176                         else // we are at beginning of list
00177                         {
00178                                 mHead.mNextp = currentp->mNextp;
00179                         }
00180 
00181                         // remove the node
00182                         delete currentp;
00183                         mLength--;
00184                         break;
00185                 }
00186                 currentp = currentp->mNextp; 
00187         }
00188 
00189         return b_found;
00190 }
00191 
00192 
00193 // remove all nodes from the list but do not delete associated data
00194 template <class DATA_TYPE>
00195 void LLLinkedQueue<DATA_TYPE>::reset()
00196 {
00197         LLLinkedQueueNode<DATA_TYPE> *currentp;
00198         LLLinkedQueueNode<DATA_TYPE> *nextp;
00199         currentp = mHead.mNextp;
00200 
00201         while (currentp)
00202         {
00203                 nextp = currentp->mNextp;
00204                 delete currentp;
00205                 currentp = nextp;
00206         }
00207 
00208         // reset mHead and mCurrentp
00209         mHead.mNextp = NULL;
00210         mTail.mPrevp = NULL;
00211         mLength = 0;
00212 }
00213 
00214 template <class DATA_TYPE>
00215 S32 LLLinkedQueue<DATA_TYPE>::getLength() const
00216 {
00217         return mLength;
00218 }
00219 
00220 template <class DATA_TYPE>
00221 BOOL LLLinkedQueue<DATA_TYPE>::isEmpty() const
00222 {
00223         return mLength <= 0;
00224 }
00225 
00226 // check to see if data is in list
00227 // set mCurrentp and mQueuep to the target of search if found, otherwise set mCurrentp to mQueuep
00228 // return TRUE if found, FALSE if not found
00229 template <class DATA_TYPE>
00230 BOOL LLLinkedQueue<DATA_TYPE>::checkData(const DATA_TYPE data) const
00231 {
00232         LLLinkedQueueNode<DATA_TYPE> *currentp = mHead.mNextp;
00233 
00234         while (currentp)
00235         {
00236                 if (currentp->mData == data)
00237                 {
00238                         return TRUE;
00239                 }
00240                 currentp = currentp->mNextp;
00241         }
00242         return FALSE;
00243 }
00244 
00245 template <class DATA_TYPE>
00246 BOOL LLLinkedQueue<DATA_TYPE>::pop(DATA_TYPE &data)
00247 {
00248         LLLinkedQueueNode<DATA_TYPE> *currentp;
00249 
00250         currentp = mHead.mNextp;
00251         if (!currentp)
00252         {
00253                 return FALSE;
00254         }
00255 
00256         mHead.mNextp = currentp->mNextp;
00257         if (currentp->mNextp)
00258         {
00259                 currentp->mNextp->mPrevp = currentp->mPrevp;
00260         }
00261         else
00262         {
00263                 mTail.mPrevp = currentp->mPrevp;
00264         }
00265 
00266         data = currentp->mData;
00267         delete currentp;
00268         mLength--;
00269         return TRUE;
00270 }
00271 
00272 template <class DATA_TYPE>
00273 BOOL LLLinkedQueue<DATA_TYPE>::peek(DATA_TYPE &data)
00274 {
00275         LLLinkedQueueNode<DATA_TYPE> *currentp;
00276 
00277         currentp = mHead.mNextp;
00278         if (!currentp)
00279         {
00280                 return FALSE;
00281         }
00282         data = currentp->mData;
00283         return TRUE;
00284 }
00285 
00286 
00288 // private members
00290 
00291 
00292 // add node to end of list
00293 // set mCurrentp to mQueuep
00294 template <class DATA_TYPE>
00295 void LLLinkedQueue<DATA_TYPE>::addNodeAtEnd(LLLinkedQueueNode<DATA_TYPE> *nodep)
00296 {
00297         // add the node to the end of the list
00298         nodep->mNextp = NULL;
00299         nodep->mPrevp = mTail.mPrevp;
00300         mTail.mPrevp = nodep;
00301 
00302         // if there's something in the list, fix its back pointer
00303         if (nodep->mPrevp)
00304         {
00305                 nodep->mPrevp->mNextp = nodep;
00306         }
00307         else    // otherwise fix the head node
00308         {
00309                 mHead.mNextp = nodep;
00310         }
00311         mLength++;
00312 }
00313 
00314 #endif

Generated on Fri May 16 08:32:03 2008 for SecondLife by  doxygen 1.5.5