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                                                     \
Shinya Kitaoka 120a6e
  \
Shinya Kitaoka 120a6e
private:                                                                       \
Shinya Kitaoka 120a6e
  static const TSmartObject::ClassCode m_classCode;                            \
Shinya Kitaoka 120a6e
  \
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>
Shinya Kitaoka 120a6e
class DVAPI TSmartPointerT {
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  T *m_pointer;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TSmartPointerT() : m_pointer(0) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TSmartPointerT(const TSmartPointerT &src) : m_pointer(src.m_pointer) {
Shinya Kitaoka 120a6e
    if (m_pointer) m_pointer->addRef();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TSmartPointerT(T *pointer) : m_pointer(pointer) {
Shinya Kitaoka 120a6e
    if (m_pointer) m_pointer->addRef();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  virtual ~TSmartPointerT() {
Shinya Kitaoka 120a6e
    if (m_pointer) {
Shinya Kitaoka 120a6e
      m_pointer->release();
Shinya Kitaoka 120a6e
      m_pointer = 0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TSmartPointerT &operator=(const TSmartPointerT &src) {
Shinya Kitaoka 120a6e
    // prima addRef  e poi release per evitare brutti scherzi
Shinya Kitaoka 120a6e
    // in caso di parentela
Shinya Kitaoka 120a6e
    T *old    = m_pointer;
Shinya Kitaoka 120a6e
    m_pointer = src.m_pointer;
Shinya Kitaoka 120a6e
    if (m_pointer) m_pointer->addRef();
Shinya Kitaoka 120a6e
    if (old) old->release();
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  T *operator->() const {
Shinya Kitaoka 120a6e
    assert(m_pointer);
Shinya Kitaoka 120a6e
    return m_pointer;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  T &operator*() const {
Shinya Kitaoka 120a6e
    assert(m_pointer);
Shinya Kitaoka 120a6e
    return *m_pointer;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  T *getPointer() const { return m_pointer; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool operator!() const { return m_pointer == 0; }
Shinya Kitaoka 120a6e
  operator bool() const { return m_pointer != 0; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool operator==(const TSmartPointerT &p) const {
Shinya Kitaoka 120a6e
    return m_pointer == p.m_pointer;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  bool operator!=(const TSmartPointerT &p) const {
Shinya Kitaoka 120a6e
    return m_pointer != p.m_pointer;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool operator<(const TSmartPointerT &p) const {
Shinya Kitaoka 120a6e
    return m_pointer < p.m_pointer;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  bool operator>(const TSmartPointerT &p) const {
Shinya Kitaoka 120a6e
    return m_pointer > p.m_pointer;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class base="" class="" derived,=""></class>
Shinya Kitaoka 120a6e
class DVAPI TDerivedSmartPointerT : public TSmartPointerT<derived> {</derived>
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  typedef TDerivedSmartPointerT<derived, base=""> DerivedSmartPointer;</derived,>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TDerivedSmartPointerT(){};
Shinya Kitaoka 120a6e
  TDerivedSmartPointerT(DERIVED *pointer) : TSmartPointerT<derived>(pointer) {}</derived>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TDerivedSmartPointerT(const TSmartPointerT<base> &p) {
Shinya Kitaoka 120a6e
    TSmartPointerT<derived>::m_pointer =</derived>
Shinya Kitaoka 120a6e
        dynamic_cast<derived *="">(p.getPointer());</derived>
Shinya Kitaoka 120a6e
    if (TSmartPointerT<derived>::m_pointer)</derived>
Shinya Kitaoka 120a6e
      TSmartPointerT<derived>::m_pointer->addRef();</derived>
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif