|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T t
Length: 10488 (0x28f8) Types: TextFile Names: »tgwrapper.cc«
└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89 └─⟦cc8755de2⟧ »./libg++-1.36.1.tar.Z« └─⟦23757c458⟧ └─⟦this⟧ »libg++/tests/tgwrapper.cc«
/* another test file for Integer class */ #include <std.h> #include <Integer.h> #define INLINE #define MEMOIZE_TYPE(TYPE) \ class Memoized ## TYPE; \ struct _Memoized ## TYPE ## _rep \ { \ unsigned short Arity; /* Arity of the function */ \ unsigned short Ref; /* Reference count */ \ TYPE (Memoized ## TYPE::*Fn)(...); /* member function being memoized */ \ TYPE Value; /* value returned from function applied to arguments */ \ TYPE *Args; /* arguments to member function */ \ \ INLINE _Memoized ## TYPE ## _rep (int arity = 0) \ { \ Arity = arity; \ Ref = 1; \ Fn = 0; \ Args = new TYPE [arity]; \ /* Value gets default initilaization. */ \ } \ INLINE ~_Memoized ## TYPE ## _rep () \ { \ if (--Ref == 0) \ { \ delete [Arity] Args; \ delete Args; \ } \ } \ }; \ \ /* Declare `NIL' for this type. */ \ _Memoized ## TYPE ## _rep _nil_ ## TYPE ## _rep; \ void init_nil() { _nil_ ## TYPE ## _rep.Ref = (unsigned)(-1); } \ \ class Memoized ## TYPE ## Elem \ { \ _Memoized ## TYPE ## _rep *rep; \ public: \ INLINE Memoized ## TYPE ## Elem () \ { rep = &_nil_ ## TYPE ## _rep; } \ INLINE Memoized ## TYPE ## Elem (Memoized ## TYPE ## Elem& E) \ { rep = E.rep; rep->Ref++; } \ Memoized ## TYPE ## Elem (int arity, TYPE (Memoized ## TYPE::*Fn)(...), TYPE x, ...) \ { rep = &_nil_ ## TYPE ## _rep; copy (arity, Fn, &x); } \ INLINE ~Memoized ## TYPE ## Elem () \ { if (rep != &_nil_ ## TYPE ## _rep && --rep->Ref == 0) delete rep; } \ \ void copy (const int, TYPE (Memoized ## TYPE::*Fn)(...), TYPE*); \ int operator==(Memoized ## TYPE ## Elem&); \ Memoized ## TYPE ## Elem& operator=(Memoized ## TYPE ## Elem&); \ INLINE Memoized ## TYPE ## Elem& operator=(const TYPE& x) { rep->Value = x; return *this; } \ INLINE operator TYPE () { return rep->Value; } \ }; \ \ void Memoized ## TYPE ## Elem::copy \ (const int arity, TYPE (Memoized ## TYPE::*Fn)(...), TYPE* pI) \ { \ if (rep == &_nil_ ## TYPE ## _rep) \ rep = new _Memoized ## TYPE ## _rep (arity); \ else if (rep->Ref > 1) \ { \ rep->Ref--; \ rep = new _Memoized ## TYPE ## _rep (arity); \ } \ else if (rep->Arity != arity) \ { \ delete rep; \ rep = new _Memoized ## TYPE ## _rep (arity); \ } \ for (int i = 0; i < arity; i++) \ rep->Args[i] = pI[i]; \ rep->Fn = Fn; \ } \ \ int Memoized ## TYPE ## Elem::operator==(Memoized ## TYPE ## Elem& E) \ { \ if (rep->Arity != E.rep->Arity || rep->Fn != E.rep->Fn) \ return 0; \ for (int i = 0; i < rep->Arity; i++) \ if (rep->Args[i] != E.rep->Args[i]) \ return 0; \ return 1; \ } \ \ Memoized ## TYPE ## Elem& Memoized ## TYPE ## Elem::operator=(Memoized ## TYPE ## Elem& E) \ { \ E.rep->Ref++; \ if (rep != &_nil_ ## TYPE ## _rep && --rep->Ref == 0) delete rep; \ rep = E.rep; \ return *this; \ } \ /* End of MEMOIZE_TYPE. */ #define DEFINE_MEMOIZATION(TYPE, CTOR_ARGS, CTOR_BODY, DTOR_BODY) \ MEMOIZE_TYPE (TYPE); \ class Memoized ## TYPE ## Base \ { \ int sz, start, finish; \ Memoized ## TYPE ## Elem *table; \ public: \ Memoized ## TYPE ## Base CTOR_ARGS CTOR_BODY \ ~Memoized ## TYPE ## Base () DTOR_BODY \ \ Memoized ## TYPE ## Elem* add (Memoized ## TYPE ## Elem&); \ Memoized ## TYPE ## Elem* remove (Memoized ## TYPE ## Elem&); \ int indexOf (Memoized ## TYPE ## Elem&); \ Memoized ## TYPE ## Elem& at (int); \ }; \ #define DEFINE_ADD(TYPE, DECL, BODY) \ Memoized ## TYPE ## Elem* Memoized ## TYPE ## Base::add (Memoized ## TYPE ## Elem& DECL) BODY #define DEFINE_REMOVE(TYPE, DECL, BODY) \ Memoized ## TYPE ## Elem* Memoized ## TYPE ## Base::remove (Memoized ## TYPE ## Elem& DECL) BODY #define DEFINE_INDEXOF(TYPE, INDEX_TYPE, DECL, BODY) \ INDEX_TYPE Memoized ## TYPE ## Base::indexOf (Memoized ## TYPE ## Elem& DECL) BODY #define DEFINE_AT(TYPE, INDEX_TYPE, DECL, BODY) \ Memoized ## TYPE ## Elem& Memoized ## TYPE ## Base::at (INDEX_TYPE DECL) BODY #define DEFINE_MEMOIZED_CLASS(TYPE, CLASS_BODY) \ class Memoized ## TYPE : public Memoized ## TYPE ## Base CLASS_BODY #define DEFINE_WRAPPER_1(TYPE) \ TYPE Memoized ## TYPE::()Memoized ## TYPE \ (int, TYPE (Memoized ## TYPE::*pf_I)(TYPE), TYPE I) \ { \ Memoized ## TYPE ## Elem E (1, pf_I, I); \ int i = this->indexOf (E); \ \ if (i < 0) \ { \ E = (this->*pf_I)(I); \ this->add (E); \ } \ else \ E = at (i); \ \ return E; \ } \ #define DEFINE_WRAPPER_2(TYPE) \ TYPE Memoized ## TYPE::()Memoized ## TYPE \ (int, TYPE (Memoized ## TYPE::*pf_I_I)(TYPE, TYPE), TYPE I1, TYPE I2) \ { \ Memoized ## TYPE ## Elem E (2, pf_I_I, I1, I2); \ int i = this->indexOf (E); \ \ if (i < 0) \ { \ E = (this->*pf_I_I)(I1, I2); \ this->add (E); \ } \ else \ E = at (i); \ \ return E; \ } \ #define DEFINE_WRAPPER_3(TYPE) \ TYPE Memoized ## TYPE::()Memoized ## TYPE \ (int, TYPE (Memoized ## TYPE::*pf_I_I_I)(TYPE, TYPE, TYPE), TYPE I1, TYPE I2, TYPE I3) \ { \ Memoized ## TYPE ## Elem E (3, pf_I_I, I1, I2, I3); \ int i = this->indexOf (E); \ \ if (i < 0) \ { \ E = (this->*pf_I_I_I)(I1, I2, I3); \ this->add (E); \ } \ else \ E = at (i); \ \ return E; \ } \ #define DEFINE_WRAPPER_4(TYPE) \ TYPE Memoized ## TYPE::()Memoized ## TYPE \ (int, TYPE (Memoized ## TYPE::*pf_I_I_I_I)(TYPE, TYPE, TYPE, TYPE), \ TYPE I1, TYPE I2, TYPE I3, TYPE I4) \ { \ Memoized ## TYPE ## Elem E (2, pf_I_I_I_I, I1, I2, I3, I4); \ int i = this->indexOf (E); \ \ if (i < 0) \ { \ E = (this->*pf_I_I_I_I)(I1, I2, I3, I4); \ this->add (E); \ } \ else \ E = at (i); \ \ return E; \ } \ #define DEFINE_MEMOIZED_FUNCTION(TYPE, NAME, ARGS, BODY) \ TYPE Memoized ## TYPE:: NAME ARGS BODY #define MEMOIZED_TABLE(TYPE, DECL, ARGS) \ Memoized ## TYPE DECL ARGS /* Define a memoization for class `Integer'. The initialization argument list for the constructor is `(int size)'. The bodies of the constructor taking that argument list, and the destructor are also given in this macro. */ DEFINE_MEMOIZATION (Integer, (int size), { if (size < 0) { cerr << "table size < 0 not allowed, aborting...\n"; exit (-1); } sz = size; start = 0; finish = 0; table = new MemoizedIntegerElem [sz]; }, { if (start) delete [sz] table; else delete [finish] table; /* delete table; */ }); /* Give the implementation of the memoization. In this implementation, the memization table is just a circular buffer of some fixed size. */ DEFINE_ADD (Integer, E, { if (finish == sz) { start = 1; finish = 0; } else if (start) { start++; if (start == sz) start = 0; } if (finish < sz) table[finish++] = E; return &E; }); DEFINE_REMOVE (Integer, E, { return &E/* does nothing, except uses it. */;}); DEFINE_INDEXOF (Integer, int, E, { int i; if (start) { for (i = 0; i < sz; i++) { if (table[i] == E) return i; } } else { for (i = 0; i < finish; i++) { if (table[i] == E) return i; } } return -1; }); DEFINE_AT (Integer, int, i, { return table[i]; }); DEFINE_MEMOIZED_CLASS (Integer, { public: // wrappers DEFINE_WRAPPER_1 (Integer); // functions to be wrapped Integer factorial (Integer n); Integer fibonacci (Integer n); }); DEFINE_MEMOIZED_FUNCTION (Integer, factorial, (Integer n), { Integer f = 1; while (n > 0) { f *= n; --n; } return f; }); DEFINE_MEMOIZED_FUNCTION (Integer, fibonacci, (Integer n), { if (n <= 0) return 0; else { Integer f = 1; Integer prev = 0; while (n > 1) { Integer tmp = f; f += prev; prev = tmp; --n; } return f; } }); main (int argc, char *argv[]) { int n; int size = (argc == 2 ? atoi (argv[1]) : 10); init_nil(); MEMOIZED_TABLE (Integer, m, (size)); printf ("memoizing with table size %d\n", size); while (1) { cout << "Number: "; cin >> n; if (cin.eof() || n <= 0) { cout << "bye!\n"; break; } cout << n << "! = " << m.factorial (n) << "\n"; } }