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