|
|
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: 5765 (0x1685)
Types: TextFile
Names: »twrapper.cc«
└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89
└─⟦cc8755de2⟧ »./libg++-1.36.1.tar.Z«
└─⟦23757c458⟧
└─⟦this⟧ »libg++/tests/twrapper.cc«
/*
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 << ']';
return strm;
}
_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 : public 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";
}
}