|
Shinya Kitaoka |
810553 |
#pragma once
|
|
Shinya Kitaoka |
810553 |
|
|
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 |
|
|
Shinya Kitaoka |
120a6e |
class DVAPI TSmartObject {
|
|
Shinya Kitaoka |
120a6e |
TAtomicVar m_refCount;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef INSTANCE_COUNT_ENABLED
|
|
Shinya Kitaoka |
120a6e |
const TINT32 m_classCodeRef;
|
|
Shinya Kitaoka |
120a6e |
static const TINT32 m_unknownClassCode;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
typedef short ClassCode;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSmartObject(ClassCode
|
|
Toshihiro Shimizu |
890ddd |
#ifdef INSTANCE_COUNT_ENABLED
|
|
Shinya Kitaoka |
120a6e |
classCode
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
)
|
|
Shinya Kitaoka |
120a6e |
: m_refCount()
|
|
Toshihiro Shimizu |
890ddd |
#ifdef INSTANCE_COUNT_ENABLED
|
|
Shinya Kitaoka |
120a6e |
, m_classCodeRef(classCode)
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Toshihiro Shimizu |
890ddd |
#ifdef INSTANCE_COUNT_ENABLED
|
|
Shinya Kitaoka |
120a6e |
incrementInstanceCount();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSmartObject()
|
|
Shinya Kitaoka |
120a6e |
: m_refCount()
|
|
Toshihiro Shimizu |
890ddd |
#ifdef INSTANCE_COUNT_ENABLED
|
|
Shinya Kitaoka |
120a6e |
, m_classCodeRef(m_unknownClassCode)
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Toshihiro Shimizu |
890ddd |
#ifdef INSTANCE_COUNT_ENABLED
|
|
Shinya Kitaoka |
120a6e |
incrementInstanceCount();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
virtual ~TSmartObject() {
|
|
Shinya Kitaoka |
120a6e |
assert(m_refCount == 0);
|
|
Toshihiro Shimizu |
890ddd |
#ifdef INSTANCE_COUNT_ENABLED
|
|
Shinya Kitaoka |
120a6e |
decrementInstanceCount();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void addRef() { ++m_refCount; }
|
|
Shinya Kitaoka |
120a6e |
inline void release() {
|
|
Shinya Kitaoka |
120a6e |
if ((--m_refCount) <= 0) delete this;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
inline TINT32 getRefCount() const { return m_refCount; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
static TINT32 getInstanceCount(ClassCode code);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
void incrementInstanceCount();
|
|
Shinya Kitaoka |
120a6e |
void decrementInstanceCount();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
// not implemented
|
|
Shinya Kitaoka |
120a6e |
TSmartObject(const TSmartObject &);
|
|
Shinya Kitaoka |
120a6e |
TSmartObject &operator=(const TSmartObject &);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
#define DECLARE_CLASS_CODE \
|
|
shun-iwasawa |
5b7b9f |
\
|
|
Shinya Kitaoka |
120a6e |
private: \
|
|
Shinya Kitaoka |
120a6e |
static const TSmartObject::ClassCode m_classCode; \
|
|
shun-iwasawa |
5b7b9f |
\
|
|
Shinya Kitaoka |
120a6e |
public: \
|
|
Shinya Kitaoka |
120a6e |
inline static TINT32 getInstanceCount() { \
|
|
Shinya Kitaoka |
120a6e |
return TSmartObject::getInstanceCount(m_classCode); \
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
#define DEFINE_CLASS_CODE(T, ID) \
|
|
Shinya Kitaoka |
120a6e |
const TSmartObject::ClassCode T::m_classCode = ID;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=========================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
|
5f084d |
class TSmartHolderT {
|
|
|
29623f |
public:
|
|
|
29623f |
typedef T Type;
|
|
|
5f084d |
|
|
Toshihiro Shimizu |
890ddd |
protected:
|
|
Shinya Kitaoka |
120a6e |
T *m_pointer;
|
|
|
29623f |
T& reference() const
|
|
|
29623f |
{ assert(m_pointer); return *m_pointer; }
|
|
|
5f084d |
|
|
|
5f084d |
public:
|
|
|
5f084d |
TSmartHolderT() : m_pointer(0) {}
|
|
|
5f084d |
TSmartHolderT(const TSmartHolderT &src) : m_pointer(src.m_pointer)
|
|
|
29623f |
{ if (m_pointer) m_pointer->addRef(); }
|
|
|
5f084d |
explicit TSmartHolderT(T *pointer) : m_pointer(pointer)
|
|
|
29623f |
{ if (m_pointer) m_pointer->addRef(); }
|
|
|
5f084d |
virtual ~TSmartHolderT()
|
|
|
29623f |
{ if (m_pointer) { m_pointer->release(); m_pointer = 0; } }
|
|
|
29623f |
|
|
|
5f084d |
TSmartHolderT& operator=(const TSmartHolderT &src) { set(src); return *this; }
|
|
|
5f084d |
|
|
|
29623f |
void set(T *pointer) {
|
|
|
29623f |
if (m_pointer != pointer) {
|
|
|
29623f |
// call 'addRef' before 'release'
|
|
|
29623f |
if (pointer) pointer->addRef();
|
|
|
29623f |
if (m_pointer) m_pointer->release();
|
|
|
29623f |
m_pointer = pointer;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
|
5f084d |
void set(const TSmartHolderT &src)
|
|
|
29623f |
{ set(src.m_pointer); }
|
|
|
e65e8f |
void reset()
|
|
|
e65e8f |
{ set(0); }
|
|
|
29623f |
bool operator!() const
|
|
|
29623f |
{ return m_pointer == 0; }
|
|
|
29623f |
operator bool() const
|
|
|
29623f |
{ return m_pointer != 0; }
|
|
|
e65e8f |
|
|
|
5f084d |
bool operator==(const T *p) const { return m_pointer == p; }
|
|
|
5f084d |
bool operator!=(const T *p) const { return m_pointer != p; }
|
|
|
5f084d |
bool operator< (const T *p) const { return m_pointer < p; }
|
|
|
5f084d |
bool operator> (const T *p) const { return m_pointer > p; }
|
|
|
5f084d |
bool operator<=(const T *p) const { return m_pointer <= p; }
|
|
|
5f084d |
bool operator>=(const T *p) const { return m_pointer >= p; }
|
|
|
5f084d |
|
|
|
5f084d |
template<class tt=""></class>
|
|
|
2d2bcd |
bool equal(const TT *p) const { return m_pointer == p; }
|
|
|
5f084d |
template<class tt=""></class>
|
|
|
2d2bcd |
bool less(const TT *p) const { return m_pointer < p; }
|
|
|
1906ae |
template<class tt=""></class>
|
|
|
2d2bcd |
bool greater(const TT *p) const { return m_pointer > p; }
|
|
|
2d2bcd |
|
|
|
2d2bcd |
template<class tt=""></class>
|
|
|
2d2bcd |
bool operator==(const TSmartHolderT<tt> &p) const { return p.equal(m_pointer); }</tt>
|
|
|
2d2bcd |
template<class tt=""></class>
|
|
|
2d2bcd |
bool operator!=(const TSmartHolderT<tt> &p) const { return !p.equal(m_pointer); }</tt>
|
|
|
2d2bcd |
template<class tt=""></class>
|
|
|
2d2bcd |
bool operator< (const TSmartHolderT<tt> &p) const { return p.greater(m_pointer); }</tt>
|
|
|
1906ae |
template<class tt=""></class>
|
|
|
2d2bcd |
bool operator> (const TSmartHolderT<tt> &p) const { return p.less(m_pointer); }</tt>
|
|
|
1906ae |
template<class tt=""></class>
|
|
|
2d2bcd |
bool operator<=(const TSmartHolderT<tt> &p) const { return !p.less(m_pointer); }</tt>
|
|
|
1906ae |
template<class tt=""></class>
|
|
|
2d2bcd |
bool operator>=(const TSmartHolderT<tt> &p) const { return !p.greater(m_pointer); }</tt>
|
|
|
29623f |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
|
29623f |
//=========================================================
|
|
Shinya Kitaoka |
120a6e |
|
|
|
29623f |
template <class t=""></class>
|
|
|
5f084d |
class TSmartPointerConstT: public TSmartHolderT<t> {</t>
|
|
|
29623f |
public:
|
|
|
5f084d |
typedef TSmartHolderT<t> Holder;</t>
|
|
|
5f084d |
TSmartPointerConstT() {}
|
|
|
5f084d |
TSmartPointerConstT(const TSmartPointerConstT &src): Holder(src) {}
|
|
|
5f084d |
explicit TSmartPointerConstT(T *pointer): Holder(pointer) {}
|
|
|
5f084d |
TSmartPointerConstT& operator=(const TSmartPointerConstT &src) { Holder::set(src); return *this; }
|
|
|
5f084d |
const T* getConstPointer() const { return Holder::m_pointer; }
|
|
|
5f084d |
const T* operator->() const { return &Holder::reference(); }
|
|
|
5f084d |
const T& operator*() const { return Holder::reference(); }
|
|
|
5f084d |
const T* getPointer() const { return Holder::m_pointer; }
|
|
|
29623f |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
|
29623f |
//=========================================================
|
|
Shinya Kitaoka |
120a6e |
|
|
|
29623f |
template <class t=""></class>
|
|
|
5f084d |
class TSmartPointerT: public TSmartPointerConstT<t> {</t>
|
|
|
29623f |
public:
|
|
|
5f084d |
typedef TSmartPointerConstT<t> Const;</t>
|
|
|
5f084d |
TSmartPointerT() {}
|
|
|
5f084d |
TSmartPointerT(const TSmartPointerT &src): Const(src) {}
|
|
|
5f084d |
TSmartPointerT(T *pointer): Const(pointer) {}
|
|
|
5f084d |
TSmartPointerT& operator=(const TSmartPointerT &src) { Const::set(src); return *this; }
|
|
|
5f084d |
T* operator->() const { return &Const::reference(); }
|
|
|
5f084d |
T& operator*() const { return Const::reference(); }
|
|
|
5f084d |
T* getPointer() const { return Const::m_pointer; }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=========================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class base="" class="" derived,=""></class>
|
|
|
e280ae |
class TDerivedSmartPointerT : public TSmartPointerT<derived> {</derived>
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
typedef TDerivedSmartPointerT<derived, base=""> DerivedSmartPointer;</derived,>
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
1906ae |
TDerivedSmartPointerT() { };
|
|
|
1906ae |
TDerivedSmartPointerT(DERIVED *pointer):
|
|
|
1906ae |
TSmartPointerT<derived>(pointer) { }</derived>
|
|
|
1906ae |
TDerivedSmartPointerT(const TSmartPointerT<base> &p):
|
|
|
1906ae |
TSmartPointerT<derived>(dynamic_cast<derived*>(p.getPointer())) { }</derived*></derived>
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
71b43d |
//=========================================================
|
|
|
71b43d |
|
|
|
71b43d |
typedef TSmartPointerT<tsmartobject> TSmartObjectP;</tsmartobject>
|
|
|
71b43d |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|