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 if(p != tail)
00252 {
00253 MayDay::Abort("link terminated and is not tail");
00254 }
00255 }
00256
00257 }
00258 }
00259
00260 template <class T>
00261 void
00262 List<T>::clear ()
00263 {
00264 ListLink<T>* next = 0;
00265
00266 for (ListLink<T>* p = head; p != 0; p = next)
00267 {
00268 next = p->suc;
00269 p->suc = 0;
00270
00271 p->val.~T();
00272 if(m_usePool)
00273 linkPool.returnPtr(p);
00274 else
00275 delete p;
00276
00277 }
00278 tail = head = 0;
00279 }
00280
00281 template <class T>
00282 bool
00283 List<T>::includes (const T& v) const
00284 {
00285 bool rc = false;
00286 for (ListIterator<T> li(*this); li && !rc; ++li)
00287 if (v == li())
00288 rc = true;
00289 return rc;
00290 }
00291
00292 template<class T>
00293 bool
00294 List<T>::operator== (const List<T>& rhs) const
00295 {
00296 if (length() == rhs.length())
00297 {
00298 for (ListIterator<T> li(*this), ri(rhs); li; ++li, ++ri)
00299 if (li() != ri())
00300 return false;
00301 return true;
00302 }
00303
00304 return false;
00305 }
00306
00307 template<class T>
00308 bool
00309 List<T>::operator!= (const List<T>& rhs) const
00310 {
00311 return !operator==(rhs);
00312 }
00313
00314 template <class T>
00315 void
00316 List<T>::transfer(ListIterator<T>& li)
00317 {
00318
00319 CH_assert(&(li.list) != this);
00320 List<T>& other = (List<T>&)(li.list);
00321
00322 ListLink<T>* p = li.p;
00323 li.p = p->suc;
00324
00325
00326 other.removeLink(p);
00327
00328 if(head == 0){
00329 head = tail = p;
00330 p->pre=0;
00331 p->suc=0;
00332 }
00333 else {
00334 p->suc=0;
00335 tail->suc = p;
00336 p->pre = tail;
00337 tail = p;
00338 }
00339
00340 }
00341
00342 template <class T>
00343 void
00344 List<T>::remove (ListIterator<T>& li)
00345 {
00346 ListLink<T> *np = li.p->suc;
00347 remove(li.p);
00348 li.p = np;
00349 }
00350
00351 template <class T>
00352 void
00353 List<T>::remove (const T& _v)
00354 {
00355 for (ListIterator<T> litr(*this); litr; ++litr)
00356 if (litr() == _v)
00357 remove(litr);
00358 }
00359
00360 template <class T>
00361 void
00362 List<T>::remove (const List<T>& _lv)
00363 {
00364 for (ListIterator<T> litr(_lv); litr; ++litr)
00365 remove(litr());
00366 }
00367
00368 template <class T>
00369 void
00370 List<T>::removeLink (ListLink<T>* ln)
00371 {
00372 CH_assert(head !=0 && tail != 0);
00373
00374 if (head == tail)
00375 {
00376 CH_assert(head == ln);
00377 head = tail = 0;
00378 }
00379 else if (head == ln)
00380 {
00381 CH_assert(ln->pre == 0);
00382 head = ln->suc;
00383 head->pre = 0;
00384 }
00385 else if (tail == ln)
00386 {
00387 CH_assert(ln->suc == 0);
00388 tail = ln->pre;
00389 tail->suc = 0;
00390 }
00391 else
00392 {
00393 CH_assert(ln->suc != 0 && ln->pre != 0);
00394 ln->suc->pre = ln->pre;
00395 ln->pre->suc = ln->suc;
00396 }
00397
00398 }
00399
00400 template <class T>
00401 void
00402 List<T>::remove(ListLink<T>* ln)
00403 {
00404 removeLink(ln);
00405
00406 ln->val.~T();
00407 if(m_usePool)
00408 linkPool.returnPtr(ln);
00409 else
00410 delete ln;
00411
00412 ln = 0;
00413 }
00414
00415 template <class T>
00416 void
00417 List<T>::sort()
00418 {
00419 if(head == NULL) return;
00420
00421 ListLink<T>* next = 0;
00422 bool swapped = true;
00423 while(swapped){
00424 swapped = false;
00425 for (ListLink<T>* p = head; p != 0;)
00426 {
00427 next = p->suc;
00428 if(next != NULL && next->val < p->val){
00429 swapped = true;
00430 p->swap(next);
00431 if(head == p) head = next;
00432 if(tail == next) tail = p;
00433 } else {
00434 p = next;
00435 }
00436 }
00437 }
00438
00439 }
00440
00441 #include "BaseNamespaceFooter.H"
00442 #endif