00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _LISTIMPLEM_H_
00012 #define _LISTIMPLEM_H_
00013
00014 #include "MayDay.H"
00015 #include "BaseNamespaceHeader.H"
00016
00017
00018
00019
00020 template <class T>
00021 Pool List<T>::linkPool(sizeof(ListLink<T>), typeid(T).name(), 300);
00022
00023 template <class T>
00024 List<T>::List (const List<T>& source)
00025 : head(0),
00026 tail(0),
00027 m_usePool(source.m_usePool)
00028 {
00029 if (source.isEmpty())
00030 tail = head = 0;
00031 else
00032 for (ListIterator<T> li(source); li; ++li)
00033 append(li());
00034 }
00035 template <class T>
00036 List<T>::List (bool usePool)
00037 : head(0),
00038 tail(0),
00039 m_usePool(usePool)
00040 {
00041 }
00042
00043
00044
00045
00046
00047 template <class T>
00048 void
00049 List<T>::add (const T& value)
00050 {
00051 append(value);
00052 }
00053
00054 template <class T>
00055 int
00056 List<T>::length () const
00057 {
00058 int len = 0;
00059 for (ListIterator<T> li(*this); li; ++li)
00060 len++;
00061 return len;
00062 }
00063
00064 template <class T>
00065 List<T>&
00066 List<T>::operator= (const List<T>& source)
00067 {
00068 if (!(this == &source))
00069 {
00070 clear();
00071 for (ListIterator<T> li(source); li; ++li)
00072 append(li());
00073 }
00074 return *this;
00075 }
00076
00077 template <class T>
00078 ListLink<T> *
00079 List<T>::addBefore (ListLink<T>* ln,
00080 const T& val)
00081 {
00082 CH_assert(ln != 0 || head == 0);
00083
00084 ListLink<T>* newlink;
00085
00086 if (ln == head)
00087 {
00088
00089 if (m_usePool)
00090 head = newlink = new (linkPool.getPtr()) ListLink<T>(val, 0, head);
00091 else
00092 head = newlink = new ListLink<T>(val, 0, head);
00093
00094 if (tail == 0)
00095 tail = head;
00096 else
00097 head->suc->pre = newlink;
00098 }
00099 else
00100 {
00101
00102 if (m_usePool)
00103 newlink = new (linkPool.getPtr()) ListLink<T>(val, ln->pre, ln);
00104 else
00105 newlink = new ListLink<T>(val, ln->pre, ln);
00106
00107 ln->pre->suc = newlink;
00108 ln->pre = newlink;
00109 }
00110
00111 if (newlink == 0)
00112 MayDay::Error("Out of memory in ListLink::addBefore");
00113
00114 return newlink;
00115 }
00116
00117
00118
00119
00120 template <class T>
00121 void
00122 ListLink<T>::swap(ListLink<T>* a)
00123 {
00124 CH_assert(a!= NULL);
00125 if (a->pre == this)
00126 {
00127 a->pre = this->pre;
00128 if (this->pre != NULL) pre->suc = a;
00129 this->pre = a;
00130 this->suc = a->suc;
00131 if (this->suc != NULL) suc->pre = this;
00132 a->suc = this;
00133 }
00134 else if (a->suc == this)
00135 {
00136 a->swap(this);
00137 }
00138 else
00139 {
00140 ListLink<T>* tmp = a->pre;
00141 a->pre = this->pre;
00142 if (this->pre != NULL)
00143 {
00144 pre->suc = a;
00145 }
00146 this->pre = tmp;
00147 tmp = a->suc;
00148 a->suc = this->suc;
00149 if (this->suc != NULL)
00150 {
00151 suc->pre = a;
00152 }
00153 if (this->pre!= NULL)
00154 {
00155 pre->suc = this;
00156 }
00157 this->suc = tmp;
00158 if (suc != NULL)
00159 {
00160 suc->pre = this;
00161 }
00162 }
00163 }
00164
00165 template <class T>
00166 ListLink<T>*
00167 List<T>::addAfter (ListLink<T>* ln,
00168 const T& val)
00169 {
00170 CH_assert(ln != 0 || tail == 0);
00171
00172 ListLink<T>* newlink;
00173
00174 if (ln == tail)
00175 {
00176 if (!m_usePool)
00177 tail = newlink = new ListLink<T>(val,tail,0);
00178 else
00179 tail = newlink = new (linkPool.getPtr()) ListLink<T>(val,tail,0);
00180 if (head == 0)
00181 head = tail;
00182 else
00183 tail->pre->suc = newlink;
00184 }
00185 else
00186 {
00187 if (!m_usePool)
00188 newlink = new ListLink<T>(val, ln, ln->suc);
00189 else
00190 newlink = new (linkPool.getPtr()) ListLink<T>(val, ln, ln->suc);
00191 ln->suc->pre = newlink;
00192 ln->suc = newlink;
00193 }
00194
00195 if (newlink == 0)
00196 MayDay::Error("Out of memory in ListLink::addAfter");
00197
00198 return newlink;
00199 }
00200
00201 template <class T>
00202 void
00203 List<T>::join (const List<T>& list2)
00204 {
00205 for (ListIterator<T> li2(list2); li2; ++li2)
00206 append(li2());
00207 }
00208
00209 template <class T>
00210 void
00211 List<T>::catenate (List<T>& list2)
00212 {
00213 if (list2.isEmpty())
00214
00215
00216
00217 ;
00218 else if (isEmpty())
00219 {
00220 head = list2.head;
00221 tail = list2.tail;
00222 list2.head = 0;
00223 list2.tail = 0;
00224 }
00225 else
00226 {
00227 tail->suc = list2.head;
00228 list2.head->pre = tail;
00229 tail = list2.tail;
00230 list2.head = 0;
00231 list2.tail = 0;
00232 }
00233 }
00234
00235 template <class T>
00236 void List<T>::checkLinks() const
00237 {
00238 ListLink<T>* next = 0;
00239
00240 for (ListLink<T>* p = head; p != 0; p = next)
00241 {
00242 next = p->suc;
00243 if (next != NULL)
00244 {
00245 if (next->pre != p)
00246 {
00247 MayDay::Abort("next->pre != this");
00248 }
00249 }
00250 else
00251 {
00252 if (p != tail)
00253 {
00254 MayDay::Abort("link terminated and is not tail");
00255 }
00256 }
00257
00258 }
00259 }
00260
00261 template <class T>
00262 void
00263 List<T>::clear ()
00264 {
00265 ListLink<T>* next = 0;
00266
00267 for (ListLink<T>* p = head; p != 0; p = next)
00268 {
00269 next = p->suc;
00270 p->suc = 0;
00271
00272 p->val.~T();
00273 if (m_usePool)
00274 linkPool.returnPtr(p);
00275 else
00276 delete p;
00277
00278 }
00279 tail = head = 0;
00280 }
00281
00282 template <class T>
00283 bool
00284 List<T>::includes (const T& v) const
00285 {
00286 bool rc = false;
00287 for (ListIterator<T> li(*this); li && !rc; ++li)
00288 if (v == li())
00289 rc = true;
00290 return rc;
00291 }
00292
00293 template<class T>
00294 bool
00295 List<T>::operator== (const List<T>& rhs) const
00296 {
00297 if (length() == rhs.length())
00298 {
00299 for (ListIterator<T> li(*this), ri(rhs); li; ++li, ++ri)
00300 if (li() != ri())
00301 return false;
00302 return true;
00303 }
00304
00305 return false;
00306 }
00307
00308 template<class T>
00309 bool
00310 List<T>::operator!= (const List<T>& rhs) const
00311 {
00312 return !operator==(rhs);
00313 }
00314
00315 template <class T>
00316 void
00317 List<T>::transfer(ListIterator<T>& li)
00318 {
00319
00320 CH_assert(&(li.list) != this);
00321 List<T>& other = (List<T>&)(li.list);
00322
00323 ListLink<T>* p = li.p;
00324 li.p = p->suc;
00325
00326
00327 other.removeLink(p);
00328
00329 if (head == 0)
00330 {
00331 head = tail = p;
00332 p->pre=0;
00333 p->suc=0;
00334 }
00335 else
00336 {
00337 p->suc=0;
00338 tail->suc = p;
00339 p->pre = tail;
00340 tail = p;
00341 }
00342
00343 }
00344
00345 template <class T>
00346 void
00347 List<T>::remove (ListIterator<T>& li)
00348 {
00349 ListLink<T> *np = li.p->suc;
00350 remove(li.p);
00351 li.p = np;
00352 }
00353
00354 template <class T>
00355 void
00356 List<T>::remove (const T& _v)
00357 {
00358 for (ListIterator<T> litr(*this); litr; ++litr)
00359 if (litr() == _v)
00360 remove(litr);
00361 }
00362
00363 template <class T>
00364 void
00365 List<T>::remove (const List<T>& _lv)
00366 {
00367 for (ListIterator<T> litr(_lv); litr; ++litr)
00368 remove(litr());
00369 }
00370
00371 template <class T>
00372 void
00373 List<T>::removeLink (ListLink<T>* ln)
00374 {
00375 CH_assert(head !=0 && tail != 0);
00376
00377 if (head == tail)
00378 {
00379 CH_assert(head == ln);
00380 head = tail = 0;
00381 }
00382 else if (head == ln)
00383 {
00384 CH_assert(ln->pre == 0);
00385 head = ln->suc;
00386 head->pre = 0;
00387 }
00388 else if (tail == ln)
00389 {
00390 CH_assert(ln->suc == 0);
00391 tail = ln->pre;
00392 tail->suc = 0;
00393 }
00394 else
00395 {
00396 CH_assert(ln->suc != 0 && ln->pre != 0);
00397 ln->suc->pre = ln->pre;
00398 ln->pre->suc = ln->suc;
00399 }
00400
00401 }
00402
00403 template <class T>
00404 void
00405 List<T>::remove(ListLink<T>* ln)
00406 {
00407 removeLink(ln);
00408
00409 ln->val.~T();
00410 if (m_usePool)
00411 linkPool.returnPtr(ln);
00412 else
00413 delete ln;
00414
00415 ln = 0;
00416 }
00417
00418 template <class T>
00419 void
00420 List<T>::sort()
00421 {
00422 if (head == NULL) return;
00423
00424 ListLink<T>* next = 0;
00425 bool swapped = true;
00426 while (swapped)
00427 {
00428 swapped = false;
00429 for (ListLink<T>* p = head; p != 0;)
00430 {
00431 next = p->suc;
00432 if (next != NULL && next->val < p->val)
00433 {
00434 swapped = true;
00435 p->swap(next);
00436 if (head == p) head = next;
00437 if (tail == next) tail = p;
00438 }
00439 else
00440 {
00441 p = next;
00442 }
00443 }
00444 }
00445
00446 }
00447
00448 #include "BaseNamespaceFooter.H"
00449 #endif