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 #ifndef CH_LISTIMPLEM_H
00031 #define CH_LISTIMPLEM_H
00032
00033 #include "MayDay.H"
00034
00035
00036
00037
00038
00039 template <class T>
00040 List<T>::List (const List<T>& source)
00041 : head(0),
00042 tail(0)
00043 {
00044 if (source.isEmpty())
00045 tail = head = 0;
00046 else
00047 for (ListIterator<T> li(source); li; ++li)
00048 append(li());
00049 }
00050
00051
00052
00053
00054
00055 template <class T>
00056 void
00057 List<T>::add (const T& value)
00058 {
00059 append(value);
00060 }
00061
00062 template <class T>
00063 int
00064 List<T>::length () const
00065 {
00066 int len = 0;
00067 for (ListIterator<T> li(*this); li; ++li)
00068 len++;
00069 return len;
00070 }
00071
00072 template <class T>
00073 List<T>&
00074 List<T>::operator= (const List<T>& source)
00075 {
00076 if (!(this == &source))
00077 {
00078 clear();
00079 for (ListIterator<T> li(source); li; ++li)
00080 append(li());
00081 }
00082 return *this;
00083 }
00084
00085 template <class T>
00086 ListLink<T> *
00087 List<T>::addBefore (ListLink<T>* ln,
00088 const T& val)
00089 {
00090 assert(ln != 0 || head == 0);
00091
00092 ListLink<T>* newlink;
00093
00094 if (ln == head)
00095 {
00096 head = newlink = new ListLink<T>(val, 0, head);
00097
00098 if (tail == 0)
00099 tail = head;
00100 else
00101 head->suc->pre = newlink;
00102 }
00103 else
00104 {
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 template <class T>
00118 ListLink<T>*
00119 List<T>::addAfter (ListLink<T>* ln,
00120 const T& val)
00121 {
00122 assert(ln != 0 || tail == 0);
00123
00124 ListLink<T>* newlink;
00125
00126 if (ln == tail)
00127 {
00128 tail = newlink = new ListLink<T>(val,tail,0);
00129
00130 if (head == 0)
00131 head = tail;
00132 else
00133 tail->pre->suc = newlink;
00134 }
00135 else
00136 {
00137 newlink = new ListLink<T>(val, ln, ln->suc);
00138
00139 ln->suc->pre = newlink;
00140 ln->suc = newlink;
00141 }
00142
00143 if (newlink == 0)
00144 MayDay::Error("Out of memory in ListLink::addAfter");
00145
00146 return newlink;
00147 }
00148
00149 template <class T>
00150 void
00151 List<T>::join (const List<T>& list2)
00152 {
00153 for (ListIterator<T> li2(list2); li2; ++li2)
00154 append(li2());
00155 }
00156
00157 template <class T>
00158 void
00159 List<T>::catenate (List<T>& list2)
00160 {
00161 if (list2.isEmpty())
00162
00163
00164
00165 ;
00166 else if (isEmpty())
00167 {
00168 head = list2.head;
00169 tail = list2.tail;
00170 list2.head = 0;
00171 list2.tail = 0;
00172 }
00173 else
00174 {
00175 tail->suc = list2.head;
00176 list2.head->pre = tail;
00177 tail = list2.tail;
00178 list2.head = 0;
00179 list2.tail = 0;
00180 }
00181 }
00182
00183 template <class T>
00184 void
00185 List<T>::clear ()
00186 {
00187 ListLink<T>* next = 0;
00188
00189 for (ListLink<T>* p = head; p != 0; p = next)
00190 {
00191 next = p->suc;
00192 p->suc = 0;
00193 delete p;
00194 }
00195 tail = head = 0;
00196 }
00197
00198 template <class T>
00199 bool
00200 List<T>::includes (const T& v) const
00201 {
00202 bool rc = false;
00203 for (ListIterator<T> li(*this); li && !rc; ++li)
00204 if (v == li())
00205 rc = true;
00206 return rc;
00207 }
00208
00209 template<class T>
00210 bool
00211 List<T>::operator== (const List<T>& rhs) const
00212 {
00213 if (length() == rhs.length())
00214 {
00215 for (ListIterator<T> li(*this), ri(rhs); li; ++li, ++ri)
00216 if (li() != ri())
00217 return false;
00218 return true;
00219 }
00220
00221 return false;
00222 }
00223
00224 template<class T>
00225 bool
00226 List<T>::operator!= (const List<T>& rhs) const
00227 {
00228 return !operator==(rhs);
00229 }
00230
00231 template <class T>
00232 void
00233 List<T>::remove (ListIterator<T>& li)
00234 {
00235 ListLink<T> *np = li.p->suc;
00236 remove(li.p);
00237 li.p = np;
00238 }
00239
00240 template <class T>
00241 void
00242 List<T>::remove (const T& _v)
00243 {
00244 for (ListIterator<T> litr(*this); litr; ++litr)
00245 if (litr() == _v)
00246 remove(litr);
00247 }
00248
00249 template <class T>
00250 void
00251 List<T>::remove (const List<T>& _lv)
00252 {
00253 for (ListIterator<T> litr(_lv); litr; ++litr)
00254 remove(litr());
00255 }
00256
00257 template <class T>
00258 void
00259 List<T>::remove (ListLink<T>* ln)
00260 {
00261 assert(head !=0 && tail != 0);
00262
00263 if (head == ln && tail == ln)
00264 head = tail = 0;
00265 else if (head == ln)
00266 {
00267 assert(ln->pre == 0);
00268 head = ln->suc;
00269 head->pre = 0;
00270 }
00271 else if (tail == ln)
00272 {
00273 assert(ln->suc == 0);
00274 tail = ln->pre;
00275 tail->suc = 0;
00276 }
00277 else
00278 {
00279 assert(ln->suc != 0 && ln->pre != 0);
00280 ln->suc->pre = ln->pre;
00281 ln->pre->suc = ln->suc;
00282 }
00283 delete ln;
00284 ln = 0;
00285 }
00286
00287 #endif