//################################################################################################## // // Custom Visualization Core library // Copyright (C) 2011-2012 Ceetron AS // // This library is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. // // See the GNU General Public License at <> // for more details. // //################################################################################################## #pragma once namespace caf { class PdmObject; //================================================================================================== /// Helper class for the PdmPointer class /// The add and removing of references is put into a pure static class to /// resolve circular include problems. // /// Overall idea of the referencing system: /// The addressToObjectPointer is added to a std::set in the object pointed to. /// when the object pointed to is deleted, its destructor sets the object pointers /// it has addresses to to NULL //================================================================================================== class PdmPointerImpl { private: template < class T > friend class PdmPointer; static void addReference(PdmObject ** addressToObjectPointer); static void removeReference(PdmObject ** addressToObjectPointer); }; //================================================================================================== /// Guarded pointer class to point at PdmObjects /// Use a PdmPointer in the same way as a normal pointer. /// The guarding sets the pointer to NULL if the object pointed to dies /// /// NOTE: This is not reference counting. The user is responsible to delete the objects pointed to. /// It _can_ be used together with the cvf::ref system if neccesary (this is no recomendation) //================================================================================================== template < class T > class PdmPointer { PdmObject* m_object; public : inline PdmPointer () : m_object(NULL) { } inline PdmPointer ( T * p ) : m_object(p) { PdmPointerImpl::addReference(&m_object); } inline PdmPointer ( const PdmPointer & p ) : m_object ( p.m_object ) { PdmPointerImpl::addReference(&m_object); } inline ~PdmPointer () { PdmPointerImpl::removeReference(&m_object); } T* p() const { return static_cast(const_cast(m_object)); } bool isNull() const { return !m_object; } bool notNull() const { return !isNull(); } operator T* () const { return static_cast(const_cast(m_object)); } T& operator* () const { return *static_cast(const_cast(m_object)); } T* operator->() const { return static_cast(const_cast(m_object)); } PdmPointer & operator= ( const PdmPointer& p ) { if (this != &p) PdmPointerImpl::removeReference(&m_object); m_object = p.m_object; PdmPointerImpl::addReference(&m_object); return *this; } PdmPointer & operator= ( T* p ) { if (m_object != p) PdmPointerImpl::removeReference(&m_object); m_object = p; PdmPointerImpl::addReference(&m_object); return *this; } // Private methods used by PdmField and PdmPointersField. Do not use unless you mean it ! PdmObject* rawPtr() const { return m_object; } void setRawPtr( PdmObject* p) { if (m_object != p) PdmPointerImpl::removeReference(&m_object); m_object = p; PdmPointerImpl::addReference(&m_object); } }; } // End of namespace caf