#ifndef CPP_DATASTRUCTURES_GENARRAYLIST_H
#define CPP_DATASTRUCTURES_GENARRAYLIST_H

// Eine Liste auf der dynamischen Array Klasse gen_array aufbauend
//
// Auf die Liste kann man wie auf ein Array (gen_array) zugreifen, allerdings
// auch einige typische Listenoperatoren anwenden.
//
// Achtung: Ein Schreibzugriff auf einen größeren Index, als die Liste
// lang ist, verglängert nicht automatisch die Liste. Diese wird nur durch
// die Listenoperationen verlängert und verkürzt.
//
// Autor: Jochen Becher
//
// Historie:
// Version 1.0 am 25. Juni 94

#ifndef CPP_DATASTRUCTURES_GENARRAY_H
#include <classes/datastructures/genarray.h>
#endif

class gen_arraylist : public gen_array {
public:
	gen_arraylist(ULONG es, ULONG s = 16) throw (MemoryX);
	// die wirkliche Länge der Liste
	ULONG length() const { return top; };
	VOID &addTail() throw (MemoryX);
	VOID &insert(ULONG index) throw (MemoryX);
	VOID remove(ULONG index) throw (MemoryX);
	VOID remTail();
	VOID clear();
private:
	ULONG top;
};

class gen_arraycursor {
public:
	gen_arraycursor(gen_arraylist &);
	VOID first();
	VOID last();
	VOID next();
	VOID prev();
	VOID &item() throw (MemoryX);
	BOOL isDone();
private:
	gen_arraylist *list;
	LONG pos;
};

template <class T> class arraylist : private gen_arraylist {
friend class arraycursor<T>;
public:
	arraylist(ULONG s = 16) throw (MemoryX);
	ULONG count() { return gen_arraylist::count(); };
	ULONG length() const { return gen_arraylist::length(); };
	T &operator[] (ULONG i) throw (MemoryX);
	T &addTail() throw (MemoryX);
	T &insert(ULONG index) throw (MemoryX);
	VOID remove(ULONG index) throw (MemoryX);
	VOID remTail() { gen_arraylist::remTail(); };
	VOID clear() { gen_arraylist::clear(); };
};

template <class T> class arraycursor : private gen_arraycursor {
public:
	arraycursor(arraylist<T> &l);
	VOID first() { gen_arraycursor::first(); };
	VOID last() { gen_arraycursor::last(); };
	VOID next() { gen_arraycursor::next(); };
	VOID prev() { gen_arraycursor::prev(); };
	T &item() throw (MemoryX);
	BOOL isDone() const { return gen_arraycursor::isDone(); };
};

// *************************************************************

template <class T> arraylist<T>::arraylist(ULONG s)
	: gen_arraylist(sizeof(T),s)
{
}

template <class T> T &arraylist<T>::operator[] (ULONG i)
{
	return (T &) gen_array::operator[] (i);
}

template <class T> T &arraylist<T>::addTail()
{
	return (T &) gen_arraylist::addTail();
}

template <class T> T &arraylist<T>::insert(ULONG index)
{
	return (T &) gen_arraylist::insert(index);
}

template <class T> VOID arraylist<T>::remove(ULONG index)
{
	gen_arraylist::remove(index);
}

// *************************************************************

template <class T> arraycursor<T>::arraycursor(arraylist<T> &l)
	: gen_arraycursor((gen_arraylist &) l)
{
}

template <class T> T &arraycursor<T>::item()
{
	return (T &) gen_arraycursor::item();
}

#endif
