mud++0.35/etc/
mud++0.35/etc/guilds/
mud++0.35/help/propert/
mud++0.35/mudC/
mud++0.35/player/
mud++0.35/src/interface/
mud++0.35/src/os/cygwin32/
mud++0.35/src/os/win32/
mud++0.35/src/os/win32/bcppbuilder/
mud++0.35/src/osaddon/
mud++0.35/src/util/
/*
....[@@@..[@@@..............[@.................. 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