00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00037 template<class T> class pgList
00038 {
00039 public:
00040 pgDefineException(ExceptionInvalidArgument);
00041
00045 class Item
00046 {
00047 friend class pgList<T>;
00048
00049 public:
00050 pgDefineException(ExceptionInvalidArgument);
00051 pgDefineException(ExceptionInvalidCall);
00052 pgDefineException(ExceptionNotInitialized);
00053
00057 Item()
00058 {
00059 m_self = NULL;
00060 m_list = NULL;
00061 m_prev = m_next = NULL;
00062 }
00063
00067 ~Item()
00068 {
00069 leave();
00070 }
00071
00077 void init(T* self)
00078 {
00079 if (!self)
00080 {
00081 pgThrow(ExceptionInvalidArgument);
00082 }
00083
00084 m_self = self;
00085 }
00086
00091 T* getSelf() const
00092 {
00093 if (!m_self)
00094 {
00095 pgThrow(ExceptionNotInitialized);
00096 }
00097
00098 return m_self;
00099 }
00100
00106 Item* getPrevN() const
00107 {
00108 if (!hasList())
00109 {
00110 pgThrow(ExceptionInvalidCall);
00111 }
00112
00113 return (m_prev != &m_list->m_start) ? m_prev : NULL;
00114 }
00115
00121 Item* getNextN() const
00122 {
00123 if (!hasList())
00124 {
00125 pgThrow(ExceptionInvalidCall);
00126 }
00127
00128 return (m_next != &m_list->m_end) ? m_next : NULL;
00129 }
00130
00135 bool hasList() const
00136 {
00137 return m_list ? true : false;
00138 }
00139
00145 pgList<T>* getListN() const
00146 {
00147 return m_list;
00148 }
00149
00154 void joinBefore(Item* item)
00155 {
00156 if (!item || item == this || !item->hasList())
00157 {
00158 pgThrow(ExceptionInvalidArgument);
00159 }
00160
00161 leave();
00162
00163 m_list = item->m_list;
00164
00165 m_prev = item->m_prev;
00166 m_next = item;
00167
00168 m_prev->m_next = m_next->m_prev = this;
00169
00170 m_list->m_item_num++;
00171 }
00172
00177 void joinAfter(Item* item)
00178 {
00179 if (!item || item == this || !item->hasList())
00180 {
00181 pgThrow(ExceptionInvalidArgument);
00182 }
00183
00184 leave();
00185
00186 m_list = item->m_list;
00187
00188 m_prev = item;
00189 m_next = item->m_next;
00190
00191 m_prev->m_next = m_next->m_prev = this;
00192
00193 m_list->m_item_num++;
00194 }
00195
00199 void leave()
00200 {
00201 if (m_prev && m_next)
00202 {
00203 m_list->m_item_num--;
00204
00205 m_prev->m_next = m_next;
00206 m_next->m_prev = m_prev;
00207
00208 m_list = NULL;
00209 m_prev = m_next = NULL;
00210 }
00211 }
00212
00213 private:
00214 Item(const Item&) {}
00215 void operator=(const Item&) {}
00216
00217 T* m_self;
00218 pgList<T>* m_list;
00219 Item* m_prev;
00220 Item* m_next;
00221 };
00222
00226 pgList()
00227 {
00228 m_item_num = 0;
00229
00230 m_start.m_list = m_end.m_list = this;
00231 m_start.m_next = &m_end;
00232 m_end.m_prev = &m_start;
00233 }
00234
00238 ~pgList()
00239 {
00240 clear();
00241 }
00242
00247 u32 getItemNum() const
00248 {
00249 return m_item_num;
00250 }
00251
00256 bool hasItem() const
00257 {
00258 return getFirstN() ? true : false;
00259 }
00260
00266 Item* getFirstN() const
00267 {
00268 return (m_start.m_next != &m_end) ? m_start.m_next : NULL;
00269 }
00270
00276 Item* getLastN() const
00277 {
00278 return (m_end.m_prev != &m_start) ? m_end.m_prev : NULL;
00279 }
00280
00285 void addFirst(Item* item)
00286 {
00287 if (!item)
00288 {
00289 pgThrow(ExceptionInvalidArgument);
00290 }
00291
00292 item->joinAfter(&m_start);
00293 }
00294
00299 void addLast(Item* item)
00300 {
00301 if (!item)
00302 {
00303 pgThrow(ExceptionInvalidArgument);
00304 }
00305
00306 item->joinBefore(&m_end);
00307 }
00308
00312 void clear()
00313 {
00314 while (hasItem())
00315 {
00316 getFirstN()->leave();
00317 }
00318 }
00319
00320 private:
00321 pgList(const pgList<T>&) {}
00322 void operator=(const pgList<T>&) {}
00323
00324 Item m_start;
00325 Item m_end;
00326 u32 m_item_num;
00327 };