home *** CD-ROM | disk | FTP | other *** search
- /*
- 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; \
- \
- 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 : 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, { &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);
-
- 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";
- }
- }
-