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
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #ifndef _LISTIMPLEM_H_
00053 #define _LISTIMPLEM_H_
00054
00055 #include "MayDay.H"
00056
00057
00058
00059
00060 template <class T>
00061 Pool List<T>::linkPool(sizeof(ListLink<T>), typeid(T).name(), 300);
00062
00063 template <class T>
00064 List<T>::List (const List<T>& source)
00065 : head(0),
00066 tail(0)
00067 {
00068 if (source.isEmpty())
00069 tail = head = 0;
00070 else
00071 for (ListIterator<T> li(source); li; ++li)
00072 append(li());
00073 }
00074
00075
00076
00077
00078
00079 template <class T>
00080 void
00081 List<T>::add (const T& value)
00082 {
00083 append(value);
00084 }
00085
00086 template <class T>
00087 int
00088 List<T>::length () const
00089 {
00090 int len = 0;
00091 for (ListIterator<T> li(*this); li; ++li)
00092 len++;
00093 return len;
00094 }
00095
00096 template <class T>
00097 List<T>&
00098 List<T>::operator= (const List<T>& source)
00099 {
00100 if (!(this == &source))
00101 {
00102 clear();
00103 for (ListIterator<T> li(source); li; ++li)
00104 append(li());
00105 }
00106 return *this;
00107 }
00108
00109 template <class T>
00110 ListLink<T> *
00111 List<T>::addBefore (ListLink<T>* ln,
00112 const T& val)
00113 {
00114 assert(ln != 0 || head == 0);
00115
00116 ListLink<T>* newlink;
00117
00118 if (ln == head)
00119 {
00120
00121 head = newlink = new (linkPool.getPtr()) ListLink<T>(val, 0, head);
00122 if (tail == 0)
00123 tail = head;
00124 else
00125 head->suc->pre = newlink;
00126 }
00127 else
00128 {
00129
00130 newlink = new (linkPool.getPtr()) ListLink<T>(val, ln->pre, ln);
00131 ln->pre->suc = newlink;
00132 ln->pre = newlink;
00133 }
00134
00135 if (newlink == 0)
00136 MayDay::Error("Out of memory in ListLink::addBefore");
00137
00138 return newlink;
00139 }
00140
00141 template <class T>
00142 ListLink<T>*
00143 List<T>::addAfter (ListLink<T>* ln,
00144 const T& val)
00145 {
00146 assert(ln != 0 || tail == 0);
00147
00148 ListLink<T>* newlink;
00149
00150 if (ln == tail)
00151 {
00152
00153 tail = newlink = new (linkPool.getPtr()) ListLink<T>(val,tail,0);
00154 if (head == 0)
00155 head = tail;
00156 else
00157 tail->pre->suc = newlink;
00158 }
00159 else
00160 {
00161
00162 newlink = new (linkPool.getPtr()) ListLink<T>(val, ln, ln->suc);
00163 ln->suc->pre = newlink;
00164 ln->suc = newlink;
00165 }
00166
00167 if (newlink == 0)
00168 MayDay::Error("Out of memory in ListLink::addAfter");
00169
00170 return newlink;
00171 }
00172
00173 template <class T>
00174 void
00175 List<T>::join (const List<T>& list2)
00176 {
00177 for (ListIterator<T> li2(list2); li2; ++li2)
00178 append(li2());
00179 }
00180
00181 template <class T>
00182 void
00183 List<T>::catenate (List<T>& list2)
00184 {
00185 if (list2.isEmpty())
00186
00187
00188
00189 ;
00190 else if (isEmpty())
00191 {
00192 head = list2.head;
00193 tail = list2.tail;
00194 list2.head = 0;
00195 list2.tail = 0;
00196 }
00197 else
00198 {
00199 tail->suc = list2.head;
00200 list2.head->pre = tail;
00201 tail = list2.tail;
00202 list2.head = 0;
00203 list2.tail = 0;
00204 }
00205 }
00206
00207 template <class T>
00208 void
00209 List<T>::clear ()
00210 {
00211 ListLink<T>* next = 0;
00212
00213 for (ListLink<T>* p = head; p != 0; p = next)
00214 {
00215 next = p->suc;
00216 p->suc = 0;
00217
00218 p->val.~T();
00219 linkPool.returnPtr(p);
00220
00221 }
00222 tail = head = 0;
00223 }
00224
00225 template <class T>
00226 bool
00227 List<T>::includes (const T& v) const
00228 {
00229 bool rc = false;
00230 for (ListIterator<T> li(*this); li && !rc; ++li)
00231 if (v == li())
00232 rc = true;
00233 return rc;
00234 }
00235
00236 template<class T>
00237 bool
00238 List<T>::operator== (const List<T>& rhs) const
00239 {
00240 if (length() == rhs.length())
00241 {
00242 for (ListIterator<T> li(*this), ri(rhs); li; ++li, ++ri)
00243 if (li() != ri())
00244 return false;
00245 return true;
00246 }
00247
00248 return false;
00249 }
00250
00251 template<class T>
00252 bool
00253 List<T>::operator!= (const List<T>& rhs) const
00254 {
00255 return !operator==(rhs);
00256 }
00257
00258 template <class T>
00259 void
00260 List<T>::transfer(ListIterator<T>& li)
00261 {
00262
00263 assert(&(li.list) != this);
00264 List<T>& other = (List<T>&)(li.list);
00265
00266 ListLink<T>* p = li.p;
00267 li.p = p->suc;
00268
00269
00270 other.removeLink(p);
00271
00272 if(head == 0){
00273 head = tail = p;
00274 p->pre=0;
00275 p->suc=0;
00276 }
00277 else {
00278 p->suc=0;
00279 tail->suc = p;
00280 p->pre = tail;
00281 tail = p;
00282 }
00283
00284 }
00285
00286 template <class T>
00287 void
00288 List<T>::remove (ListIterator<T>& li)
00289 {
00290 ListLink<T> *np = li.p->suc;
00291 remove(li.p);
00292 li.p = np;
00293 }
00294
00295 template <class T>
00296 void
00297 List<T>::remove (const T& _v)
00298 {
00299 for (ListIterator<T> litr(*this); litr; ++litr)
00300 if (litr() == _v)
00301 remove(litr);
00302 }
00303
00304 template <class T>
00305 void
00306 List<T>::remove (const List<T>& _lv)
00307 {
00308 for (ListIterator<T> litr(_lv); litr; ++litr)
00309 remove(litr());
00310 }
00311
00312 template <class T>
00313 void
00314 List<T>::removeLink (ListLink<T>* ln)
00315 {
00316 assert(head !=0 && tail != 0);
00317
00318 if (head == tail)
00319 {
00320 assert(head == ln);
00321 head = tail = 0;
00322 }
00323 else if (head == ln)
00324 {
00325 assert(ln->pre == 0);
00326 head = ln->suc;
00327 head->pre = 0;
00328 }
00329 else if (tail == ln)
00330 {
00331 assert(ln->suc == 0);
00332 tail = ln->pre;
00333 tail->suc = 0;
00334 }
00335 else
00336 {
00337 assert(ln->suc != 0 && ln->pre != 0);
00338 ln->suc->pre = ln->pre;
00339 ln->pre->suc = ln->suc;
00340 }
00341
00342 }
00343
00344 template <class T>
00345 void
00346 List<T>::remove(ListLink<T>* ln)
00347 {
00348 removeLink(ln);
00349
00350 ln->val.~T();
00351 linkPool.returnPtr(ln);
00352
00353 ln = 0;
00354 }
00355
00356 #endif