/////////////////////////////////////////////////////////////
// CINEMA 4D SDK                                           //
/////////////////////////////////////////////////////////////
// (c) 1989-2004 MAXON Computer GmbH, all rights reserved  //
/////////////////////////////////////////////////////////////

#ifndef _AUTOPTR_H_
#define _AUTOPTR_H_

#include "ge_math.h"
#include "c4d_memory.h"

template <class TYPE> class AutoAlloc
{
		TYPE *ptr;

	private:
		TYPE *operator = (TYPE *p);

	public:

		AutoAlloc()												{ ptr = TYPE::Alloc(); }
		AutoAlloc(LONG id)								{ ptr = TYPE::Alloc(id); }
		AutoAlloc(LONG p1, LONG p2)				{ ptr = TYPE::Alloc(p1,p2); }
		AutoAlloc(TYPE* initptr)					{ ptr = initptr; }
		~AutoAlloc()											{ TYPE::Free(ptr); ptr = NULL; }
		operator TYPE* () const						{ return ptr; }
		operator TYPE& () const						{ return *ptr; }
		TYPE *operator -> () const				{ return ptr; }
		TYPE *const *operator & () const	{ return &ptr; }
		TYPE *Release()										{ TYPE *tmp=ptr; ptr=NULL; return tmp; }
		void Free()												{ TYPE::Free(ptr); ptr=NULL; }
		void Assign(TYPE *p)							{ ptr=p; }
};

template <class TYPE> class AutoNew
{
		TYPE *ptr;

	private:
		TYPE *operator = (TYPE *p);

	public:

		AutoNew()													{ ptr = gNew TYPE; }
		~AutoNew()												{ gDelete(ptr); }
		operator TYPE* ()									{ return ptr; }
		operator TYPE& ()									{ return *ptr; }
		TYPE *operator -> () const				{ return ptr; }
		TYPE *const *operator & () const	{ return &ptr; }
		TYPE *Release()										{ TYPE *tmp=ptr; ptr=NULL; return tmp; }
		void Free()												{ gDelete(ptr); }
		void Assign(TYPE *p)							{ ptr=p; }
};

template <class TYPE> class AutoPtr
{
		TYPE *ptr;

	private:
		TYPE *operator = (TYPE *p);

	public:

		AutoPtr(TYPE *p)									{ ptr = p; }
		~AutoPtr()												{ gDelete(ptr); }
		operator TYPE* () const						{ return ptr; }
		operator TYPE& () const						{ return *ptr; }
		TYPE *operator -> () const				{ return ptr; }
		TYPE *const *operator & () const	{ return &ptr; }
		TYPE *Release()										{ TYPE *tmp=ptr; ptr=NULL; return tmp; }
		void Free()												{ gDelete(ptr); }
		void Assign(TYPE *p)							{ ptr=p; }
};

template <class TYPE> class AutoFree
{
		TYPE *ptr;

	private:
		TYPE *operator = (TYPE *p);

	public:

		AutoFree()												{ ptr = NULL; }
		AutoFree(TYPE* p)									{ ptr = p; }
		~AutoFree()												{ TYPE::Free(ptr); ptr = NULL; }
    void Set(TYPE* p)									{ ptr = p; }
		operator TYPE* () const						{ return ptr; }
		operator TYPE& () const						{ return *ptr; }
		TYPE *operator -> () const				{ return ptr; }
		TYPE *const *operator & () const	{ return &ptr; }
		TYPE *Release()										{ TYPE *tmp=ptr; ptr=NULL; return tmp; }
		void Free()												{ TYPE::Free(ptr); ptr=NULL; }
		void Assign(TYPE *p)							{ ptr=p; }
};

#endif
