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

		MCPtr.h
		Copyright: (c) 2001 Eovia Corp. All rights reserved.

		Author:	Charles
		Date:	12/10/2001

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

#ifndef __MCPtr__
#define __MCPtr__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "MCAssert.h"


/// \addtogroup MCCore
/// \{

/// TMCPtr is simply a wrapper around a regular pointer. 
/// The constructor initializes the pointer to NULL (so you'll never forget it).
/// Several operators are overridden so that the wrapper becomes transparent while still providing asserts
/// that verify as much as possible if the pointer is valid.
///
template <class T> class TMCPtr : public TMCObject
{	
public:
	explicit TMCPtr(T* ptr=NULL)
	{
		fObject=ptr;
	}

	TMCPtr(const TMCPtr<T>& ptr)
	{
		fObject=ptr.fObject;
	}

	~TMCPtr()
	{
	}

	T* operator=(T* ptr)
	{
		return (fObject = ptr);
		//MCNotify("this method should be overriden in derived class");
	}

	boolean operator==(const T* ptr) const
	{
		return (ptr == fObject);
	}

	boolean operator==(T* ptr) const
	{
		return (ptr == fObject);
	}


	T& operator*() const
	{
		MCAssertPointerCheck(fObject);
		MCAssert(fObject && !MCCheckDeceased(*(void**)fObject));
		return *fObject;
	}
	T* operator->() const
	{
		MCAssertPointerCheck(fObject);
		MCAssert(fObject && !MCCheckDeceased(*(void**)fObject));
		return fObject;
	}
	T** operator&() 
	{ 
		MCAssert(!MCCheckDeceased(fObject));
		MCAssert((fObject == NULL) || !MCCheckDeceased(*(void**)fObject));
		return &fObject;
	}
	T*const* operator&() const
	{ 
		MCAssert(!MCCheckDeceased(fObject));
		MCAssert((fObject == NULL) || !MCCheckDeceased(*(void**)fObject));
		return &fObject;
	}
	boolean operator!()
	{	
		return (fObject == NULL);
	}
	operator T*() const
	{ 
		MCAssert(!MCCheckDeceased(fObject));
		MCAssert((fObject == NULL) || !MCCheckDeceased(*(void**)fObject));
		return (T*)fObject;
	}
protected:
	T*			fObject;
};

/// \}




#endif
