home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / gnu / g__lib / twrapper.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-23  |  5.6 KB  |  296 lines

  1. /*
  2.  another test file for Integer class
  3.  */
  4.  
  5. #include <Integer.h>
  6. #include <std.h>
  7.  
  8. class MemoizedInteger;
  9.  
  10. struct _Mrep
  11. {
  12.   unsigned short Arity;        // Arity of the function
  13.   unsigned short  ref;          // reference count
  14.   Integer (MemoizedInteger::*Fn)(...);    // member function being memoized
  15.   Integer Value;        // value returned from function applied to arguments
  16.   Integer *Args;        // arguments to member function
  17.  
  18.   _Mrep (int arity = 0)
  19.     {
  20.       Arity = arity;
  21.       ref = 1;
  22.       Fn = 0;
  23.       Args = new Integer [arity];
  24.       /* Value gets default initialization.  */
  25.     }
  26.   ~_Mrep ()
  27.     {
  28.       if (--ref == 0)
  29.     {
  30.       delete [Arity] Args;
  31.       delete Args;
  32.     }
  33.     }
  34. };
  35.  
  36. class MemoizedIntegerElem
  37. {
  38.   _Mrep *rep;
  39.  public:
  40.   MemoizedIntegerElem ();
  41.   MemoizedIntegerElem (MemoizedIntegerElem&);
  42.   MemoizedIntegerElem (int, Integer (MemoizedInteger::*Fn)(...), Integer, ...);
  43.   ~MemoizedIntegerElem ();
  44.  
  45.   void copy (const int, Integer (MemoizedInteger::*Fn)(...), Integer*);
  46.   int operator==(MemoizedIntegerElem&);
  47.   MemoizedIntegerElem& operator=(MemoizedIntegerElem&);
  48.   MemoizedIntegerElem& operator=(const Integer& I) { rep->Value = I; return *this; }
  49.   operator Integer () { return rep->Value; }
  50.  
  51.   friend ostream& operator<<(ostream&, MemoizedIntegerElem&);
  52. };
  53.  
  54. ostream& operator<<(ostream &strm, MemoizedIntegerElem &E)
  55. {
  56.   strm << '[';
  57.   for (int i = 0; i < E.rep->Arity; i++)
  58.     strm << E.rep->Args[i] << ' ';
  59.   strm << "=> " << E.rep->Value << ']';
  60. }
  61.  
  62. _Mrep _nil_Mrep;
  63.  
  64. MemoizedIntegerElem::MemoizedIntegerElem ()
  65. {
  66.   rep = &_nil_Mrep;
  67. }
  68.  
  69. MemoizedIntegerElem::MemoizedIntegerElem (MemoizedIntegerElem& E)
  70. {
  71.   rep = E.rep;
  72.   rep->ref++;
  73. }
  74.  
  75. MemoizedIntegerElem::MemoizedIntegerElem (int arity,
  76.                       Integer (MemoizedInteger::*Fn)(...),
  77.                       Integer I, ...)
  78. {
  79.   rep = &_nil_Mrep;
  80.   copy (arity, Fn, &I);
  81. }
  82.  
  83. void MemoizedIntegerElem::copy (const int arity,
  84.                 Integer (MemoizedInteger::*Fn)(...),
  85.                 Integer* pI)
  86. {
  87.   if (rep == &_nil_Mrep)
  88.     rep = new _Mrep (arity);
  89.   else if (rep->ref > 1)
  90.     {
  91.       rep->ref--;
  92.       rep = new _Mrep (arity);
  93.     }
  94.   else if (rep->Arity != arity)
  95.     {
  96.       delete rep;
  97.       rep = new _Mrep (arity);
  98.     }
  99.   for (int i = 0; i < arity; i++)
  100.     rep->Args[i] = pI[i];
  101.   rep->Fn = Fn;
  102. }
  103.  
  104. MemoizedIntegerElem::~MemoizedIntegerElem ()
  105. {
  106.   if (rep != &_nil_Mrep && --rep->ref == 0) delete rep;
  107. }
  108.  
  109. int MemoizedIntegerElem::operator==(MemoizedIntegerElem& E)
  110. {
  111.   if (rep->Arity != E.rep->Arity || rep->Fn != E.rep->Fn)
  112.     return 0;
  113.   for (int i = 0; i < rep->Arity; i++)
  114.     if (rep->Args[i] != E.rep->Args[i])
  115.       return 0;
  116.   return 1;
  117. }
  118.  
  119. MemoizedIntegerElem& MemoizedIntegerElem::operator=(MemoizedIntegerElem& E)
  120. {
  121.   E.rep->ref++;
  122.   if (rep != &_nil_Mrep && --rep->ref == 0) delete rep;
  123.   rep = E.rep;
  124.   return *this;
  125. }
  126.  
  127. class MemoizedIntegerBase
  128. {
  129.   int sz, start, finish;
  130.   MemoizedIntegerElem *table;
  131.  public:
  132.   MemoizedIntegerBase (int size)
  133.     {
  134.       if (size < 0)
  135.     {
  136.       cerr << "table size < 0 not allowed, aborting...\n";
  137.       exit (-1);
  138.     }
  139.       sz = size;
  140.       start = 0;
  141.       finish = 0;
  142.       table = new MemoizedIntegerElem [sz];
  143.     };
  144.   ~MemoizedIntegerBase ()
  145.     {
  146.       if (start) delete [sz] table;
  147.       else delete [finish] table;
  148.       delete table;
  149.     };
  150.  
  151.   int indexOf (MemoizedIntegerElem&);
  152.   MemoizedIntegerElem& at (int i) { return table[i]; }
  153.   MemoizedIntegerElem* add (MemoizedIntegerElem&);
  154. };
  155.  
  156. MemoizedIntegerElem* MemoizedIntegerBase::add (MemoizedIntegerElem& E)
  157. {
  158.   if (finish == sz)
  159.     {
  160.       start = 1;
  161.       finish = 0;
  162.     }
  163.   else if (start)
  164.     {
  165.       start++;
  166.       if (start == sz)
  167.     start = 0;
  168.     }
  169.  
  170.   if (finish < sz)
  171.     table[finish++] = E;
  172.  
  173.   return &E;
  174. }
  175.  
  176. int MemoizedIntegerBase::indexOf (MemoizedIntegerElem& E)
  177. {
  178.   if (start)
  179.     {
  180.       for (int i = 0; i < sz; i++)
  181.     {
  182.       if (table[i] == E)
  183.         return i;
  184.     }
  185.     }
  186.   else
  187.     {
  188.       for (int i = 0; i < finish; i++)
  189.     {
  190.       if (table[i] == E)
  191.         return i;
  192.     }
  193.     }
  194.   return -1;
  195. }
  196.  
  197. class MemoizedInteger : MemoizedIntegerBase
  198. {
  199.  public:
  200.   // wrappers
  201.   Integer MemoizedInteger::() MemoizedInteger
  202.     (int, Integer (MemoizedInteger::*)(Integer), Integer);
  203.   Integer MemoizedInteger::() MemoizedInteger
  204.     (int, Integer (MemoizedInteger::*)(Integer, Integer), Integer, Integer);
  205.  
  206.   // functions to be wrapped
  207.   Integer factorial (Integer n);
  208.   Integer fibonacci (Integer n);
  209. };
  210.  
  211. Integer MemoizedInteger::()MemoizedInteger
  212.        (int, Integer (MemoizedInteger::*pf_I)(Integer), Integer I)
  213. {
  214.   MemoizedIntegerElem E (1, pf_I, I);
  215.   int i = this->indexOf (E);
  216.  
  217.   if (i < 0)
  218.     {
  219.       E = (this->*pf_I)(I);
  220.       this->add (E);
  221.     }
  222.   else
  223.     E = at (i);
  224.  
  225.   return E;
  226. }
  227.  
  228. Integer MemoizedInteger::()MemoizedInteger
  229.        (int, Integer (MemoizedInteger::*pf_I_I)(Integer, Integer), Integer I1, Integer I2)
  230. {
  231.   MemoizedIntegerElem E (2, pf_I_I, I1, I2);
  232.   int i = this->indexOf (E);
  233.  
  234.   if (i < 0)
  235.     {
  236.       E = (this->*pf_I_I)(I1, I2);
  237.       this->add (E);
  238.     }
  239.   else
  240.     E = at (i);
  241.  
  242.   return E;
  243. }
  244.  
  245. Integer MemoizedInteger::factorial(Integer n)
  246. {
  247.   Integer f = 1;
  248.   while (n > 0)
  249.   {
  250.     f *= n;
  251.     --n;
  252.   }
  253.   return f;
  254. }
  255.  
  256. Integer MemoizedInteger::fibonacci(Integer n)
  257. {
  258.   if (n <= 0)
  259.     return 0;
  260.   else
  261.   {
  262.     Integer f = 1;
  263.     Integer prev = 0;
  264.     while (n > 1)
  265.     {
  266.       Integer tmp = f;
  267.       f += prev;
  268.       prev = tmp;
  269.       --n;
  270.     }
  271.     return f;
  272.   }
  273. }
  274.  
  275. main (int argc, char *argv[])
  276. {
  277.   _nil_Mrep.ref = (unsigned)(-1);
  278.   int n;
  279.   int size = (argc == 2 ? atoi (argv[1]) : 10);
  280.  
  281.   MemoizedInteger m (size);
  282.  
  283.   printf ("memoizing with table size %d\n", size);
  284.   while (1)
  285.     {
  286.       cout << "Number: ";
  287.       cin >> n;
  288.       if (cin.eof() || n <= 0)
  289.     {
  290.       cout << "bye!\n";
  291.       break;
  292.     }
  293.       cout << n << "! = " << m.factorial (n) << "\n";
  294.     }
  295. }
  296.