keylist.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 _KEYLIST_H
00032 #define _KEYLIST_H
00033 
00034 /*
00035  * keylist.h - list ADT - with a destructor and copy constructor
00036  *             implements copy semantics
00037  *             uses void * key 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 "keylist.h" ' in 
00044  *           a the file where you want the code generated
00045  *       2) put '#include "<prefix>/keylist.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  *
00056  *
00057  * $Log: keylist.h,v $
00058  * Revision 1.1  1994/08/17 18:23:48  markc
00059  * Added new classes: Cstring KeyList, KList
00060  * Added new function: RPCgetArg
00061  * Changed typedefs in machineType.h to #defines
00062  *
00063  */
00064 
00065 #define KYL_TRUE 1
00066 #define KYL_FALSE 0
00067 typedef int KYL_BOOL;
00068 
00069 #ifdef KYL_PRINT
00070 #include <iostream.h>
00071 #endif
00072 
00073 #pragma interface
00074 
00075 #define ListHash(ptr, size) (((unsigned int)(ptr) % (unsigned int)(size)))
00076 
00077 template <class Type> class KeyList;
00078 
00079 template <class Type>
00080 class KeyListItem {
00081 friend class KeyList<Type>;
00082 public:
00083   KeyListItem(const Type &d, const void *k) {
00084     data =d;
00085     next = (KeyListItem<Type>*) 0;
00086     key = k;
00087   }
00088   KeyListItem(const KeyListItem<Type> &it) {
00089     data = it.data;
00090     key = it.key;
00091     next = (KeyListItem<Type>*) 0;
00092   }
00093   ~KeyListItem() {;}
00094   KeyListItem<Type> & operator = (const KeyListItem<Type> &it) {
00095     if (this == &it)
00096       return (*this);
00097     else {
00098       data = it.data;
00099       key = it.key;
00100       return (*this);
00101     }
00102   }
00103 private:
00104   Type data;
00105   void *key;
00106   KeyListItem<Type> *next;
00107 };
00108 
00109 template <class Type>
00110 class KeyList {
00111 public:
00112   KeyList() { head = (KeyListItem<Type>*) 0; }
00113   KeyList(const KeyList<Type> &from);
00114   ~KeyList() { destroy(); }
00115 
00116   KYL_BOOL destroy();
00117   KYL_BOOL remove (void *key) {
00118     int f;
00119     find(key, f, 1);
00120     return f;
00121   }
00122 
00123   int empty() const { return (head == (KeyListItem<Type>*) 0);}
00124   int count() const;
00125 
00126   KYL_BOOL inList(const void *key);
00127   void reverse();
00128 
00129   KYL_BOOL append(const Type &data, const void *key);
00130   KYL_BOOL prepend(const Type &data, const void *key);
00131   KYL_BOOL appendUnique (const Type &i3, const void *key);
00132   KYL_BOOL prependUnique (const Type &i3, const void *key);
00133 
00134   KeyList<Type> & operator += (const KeyList<Type> &mergee);
00135   KeyList<Type> & operator = (const KeyList<Type> &from);
00136 
00137   void map (void (*map_function)(const Type &item)) const;
00138 
00139   Type car(KYL_BOOL &valid);
00140   KeyList<Type> cdr();
00141 
00142   // modifies the list elements in place
00143   void modify(Type (*mod_func)(Type &input));
00144 
00145   // removeMe == 0 --> the matched element is removed
00146   // found --> signifies results of match
00147   Type find(const void *key, KYL_BOOL &found, const int removeMe=0);
00148 
00149 #ifdef KYL_PRINT
00150   friend ostream &operator << (ostream& os, const KeyList<Type>& S) {
00151     KeyListItem<Type> *temp;
00152     for (temp=S.head; temp; temp=temp->next)
00153       os << " : d=" << temp->data << "  k=" << temp->key << " : " << endl;
00154     return os;
00155   }
00156 #endif
00157 
00158 protected:
00159   KeyListItem<Type> *last() {
00160     KeyListItem<Type> *tmp, *lag;
00161     for (tmp=head, lag=0; tmp; lag=tmp, tmp=tmp->next)
00162       ;
00163     return lag;
00164   }
00165   KeyListItem<Type> *head;
00166 };
00167 
00168 
00169 template <class Type>
00170 KeyList<Type>::KeyList (const KeyList<Type> &from) {
00171   KeyListItem<Type> *temp;
00172   head = 0;
00173   for (temp=from.head; temp; temp = temp-> next) {
00174     prepend(temp->data, temp->key);
00175   }
00176   reverse();
00177 }
00178 
00179 template <class Type>
00180 void KeyList<Type>::reverse() 
00181 {
00182   KeyListItem<Type> *curr, *lag=0, *ahead;
00183 
00184   for (curr=head; curr; curr=ahead) {
00185     ahead = curr->next;
00186     curr->next = lag;
00187     lag = curr;
00188   }
00189   head = lag;
00190 }
00191 
00192 template <class Type>
00193 int KeyList<Type>::count() const
00194 {
00195   int c=0;
00196   KeyListItem<Type> *temp;
00197   for (temp=head; temp; temp = temp->next)
00198     c++;
00199   return c;
00200 }
00201 
00202 template <class Type>
00203 KYL_BOOL KeyList<Type>::destroy()
00204 {
00205   KeyListItem<Type> *temp, *next;
00206   
00207   for (temp=head; temp; temp = next) {
00208     next = temp->next;
00209     delete (temp);
00210   } 
00211   head = 0;
00212   return KYL_TRUE;
00213 }
00214 
00215 template <class Type>
00216 KeyList<Type> &KeyList<Type>::operator = (const KeyList<Type> &from)
00217 {
00218   KeyListItem<Type> *temp;
00219 
00220   if (this == &from)
00221     return (*this);
00222 
00223   destroy();
00224   
00225   for (temp=from.head; temp; temp = temp->next)
00226     prepend(temp->data, temp->key);
00227   reverse();
00228   return (*this);
00229 }
00230 
00231 
00232 template <class Type>
00233 KeyList<Type> &KeyList<Type>::operator +=(const KeyList<Type> &mergee)
00234 {
00235   KeyListItem<Type> *curr;
00236 
00237   if (this == &mergee)
00238     return (*this);
00239 
00240   for (curr=mergee.head; curr; curr=curr->next) {
00241     append(curr->data, curr->key);
00242   }
00243   return (*this);
00244 }
00245 
00246 template <class Type>
00247 void KeyList<Type>::map (void (*map_function)(const Type &item)) const
00248 {
00249   const KeyListItem<Type> *temp = 0;
00250 
00251   if (!map_function) return;
00252   for (temp = head; temp; temp = temp->next)
00253     map_function (temp->data);
00254 }
00255 
00256 template <class Type>
00257 void KeyList<Type>::modify (Type (*mod_f)(Type &item))
00258 {
00259   KeyListItem<Type> *temp = 0;
00260 
00261   if (!mod_f) return;
00262   for (temp = head; temp; temp = temp->next) 
00263     temp->data = mod_f(temp->data);
00264 }
00265 
00266 template <class Type>
00267 KYL_BOOL KeyList<Type>::prependUnique (const Type &comp_me, const void *key)
00268 {
00269   KeyListItem<Type> *temp = 0;
00270 
00271   for (temp = head; temp; temp = temp->next)
00272     if (temp->key == key) {
00273       temp->data = comp_me; 
00274       return KYL_TRUE;
00275     }
00276   // not found on list, so add it
00277   return (prepend(comp_me, key));
00278 }
00279 
00280 template <class Type>
00281 KYL_BOOL KeyList<Type>::appendUnique (const Type &comp_me, const void *key)
00282 {
00283   KeyListItem<Type> *temp = 0;
00284 
00285   for (temp = head; temp; temp = temp->next)
00286     if (temp->key == key) {
00287       temp->data = comp_me; 
00288       return KYL_TRUE;
00289     }
00290   // not found on list, so add it
00291   return (append(comp_me, key));
00292 }
00293 
00294 template <class Type>
00295 KYL_BOOL KeyList<Type>::prepend (const Type &data, const void *key) 
00296 { 
00297   KeyListItem<Type> *ni;
00298 
00299   ni = new KeyListItem<Type>(data, key);
00300   if (!ni)
00301     return KYL_FALSE;
00302 
00303   ni->next = head;
00304   head = ni;
00305   return KYL_TRUE;
00306 }
00307 
00308 
00309 template <class Type>
00310 KYL_BOOL KeyList<Type>::append(const Type &data, const void *key) 
00311 { 
00312   KeyListItem<Type> *ni;
00313   KeyListItem<Type> *tl;
00314 
00315   ni = new KeyListItem<Type>(data, key);
00316   if (!ni)
00317     return KYL_FALSE;
00318 
00319   tl = last();
00320   if (tl) {
00321     tl->next = ni;
00322   } else {
00323     ni->next = head;
00324     head = ni;
00325   }
00326   return KYL_TRUE;
00327 }
00328 
00329 template <class Type>
00330 KYL_BOOL KeyList<Type>::inList (const void *key)
00331 {
00332   KeyListItem<Type> *curr;
00333   for (curr=head; curr; curr=curr->next) {
00334     if (curr->key == key)
00335       return KYL_TRUE;
00336   }
00337   return KYL_FALSE;
00338 }
00339 
00340 template <class Type>
00341 Type KeyList<Type>::find(const void *key, KYL_BOOL &found, const int removeMe)
00342 {
00343   KeyListItem<Type> *lag, *curr;
00344   Type ret;
00345 
00346   for (curr=head, lag = (KeyListItem<Type>*) 0; curr; curr=curr->next) {
00347     if (curr->key == key)
00348       break;
00349     lag = curr;
00350   }
00351 
00352   if (curr) {
00353     found = KYL_TRUE;
00354     ret = curr->data;
00355     if (removeMe) {
00356       if (lag)
00357     lag->next = curr->next;
00358       else
00359     head = curr->next;
00360       delete(curr);
00361     }
00362   }
00363   // this may not be data from a found element
00364   return ret;
00365 }
00366 
00367 template <class Type>
00368 Type KeyList<Type>::car(KYL_BOOL &valid)
00369 {
00370   KeyListItem<Type> *nx;
00371   Type ret;
00372 
00373   if (head) {
00374     nx = head;
00375     ret = nx->data;
00376     head = head->next;
00377     delete nx;
00378     valid = KYL_TRUE;
00379     return ret;
00380   } else {
00381     valid = KYL_FALSE;
00382     return ret;
00383   }
00384 }
00385 
00386 
00387 template <class Type>
00388 KeyList<Type> KeyList<Type>::cdr()
00389 {
00390   KeyList<Type> ret;
00391   int val;
00392 
00393   ret = *this;
00394   ret.car(val);
00395   return ret;
00396 }
00397 
00398 
00399 // Hash table using KLists
00400 template <class Type> class KHTable {
00401 public:
00402   // placing function def here makes gcc happy 
00403 #ifdef KYL_PRINT
00404 friend ostream &operator<<(ostream &os, KHTable<Type> &data) {
00405   int i;
00406   for (i=0; i < data.tableSize; i++) {
00407     if (data.table[i]) {
00408       os << " list # " << i << endl;
00409       os << *data.table[i];
00410     }
00411   }
00412   return os;
00413 }
00414 #endif
00415 
00416   KHTable(const int size=97) {
00417     int s;
00418     tableSize = size;
00419     if (tableSize <= 0) tableSize = 97;
00420     table = new KeyList<Type>*[tableSize];
00421     for (s=0; s<size; ++s)
00422       table[s] = 0;
00423   }
00424 
00425   KHTable(const KHTable<Type> &data) {
00426     int j;
00427     tableSize = data.tableSize;
00428     table = new KeyList<Type>*[tableSize];
00429     for (j=0; j < tableSize; ++j)
00430       table[j] = data.table[j];
00431   }
00432 
00433   ~KHTable() {delete [] table;}
00434   KYL_BOOL destroy();
00435 
00436   Type find(const void *key, int &valid, const int removeMe=0);
00437   KYL_BOOL add(const Type &data, const void *key);
00438   KYL_BOOL addUnique(const Type &data, const void *key);
00439 
00440   KYL_BOOL remove(const void *key) {
00441     int val;
00442     find(key, val, 1);
00443     return(val);
00444   }
00445 
00446   KHTable<Type> & operator =(const KHTable<Type> & arg);
00447   KYL_BOOL operator == (const KHTable<Type> & arg);
00448 
00449   KYL_BOOL inTable(const void *key);
00450   int count() const;
00451 
00452 private:
00453   KeyList<Type> **table;
00454   int tableSize;
00455 };
00456 
00457 
00458 template <class Type>
00459 KYL_BOOL KHTable<Type>::destroy()
00460 {
00461   int j;
00462   for (j=0; j<tableSize; ++j) 
00463     if (table[j]) {
00464       delete (table[j]);
00465       table[j] = 0;
00466     }
00467   return KYL_TRUE;
00468 }
00469 
00470 template <class Type>
00471 Type KHTable<Type>::find(const void *key, int &valid, const int removeMe)
00472 {
00473   int hid;
00474   Type ret;
00475 
00476   hid = ListHash(key, tableSize);
00477   if ((hid < 0) ||
00478       (hid > tableSize)) {
00479     valid = KYL_FALSE;
00480     return ret;
00481   } else if (!table[hid]) {
00482     valid = KYL_FALSE;
00483     return ret;
00484   } else {
00485     return(table[hid]->find(key, valid, removeMe));
00486   }
00487 }
00488 
00489 template <class Type>
00490 KYL_BOOL KHTable<Type>::add(const Type &data, const void *key)
00491 {
00492   int hid;
00493 
00494   hid = ListHash(key, tableSize);
00495   if (hid <0 || hid > tableSize) 
00496     return KYL_FALSE;
00497 
00498   if (!table[hid])
00499     table[hid] = new(KeyList<Type>);
00500 
00501   return (table[hid]->prepend(data, key));
00502 }
00503 
00504 template <class Type>
00505 KHTable<Type> & KHTable<Type>::operator = (const KHTable<Type> &arg)
00506 {
00507   int j;
00508 
00509   if (this == &arg)
00510     return (*this);
00511 
00512   destroy();
00513   tableSize = arg.tableSize;
00514   table = new KeyList<Type>*[tableSize];
00515   for (j=0; j < arg.tableSize; ++j)
00516     table[j] = arg.table[j];
00517   return(*this);
00518 }
00519 
00520 template <class Type>
00521 KYL_BOOL KHTable<Type>::operator == (const KHTable<Type> &arg)
00522 {
00523   int i;
00524   if (tableSize != arg.tableSize)
00525     return KYL_FALSE;
00526   else {
00527     for (i=0; i<tableSize; ++i) {
00528       if (!(table[i] == arg.table[i]))
00529     return KYL_FALSE;
00530     }
00531   }
00532   return KYL_TRUE;
00533 }
00534 
00535 template <class Type> 
00536 KYL_BOOL KHTable<Type>::addUnique(const Type &data, const void *key)
00537 {
00538   if (inTable(key))
00539     return KYL_FALSE;
00540   else
00541     return (add(data, key));
00542 }
00543 
00544 template <class Type>
00545 int KHTable<Type>::count() const {
00546   int i, total=0;
00547   for (i=0; i < tableSize; i++) {
00548     if (table[i]) {
00549       total += table[i]->count();
00550     }
00551   }
00552   return(total);
00553 }
00554 
00555 template <class Type>
00556 KYL_BOOL KHTable<Type>::inTable(const void *key)
00557 {
00558   int hid;
00559 
00560   hid = ListHash(key, tableSize);
00561   if ((hid < 0) ||
00562       (hid > tableSize))
00563     return KYL_FALSE;
00564   else if (!table[hid])
00565     return KYL_FALSE;
00566   else
00567     return(table[hid]->inList(key));
00568 }
00569 
00570 #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