#ifndef __REFCOUNT_H__
#define __REFCOUNT_H__

class ReferenceCounted 
{
public:
	ReferenceCounted() { nReferences = 0; }
	mutable int nReferences;
private:
//	ReferenceCounted( const ReferenceCounted & );
	ReferenceCounted &operator=( const ReferenceCounted & );
};

template <class T> class Reference 
{
public:
	// Reference constructors
	Reference( T *p = 0 ) 
	{
		ptr = p;
		if ( ptr ) ++ptr->nReferences;
	}
	Reference( const Reference<T> &r ) 
	{
		ptr = r.ptr;
		if ( ptr ) ++ptr->nReferences;
	}
	// Reference assignment operators
	Reference &operator=( const Reference<T> &r ) 
	{
		return operator=( r.ptr );
	}
	Reference &operator=( T *p ) 
	{
		if (p) p->nReferences++;
		if ( ptr && --ptr->nReferences == 0 ) delete ptr;
		ptr = p;
		return *this;
	}
	// Reference destructor
	~Reference() 
	{
		if ( ptr && --ptr->nReferences == 0 )
			delete ptr;
	}
	// Reference operators
	const T *operator->() const { return ptr; }
	T *operator->() { return ptr; }
	const T *get() const { return ptr; }
	T *get() { return ptr; }
	operator bool() const { return ptr != NULL; }
	T *edit()
	{
		if ( !ptr )
		{
			ptr = new T();
			ptr->nReferences = 1;
		}
		else if ( ptr->nReferences > 1 )
		{
			ptr->nReferences--;
			ptr = new T( *ptr );
			ptr->nReferences = 1;
		}
		return ptr;
	}
private:
	T *ptr;
};

#endif //__REFCOUNT_H__
