util.h
Go to the documentation of this file.
00001 /* 00002 * 00003 * D-Bus++ - C++ bindings for D-Bus 00004 * 00005 * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> 00006 * 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 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 * Very simple reference counting 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 * Reference counting pointers (emulate boost::shared_ptr) 00110 */ 00111 00112 template <class T> 00113 class RefPtrI // RefPtr to incomplete type 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 * Typed callback template 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 // TODO: think about return type in this case 00244 // this assert should help me to find the use case where it's needed... 00245 //assert (false); 00246 return _cb->call(param); 00247 } 00248 00249 R call(P param) const 00250 { 00251 if (!empty()) 00252 { 00253 return _cb->call(param); 00254 } 00255 00256 // TODO: think about return type in this case 00257 // this assert should help me to find the use case where it's needed... 00258 //assert (false); 00259 return _cb->call(param); 00260 00261 } 00262 00263 bool empty() const 00264 { 00265 return _cb.get() == 0; 00266 } 00267 00268 private: 00269 00270 RefPtr< Callback_Base<R, P> > _cb; 00271 }; 00272 00273 template <class C, class R, class P> 00274 class Callback : public Callback_Base<R, P> 00275 { 00276 public: 00277 00278 typedef R(C::*M)(P); 00279 00280 Callback(C *c, M m) 00281 : _c(c), _m(m) 00282 {} 00283 00284 R call(P param) const 00285 { 00286 /*if (_c)*/ return (_c->*_m)(param); 00287 } 00288 00289 private: 00290 00291 C *_c; 00292 M _m; 00293 }; 00294 00296 template <typename T> 00297 std::string toString(const T &thing, int w = 0, int p = 0) 00298 { 00299 std::ostringstream os; 00300 os << std::setw(w) << std::setprecision(p) << thing; 00301 return os.str(); 00302 } 00303 00304 } /* namespace DBus */ 00305 00306 #endif//__DBUSXX_UTIL_H