dbus-cplusplus/include/dbus-c++/util.h

277 lines
3.7 KiB
C++

/*
*
* D-Bus++ - C++ bindings for D-Bus
*
* Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com>
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef __DBUSXX_UTIL_H
#define __DBUSXX_UTIL_H
#ifdef HAVE_CONFIG_H
#include <dbus-c++/config.h>
#endif
#include "api.h"
#include "debug.h"
namespace DBus {
/*
* Very simple reference counting
*/
class DXXAPI RefCnt
{
public:
RefCnt()
{
__ref = new int;
(*__ref) = 1;
}
RefCnt( const RefCnt& rc )
{
__ref = rc.__ref;
ref();
}
virtual ~RefCnt()
{
unref();
}
RefCnt& operator = ( const RefCnt& ref )
{
ref.ref();
unref();
__ref = ref.__ref;
return *this;
}
bool noref() const
{
return (*__ref) == 0;
}
bool one() const
{
return (*__ref) == 1;
}
private:
DXXAPILOCAL void ref() const
{
++ (*__ref);
}
DXXAPILOCAL void unref() const
{
-- (*__ref);
if( (*__ref) < 0 )
{
debug_log("%p: refcount dropped below zero!", __ref);
}
if( noref() )
{
delete __ref;
}
}
private:
int *__ref;
};
/*
* Reference counting pointers (emulate boost::shared_ptr)
*/
template <class T>
class RefPtrI // RefPtr to incomplete type
{
public:
RefPtrI( T* ptr = 0 );
~RefPtrI();
RefPtrI& operator = ( const RefPtrI& ref )
{
if( this != &ref )
{
if(__cnt.one()) delete __ptr;
__ptr = ref.__ptr;
__cnt = ref.__cnt;
}
return *this;
}
T& operator *() const
{
return *__ptr;
}
T* operator ->() const
{
if(__cnt.noref()) return 0;
return __ptr;
}
T* get() const
{
if(__cnt.noref()) return 0;
return __ptr;
}
private:
T* __ptr;
RefCnt __cnt;
};
template <class T>
class RefPtr
{
public:
RefPtr( T* ptr = 0)
: __ptr(ptr)
{}
~RefPtr()
{
if(__cnt.one()) delete __ptr;
}
RefPtr& operator = ( const RefPtr& ref )
{
if( this != &ref )
{
if(__cnt.one()) delete __ptr;
__ptr = ref.__ptr;
__cnt = ref.__cnt;
}
return *this;
}
T& operator *() const
{
return *__ptr;
}
T* operator ->() const
{
if(__cnt.noref()) return 0;
return __ptr;
}
T* get() const
{
if(__cnt.noref()) return 0;
return __ptr;
}
private:
T* __ptr;
RefCnt __cnt;
};
/*
* Typed callback template
*/
template <class R, class P>
class Callback_Base
{
public:
virtual R call( P param ) const = 0;
virtual ~Callback_Base()
{}
};
template <class R, class P>
class Slot
{
public:
Slot& operator = ( Callback_Base<R,P>* s )
{
_cb = s;
return *this;
}
R operator()( P param ) const
{
/*if(_cb.get())*/ return _cb->call(param);
}
R call( P param ) const
{
/*if(_cb.get())*/ return _cb->call(param);
}
bool empty()
{
return _cb.get() == 0;
}
private:
RefPtr< Callback_Base<R,P> > _cb;
};
template <class C, class R, class P>
class Callback : public Callback_Base<R,P>
{
public:
typedef R (C::*M)(P);
Callback( C* c, M m )
: _c(c), _m(m)
{}
R call( P param ) const
{
/*if(_c)*/ return (_c->*_m)(param);
}
private:
C* _c; M _m;
};
} /* namespace DBus */
#endif//__DBUSXX_UTIL_H