/* ....[@@@..[@@@..............[@.................. 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