klist.h

Go to the documentation of this file.
00001 /*
00002  * See the dyninst/COPYRIGHT file for copyright information.
00003  * 
00004  * We provide the Paradyn Tools (below described as "Paradyn")
00005  * on an AS IS basis, and do not warrant its validity or performance.
00006  * We reserve the right to update, modify, or discontinue this
00007  * software at any time.  We shall have no obligation to supply such
00008  * updates or modifications or any other form of support to you.
00009  * 
00010  * By your use of Paradyn, you understand and agree that we (or any
00011  * other person or entity with proprietary rights in Paradyn) are
00012  * under no obligation to provide either maintenance services,
00013  * update services, notices of latent defects, or correction of
00014  * defects for Paradyn.
00015  * 
00016  * This library is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU Lesser General Public
00018  * License as published by the Free Software Foundation; either
00019  * version 2.1 of the License, or (at your option) any later version.
00020  * 
00021  * This library is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * Lesser General Public License for more details.
00025  * 
00026  * You should have received a copy of the GNU Lesser General Public
00027  * License along with this library; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00029  */
00030 
00031 #ifndef _KLIST_H
00032 #define _KLIST_H
00033 
00034 /*
00035  * klist.h - list ADT - with a destructor and copy constructor
00036  *           implements copy semantics
00037  *           uses == for comparison
00038  *           this class has been purified
00039  *           
00040  * See the tests subdirectory for examples of its use.
00041  *
00042  * To use this class: 
00043  *       1) put 'pragma implementation "klist.h" ' in 
00044  *           a the file where you want the code generated
00045  *       2) put '#include "<prefix>/klist.h" after line 1
00046  *           in the same file
00047  *       3) this class is instantiated with class Type
00048  *          if class Type is not a basic Type (int, char)
00049  *          then you need to implement the following for
00050  *          class Type if copy semantics are to be upheld
00051  *          if this is not done, purify will complain and
00052  *          the class behavior will be incorrect
00053  *            a) a copy constructor --> Type::Type(Type &c)
00054  *            b) the = operator --> Type & Type::operator =(Type&)
00055  *            c) the == operator --> int Type::operator== (Type&)
00056  *
00057  *
00058  * $Log: klist.h,v $
00059  * Revision 1.1  1994/08/17 18:23:49  markc
00060  * Added new classes: Cstring KeyList, KList
00061  * Added new function: RPCgetArg
00062  * Changed typedefs in machineType.h to #defines
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   // iterates until map_func(i1, i2) != 0
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   // modifies the list elements in place
00143   void modify(Type (*mod_func)(Type &input));
00144 
00145   // gcc doesn't compile this when only the declaration is here
00146   // removeMe == 0 --> the matched element is removed
00147   // found --> signifies results of match
00148   // you provide the cmp function, or the class uses == 
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       // this may not be data from a found element
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   // not found on list, so add it
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   // not found on list, so add it
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 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1