From 29623f5ab3530feba278598bba9a4d906a491d25 Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: May 01 2023 07:52:44 +0000 Subject: #assistants: TSmartRefT --- diff --git a/toonz/sources/include/tsmartpointer.h b/toonz/sources/include/tsmartpointer.h index ed1e3fc..321ce87 100644 --- a/toonz/sources/include/tsmartpointer.h +++ b/toonz/sources/include/tsmartpointer.h @@ -102,66 +102,81 @@ public: \ //========================================================= template -class TSmartPointerT { +class TSmartPointerBaseT { +public: + typedef T Type; protected: T *m_pointer; - + T& reference() const + { assert(m_pointer); return *m_pointer; } public: - 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; + TSmartPointerBaseT() : m_pointer(0) {} + TSmartPointerBaseT(const TSmartPointerBaseT &src) : m_pointer(src.m_pointer) + { if (m_pointer) m_pointer->addRef(); } + TSmartPointerBaseT(T *pointer) : m_pointer(pointer) + { if (m_pointer) m_pointer->addRef(); } + virtual ~TSmartPointerBaseT() + { if (m_pointer) { m_pointer->release(); m_pointer = 0; } } + TSmartPointerBaseT& operator=(const TSmartPointerBaseT &src) + { set(src); return *this; } + + void set(T *pointer) { + if (m_pointer != pointer) { + // call 'addRef' before 'release' + if (pointer) pointer->addRef(); + if (m_pointer) m_pointer->release(); + m_pointer = pointer; } } + void set(const TSmartPointerBaseT &src) + { set(src.m_pointer); } + bool operator!() const + { return m_pointer == 0; } + operator bool() const + { return m_pointer != 0; } + bool operator==(const TSmartPointerBaseT &p) const + { return m_pointer == p.m_pointer; } + bool operator!=(const TSmartPointerBaseT &p) const + { return m_pointer != p.m_pointer; } + bool operator<(const TSmartPointerBaseT &p) const + { return m_pointer < p.m_pointer; } + bool operator>(const TSmartPointerBaseT &p) const + { return m_pointer > p.m_pointer; } +}; - 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; } +template +class TSmartPointerT: public TSmartPointerBaseT { +public: + typedef TSmartPointerBaseT Base; + TSmartPointerT() {} + TSmartPointerT(const TSmartPointerT &src): Base(src) {} + TSmartPointerT(T *pointer): Base(pointer) {} + TSmartPointerT& operator=(const TSmartPointerT &src) { Base::set(src); return *this; } + T* operator->() const { return &Base::reference(); } + T& operator*() const { return Base::reference(); } + T* getPointer() const { return Base::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; - } - bool operator>(const TSmartPointerT &p) const { - return m_pointer > p.m_pointer; - } +//! smart reference returns constant pointer when reference is constant +//! and returns non-constant pointer when reference is non-constant +template +class TSmartRefT: public TSmartPointerBaseT { +public: + typedef TSmartPointerBaseT Base; + TSmartRefT() {} + TSmartRefT(const TSmartRefT &src): Base(src) {} + TSmartRefT(T *pointer): Base(pointer) {} + TSmartRefT& operator=(const TSmartRefT &src) { Base::set(src); return *this; } + const T* operator->() const { return &Base::reference(); } + const T& operator*() const { return Base::reference(); } + const T* getPointer() const { return Base::m_pointer; } + T* operator->() { return &Base::reference(); } + T& operator*() { return Base::reference(); } + T* getPointer() { return Base::m_pointer; } }; //=========================================================