//	SimpleVector.h                                      JJS  5/26/97//	http://www.strout.net/macdev///	a simple replacement for the old STL vector template class#ifndef __SIMPLEVECTOR_H#define __SIMPLEVECTOR_H// declare return type for bufbytes -- Size is defined in <Types.h>#ifndef _SIZE_T_DEFINED#include <size_t.h>#endiftemplate <class T>class SimpleVector {  public:	// constructors	inline SimpleVector();						// sets size to 0	inline SimpleVector(const short n);			// allocates n slots	inline SimpleVector(const SimpleVector<T>&);	// copy-constructor (copies data)	// assignment-op	inline SimpleVector& operator=(const SimpleVector<T>&);	// (copies data)	// destructor	inline ~SimpleVector();		// inspectors	inline unsigned short size() const;			// get number of items	inline unsigned short bufitems() const;		// number of items the buffer can hold	inline size_t bufbytes() const;				// size of buffer in bytes		// treating it like an array	inline T& operator[](const short idx);		// get item reference by index	inline T& operator[](const short idx) const;		// treating it like a stack	inline void push_back(const T& item);		// push onto end of the vector	inline T pop_back();						// get last item, remove from vector		// other ways to delete items	inline void deleteIdx(const short idx);		// delete an item by its index	inline void deleteAll();					// delete all items			// buffer management	inline void resize(const short n);			// allocate n slots, keeping current data	unsigned short mBlockItems;		// number of items to allocate when we expand  protected:	T *mBuf;						// array of items	unsigned short mQtyItems;		// how many items we actually have	unsigned short mBufItems;		// number of items the buffer can hold};#define VecIterate(var,vec) for (short var=0;var<vec.size();var++)#define VecReverseIterate(var,vec) for (short var=vec.size()-1;var>=0;var--)template <class T>inline SimpleVector<T>::SimpleVector(): mBlockItems(16), mBufItems(0), mBuf(0), mQtyItems(0){}template <class T>inline SimpleVector<T>::SimpleVector(const short n): mBlockItems(16), mBufItems(n), mQtyItems(n){	mBuf = new T[mBufItems];	if (!mBuf) {		throw memFullErr;	}}template <class T>inline SimpleVector<T>::SimpleVector(const SimpleVector<T>& vec): mBufItems(0), mBuf(0){	*this = vec;}	template <class T>inline SimpleVector<T>& SimpleVector<T>::operator=(const SimpleVector<T>& vec){	if (mBuf) delete[] mBuf;	mBlockItems = vec.mBlockItems;	mBufItems = vec.mBufItems;	mQtyItems = vec.mQtyItems;	mBuf = new T[mBufItems];	if (!mBuf) {		throw memFullErr;	}	BlockMove( vec.mBuf, mBuf, vec.bufbytes() );	return *this;}template <class T>inline SimpleVector<T>::~SimpleVector(){	if (mBuf) delete[] mBuf;}template <class T>inline unsigned short SimpleVector<T>::size() const{	return mQtyItems;}template <class T>inline unsigned short SimpleVector<T>::bufitems() const{	return mBufItems;}template <class T>inline size_t SimpleVector<T>::bufbytes() const{	return mBufItems * sizeof(T);}template <class T>inline T& SimpleVector<T>::operator[](const short idx){	if (idx < 0) throw memAdrErr;	/***	   NOTE: the buffer is no longer grown automatically when you refer	   to an index beyond the buffer size; it was pointed out that this	   makes for confusing code.  Instead, explicitly resize() your	   buffer, or use push_back to add items. 	   	if (idx >= mBufItems) {		// an item beyond the buffer size was requested;		// increase the buffer to accomodate		unsigned short qtyToAdd = (1 + (idx-mBufItems)/mBlockItems) * mBlockItems;		resize( mBufItems + qtyToAdd );	}	****/	if (idx >= mBufItems) throw memAdrErr;		// if the item requested is beyond the "top" item of the stack metaphor,	// increase that up to the requested point	if (idx >= mQtyItems) mQtyItems = idx+1;	return mBuf[idx];}template <class T>inline T& SimpleVector<T>::operator[](const short idx) const{	if (idx < 0 || idx >= mBufItems) throw memAdrErr;	return mBuf[idx];}template <class T>inline void SimpleVector<T>::push_back(const T& item){	// do we need to increase the buffer size?	while (mQtyItems >= mBufItems) {		// yes -- expand it by one block (should never need more than that!)		resize( mBufItems + mBlockItems );	}	// stuff the item	mBuf[mQtyItems] = item;	mQtyItems++;}template <class T>inline T SimpleVector<T>::pop_back(){	if (mQtyItems > mBufItems || mQtyItems <= 0) throw memAdrErr;	return mBuf[--mQtyItems];}template <class T>inline void SimpleVector<T>::deleteIdx(const short idx){	if (idx < 0 || idx >= mQtyItems) throw memAdrErr;	if (idx == mQtyItems-1) {		// special case -- deleting last item, no need to copy		mQtyItems -= 1;	} else {		// if deleting any but the last item, move remaining ones down		BlockMove(	&mBuf[idx+1],							// source					&mBuf[idx],								// dest					sizeof(T) * (mQtyItems - idx - 1) );		// bytes		mQtyItems -= 1;	}	// now check -- should we shrink the buffer down?						// do so if the unused spaces are more than twice the block size	unsigned short unused = (mBufItems - mQtyItems);	if (unused > mBlockItems*2) {		unsigned short newqty = (1 + mQtyItems / mBlockItems) * mBlockItems;		resize(newqty);	}}template <class T>inline void SimpleVector<T>::deleteAll(){	delete[] mBuf;	mBuf = 0;	mBufItems = mQtyItems = 0;}template <class T>inline void SimpleVector<T>::resize(const short n){	if (n == mBufItems) return;	T *newbuf = new T[n];	if (!newbuf) throw memFullErr;	if (mBuf) {		BlockMove(	mBuf,								// source					newbuf,								// dest					sizeof(T) * mQtyItems );			// bytes		delete[] mBuf;	}	mBuf = newbuf;	mBufItems = n;}#endif