/*
....[@@@..[@@@..............[@.................. MUD++ is a written from
....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and
....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++.
....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing
....[@......[@..[@@@@@..[@@@@@.................. development project. All
................................................ contributions are welcome.
....Copyright(C).1995.Melvin.Smith.............. Enjoy.
------------------------------------------------------------------------------
Melvin Smith (aka Fusion) msmith@hom.net
MUD++ development mailing list mudpp@van.ml.org
------------------------------------------------------------------------------
array.h
*/
#ifndef _ARRAY_H
#define _ARRAY_H
#include "erratum.h"
#include "streamable.h"
#include "io.h"
#define DEBUG_ARRAY 1
const int DEFAULT_SIZE = 10;
const int DEFAULT_DELTA = 5;
template < class T >
class Array : public Streamable
{
private:
T * table;
int count; // how many important elements array has
int size; // real size of array
int delta; // how much will the array grow when needed
int focus; // for llist like interface 'current'
public:
Array()
: count(0), size( DEFAULT_SIZE ), delta( DEFAULT_DELTA )
{
table = new T[size];
}
Array( int siz, int del)
: count(0), size(siz), delta(del)
{
table = new T[size];
}
Array( const Array & x )
: count(x.count), size(x.size), delta(x.delta)
{
table = new T[size];
memcpy ( table, x.table, count * sizeof(T) );
}
~Array() { delete table; }
T & operator[]( int );
int length() const { return count; }
int getDelta() const { return delta; }
void setDelta(int i ) { delta = i; }
void add( const T & );
void add( const T * obj) { add( *obj ); }
T getAt( int ) const;
void remove( int );
T removeTop();
void insert( int, const T & );
void insert( int index, const T * obj ) { insert(index,*obj); }
void clr() { count = 0; }
void trim();
void grow( int );
void ensureCapacity();
// LList interface to allow use of lovely for_each
void reset() { focus = 0; }
void next() { focus++; }
T & peek() { return operator[](focus); }
void destroyList();
bool elementAtFocus() { return (focus < count); }
bool hasMoreElements() { return (focus < (count-1)); }
virtual int readFrom( StaticInput & );
virtual int writeTo( Output & ) const;
};
template < class T >
inline void Array< T >::ensureCapacity()
{
if ( count > size )
{
T * ntable = new T[size+delta];
memcpy( ntable, table, size * sizeof(T) );
size += delta;
delete table;
table = ntable;
}
}
template < class T >
inline T & Array< T >::operator[]( int index )
{
#ifdef DEBUG_ARRAY
if ( index >= count )
Error::dumpf("Array index %d out of bounds(count = %d)", index, count);
#endif
return table[index];
}
template <class T>
inline T Array< T >::getAt( int index ) const
{
#ifdef DEBUG_ARRAY
if ( index >= count )
Error::dumpf("Array index %d out of bounds(count = %d)", index, count);
#endif
return table[index];
}
template <class T>
inline void Array< T >::add( const T & obj )
{
count++;
ensureCapacity();
table[count-1] = obj;
}
template < class T >
inline T Array< T >::removeTop()
{
#ifdef DEBUG_ARRAY
if ( count <= 0 )
Error::dump("Tried to removeTop from empty array");
#endif
count--;
return table[count];
}
template < class T >
class ArrayEnumerator
{
private:
const Array< T > * array;
int focus;
int count;
public:
ArrayEnumerator( const Array<T> & ar )
: array(&ar), focus(0), count(ar.length())
{
}
void reset() { focus = 0; }
void next() { focus++; }
T peek() { return array->getAt(focus); }
bool elementAtFocus() { return (focus < count); }
bool hasMoreElements() { return (focus < (count-1)); }
};
#endif // ARRAY_H