#pragma once
// Pointer to <> classes, without neccessary compiler support for template
// specialization
#ifndef PVECT_DECL_SPEC
#define PVECT_DECL_SPEC
#endif
  #ifndef max
#define max(a, b) ( (a) > (b) ? (a) : (b) )
#define ownmax
#endif
  #ifndef min
#define min(a, b) ( (a) < (b) ? (a) : (b) )
#define ownmin
#endif
  class PVECT_DECL_SPEC pvoidvect
{
public:
	// These data members are made public here so that the vector can be used as a plain array.
	void** data;
	int count;
	int capacity;
  	pvoidvect(void)
	{
		count = 0;
		capacity = 0;
		data = NULL;
	}
	explicit pvoidvect(int _reserve)
	{
		count = 0;
		capacity = 0;
		data = NULL;
		reserve(_reserve);
	}
	
	// copy constructor
	pvoidvect(const pvoidvect& b)
	{
		data = NULL;
		capacity = 0;
		count = 0;
		if (b.count > 0) {
			reserve(b.count);
			memcpy(data, b.data, sizeof(void*)*b.count);
		}
		count = b.count;
	}
  	~pvoidvect(void)
	{
		if (data)
			delete []data;
	}
	pvoidvect& operator=(const pvoidvect &b) 
	{
		if (b.count > 0) 
		{
			reserve(b.count);
			memcpy(data, b.data, sizeof(void*)*b.count);
		}
		count = b.count;
		return *this;
	}
  	// safe set. Will resize if neccessary
	void set(int pos, const void* a) {
		if (pos >= count) {
			// Do we need to resize, or can we just up our count?
			if (pos >= capacity) 
				resize(pos+1);
			else
				count = pos+1;
		}
		data[pos] = const_cast<void*>(a);
	}
  	void insert(int pos, const void* a) 
	{
		if (pos >= capacity || count+1 > capacity)
			reserve(max(capacity*2, pos+4));
		//if (pos >= count)
		//	count = pos+1;
		int nmove = count - pos;
		if (nmove > 0)
			memmove(&(data[pos+1]), &(data[pos]), nmove*sizeof(void*));
		data[pos] = const_cast<void*>(a);
		count++;
	}
  	void erase(int pos1, int pos2 = -1) 
	{
		if (pos2 == -1) 
			pos2 = pos1;
		int nmove = (count - pos2) - 1;
		if (nmove > 0)
			memmove(&(data[pos1]), &(data[pos2+1]), nmove*sizeof(void*));
		count -= 1 + (pos2 - pos1);
	}
  	// Grift....
	void* pop_back() 
	{
		if (count > 0)
			count--;
		return data[count];
	}
  	void push_back(const void* a) 
	{
		if (count >= capacity)
			reserve(capacity*2);
		data[count++] = const_cast<void*>(a);
	}
	const void* operator[](int i) const 
	{
		return data[i];
	}
  	void*& operator[](int i) 
	{
		return data[i];
	}
	//void*& v(int i) {
	//	return data[i];
	//}
	void* back() const 
	{
		return data[count-1];
	}
	void*& back() 
	{
		return data[count-1];
	}
  	// returns -1 on failure
	int find( const void* t ) const
	{
		for (int i = 0; i < count; i++)
			if (data[i] == t) return i;
		return -1;
	}
  	void clear() 
	{
		if (data)
			delete []data;
		data = NULL;
		count = 0;
		capacity = 0;
	}
	int size() const 
	{
		return count;
	}
	// preserves existing entities but doesn't set count
	void reserve(int newsize) 
	{
		int oc = count;
		resize(max(newsize, count));
		count = oc;
	}
	// preserves existing entities and sets count to newsize
	void resize(int newsize) 
	{
		int ocount = count;
		count = newsize;
		if (newsize == 0) newsize = 2;
		void** nd = new void*[newsize];
		if (ocount > 0) 
			memcpy(nd, data, sizeof(void*)*min(ocount, newsize));
		if (data) 
			delete []data;
		data = nd;
		capacity = newsize;
	}
};
  
template < class T > class PVECT_DECL_SPEC pvect : public pvoidvect
{
public:
	typedef pvoidvect Base;
  	pvect() : Base() {}
  	explicit pvect(int reserve) : Base(reserve) {}
  	pvect(const pvect& b) : Base(b) {}
  	pvect& operator=(const pvect &b) { return (pvect&) Base::operator=(b); }
  	void set(int pos, const T* a) { Base::set(pos,a); }
  	void insert(int pos, const T* a) { Base::insert(pos, a); }
  	void erase(int pos1, int pos2 = -1) { Base::erase(pos1, pos2); }
  	T* pop_back() { return static_cast<T*>(Base::pop_back()); }
  	void push_back(const T* a) { Base::push_back(a); }
  	const T* operator[](int i) const { return static_cast<const T*>(Base::operator[](i)); }
  	T*& operator[](int i) { return (T*&) Base::operator[](i); }
  	//T*& operator[](int i) { return static_cast<T*&>( Base::v(i) ); }
	T* back() const { return static_cast<T*>(Base::back()); }
  	int find( const T* a ) const { return Base::find(a); }
  	void clear() { Base::clear(); }
  	void deleteall() 
	{ 
		for (int i = 0; i < count; i++) 
			delete static_cast<T*>( data[i] );
		clear();
	}
  	int size() const { return Base::size(); }
  	void reserve(int newsize) { Base::reserve(newsize); }
  	void resize(int newsize) { Base::resize(newsize); }
};
  
#ifdef ownmax
#undef max
#undef ownmax
#endif
  #ifdef ownmin
#undef min
#undef ownmin
#endif
     |