/*************************************************************************** * Copyright (C) 2006-2007 by Rajko Albrecht * * ral@alwins-world.de * * * * This program 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 2 of the License, or * * (at your option) any later version. * * * * This program 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 for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef SVNTQT_SHARED_POINTER_HPP #define SVNTQT_SHARED_POINTER_HPP #include "svnqt/smart_pointer.h" /*! * \file shared_pointer.h * \brief shared pointer adapter * \sa smart_pointer.h */ namespace svn { template class SharedPointer; /*! * Data container for svn::SharedPointer */ template class SharedPointerData:public ref_count { friend class SharedPointer; protected: //! The protected pointer T*data; public: //! Constructor /*! * Take ownership of pointer dt * \param dt the data to wrap **/ SharedPointerData(T*dt){ data = dt; } //! Destructor /*! * Release content data */ ~SharedPointerData() { delete data; } }; //! Shared pointer adapater /*! * Implements a thread safe reference counter around any pointer. * This class takes ownership of data, eg., last reference will delete * the data it inspects. */ template class SharedPointer { typedef SharedPointerData Data; Data*data; //! count down reference of data and release if it was the last share void unref(){ if (data) { data->Decr(); if (!data->Shared()) { delete data; } data = 0; } } public: //! empty constructor SharedPointer():data(0){} //! copy constructor /*! * \param p Data to increase reference for */ SharedPointer(const SharedPointer& p) { if ( (data = p.data) ) data->Incr(); } //! assignment constructor /*! * Take ownership of data pointer t * \param t data pointer to store inside */ SharedPointer(T*t) { data = new Data(t);data->Incr(); } //! destructor /*! * decrease reference, if reference == 0 release data */ ~SharedPointer() { unref(); } //! assignment operator /*! * \param p Data to increase reference for */ SharedPointer &operator=(const SharedPointer&p) { // we always have a reference to the data if (data==p.data) return *this; unref(); if ((data=p.data)) data->Incr(); return *this; } //! assignment operator /*! * \param p Data to increase reference for */ SharedPointer &operator=(T*p) { if (data && data->data==p) { return *this; } unref(); data = new Data(p); data->Incr(); return *this; } //! access operator /*! * Use this operator with care! * \return pointer to wrapped data */ operator T*()const {return data->data;} //! access operator /*! * \return reference to wrapped data */ T& operator*() {return *data->data;} //! access operator /*! * \return const reference to wrapped data */ const T& operator*()const{return *data->data;} //! access operator /*! * \return pointer to wrapped data */ T*operator->() {return data->data;} //! access operator /*! * \return const pointer to wrapped data */ const T*operator->()const{return data->data;} //! Bool operator /*! * \return true if content set and not a null-pointer, otherwise false */ operator bool () const { return (data != 0 && data->data != 0); } //! Bool operator /*! * \return true if content set and not a null-pointer, otherwise false */ operator bool () { return ( data != 0 && data->data != 0 );} //! Negation operator /*! * \return true if content not set or a null-pointer, otherwise false */ bool operator! () const { return (data == 0 || data->data == 0); } //! Negation operator /*! * \return true if content not set or a null-pointer, otherwise false */ bool operator! () { return (data == 0 || data->data == 0); } }; } #endif