You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdesvn/src/svnqt/shared_pointer.hpp

194 lines
5.3 KiB

/***************************************************************************
* 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.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