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

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

		Author:	Arnaud
		Date:	3/2/2006

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

#ifndef __MCConstPtr__
#define __MCConstPtr__

#if CP_PRAGMA_ONCE
#pragma once
#endif


#include "MCAssert.h"


/// \addtogroup MCCore
/// \{

/// TMCConstPtr is simply a wrapper around a regular const 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 TMCConstPtr : public TMCObject
{	
public:
	explicit TMCConstPtr(const T* ptr=NULL)
	{
		fObject=ptr;
	}

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

	~TMCConstPtr()
	{
	}

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

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

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


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

/// \}




#endif
