00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef CATQueue_H_
00015 #define CATQueue_H_
00016
00017 #include "CATInternal.h"
00018
00019
00020
00021
00022 template<class T>
00023 class CATQueue
00024 {
00025 public:
00026
00027
00028 typedef void (*CATQueueENUMCB)(T& object, void* userParam);
00029
00030 protected:
00031
00032
00033
00034
00035 template<class T>
00036 class Node
00037 {
00038 friend CATQueue<T>;
00039 protected:
00040 Node(T& data)
00041 {
00042 fData = data;
00043 fNext = 0;
00044 }
00045
00046
00047
00048
00049 virtual ~Node()
00050 {
00051 }
00052
00053 private:
00054 T fData;
00055 Node<T>* fNext;
00056 };
00057
00058
00059 public:
00060
00061 CATQueue()
00062 {
00063 fHead = 0;
00064 fTail = 0;
00065 fSize = 0;
00066 }
00067
00068
00069 CATQueue(const CATQueue& srcQueue)
00070 {
00071 int size = srcQueue.Size();
00072
00073 Node<T>* curNode = srcQueue.fHead;
00074 while (curNode)
00075 {
00076 this->Queue(curNode->fData);
00077 curNode = curNode->fNext;
00078 }
00079 }
00080
00081
00082 virtual ~CATQueue()
00083 {
00084 Clear();
00085 }
00086
00087
00088
00089
00090
00091 void Clear()
00092 {
00093 T object;
00094 while (CATSUCCEEDED(this->Next(object)));
00095 }
00096
00097
00098 CATQueue& operator=(const CATQueue& srcQueue)
00099 {
00100
00101 if (&srcQueue == this)
00102 return *this;
00103
00104 int size = srcQueue.Size();
00105
00106 Node<T>* curNode = srcQueue.fHead;
00107 while (curNode)
00108 {
00109 this->Queue(curNode->fData);
00110 curNode = curNode->fNext;
00111 }
00112
00113 return *this;
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123 CATResult Queue(T& object)
00124 {
00125 Node<T>* node = 0;
00126 try
00127 {
00128 node = new Node<T>(object);
00129 }
00130 catch(...)
00131 {
00132
00133
00134
00135
00136
00137 node = 0;
00138 }
00139
00140 if (node == 0)
00141 {
00142 return CATRESULT(CAT_ERR_OUT_OF_MEMORY);
00143 }
00144
00145 if (fTail == 0)
00146 {
00147 CATASSERT(fHead == 0, "Tail is null, but head isn't. Error in queue.");
00148 fHead = node;
00149 fTail = node;
00150 }
00151 else
00152 {
00153 fTail->fNext = node;
00154 fTail = node;
00155 }
00156
00157 fSize++;
00158 return CATRESULT(CAT_SUCCESS);
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168 CATResult Next(T& object)
00169 {
00170 if (fSize == 0)
00171 {
00172 return CATRESULT(CAT_ERR_QUEUE_EMPTY);
00173 }
00174 Node<T>* node = fHead;
00175 object = node->fData;
00176 fHead = node->fNext;
00177 delete node;
00178 fSize--;
00179
00180 if (fHead == 0)
00181 {
00182 fTail = 0;
00183 }
00184
00185 return CATRESULT(CAT_SUCCESS);
00186 }
00187
00188
00189 CATUInt32 Size() const
00190 {
00191 return fSize;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200
00201 void Enumerate(CATQueueENUMCB enumCallback, void* userParam)
00202 {
00203 CATASSERT(enumCallback != 0, "Callback must be valid.");
00204
00205 if (!enumCallback)
00206 return;
00207
00208 Node<T>* curNode = fHead;
00209 while (curNode != 0)
00210 {
00211 enumCallback(curNode->fData,userParam);
00212 curNode = curNode->fNext;
00213 }
00214 }
00215
00216
00217 private:
00218 Node<T>* fHead;
00219 Node<T>* fTail;
00220 CATUInt32 fSize;
00221 };
00222
00223
00224
00225 #endif // CATQueue_H_