blob: 225e1cae65c95bb68ec6faa7481750d960427a8e [file] [log] [blame]
/*
*
* 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
#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