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

  1. /*
  2.  another test file for Integer class
  3.  */
  4.  
  5. #include <std.h>
  6. #include <Integer.h>
  7.  
  8. #define INLINE
  9.  
  10. #define MEMOIZE_TYPE(TYPE)                              \
  11.   class Memoized ## TYPE;                              \
  12.   struct _Memoized ## TYPE ## _rep                          \
  13.   {                                          \
  14.     unsigned short Arity;    /* Arity of the function    */          \
  15.     unsigned short Ref;        /* Reference count        */          \
  16.     TYPE (Memoized ## TYPE::*Fn)(...);    /* member function being memoized */  \
  17.     TYPE Value;            /* value returned from function applied to arguments */ \
  18.     TYPE *Args;            /* arguments to member function    */          \
  19.                                             \
  20.     INLINE _Memoized ## TYPE ## _rep (int arity = 0)                  \
  21.       {                                          \
  22.     Arity = arity;                                  \
  23.     Ref = 1;                                  \
  24.     Fn = 0;                                      \
  25.     Args = new TYPE [arity];                          \
  26.     /* Value gets default initilaization.  */                  \
  27.       }                                          \
  28.     INLINE ~_Memoized ## TYPE ## _rep ()                      \
  29.       {                                          \
  30.         if (--Ref == 0)                                  \
  31.       {                                      \
  32.         delete [Arity] Args;                              \
  33.         delete Args;                                  \
  34.       }                                      \
  35.       }                                          \
  36.   };                                          \
  37.                                             \
  38.   /* Declare `NIL' for this type.  */                          \
  39.   _Memoized ## TYPE ## _rep _nil_ ## TYPE ## _rep;                  \
  40.                                             \
  41.   class Memoized ## TYPE ## Elem                          \
  42.   {                                          \
  43.     _Memoized ## TYPE ## _rep *rep;                          \
  44.    public:                                      \
  45.     INLINE Memoized ## TYPE ## Elem ()                          \
  46.       { rep = &_nil_ ## TYPE ## _rep; }                          \
  47.     INLINE Memoized ## TYPE ## Elem (Memoized ## TYPE ## Elem& E)          \
  48.       { rep = E.rep; rep->Ref++; }                          \
  49.     Memoized ## TYPE ## Elem (int arity, TYPE (Memoized ## TYPE::*Fn)(...), TYPE x, ...)  \
  50.       { rep = &_nil_ ## TYPE ## _rep; copy (arity, Fn, &x); }              \
  51.     INLINE ~Memoized ## TYPE ## Elem ()                          \
  52.       { if (rep != &_nil_ ## TYPE ## _rep && --rep->Ref == 0) delete rep; }   \
  53.                                             \
  54.     void copy (const int, TYPE (Memoized ## TYPE::*Fn)(...), TYPE*);          \
  55.     int operator==(Memoized ## TYPE ## Elem&);                      \
  56.     Memoized ## TYPE ## Elem& operator=(Memoized ## TYPE ## Elem&);          \
  57.     INLINE Memoized ## TYPE ## Elem& operator=(const TYPE& x) { rep->Value = x;  return *this; } \
  58.     INLINE operator TYPE () { return rep->Value; }                  \
  59.   };                                          \
  60.                                             \
  61.   void Memoized ## TYPE ## Elem::copy                          \
  62.     (const int arity, TYPE (Memoized ## TYPE::*Fn)(...), TYPE* pI)          \
  63.   {                                          \
  64.     if (rep == &_nil_ ## TYPE ## _rep)                          \
  65.       rep = new _Memoized ## TYPE ## _rep (arity);                  \
  66.     else if (rep->Ref > 1)                              \
  67.       {                                          \
  68.         rep->Ref--;                                  \
  69.         rep = new _Memoized ## TYPE ## _rep (arity);                  \
  70.       }                                          \
  71.     else if (rep->Arity != arity)                          \
  72.       {                                          \
  73.         delete rep;                                  \
  74.         rep = new _Memoized ## TYPE ## _rep (arity);                  \
  75.       }                                          \
  76.     for (int i = 0; i < arity; i++)                          \
  77.       rep->Args[i] = pI[i];                              \
  78.     rep->Fn = Fn;                                  \
  79.   }                                          \
  80.                                             \
  81.   int Memoized ## TYPE ## Elem::operator==(Memoized ## TYPE ## Elem& E)          \
  82.   {                                          \
  83.     if (rep->Arity != E.rep->Arity || rep->Fn != E.rep->Fn)              \
  84.       return 0;                                      \
  85.     for (int i = 0; i < rep->Arity; i++)                      \
  86.       if (rep->Args[i] != E.rep->Args[i])                      \
  87.         return 0;                                  \
  88.     return 1;                                      \
  89.   }                                          \
  90.                                             \
  91.   Memoized ## TYPE ## Elem& Memoized ## TYPE ## Elem::operator=(Memoized ## TYPE ## Elem& E) \
  92.   {                                          \
  93.     E.rep->Ref++;                                  \
  94.     if (rep != &_nil_ ## TYPE ## _rep && --rep->Ref == 0) delete rep;          \
  95.     rep = E.rep;                                  \
  96.     return *this;                                  \
  97.   }                                          \
  98. /* End of MEMOIZE_TYPE.  */
  99.  
  100. #define DEFINE_MEMOIZATION(TYPE, CTOR_ARGS, CTOR_BODY, DTOR_BODY)          \
  101.   MEMOIZE_TYPE (TYPE);                                  \
  102.   class Memoized ## TYPE ## Base                          \
  103.   {                                          \
  104.     int sz, start, finish;                              \
  105.     Memoized ## TYPE ## Elem *table;                          \
  106.    public:                                      \
  107.     Memoized ## TYPE ## Base CTOR_ARGS CTOR_BODY                  \
  108.     ~Memoized ## TYPE ## Base () DTOR_BODY                      \
  109.                                             \
  110.     Memoized ## TYPE ## Elem* add (Memoized ## TYPE ## Elem&);              \
  111.     Memoized ## TYPE ## Elem* remove (Memoized ## TYPE ## Elem&);          \
  112.     int indexOf (Memoized ## TYPE ## Elem&);                      \
  113.     Memoized ## TYPE ## Elem& at (int);                          \
  114.   };                                          \
  115.  
  116. #define DEFINE_ADD(TYPE, DECL, BODY) \
  117.   Memoized ## TYPE ## Elem* Memoized ## TYPE ## Base::add (Memoized ## TYPE ## Elem& DECL) BODY
  118.  
  119. #define DEFINE_REMOVE(TYPE, DECL, BODY) \
  120.   Memoized ## TYPE ## Elem* Memoized ## TYPE ## Base::remove (Memoized ## TYPE ## Elem& DECL) BODY
  121.  
  122. #define DEFINE_INDEXOF(TYPE, INDEX_TYPE, DECL, BODY) \
  123.   INDEX_TYPE Memoized ## TYPE ## Base::indexOf (Memoized ## TYPE ## Elem& DECL) BODY
  124.  
  125. #define DEFINE_AT(TYPE, INDEX_TYPE, DECL, BODY) \
  126.   Memoized ## TYPE ## Elem& Memoized ## TYPE ## Base::at (INDEX_TYPE DECL) BODY
  127.  
  128. #define DEFINE_MEMOIZED_CLASS(TYPE, CLASS_BODY) \
  129.   class Memoized ## TYPE : Memoized ## TYPE ## Base CLASS_BODY
  130.  
  131. #define DEFINE_WRAPPER_1(TYPE) \
  132.   TYPE Memoized ## TYPE::()Memoized ## TYPE                      \
  133.     (int, TYPE (Memoized ## TYPE::*pf_I)(TYPE), TYPE I)                  \
  134.   {                                          \
  135.     Memoized ## TYPE ## Elem E (1, pf_I, I);                      \
  136.     int i = this->indexOf (E);                              \
  137.                                             \
  138.     if (i < 0)                                      \
  139.       {                                          \
  140.     E = (this->*pf_I)(I);                              \
  141.     this->add (E);                                  \
  142.       }                                          \
  143.     else                                      \
  144.       E = at (i);                                  \
  145.                                             \
  146.     return E;                                      \
  147.   }                                          \
  148.  
  149. #define DEFINE_WRAPPER_2(TYPE) \
  150.   TYPE Memoized ## TYPE::()Memoized ## TYPE                      \
  151.          (int, TYPE (Memoized ## TYPE::*pf_I_I)(TYPE, TYPE), TYPE I1, TYPE I2) \
  152.   {                                          \
  153.     Memoized ## TYPE ## Elem E (2, pf_I_I, I1, I2);                  \
  154.     int i = this->indexOf (E);                              \
  155.                                             \
  156.     if (i < 0)                                      \
  157.       {                                          \
  158.         E = (this->*pf_I_I)(I1, I2);                          \
  159.         this->add (E);                                  \
  160.       }                                          \
  161.     else                                      \
  162.       E = at (i);                                  \
  163.                                             \
  164.     return E;                                      \
  165.   }                                          \
  166.  
  167. #define DEFINE_WRAPPER_3(TYPE) \
  168.   TYPE Memoized ## TYPE::()Memoized ## TYPE                      \
  169.          (int, TYPE (Memoized ## TYPE::*pf_I_I_I)(TYPE, TYPE, TYPE), TYPE I1, TYPE I2, TYPE I3) \
  170.   {                                          \
  171.     Memoized ## TYPE ## Elem E (3, pf_I_I, I1, I2, I3);                  \
  172.     int i = this->indexOf (E);                              \
  173.                                             \
  174.     if (i < 0)                                      \
  175.       {                                          \
  176.         E = (this->*pf_I_I_I)(I1, I2, I3);                      \
  177.         this->add (E);                                  \
  178.       }                                          \
  179.     else                                      \
  180.       E = at (i);                                  \
  181.                                             \
  182.     return E;                                      \
  183.   }                                          \
  184.  
  185. #define DEFINE_WRAPPER_4(TYPE) \
  186.   TYPE Memoized ## TYPE::()Memoized ## TYPE                      \
  187.          (int, TYPE (Memoized ## TYPE::*pf_I_I_I_I)(TYPE, TYPE, TYPE, TYPE),  \
  188.       TYPE I1, TYPE I2, TYPE I3, TYPE I4)                      \
  189.   {                                          \
  190.     Memoized ## TYPE ## Elem E (2, pf_I_I_I_I, I1, I2, I3, I4);              \
  191.     int i = this->indexOf (E);                              \
  192.                                             \
  193.     if (i < 0)                                      \
  194.       {                                          \
  195.         E = (this->*pf_I_I_I_I)(I1, I2, I3, I4);                  \
  196.         this->add (E);                                  \
  197.       }                                          \
  198.     else                                      \
  199.       E = at (i);                                  \
  200.                                             \
  201.     return E;                                      \
  202.   }                                          \
  203.  
  204. #define DEFINE_MEMOIZED_FUNCTION(TYPE, NAME, ARGS, BODY) \
  205.   TYPE Memoized ## TYPE:: NAME ARGS BODY
  206.  
  207. #define MEMOIZED_TABLE(TYPE, DECL, ARGS) \
  208.   Memoized ## TYPE DECL ARGS
  209.  
  210.  
  211.  
  212. /* Define a memoization for class `Integer'.
  213.    The initialization argument list for the constructor is `(int size)'.
  214.    The bodies of the constructor taking that argument list,
  215.    and the destructor are also given in this macro.  */
  216. DEFINE_MEMOIZATION (Integer,
  217.             (int size),
  218.             {
  219.               if (size < 0)
  220.             {
  221.               cerr << "table size < 0 not allowed, aborting...\n";
  222.               exit (-1);
  223.             }
  224.               sz = size;
  225.               start = 0;
  226.               finish = 0;
  227.               table = new MemoizedIntegerElem [sz];
  228.             },
  229.             {
  230.               if (start) delete [sz] table;
  231.               else delete [finish] table;
  232.               delete table;
  233.             });
  234.  
  235. /* Give the implementation of the memoization.
  236.  
  237.    In this implementation, the memization table is just
  238.    a circular buffer of some fixed size.  */
  239. DEFINE_ADD (Integer, E,
  240.         {
  241.           if (finish == sz)
  242.         {
  243.           start = 1;
  244.           finish = 0;
  245.         }
  246.           else if (start)
  247.         {
  248.           start++;
  249.           if (start == sz)
  250.             start = 0;
  251.         }
  252.  
  253.           if (finish < sz)
  254.         table[finish++] = E;
  255.  
  256.           return &E;
  257.         });
  258.  
  259. DEFINE_REMOVE (Integer, E, { &E/* does nothing, except uses it. */; });
  260.  
  261. DEFINE_INDEXOF (Integer, int, E,
  262.         {
  263.           int i;
  264.  
  265.           if (start)
  266.             {
  267.               for (i = 0; i < sz; i++)
  268.             {
  269.               if (table[i] == E)
  270.                 return i;
  271.             }
  272.             }
  273.           else
  274.             {
  275.               for (i = 0; i < finish; i++)
  276.             {
  277.               if (table[i] == E)
  278.                 return i;
  279.             }
  280.             }
  281.           return -1;
  282.         });
  283.  
  284. DEFINE_AT (Integer, int, i, { return table[i]; });
  285.  
  286. DEFINE_MEMOIZED_CLASS (Integer,
  287.                {
  288.                public:
  289.              // wrappers
  290.              DEFINE_WRAPPER_1 (Integer);
  291.  
  292.              // functions to be wrapped
  293.              Integer factorial (Integer n);
  294.              Integer fibonacci (Integer n);
  295.                });
  296.  
  297. DEFINE_MEMOIZED_FUNCTION (Integer, factorial, (Integer n),
  298.   {
  299.     Integer f = 1;
  300.     while (n > 0)
  301.       {
  302.     f *= n;
  303.     --n;
  304.       }
  305.     return f;
  306.   });
  307.  
  308. DEFINE_MEMOIZED_FUNCTION (Integer, fibonacci, (Integer n),
  309.   {
  310.     if (n <= 0)
  311.       return 0;
  312.     else
  313.       {
  314.     Integer f = 1;
  315.     Integer prev = 0;
  316.     while (n > 1)
  317.       {
  318.         Integer tmp = f;
  319.         f += prev;
  320.         prev = tmp;
  321.         --n;
  322.       }
  323.     return f;
  324.       }
  325.   });
  326.  
  327. main (int argc, char *argv[])
  328. {
  329.   int n;
  330.   int size = (argc == 2 ? atoi (argv[1]) : 10);
  331.  
  332.   MEMOIZED_TABLE (Integer, m, (size));
  333.  
  334.   printf ("memoizing with table size %d\n", size);
  335.   while (1)
  336.     {
  337.       cout << "Number: ";
  338.       cin >> n;
  339.       if (cin.eof() || n <= 0)
  340.     {
  341.       cout << "bye!\n";
  342.       break;
  343.     }
  344.       cout << n << "! = " << m.factorial (n) << "\n";
  345.     }
  346. }
  347.