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 <sstream>
00029 #include <iostream>
00030 #include <iomanip>
00031 #include <cassert>
00032
00033 #include "api.h"
00034 #include "debug.h"
00035
00036 namespace DBus
00037 {
00038
00039
00040
00041
00042
00043 class DXXAPI RefCnt
00044 {
00045 public:
00046
00047 RefCnt()
00048 {
00049 __ref = new int;
00050 (*__ref) = 1;
00051 }
00052
00053 RefCnt(const RefCnt &rc)
00054 {
00055 __ref = rc.__ref;
00056 ref();
00057 }
00058
00059 virtual ~RefCnt()
00060 {
00061 unref();
00062 }
00063
00064 RefCnt &operator = (const RefCnt &ref)
00065 {
00066 ref.ref();
00067 unref();
00068 __ref = ref.__ref;
00069 return *this;
00070 }
00071
00072 bool noref() const
00073 {
00074 return (*__ref) == 0;
00075 }
00076
00077 bool one() const
00078 {
00079 return (*__ref) == 1;
00080 }
00081
00082 private:
00083
00084 DXXAPILOCAL void ref() const
00085 {
00086 ++ (*__ref);
00087 }
00088 DXXAPILOCAL void unref() const
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 }
00101 }
00102
00103 private:
00104
00105 int *__ref;
00106 };
00107
00108
00109
00110
00111
00112 template <class T>
00113 class RefPtrI
00114 {
00115 public:
00116
00117 RefPtrI(T *ptr = 0);
00118
00119 ~RefPtrI();
00120
00121 RefPtrI &operator = (const RefPtrI &ref)
00122 {
00123 if (this != &ref)
00124 {
00125 if (__cnt.one()) delete __ptr;
00126
00127 __ptr = ref.__ptr;
00128 __cnt = ref.__cnt;
00129 }
00130 return *this;
00131 }
00132
00133 T &operator *() const
00134 {
00135 return *__ptr;
00136 }
00137
00138 T *operator ->() const
00139 {
00140 if (__cnt.noref()) return 0;
00141
00142 return __ptr;
00143 }
00144
00145 T *get() const
00146 {
00147 if (__cnt.noref()) return 0;
00148
00149 return __ptr;
00150 }
00151
00152 private:
00153
00154 T *__ptr;
00155 RefCnt __cnt;
00156 };
00157
00158 template <class T>
00159 class RefPtr
00160 {
00161 public:
00162
00163 RefPtr(T *ptr = 0)
00164 : __ptr(ptr)
00165 {}
00166
00167 ~RefPtr()
00168 {
00169 if (__cnt.one()) delete __ptr;
00170 }
00171
00172 RefPtr &operator = (const RefPtr &ref)
00173 {
00174 if (this != &ref)
00175 {
00176 if (__cnt.one()) delete __ptr;
00177
00178 __ptr = ref.__ptr;
00179 __cnt = ref.__cnt;
00180 }
00181 return *this;
00182 }
00183
00184 T &operator *() const
00185 {
00186 return *__ptr;
00187 }
00188
00189 T *operator ->() const
00190 {
00191 if (__cnt.noref()) return 0;
00192
00193 return __ptr;
00194 }
00195
00196 T *get() const
00197 {
00198 if (__cnt.noref()) return 0;
00199
00200 return __ptr;
00201 }
00202
00203 private:
00204
00205 T *__ptr;
00206 RefCnt __cnt;
00207 };
00208
00209
00210
00211
00212
00213 template <class R, class P>
00214 class Callback_Base
00215 {
00216 public:
00217
00218 virtual R call(P param) const = 0;
00219
00220 virtual ~Callback_Base()
00221 {}
00222 };
00223
00224 template <class R, class P>
00225 class Slot
00226 {
00227 public:
00228
00229 Slot &operator = (Callback_Base<R, P>* s)
00230 {
00231 _cb = s;
00232
00233 return *this;
00234 }
00235
00236 R operator()(P param) const
00237 {
00238 if (!empty())
00239 {
00240 return _cb->call(param);
00241 }
00242
00243
00244
00245
00246 }
00247
00248 R call(P param) const
00249 {
00250 if (!empty())
00251 {
00252 return _cb->call(param);
00253 }
00254
00255
00256
00257
00258 }
00259
00260 bool empty() const
00261 {
00262 return _cb.get() == 0;
00263 }
00264
00265 private:
00266
00267 RefPtr< Callback_Base<R, P> > _cb;
00268 };
00269
00270 template <class C, class R, class P>
00271 class Callback : public Callback_Base<R, P>
00272 {
00273 public:
00274
00275 typedef R(C::*M)(P);
00276
00277 Callback(C *c, M m)
00278 : _c(c), _m(m)
00279 {}
00280
00281 R call(P param) const
00282 {
00283 return (_c->*_m)(param);
00284 }
00285
00286 private:
00287
00288 C *_c;
00289 M _m;
00290 };
00291
00293 template <typename T>
00294 std::string toString(const T &thing, int w = 0, int p = 0)
00295 {
00296 std::ostringstream os;
00297 os << std::setw(w) << std::setprecision(p) << thing;
00298 return os.str();
00299 }
00300
00301 }
00302
00303 #endif//__DBUSXX_UTIL_H