tahoma2d/toonz/sources/include/tsmartpointer.h

186 lines
4.3 KiB
C
Raw Normal View History

2016-05-17 03:04:11 +12:00
#pragma once
2016-03-19 06:57:51 +13:00
#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
//=========================================================
2016-06-15 18:43:10 +12:00
class DVAPI TSmartObject {
TAtomicVar m_refCount;
2016-03-19 06:57:51 +13:00
#ifdef INSTANCE_COUNT_ENABLED
2016-06-15 18:43:10 +12:00
const TINT32 m_classCodeRef;
static const TINT32 m_unknownClassCode;
2016-03-19 06:57:51 +13:00
#endif
public:
2016-06-15 18:43:10 +12:00
typedef short ClassCode;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TSmartObject(ClassCode
2016-03-19 06:57:51 +13:00
#ifdef INSTANCE_COUNT_ENABLED
2016-06-15 18:43:10 +12:00
classCode
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
)
: m_refCount()
2016-03-19 06:57:51 +13:00
#ifdef INSTANCE_COUNT_ENABLED
2016-06-15 18:43:10 +12:00
, m_classCodeRef(classCode)
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
{
2016-03-19 06:57:51 +13:00
#ifdef INSTANCE_COUNT_ENABLED
2016-06-15 18:43:10 +12:00
incrementInstanceCount();
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TSmartObject()
: m_refCount()
2016-03-19 06:57:51 +13:00
#ifdef INSTANCE_COUNT_ENABLED
2016-06-15 18:43:10 +12:00
, m_classCodeRef(m_unknownClassCode)
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
{
2016-03-19 06:57:51 +13:00
#ifdef INSTANCE_COUNT_ENABLED
2016-06-15 18:43:10 +12:00
incrementInstanceCount();
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
virtual ~TSmartObject() {
assert(m_refCount == 0);
2016-03-19 06:57:51 +13:00
#ifdef INSTANCE_COUNT_ENABLED
2016-06-15 18:43:10 +12:00
decrementInstanceCount();
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
inline void addRef() { ++m_refCount; }
inline void release() {
if ((--m_refCount) <= 0) delete this;
};
inline TINT32 getRefCount() const { return m_refCount; }
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
static TINT32 getInstanceCount(ClassCode code);
2016-03-19 06:57:51 +13:00
private:
2016-06-15 18:43:10 +12:00
void incrementInstanceCount();
void decrementInstanceCount();
2016-03-19 06:57:51 +13:00
private:
2016-06-15 18:43:10 +12:00
// not implemented
TSmartObject(const TSmartObject &);
TSmartObject &operator=(const TSmartObject &);
2016-03-19 06:57:51 +13:00
};
2016-06-15 18:43:10 +12:00
#define DECLARE_CLASS_CODE \
2017-06-07 00:19:00 +12:00
\
2016-06-15 18:43:10 +12:00
private: \
static const TSmartObject::ClassCode m_classCode; \
2017-06-07 00:19:00 +12:00
\
2016-06-15 18:43:10 +12:00
public: \
inline static TINT32 getInstanceCount() { \
return TSmartObject::getInstanceCount(m_classCode); \
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
#define DEFINE_CLASS_CODE(T, ID) \
const TSmartObject::ClassCode T::m_classCode = ID;
2016-03-19 06:57:51 +13:00
//=========================================================
template <class T>
class TSmartPointerT {
2016-03-19 06:57:51 +13:00
protected:
2016-06-15 18:43:10 +12:00
T *m_pointer;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TSmartPointerT() : m_pointer(0) {}
TSmartPointerT(const TSmartPointerT &src) : m_pointer(src.m_pointer) {
if (m_pointer) m_pointer->addRef();
}
TSmartPointerT(T *pointer) : m_pointer(pointer) {
if (m_pointer) m_pointer->addRef();
}
virtual ~TSmartPointerT() {
if (m_pointer) {
m_pointer->release();
m_pointer = 0;
}
}
TSmartPointerT &operator=(const TSmartPointerT &src) {
// prima addRef e poi release per evitare brutti scherzi
// in caso di parentela
T *old = m_pointer;
m_pointer = src.m_pointer;
if (m_pointer) m_pointer->addRef();
if (old) old->release();
return *this;
}
T *operator->() const {
assert(m_pointer);
return m_pointer;
}
T &operator*() const {
assert(m_pointer);
return *m_pointer;
}
T *getPointer() const { return m_pointer; }
bool operator!() const { return m_pointer == 0; }
operator bool() const { return m_pointer != 0; }
bool operator==(const TSmartPointerT &p) const {
return m_pointer == p.m_pointer;
}
bool operator!=(const TSmartPointerT &p) const {
return m_pointer != p.m_pointer;
}
bool operator<(const TSmartPointerT &p) const {
return m_pointer < p.m_pointer;
}
bool operator>(const TSmartPointerT &p) const {
return m_pointer > p.m_pointer;
}
2016-03-19 06:57:51 +13:00
};
//=========================================================
template <class DERIVED, class BASE>
class TDerivedSmartPointerT : public TSmartPointerT<DERIVED> {
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
typedef TDerivedSmartPointerT<DERIVED, BASE> DerivedSmartPointer;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TDerivedSmartPointerT(){};
TDerivedSmartPointerT(DERIVED *pointer) : TSmartPointerT<DERIVED>(pointer) {}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TDerivedSmartPointerT(const TSmartPointerT<BASE> &p) {
TSmartPointerT<DERIVED>::m_pointer =
dynamic_cast<DERIVED *>(p.getPointer());
if (TSmartPointerT<DERIVED>::m_pointer)
TSmartPointerT<DERIVED>::m_pointer->addRef();
}
2016-03-19 06:57:51 +13:00
};
#endif