Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TSMARTPOINTER_INCLUDED
Toshihiro Shimizu 890ddd
#define TSMARTPOINTER_INCLUDED
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tutil.h"
Toshihiro Shimizu 890ddd
#include "tatomicvar.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#undef DVAPI
Toshihiro Shimizu 890ddd
#undef DVVAR
Toshihiro Shimizu 890ddd
#ifdef TNZCORE_EXPORTS
Toshihiro Shimizu 890ddd
#define DVAPI DV_EXPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_EXPORT_VAR
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define DVAPI DV_IMPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_IMPORT_VAR
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef NDEBUG
Toshihiro Shimizu 890ddd
#define INSTANCE_COUNT_ENABLED
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class DVAPI TSmartObject
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TAtomicVar m_refCount;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef INSTANCE_COUNT_ENABLED
Toshihiro Shimizu 890ddd
	const TINT32 m_classCodeRef;
Toshihiro Shimizu 890ddd
	static const TINT32 m_unknownClassCode;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	typedef short ClassCode;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TSmartObject(ClassCode
Toshihiro Shimizu 890ddd
#ifdef INSTANCE_COUNT_ENABLED
Toshihiro Shimizu 890ddd
					 classCode
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
				 )
Toshihiro Shimizu 890ddd
		: m_refCount()
Toshihiro Shimizu 890ddd
#ifdef INSTANCE_COUNT_ENABLED
Toshihiro Shimizu 890ddd
		  ,
Toshihiro Shimizu 890ddd
		  m_classCodeRef(classCode)
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
#ifdef INSTANCE_COUNT_ENABLED
Toshihiro Shimizu 890ddd
		incrementInstanceCount();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TSmartObject()
Toshihiro Shimizu 890ddd
		: m_refCount()
Toshihiro Shimizu 890ddd
#ifdef INSTANCE_COUNT_ENABLED
Toshihiro Shimizu 890ddd
		  ,
Toshihiro Shimizu 890ddd
		  m_classCodeRef(m_unknownClassCode)
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
#ifdef INSTANCE_COUNT_ENABLED
Toshihiro Shimizu 890ddd
		incrementInstanceCount();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	virtual ~TSmartObject()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(m_refCount == 0);
Toshihiro Shimizu 890ddd
#ifdef INSTANCE_COUNT_ENABLED
Toshihiro Shimizu 890ddd
		decrementInstanceCount();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	inline void addRef()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		++m_refCount;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	inline void release()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if ((--m_refCount) <= 0)
Toshihiro Shimizu 890ddd
			delete this;
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
	inline TINT32 getRefCount() const { return m_refCount; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	static TINT32 getInstanceCount(ClassCode code);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	void incrementInstanceCount();
Toshihiro Shimizu 890ddd
	void decrementInstanceCount();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	// not implemented
Toshihiro Shimizu 890ddd
	TSmartObject(const TSmartObject &);
Toshihiro Shimizu 890ddd
	TSmartObject &operator=(const TSmartObject &);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define DECLARE_CLASS_CODE                                  \
Toshihiro Shimizu 890ddd
private:                                                    \
Toshihiro Shimizu 890ddd
	static const TSmartObject::ClassCode m_classCode;       \
Toshihiro Shimizu 890ddd
                                                            \
Toshihiro Shimizu 890ddd
public:                                                     \
Toshihiro Shimizu 890ddd
	inline static TINT32 getInstanceCount()                 \
Toshihiro Shimizu 890ddd
	{                                                       \
Toshihiro Shimizu 890ddd
		return TSmartObject::getInstanceCount(m_classCode); \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define DEFINE_CLASS_CODE(T, ID) \
Toshihiro Shimizu 890ddd
	const TSmartObject::ClassCode T::m_classCode = ID;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
class DVAPI TSmartPointerT
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
protected:
Toshihiro Shimizu 890ddd
	T *m_pointer;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	TSmartPointerT() : m_pointer(0) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TSmartPointerT(const TSmartPointerT &src) : m_pointer(src.m_pointer)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_pointer)
Toshihiro Shimizu 890ddd
			m_pointer->addRef();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TSmartPointerT(T *pointer) : m_pointer(pointer)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_pointer)
Toshihiro Shimizu 890ddd
			m_pointer->addRef();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	virtual ~TSmartPointerT()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_pointer) {
Toshihiro Shimizu 890ddd
			m_pointer->release();
Toshihiro Shimizu 890ddd
			m_pointer = 0;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TSmartPointerT &operator=(const TSmartPointerT &src)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		// prima addRef  e poi release per evitare brutti scherzi
Toshihiro Shimizu 890ddd
		// in caso di parentela
Toshihiro Shimizu 890ddd
		T *old = m_pointer;
Toshihiro Shimizu 890ddd
		m_pointer = src.m_pointer;
Toshihiro Shimizu 890ddd
		if (m_pointer)
Toshihiro Shimizu 890ddd
			m_pointer->addRef();
Toshihiro Shimizu 890ddd
		if (old)
Toshihiro Shimizu 890ddd
			old->release();
Toshihiro Shimizu 890ddd
		return *this;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	T *operator->() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(m_pointer);
Toshihiro Shimizu 890ddd
		return m_pointer;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	T &operator*() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(m_pointer);
Toshihiro Shimizu 890ddd
		return *m_pointer;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	T *getPointer() const { return m_pointer; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool operator!() const { return m_pointer == 0; }
Toshihiro Shimizu 890ddd
	operator bool() const { return m_pointer != 0; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool operator==(const TSmartPointerT &p) const { return m_pointer == p.m_pointer; }
Toshihiro Shimizu 890ddd
	bool operator!=(const TSmartPointerT &p) const { return m_pointer != p.m_pointer; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool operator<(const TSmartPointerT &p) const { return m_pointer < p.m_pointer; }
Toshihiro Shimizu 890ddd
	bool operator>(const TSmartPointerT &p) const { return m_pointer > p.m_pointer; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class base="" class="" derived,=""></class>
Toshihiro Shimizu 890ddd
class DVAPI TDerivedSmartPointerT : public TSmartPointerT<derived></derived>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	typedef TDerivedSmartPointerT<derived, base=""> DerivedSmartPointer;</derived,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TDerivedSmartPointerT(){};
Toshihiro Shimizu 890ddd
	TDerivedSmartPointerT(DERIVED *pointer) : TSmartPointerT<derived>(pointer) {}</derived>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TDerivedSmartPointerT(const TSmartPointerT<base> &p)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TSmartPointerT<derived>::m_pointer = dynamic_cast<derived *="">(p.getPointer());</derived></derived>
Toshihiro Shimizu 890ddd
		if (TSmartPointerT<derived>::m_pointer)</derived>
Toshihiro Shimizu 890ddd
			TSmartPointerT<derived>::m_pointer->addRef();</derived>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif