summaryrefslogtreecommitdiffstats
path: root/src/svnqt/shared_pointer.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/svnqt/shared_pointer.hpp')
-rw-r--r--src/svnqt/shared_pointer.hpp193
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 *
+ * *
+ * 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