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 >
Wrap
C/C++ Source or Header
|
1993-07-23
|
10KB
|
347 lines
/*
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";
}
}