| #pragma once |
| |
| #ifndef TSMARTPOINTER_INCLUDED |
| #define TSMARTPOINTER_INCLUDED |
| |
| #include "tutil.h" |
| #include "tatomicvar.h" |
| |
| #undef DVAPI |
| #undef DVVAR |
| #ifdef TNZCORE_EXPORTS |
| #define DVAPI DV_EXPORT_API |
| #define DVVAR DV_EXPORT_VAR |
| #else |
| #define DVAPI DV_IMPORT_API |
| #define DVVAR DV_IMPORT_VAR |
| #endif |
| |
| |
| |
| #ifndef NDEBUG |
| #define INSTANCE_COUNT_ENABLED |
| #endif |
| |
| |
| |
| class DVAPI TSmartObject { |
| TAtomicVar m_refCount; |
| |
| #ifdef INSTANCE_COUNT_ENABLED |
| const TINT32 m_classCodeRef; |
| static const TINT32 m_unknownClassCode; |
| #endif |
| |
| public: |
| typedef short ClassCode; |
| |
| TSmartObject(ClassCode |
| #ifdef INSTANCE_COUNT_ENABLED |
| classCode |
| #endif |
| ) |
| : m_refCount() |
| #ifdef INSTANCE_COUNT_ENABLED |
| , m_classCodeRef(classCode) |
| #endif |
| { |
| #ifdef INSTANCE_COUNT_ENABLED |
| incrementInstanceCount(); |
| #endif |
| } |
| |
| TSmartObject() |
| : m_refCount() |
| #ifdef INSTANCE_COUNT_ENABLED |
| , m_classCodeRef(m_unknownClassCode) |
| #endif |
| { |
| #ifdef INSTANCE_COUNT_ENABLED |
| incrementInstanceCount(); |
| #endif |
| } |
| |
| virtual ~TSmartObject() { |
| assert(m_refCount == 0); |
| #ifdef INSTANCE_COUNT_ENABLED |
| decrementInstanceCount(); |
| #endif |
| } |
| |
| inline void addRef() { ++m_refCount; } |
| inline void release() { |
| if ((--m_refCount) <= 0) delete this; |
| }; |
| inline TINT32 getRefCount() const { return m_refCount; } |
| |
| static TINT32 getInstanceCount(ClassCode code); |
| |
| private: |
| void incrementInstanceCount(); |
| void decrementInstanceCount(); |
| |
| private: |
| |
| TSmartObject(const TSmartObject &); |
| TSmartObject &operator=(const TSmartObject &); |
| }; |
| |
| #define DECLARE_CLASS_CODE \ |
| \ |
| private: \ |
| static const TSmartObject::ClassCode m_classCode; \ |
| \ |
| public: \ |
| inline static TINT32 getInstanceCount() { \ |
| return TSmartObject::getInstanceCount(m_classCode); \ |
| } |
| |
| #define DEFINE_CLASS_CODE(T, ID) \ |
| const TSmartObject::ClassCode T::m_classCode = ID; |
| |
| |
| |
| template <class T> |
| class TSmartHolderT { |
| public: |
| typedef T Type; |
| |
| protected: |
| T *m_pointer; |
| T& reference() const |
| { assert(m_pointer); return *m_pointer; } |
| |
| public: |
| TSmartHolderT() : m_pointer(0) {} |
| TSmartHolderT(const TSmartHolderT &src) : m_pointer(src.m_pointer) |
| { if (m_pointer) m_pointer->addRef(); } |
| explicit TSmartHolderT(T *pointer) : m_pointer(pointer) |
| { if (m_pointer) m_pointer->addRef(); } |
| virtual ~TSmartHolderT() |
| { if (m_pointer) { m_pointer->release(); m_pointer = 0; } } |
| |
| TSmartHolderT& operator=(const TSmartHolderT &src) { set(src); return *this; } |
| |
| void set(T *pointer) { |
| if (m_pointer != pointer) { |
| |
| if (pointer) pointer->addRef(); |
| if (m_pointer) m_pointer->release(); |
| m_pointer = pointer; |
| } |
| } |
| void set(const TSmartHolderT &src) |
| { set(src.m_pointer); } |
| void reset() |
| { set(0); } |
| bool operator!() const |
| { return m_pointer == 0; } |
| operator bool() const |
| { return m_pointer != 0; } |
| |
| bool operator==(const T *p) const { return m_pointer == p; } |
| bool operator!=(const T *p) const { return m_pointer != p; } |
| bool operator< (const T *p) const { return m_pointer < p; } |
| bool operator> (const T *p) const { return m_pointer > p; } |
| bool operator<=(const T *p) const { return m_pointer <= p; } |
| bool operator>=(const T *p) const { return m_pointer >= p; } |
| |
| template<class TT> |
| bool equal(const TT *p) const { return m_pointer == p; } |
| template<class TT> |
| bool less(const TT *p) const { return m_pointer < p; } |
| template<class TT> |
| bool greater(const TT *p) const { return m_pointer > p; } |
| |
| template<class TT> |
| bool operator==(const TSmartHolderT<TT> &p) const { return p.equal(m_pointer); } |
| template<class TT> |
| bool operator!=(const TSmartHolderT<TT> &p) const { return !p.equal(m_pointer); } |
| template<class TT> |
| bool operator< (const TSmartHolderT<TT> &p) const { return p.greater(m_pointer); } |
| template<class TT> |
| bool operator> (const TSmartHolderT<TT> &p) const { return p.less(m_pointer); } |
| template<class TT> |
| bool operator<=(const TSmartHolderT<TT> &p) const { return !p.less(m_pointer); } |
| template<class TT> |
| bool operator>=(const TSmartHolderT<TT> &p) const { return !p.greater(m_pointer); } |
| }; |
| |
| |
| |
| template <class T> |
| class TSmartPointerConstT: public TSmartHolderT<T> { |
| public: |
| typedef TSmartHolderT<T> Holder; |
| TSmartPointerConstT() {} |
| TSmartPointerConstT(const TSmartPointerConstT &src): Holder(src) {} |
| explicit TSmartPointerConstT(T *pointer): Holder(pointer) {} |
| TSmartPointerConstT& operator=(const TSmartPointerConstT &src) { Holder::set(src); return *this; } |
| const T* getConstPointer() const { return Holder::m_pointer; } |
| const T* operator->() const { return &Holder::reference(); } |
| const T& operator*() const { return Holder::reference(); } |
| const T* getPointer() const { return Holder::m_pointer; } |
| }; |
| |
| |
| |
| template <class T> |
| class TSmartPointerT: public TSmartPointerConstT<T> { |
| public: |
| typedef TSmartPointerConstT<T> Const; |
| TSmartPointerT() {} |
| TSmartPointerT(const TSmartPointerT &src): Const(src) {} |
| TSmartPointerT(T *pointer): Const(pointer) {} |
| TSmartPointerT& operator=(const TSmartPointerT &src) { Const::set(src); return *this; } |
| T* operator->() const { return &Const::reference(); } |
| T& operator*() const { return Const::reference(); } |
| T* getPointer() const { return Const::m_pointer; } |
| }; |
| |
| |
| |
| template <class DERIVED, class BASE> |
| class TDerivedSmartPointerT : public TSmartPointerT<DERIVED> { |
| public: |
| typedef TDerivedSmartPointerT<DERIVED, BASE> DerivedSmartPointer; |
| |
| TDerivedSmartPointerT() { }; |
| TDerivedSmartPointerT(DERIVED *pointer): |
| TSmartPointerT<DERIVED>(pointer) { } |
| TDerivedSmartPointerT(const TSmartPointerT<BASE> &p): |
| TSmartPointerT<DERIVED>(dynamic_cast<DERIVED*>(p.getPointer())) { } |
| }; |
| |
| |
| |
| typedef TSmartPointerT<TSmartObject> TSmartObjectP; |
| |
| #endif |