klist.h
Go to the documentation of this file.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 #ifndef _KLIST_H
00032 #define _KLIST_H
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #define KL_TRUE 1
00067 #define KL_FALSE 0
00068 typedef int KL_BOOL;
00069
00070 #ifdef KL_PRINT
00071 #include <iostream.h>
00072 #endif
00073
00074 #pragma interface
00075
00076
00077 template <class Type> class KList;
00078
00079 template <class Type>
00080 class KListItem {
00081 friend class KList<Type>;
00082 public:
00083 KListItem(const Type &d) {
00084 data =d;
00085 next = (KListItem<Type>*) 0;
00086 }
00087 KListItem(const KListItem<Type> &it) {
00088 data = it.data;
00089 next = (KListItem<Type>*) 0;
00090 }
00091 ~KListItem() {;}
00092 KListItem<Type> & operator = (const KListItem<Type> &it) {
00093 if (this == &it)
00094 return (*this);
00095 else {
00096 data = it.data;
00097 return (*this);
00098 }
00099 }
00100 private:
00101 Type data;
00102 KListItem<Type> *next;
00103 };
00104
00105 template <class Type>
00106 class KList {
00107 public:
00108 KList() { head = (KListItem<Type>*) 0; }
00109 KList(const KList<Type> &from);
00110 ~KList() { destroy(); }
00111
00112 KL_BOOL destroy();
00113 KL_BOOL remove(const Type &it) {
00114 int f;
00115 find(it, f, 1);
00116 return f;
00117 }
00118
00119 int empty() const { return (head == (KListItem<Type>*) 0);}
00120 int count() const;
00121
00122 void reverse();
00123
00124 KL_BOOL append(const Type &data);
00125 KL_BOOL prepend(const Type &data);
00126 KL_BOOL appendUnique (const Type &i3);
00127 KL_BOOL prependUnique (const Type &i3);
00128
00129 KList<Type> & operator += (const KList<Type> &mergee);
00130 KList<Type> & operator = (const KList<Type> &from);
00131
00132 KList<Type> pure_map(Type (*map_f)(const Type &it)) const;
00133 void map (void (*map_function)(const Type &item)) const;
00134
00135
00136 void mapUntil (const Type &item, int (*map_func)(const Type &i1,
00137 const Type &i2)) const;
00138
00139 Type car(KL_BOOL &valid);
00140 KList<Type> cdr();
00141
00142
00143 void modify(Type (*mod_func)(Type &input));
00144
00145
00146
00147
00148
00149 Type find(const Type &inE, KL_BOOL &found, int removeMe=0,
00150 int (*cmp_f)(const Type &a, const Type &b)= 0)
00151 {
00152 KListItem<Type> *lag, *curr;
00153 Type ret;
00154
00155 for (curr=head, lag = (KListItem<Type>*) 0; curr; curr=curr->next) {
00156 if (cmp_f) {
00157 if (cmp_f(curr->data, inE))
00158 break;
00159 } else if (curr->data == inE)
00160 break;
00161 lag = curr;
00162 }
00163
00164 if (curr) {
00165 found = KL_TRUE;
00166 ret = curr->data;
00167 if (removeMe) {
00168 if (lag)
00169 lag->next = curr->next;
00170 else
00171 head = curr->next;
00172 delete(curr);
00173 }
00174 }
00175
00176 return ret;
00177 }
00178
00179
00180 #ifdef KL_PRINT
00181 friend ostream &operator << (ostream& os, const KList<Type>& S) {
00182 KListItem<Type> *temp;
00183 for (temp=S.head; temp; temp=temp->next)
00184 os << " : " << temp->data << " : ";
00185 return os;
00186 }
00187 #endif
00188
00189 protected:
00190 KListItem<Type> *last() {
00191 KListItem<Type> *tmp, *lag;
00192 for (tmp=head, lag=0; tmp; lag=tmp, tmp=tmp->next)
00193 ;
00194 return lag;
00195 }
00196 KListItem<Type> *head;
00197 };
00198
00199
00200 template <class Type>
00201 KList<Type>::KList (const KList<Type> &from) {
00202 KListItem<Type> *temp;
00203 head = 0;
00204 for (temp=from.head; temp; temp = temp-> next) {
00205 prepend(temp->data);
00206 }
00207 reverse();
00208 }
00209
00210 template <class Type>
00211 int KList<Type>::count() const
00212 {
00213 int c=0;
00214 KListItem<Type> *temp;
00215 for (temp=head; temp; temp = temp->next)
00216 c++;
00217 return c;
00218 }
00219
00220 template <class Type>
00221 KL_BOOL KList<Type>::destroy()
00222 {
00223 KListItem<Type> *temp, *next;
00224
00225 for (temp=head; temp; temp = next) {
00226 next = temp->next;
00227 delete (temp);
00228 }
00229 head = 0;
00230 return KL_TRUE;
00231 }
00232
00233 template <class Type>
00234 KList<Type> &KList<Type>::operator = (const KList<Type> &from)
00235 {
00236 KListItem<Type> *temp;
00237
00238 if (this == &from)
00239 return (*this);
00240
00241 destroy();
00242
00243 for (temp=from.head; temp; temp = temp->next)
00244 prepend(temp->data);
00245
00246 reverse();
00247 return (*this);
00248 }
00249
00250
00251 template <class Type>
00252 KList<Type> &KList<Type>::operator +=(const KList<Type> &mergee)
00253 {
00254 KListItem<Type> *curr;
00255
00256 if (this == &mergee)
00257 return (*this);
00258
00259 for (curr=mergee.head; curr; curr=curr->next) {
00260 append(curr->data);
00261 }
00262 return (*this);
00263 }
00264
00265 template <class Type>
00266 KList<Type>
00267 KList<Type>::pure_map(Type (*map_f)(const Type &it)) const
00268 {
00269 KListItem<Type> *temp;
00270 KList<Type> Ret;
00271 for (temp=head; temp; temp=temp->next) {
00272 Ret.append(map_f(temp->data));
00273 }
00274 return Ret;
00275 }
00276
00277 template <class Type>
00278 void KList<Type>::map (void (*map_function)(const Type &item)) const
00279 {
00280 const KListItem<Type> *temp = 0;
00281
00282 if (!map_function) return;
00283 for (temp = head; temp; temp = temp->next)
00284 map_function (temp->data);
00285 }
00286
00287 template <class Type>
00288 void KList<Type>::modify (Type (*mod_f)(Type &item))
00289 {
00290 KListItem<Type> *temp = 0;
00291
00292 if (!mod_f) return;
00293 for (temp = head; temp; temp = temp->next)
00294 temp->data = mod_f(temp->data);
00295 }
00296
00297 template <class Type>
00298 void KList<Type>::mapUntil (const Type &item,
00299 int (*map_func)(const Type &i1,
00300 const Type &i2)) const
00301 {
00302 const KListItem<Type> *temp = 0;
00303
00304 if (!map_func) return;
00305 for (temp = head; temp; temp = temp->next)
00306 if (map_func (temp->data, item))
00307 return;
00308 }
00309
00310 template <class Type>
00311 KL_BOOL KList<Type>::prependUnique (const Type &comp_me)
00312 {
00313 KListItem<Type> *temp = 0;
00314
00315 for (temp = head; temp; temp = temp->next)
00316 if (temp->data == comp_me) {
00317 temp->data = comp_me;
00318 return KL_TRUE;
00319 }
00320
00321 return (prepend(comp_me));
00322 }
00323
00324 template <class Type>
00325 KL_BOOL KList<Type>::appendUnique (const Type &comp_me)
00326 {
00327 KListItem<Type> *temp = 0;
00328
00329 for (temp = head; temp; temp = temp->next)
00330 if (temp->data == comp_me) {
00331 temp->data = comp_me;
00332 return KL_TRUE;
00333 }
00334
00335 return (append(comp_me));
00336 }
00337
00338 template <class Type>
00339 KL_BOOL KList<Type>::prepend (const Type &data)
00340 {
00341 KListItem<Type> *ni;
00342
00343 ni = new KListItem<Type>(data);
00344 if (!ni)
00345 return KL_FALSE;
00346
00347 ni->next = head;
00348 head = ni;
00349 return KL_TRUE;
00350 }
00351
00352
00353 template <class Type>
00354 KL_BOOL KList<Type>::append(const Type &data)
00355 {
00356 KListItem<Type> *ni;
00357 KListItem<Type> *tl;
00358
00359 ni = new KListItem<Type>(data);
00360 if (!ni)
00361 return KL_FALSE;
00362
00363 tl = last();
00364 if (tl) {
00365 tl->next = ni;
00366 } else {
00367 ni->next = head;
00368 head = ni;
00369 }
00370 return KL_TRUE;
00371 }
00372
00373 template <class Type>
00374 Type KList<Type>::car(KL_BOOL &valid)
00375 {
00376 KListItem<Type> *nx;
00377 Type ret;
00378
00379 if (head) {
00380 nx = head;
00381 ret = nx->data;
00382 head = head->next;
00383 delete nx;
00384 valid = KL_TRUE;
00385 return ret;
00386 } else {
00387 valid = KL_FALSE;
00388 return ret;
00389 }
00390 }
00391
00392
00393 template <class Type>
00394 KList<Type> KList<Type>::cdr()
00395 {
00396 KList<Type> ret;
00397 int val;
00398
00399 ret = *this;
00400 ret.car(val);
00401 return ret;
00402 }
00403
00404 template <class Type>
00405 void KList<Type>::reverse()
00406 {
00407 KListItem<Type> *curr, *lag=0, *ahead;
00408
00409 for (curr=head; curr; curr=ahead) {
00410 ahead = curr->next;
00411 curr->next = lag;
00412 lag = curr;
00413 }
00414 head = lag;
00415 }
00416
00417 #endif