DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T t

⟦a38a4178c⟧ TextFile

    Length: 5765 (0x1685)
    Types: TextFile
    Names: »twrapper.cc«

Derivation

└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89
    └─⟦cc8755de2⟧ »./libg++-1.36.1.tar.Z« 
        └─⟦23757c458⟧ 
            └─⟦this⟧ »libg++/tests/twrapper.cc« 

TextFile

/*
 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";
    }
}