home *** CD-ROM | disk | FTP | other *** search
- /*
- another test file for Integer class
- */
-
- #include <Integer.h>
- #include <std.h>
-
- class MemoizedInteger;
-
- struct _Mrep
- {
- unsigned short Arity; // Arity of the function
- unsigned short ref; // reference count
- Integer (MemoizedInteger::*Fn)(...); // member function being memoized
- Integer Value; // value returned from function applied to arguments
- Integer *Args; // arguments to member function
-
- _Mrep (int arity = 0)
- {
- Arity = arity;
- ref = 1;
- Fn = 0;
- Args = new Integer [arity];
- /* Value gets default initialization. */
- }
- ~_Mrep ()
- {
- if (--ref == 0)
- {
- delete [Arity] Args;
- delete Args;
- }
- }
- };
-
- class MemoizedIntegerElem
- {
- _Mrep *rep;
- public:
- MemoizedIntegerElem ();
- MemoizedIntegerElem (MemoizedIntegerElem&);
- MemoizedIntegerElem (int, Integer (MemoizedInteger::*Fn)(...), Integer, ...);
- ~MemoizedIntegerElem ();
-
- void copy (const int, Integer (MemoizedInteger::*Fn)(...), Integer*);
- int operator==(MemoizedIntegerElem&);
- MemoizedIntegerElem& operator=(MemoizedIntegerElem&);
- MemoizedIntegerElem& operator=(const Integer& I) { rep->Value = I; return *this; }
- operator Integer () { return rep->Value; }
-
- friend ostream& operator<<(ostream&, MemoizedIntegerElem&);
- };
-
- ostream& operator<<(ostream &strm, MemoizedIntegerElem &E)
- {
- strm << '[';
- for (int i = 0; i < E.rep->Arity; i++)
- strm << E.rep->Args[i] << ' ';
- strm << "=> " << E.rep->Value << ']';
- }
-
- _Mrep _nil_Mrep;
-
- MemoizedIntegerElem::MemoizedIntegerElem ()
- {
- rep = &_nil_Mrep;
- }
-
- MemoizedIntegerElem::MemoizedIntegerElem (MemoizedIntegerElem& E)
- {
- rep = E.rep;
- rep->ref++;
- }
-
- MemoizedIntegerElem::MemoizedIntegerElem (int arity,
- Integer (MemoizedInteger::*Fn)(...),
- Integer I, ...)
- {
- rep = &_nil_Mrep;
- copy (arity, Fn, &I);
- }
-
- void MemoizedIntegerElem::copy (const int arity,
- Integer (MemoizedInteger::*Fn)(...),
- Integer* pI)
- {
- if (rep == &_nil_Mrep)
- rep = new _Mrep (arity);
- else if (rep->ref > 1)
- {
- rep->ref--;
- rep = new _Mrep (arity);
- }
- else if (rep->Arity != arity)
- {
- delete rep;
- rep = new _Mrep (arity);
- }
- for (int i = 0; i < arity; i++)
- rep->Args[i] = pI[i];
- rep->Fn = Fn;
- }
-
- MemoizedIntegerElem::~MemoizedIntegerElem ()
- {
- if (rep != &_nil_Mrep && --rep->ref == 0) delete rep;
- }
-
- int MemoizedIntegerElem::operator==(MemoizedIntegerElem& 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;
- }
-
- MemoizedIntegerElem& MemoizedIntegerElem::operator=(MemoizedIntegerElem& E)
- {
- E.rep->ref++;
- if (rep != &_nil_Mrep && --rep->ref == 0) delete rep;
- rep = E.rep;
- return *this;
- }
-
- class MemoizedIntegerBase
- {
- int sz, start, finish;
- MemoizedIntegerElem *table;
- public:
- MemoizedIntegerBase (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];
- };
- ~MemoizedIntegerBase ()
- {
- if (start) delete [sz] table;
- else delete [finish] table;
- delete table;
- };
-
- int indexOf (MemoizedIntegerElem&);
- MemoizedIntegerElem& at (int i) { return table[i]; }
- MemoizedIntegerElem* add (MemoizedIntegerElem&);
- };
-
- MemoizedIntegerElem* MemoizedIntegerBase::add (MemoizedIntegerElem& 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;
- }
-
- int MemoizedIntegerBase::indexOf (MemoizedIntegerElem& E)
- {
- if (start)
- {
- for (int i = 0; i < sz; i++)
- {
- if (table[i] == E)
- return i;
- }
- }
- else
- {
- for (int i = 0; i < finish; i++)
- {
- if (table[i] == E)
- return i;
- }
- }
- return -1;
- }
-
- class MemoizedInteger : MemoizedIntegerBase
- {
- public:
- // wrappers
- Integer MemoizedInteger::() MemoizedInteger
- (int, Integer (MemoizedInteger::*)(Integer), Integer);
- Integer MemoizedInteger::() MemoizedInteger
- (int, Integer (MemoizedInteger::*)(Integer, Integer), Integer, Integer);
-
- // functions to be wrapped
- Integer factorial (Integer n);
- Integer fibonacci (Integer n);
- };
-
- Integer MemoizedInteger::()MemoizedInteger
- (int, Integer (MemoizedInteger::*pf_I)(Integer), Integer I)
- {
- MemoizedIntegerElem 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;
- }
-
- Integer MemoizedInteger::()MemoizedInteger
- (int, Integer (MemoizedInteger::*pf_I_I)(Integer, Integer), Integer I1, Integer I2)
- {
- MemoizedIntegerElem 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;
- }
-
- Integer MemoizedInteger::factorial(Integer n)
- {
- Integer f = 1;
- while (n > 0)
- {
- f *= n;
- --n;
- }
- return f;
- }
-
- Integer MemoizedInteger::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[])
- {
- _nil_Mrep.ref = (unsigned)(-1);
- int n;
- int size = (argc == 2 ? atoi (argv[1]) : 10);
-
- MemoizedInteger 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";
- }
- }
-