/* * * D-Bus++ - C++ bindings for D-Bus * * Copyright (C) 2005-2007 Paolo Durante * * * 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 #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 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 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 Callback_Base { public: virtual R call( P param ) const = 0; virtual ~Callback_Base() {} }; template class Slot { public: Slot& operator = ( Callback_Base* 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 > _cb; }; template class Callback : public Callback_Base { 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