00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef __DBUSXX_UTIL_H
00026 #define __DBUSXX_UTIL_H
00027
00028 #include "api.h"
00029 #include "debug.h"
00030
00031 namespace DBus {
00032
00033
00034
00035
00036
00037 class DXXAPI RefCnt
00038 {
00039 public:
00040
00041 RefCnt()
00042 {
00043 __ref = new int;
00044 (*__ref) = 1;
00045 }
00046
00047 RefCnt(const RefCnt &rc)
00048 {
00049 __ref = rc.__ref;
00050 ref();
00051 }
00052
00053 virtual ~RefCnt()
00054 {
00055 unref();
00056 }
00057
00058 RefCnt &operator = (const RefCnt &ref)
00059 {
00060 ref.ref();
00061 unref();
00062 __ref = ref.__ref;
00063 return *this;
00064 }
00065
00066 bool noref() const
00067 {
00068 return __ref ? (*__ref) == 0 : true;
00069 }
00070
00071 bool one() const
00072 {
00073 return __ref ? (*__ref) == 1 : false;
00074 }
00075
00076 private:
00077
00078 DXXAPILOCAL void ref() const
00079 {
00080 if (!__ref)
00081 return;
00082
00083 ++ (*__ref);
00084 }
00085 DXXAPILOCAL void unref()
00086 {
00087 if (!__ref)
00088 return;
00089
00090 -- (*__ref);
00091
00092 if ((*__ref) < 0)
00093 {
00094 debug_log("%p: refcount dropped below zero!", __ref);
00095 }
00096
00097 if (noref())
00098 {
00099 delete __ref;
00100 __ref = 0;
00101 }
00102 }
00103
00104 private:
00105
00106 int *__ref;
00107 };
00108
00109
00110
00111
00112
00113 template <class T>
00114 class RefPtrI
00115 {
00116 public:
00117
00118 RefPtrI(T *ptr = 0);
00119
00120 ~RefPtrI();
00121
00122 RefPtrI &operator = (const RefPtrI &ref)
00123 {
00124 if (this != &ref)
00125 {
00126 if (__cnt.one()) delete __ptr;
00127
00128 __ptr = ref.__ptr;
00129 __cnt = ref.__cnt;
00130 }
00131 return *this;
00132 }
00133
00134 T &operator *() const
00135 {
00136 return *__ptr;
00137 }
00138
00139 T *operator ->() const
00140 {
00141 if (__cnt.noref()) return 0;
00142
00143 return __ptr;
00144 }
00145
00146 T *get() const
00147 {
00148 if (__cnt.noref()) return 0;
00149
00150 return __ptr;
00151 }
00152
00153 private:
00154
00155 T *__ptr;
00156 RefCnt __cnt;
00157 };
00158
00159 template <class T>
00160 class RefPtr
00161 {
00162 public:
00163
00164 RefPtr(T *ptr = 0)
00165 : __ptr(ptr)
00166 {}
00167
00168 ~RefPtr()
00169 {
00170 if (__cnt.one()) delete __ptr;
00171 }
00172
00173 RefPtr &operator = (const RefPtr &ref)
00174 {
00175 if (this != &ref)
00176 {
00177 if (__cnt.one()) delete __ptr;
00178
00179 __ptr = ref.__ptr;
00180 __cnt = ref.__cnt;
00181 }
00182 return *this;
00183 }
00184
00185 T &operator *() const
00186 {
00187 return *__ptr;
00188 }
00189
00190 T *operator ->() const
00191 {
00192 if (__cnt.noref()) return 0;
00193
00194 return __ptr;
00195 }
00196
00197 T *get() const
00198 {
00199 if (__cnt.noref()) return 0;
00200
00201 return __ptr;
00202 }
00203
00204 private:
00205
00206 T *__ptr;
00207 RefCnt __cnt;
00208 };
00209
00210
00211
00212
00213
00214 template <class R, class P>
00215 class Callback_Base
00216 {
00217 public:
00218
00219 virtual R call(P param) const = 0;
00220
00221 virtual ~Callback_Base()
00222 {}
00223 };
00224
00225 template <class R, class P>
00226 class Slot
00227 {
00228 public:
00229
00230 Slot &operator = (Callback_Base<R,P>* s)
00231 {
00232 _cb = s;
00233
00234 return *this;
00235 }
00236
00237 R operator()(P param) const
00238 {
00239 return _cb->call(param);
00240 }
00241
00242 R call(P param) const
00243 {
00244 return _cb->call(param);
00245 }
00246
00247 bool empty()
00248 {
00249 return _cb.get() == 0;
00250 }
00251
00252 private:
00253
00254 RefPtr< Callback_Base<R,P> > _cb;
00255 };
00256
00257 template <class C, class R, class P>
00258 class Callback : public Callback_Base<R,P>
00259 {
00260 public:
00261
00262 typedef R (C::*M)(P);
00263
00264 Callback(C *c, M m)
00265 : _c(c), _m(m)
00266 {}
00267
00268 R call(P param) const
00269 {
00270 return (_c->*_m)(param);
00271 }
00272
00273 private:
00274
00275 C *_c; M _m;
00276 };
00277
00278 }
00279
00280 #endif//__DBUSXX_UTIL_H