blob: 183ff81eab749fbb13bee8c2847320f155195947 [file] [log] [blame]
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Written by Ashok Sreenivasan, TRDDC, Pune, India. 1993. May be
// distributed freely, provided this comment is displayed at the top.
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#include "onlyobj.h"
static int strlen(char *str1) {return 0;}
static int strcmp(char *str1, char *str2) {return 0;}
static char *strcpy(char *str1, char *str2) {return "";}
static char *strncpy(char *str1, char *str2, int i) {return "";}
static char *strcat(char *str1, char *str2) {return "";}
#include "artest.h"
#define abs(x) ((x) > 0 ? (x) : (-x))
// The search function for a table searches for the element linearly and
// returns the index of the element in the list. If not found, a -1 is
// returned. The comparison of objects is done through the '==' operator.
int Table::Search (Object &obj)
{
for (int i = 0; i < nelem; i++)
if (obj == * (Get(i)))
return i;
return -1;
}
// The table == operator is used to check for equality of tables themselves!
// This operator checks first if the types of the two tables are the same,
// then if the no. of elements are the same, and finally if each and every
// element is the same. Only then are the tables deemed equal. Note that
// if the tables are large, this could be an expensive operation.
int Table::operator == (Object &tblobj)
{
char *a;
if (strcmp (a=tblobj.Type (), Type ())) // Type check
return 0;
Table *tblptr = (Table *) &tblobj;
if (tblptr->Nelem () == nelem) // Count check
{
Object *b;
for (int i = 0; i < nelem; i++)
if (*(b=tblptr->Get (i)) != *(Get(i))) // Elementwise check
return 0;
}
else
return 0;
return 1;
}
// The array constructor allocates the reqd space and initialises the elems
// explicitly to NULL.
Array::Array (int sz, enum TblType t) : Table (t)
{
array = new Objp [sz];
size = sz;
for (int i = 0; i < sz; i++) // Explicitly NULLify
array [i] = 0;
}
// The array destructor - deletes the elements from the rightmost to leftmost
// first. Once the elements are rid, the array pointer itself is deleted.
Array::~Array ()
{
if (type == VOLAT)
{
for (int i = nelem - 1; i >= 0; i--)
Remove (i);
}
if (array)
{
delete array;
array = 0;
}
Init ();
}
// The array append function increments nelem and sets curind and adds the
// passed element at the end. Appending to an empty array is an error.
int Array::Append (Object *o)
{
if (nelem == size)
return 0;
array [curind = nelem] = o;
nelem ++;
return 1;
}
// The Array insert function inserts the object at the given position and
// moves the objects to the right by one position as required. Cannot insert
// far to the right of rightmost element. Returns a boolean success / fail
// value. Insertion also fails when the array is full.
int Array::Insert (Object *obj, int pos)
{
if (pos > nelem || pos < 0 || nelem >= size)
return 0;
for (int i = nelem; i > pos; i--)
array [i] = array [i - 1]; // Move objects right.
array [pos] = obj;
nelem ++;
curind = pos;
return 1;
}
// The Array assign function overwrites the object at the given position with
// the passed object if the passed position is valid.
int Array::Assign (Object *obj, int pos)
{
if (pos > nelem || pos < 0 || nelem >= size)
return 0;
if (pos == nelem)
nelem ++; // Adding new element
array [curind = pos] = obj;
return 1;
}
// The array get function just performs a simple array access on the array
// after validating bounds.
Object *Array::Get (int idx)
{
if (idx >= nelem || idx < 0)
return 0;
curind = idx;
return array [idx];
}
// The Fetch function gets an object from a list and returns it to the caller
// without deleting it. It also takes care of shifting elements
// appropriately etc.
Object *Array::Fetch (int idx)
{
if (idx >= nelem || idx < 0)
return 0;
Object *ret = Get (idx);
for (int i = idx; i < nelem - 1; i++)
array [i] = array [i + 1];
array [nelem - 1] = 0;
if (idx == nelem - 1) // Right most element
curind = idx - 1;
else
curind = idx;
nelem --;
return ret;
}
// The assign function is the only way to add / overwrite elements in a
// sparse array. It just overwrites the element in the position with the new
// object, while deleting the old one if one existed.
int SpArray::Assign (Object *o, int pos)
{
if (pos >= size || pos < 0)
return 0;
if (array [pos] == 0)
nelem ++; // increase element count
array [curind = pos] = o;
return 1;
}
// The Get function gets the required array element and returns it.
Object *SpArray::Get (int idx)
{
if (idx >= size || idx < 0)
return 0;
curind = idx;
return array [idx];
}
// The Fetch function just gets an array element and returns it, and forgets
// it from the sparse array.
Object *SpArray::Fetch (int pos)
{
Object *ret = Get (pos);
if (ret) // Location was occupied
{
array [pos] = 0;
if (pos == nelem - 1)
curind = pos - 1;
else
curind = pos;
nelem --;
}
return ret;
}
// Search all the elements in the array - as nelem is no limiting factor !
int SpArray::Search (Object &o)
{
for (int i = 0; i < size; i++)
{
Object *p = array [i];
if (p != 0) // Location is occupied
if (*p == o)
return i;
}
return -1;
}
// The sparse array destructor - deletes the elements from the rightmost to
// leftmost first. Once the elements are rid, the array pointer itself is
// deleted.
SpArray::~SpArray ()
{
if (type == VOLAT)
{
for (int i = size - 1; i >= 0; i--)
if (array [i] != 0)
Remove (i);
}
if (array)
{
delete array;
array = 0;
}
Init ();
}
class A : public Object
{
public :
int operator == (Object &o)
{ char *a;
if (strcmp (a=o.Type (),Type ())) return 0;
return i == ((A&)o).i; }
char *Type () { return "A"; }
A (int j = 0) : i(j) {}
operator int () { return i; }
~A () {}
protected :
int i;
};
class B : public A
{
public :
int operator == (Object &o)
{ char *a;
if (strcmp (a=o.Type (),Type ())) return 0;
return j == ((B&)o).j; }
char *Type () { return "B"; }
B (int j=0) {}
operator int () { return j; }
~B () {}
protected :
int j;
};
int main ()
{
A *a1 = new A(1);
A *a2 = new A(2);
A *a3;
Array *ar = new Array(3,VOLAT);
SpArray *sar = new SpArray(3,VOLAT);
Array *a;
if (0)
a = ar;
else
a = sar;
a->Assign(a1);
a->Assign(a2, 2);
a3 = (A *)a->Fetch(2);
a3->Type();
}