diff options
Diffstat (limited to 'src/svnqt/shared_pointer.hpp')
-rw-r--r-- | src/svnqt/shared_pointer.hpp | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/src/svnqt/shared_pointer.hpp b/src/svnqt/shared_pointer.hpp new file mode 100644 index 0000000..cd1587e --- /dev/null +++ b/src/svnqt/shared_pointer.hpp @@ -0,0 +1,193 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 by Rajko Albrecht * + * [email protected] * + * * + * 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 SVNQT_SHARED_POINTER_HPP +#define SVNQT_SHARED_POINTER_HPP + +#include "svnqt/smart_pointer.hpp" + +/*! + * \file shared_pointer.hpp + * \brief shared pointer adapter + * \sa smart_pointer.hpp + */ + +namespace svn +{ + +template<class T> class SharedPointer; + +/*! + * Data container for svn::SharedPointer + */ +template<class T> class SharedPointerData:public ref_count +{ + friend class SharedPointer<T>; +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 T> class SharedPointer +{ + typedef SharedPointerData<T> 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<T>& 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<T> &operator=(const SharedPointer<T>&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<T> &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 |