home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / IDIOMS.ZIP / 7-5.C < prev    next >
C/C++ Source or Header  |  1991-12-04  |  3KB  |  118 lines

  1. /* Copyright (c) 1992 by AT&T Bell Laboratories. */
  2. /* Advanced C++ Programming Styles and Idioms */
  3. /* James O. Coplien */
  4. /* All rights reserved. */
  5.  
  6. template <class T> class ListItem;
  7.  
  8. template <class T> class List {
  9. public:
  10.     void sort();          // sort list in place
  11.     void put(T& t);
  12.     T get();
  13.     int element(const T&) const;
  14.     int size() const;
  15.     //  . .               // many other interesting operations
  16.     List() { head = 0; }  // default constructor
  17. private:
  18.     ListItem<T> *head;    // list head
  19. };
  20.  
  21. template <class T> class ListItem {
  22. friend class List<T>;
  23. private:
  24.     ListItem<T> *next;
  25.     T *item;
  26.     ~ListItem() { delete item; }
  27.     ListItem(const ListItem<T> *n, T *i)
  28.         { item=new T(*i); next=(ListItem<T>*)n; }
  29. };
  30.  
  31. template <class T> T List<T>::get() {             // get from head of list
  32.     T retval = *(head->item);
  33.     ListItem<T> *temp = head;
  34.     head = head->next;
  35.     delete temp;
  36.     return retval;
  37. }
  38.  
  39. template <class T> void
  40. List<T>::put(T& t) { head = new ListItem<T>(head, &t); }
  41.  
  42. class SetBase {
  43. friend ErsatzListElement;
  44. private:
  45.     virtual int comparelt(const void*, const void*)
  46.         const = 0;
  47.     virtual int compareeq(const void*, const void*)
  48.         const = 0;
  49. };
  50.  
  51. class ErsatzListElement {
  52.     // this is unparameterized, which means that there is one
  53.     // List template instantiation to serve all Sets.
  54. public:
  55.     void *rep;
  56.     int operator< (const ErsatzListElement& l) const {
  57.         return theSet->comparelt(this,&l);
  58.     }
  59.     int operator==(const ErsatzListElement& l) const {
  60.         return theSet->compareeq(this,&l);
  61.     }
  62.     ErsatzListElement(const void* v = 0) { rep = (void*)v; }
  63.     ErsatzListElement(SetBase *s, void *v=0): theSet(s) {
  64.         rep = v;
  65.     }
  66. private:
  67.     SetBase *theSet;
  68. };
  69.  
  70. template <class T> class Set: private SetBase {
  71. public:
  72.     void add(T t2) {
  73.         ErsatzListElement t(this, new T(t2)); rep.put(t);
  74.     }
  75.     T get() {
  76.         ErsatzListElement l=rep.get(); return *((T*)(l.rep));
  77.     }
  78.     void remove(const T&);
  79.     int exists(const T& e) {
  80.         ErsatzListElement t(this, (T*)&e);
  81.         return rep.element(t);
  82.     }
  83.     Set<T> Union(const Set<T>&) const;
  84.     Set<T> Intersection(const Set<T>&) const;
  85.     int size() const { return rep.size(); }
  86.     void sort() { rep.sort(); }
  87.     Set();
  88. private:
  89.     List<ErsatzListElement> rep;
  90.     int comparelt(const void* v1, const void* v2) const {
  91.         const T* t1 = (const T*) v1;
  92.         const T* t2 = (const T*) v2;
  93.         return *t1<*t2;
  94.     }
  95.     int compareeq(const void* v1, const void* v2) const {
  96.         const T* t1 = (const T*) v1;
  97.         const T* t2 = (const T*) v2;
  98.         return *t1==*t2;
  99.     }
  100. };
  101.  
  102. template <class T> Set<T>::Set() { }
  103.  
  104. #include <iostream.h>
  105.  
  106. int main() {
  107.     Set<int> foo;
  108.     Set<double> bar;
  109.     foo.add(1);
  110.     foo.add(2);
  111.     cout << foo.get() << "\n";
  112.     cout << foo.get() << "\n";
  113.     bar.add(3.0);
  114.     bar.add(4.0);
  115.     cout << bar.get() << "\n";
  116.     cout << bar.get() << "\n";
  117. }
  118.