refptr.h
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
00026 #ifndef __CORE_UTILS_REFPTR_H_
00027 #define __CORE_UTILS_REFPTR_H_
00028
00029 #include <core/threading/mutex.h>
00030
00031 namespace fawkes {
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 template <class T_CppObject>
00050 class RefPtr
00051 {
00052 public:
00053
00054
00055
00056
00057 inline RefPtr();
00058
00059
00060 inline ~RefPtr();
00061
00062
00063
00064
00065
00066
00067
00068 explicit inline RefPtr(T_CppObject* cpp_object);
00069
00070
00071
00072
00073
00074 inline RefPtr(const RefPtr<T_CppObject>& src);
00075
00076
00077
00078
00079
00080 template <class T_CastFrom>
00081 inline RefPtr(const RefPtr<T_CastFrom>& src);
00082
00083
00084
00085
00086
00087
00088
00089 inline void swap(RefPtr<T_CppObject>& other);
00090
00091
00092
00093
00094
00095 inline RefPtr<T_CppObject>& operator=(const RefPtr<T_CppObject>& src);
00096
00097
00098
00099
00100
00101
00102 template <class T_CastFrom>
00103 inline RefPtr<T_CppObject>& operator=(const RefPtr<T_CastFrom>& src);
00104
00105
00106
00107
00108
00109 inline RefPtr<T_CppObject>& operator=(T_CppObject *ptr);
00110
00111
00112
00113
00114
00115
00116 inline bool operator==(const RefPtr<T_CppObject>& src) const;
00117
00118
00119
00120
00121
00122 inline bool operator!=(const RefPtr<T_CppObject>& src) const;
00123
00124
00125
00126
00127
00128
00129 inline T_CppObject* operator->() const;
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 inline operator bool() const;
00140
00141
00142 inline void clear();
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 template <class T_CastFrom>
00155 static inline RefPtr<T_CppObject> cast_dynamic(const RefPtr<T_CastFrom>& src);
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 template <class T_CastFrom>
00167 static inline RefPtr<T_CppObject> cast_static(const RefPtr<T_CastFrom>& src);
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 template <class T_CastFrom>
00179 static inline RefPtr<T_CppObject> cast_const(const RefPtr<T_CastFrom>& src);
00180
00181
00182
00183
00184
00185
00186 explicit inline RefPtr(T_CppObject *cpp_object, int *refcount, Mutex *refmutex);
00187
00188
00189
00190
00191
00192
00193
00194 inline int * refcount_ptr() const { return __ref_count; }
00195
00196
00197
00198
00199
00200 inline Mutex * refmutex_ptr() const { return __ref_mutex; }
00201
00202 private:
00203
00204 T_CppObject *__cpp_object;
00205 mutable int *__ref_count;
00206 mutable Mutex *__ref_mutex;
00207
00208 };
00209
00210
00211
00212
00213
00214 template <class T_CppObject> inline
00215 T_CppObject* RefPtr<T_CppObject>::operator->() const
00216 {
00217 return __cpp_object;
00218 }
00219
00220 template <class T_CppObject> inline
00221 RefPtr<T_CppObject>::RefPtr()
00222 :
00223 __cpp_object(0),
00224 __ref_count(0),
00225 __ref_mutex(0)
00226 {}
00227
00228 template <class T_CppObject> inline
00229 RefPtr<T_CppObject>::~RefPtr()
00230 {
00231 if(__ref_count && __ref_mutex)
00232 {
00233 __ref_mutex->lock();
00234
00235 --(*__ref_count);
00236
00237 if(*__ref_count == 0)
00238 {
00239 if(__cpp_object)
00240 {
00241 delete __cpp_object;
00242 __cpp_object = 0;
00243 }
00244
00245 delete __ref_count;
00246 delete __ref_mutex;
00247 __ref_count = 0;
00248 __ref_mutex = 0;
00249 } else {
00250 __ref_mutex->unlock();
00251 }
00252 }
00253 }
00254
00255
00256 template <class T_CppObject> inline
00257 RefPtr<T_CppObject>::RefPtr(T_CppObject* cpp_object)
00258 :
00259 __cpp_object(cpp_object),
00260 __ref_count(0),
00261 __ref_mutex(0)
00262 {
00263 if(cpp_object)
00264 {
00265 __ref_count = new int;
00266 __ref_mutex = new Mutex();
00267 *__ref_count = 1;
00268 }
00269 }
00270
00271
00272 template <class T_CppObject> inline
00273 RefPtr<T_CppObject>::RefPtr(T_CppObject* cpp_object, int* refcount, Mutex *refmutex)
00274 :
00275 __cpp_object(cpp_object),
00276 __ref_count(refcount),
00277 __ref_mutex(refmutex)
00278 {
00279 if(__cpp_object && __ref_count && __ref_mutex) {
00280 __ref_mutex->lock();
00281 ++(*__ref_count);
00282 __ref_mutex->unlock();
00283 }
00284 }
00285
00286 template <class T_CppObject> inline
00287 RefPtr<T_CppObject>::RefPtr(const RefPtr<T_CppObject>& src)
00288 :
00289 __cpp_object (src.__cpp_object),
00290 __ref_count(src.__ref_count),
00291 __ref_mutex(src.__ref_mutex)
00292 {
00293 if(__cpp_object && __ref_count && __ref_mutex)
00294 {
00295 __ref_mutex->lock();
00296 ++(*__ref_count);
00297 __ref_mutex->unlock();
00298 }
00299 }
00300
00301
00302
00303
00304 template <class T_CppObject>
00305 template <class T_CastFrom>
00306 inline
00307 RefPtr<T_CppObject>::RefPtr(const RefPtr<T_CastFrom>& src)
00308 :
00309
00310
00311
00312 __cpp_object (src.operator->()),
00313 __ref_count(src.refcount_ptr()),
00314 __ref_mutex(src.refmutex_ptr())
00315 {
00316 if(__cpp_object && __ref_count && __ref_mutex) {
00317 __ref_mutex->lock();
00318 ++(*__ref_count);
00319 __ref_mutex->unlock();
00320 }
00321 }
00322
00323 template <class T_CppObject> inline
00324 void
00325 RefPtr<T_CppObject>::swap(RefPtr<T_CppObject>& other)
00326 {
00327 T_CppObject *const temp = __cpp_object;
00328 int *temp_count = __ref_count;
00329 Mutex *temp_mutex = __ref_mutex;
00330
00331 __cpp_object = other.__cpp_object;
00332 __ref_count = other.__ref_count;
00333 __ref_mutex = other.__ref_mutex;
00334
00335 other.__cpp_object = temp;
00336 other.__ref_count = temp_count;
00337 other.__ref_mutex = temp_mutex;
00338 }
00339
00340 template <class T_CppObject> inline
00341 RefPtr<T_CppObject>&
00342 RefPtr<T_CppObject>::operator=(const RefPtr<T_CppObject>& src)
00343 {
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 RefPtr<T_CppObject> temp (src);
00369 this->swap(temp);
00370 return *this;
00371 }
00372
00373 template <class T_CppObject> inline
00374 RefPtr<T_CppObject>&
00375 RefPtr<T_CppObject>::operator=(T_CppObject *ptr)
00376 {
00377 RefPtr<T_CppObject> temp(ptr);
00378 this->swap(temp);
00379 return *this;
00380 }
00381
00382
00383 template <class T_CppObject>
00384 template <class T_CastFrom>
00385 inline
00386 RefPtr<T_CppObject>&
00387 RefPtr<T_CppObject>::operator=(const RefPtr<T_CastFrom>& src)
00388 {
00389 RefPtr<T_CppObject> temp (src);
00390 this->swap(temp);
00391 return *this;
00392 }
00393
00394 template <class T_CppObject> inline
00395 bool
00396 RefPtr<T_CppObject>::operator==(const RefPtr<T_CppObject>& src) const
00397 {
00398 return (__cpp_object == src.__cpp_object);
00399 }
00400
00401 template <class T_CppObject> inline
00402 bool
00403 RefPtr<T_CppObject>::operator!=(const RefPtr<T_CppObject>& src) const
00404 {
00405 return (__cpp_object != src.__cpp_object);
00406 }
00407
00408 template <class T_CppObject> inline
00409 RefPtr<T_CppObject>::operator bool() const
00410 {
00411 return (__cpp_object != 0);
00412 }
00413
00414 template <class T_CppObject> inline
00415 void RefPtr<T_CppObject>::clear()
00416 {
00417 RefPtr<T_CppObject> temp;
00418 this->swap(temp);
00419 }
00420
00421 template <class T_CppObject>
00422 template <class T_CastFrom>
00423 inline
00424 RefPtr<T_CppObject>
00425 RefPtr<T_CppObject>::cast_dynamic(const RefPtr<T_CastFrom>& src)
00426 {
00427 T_CppObject *const cpp_object = dynamic_cast<T_CppObject*>(src.operator->());
00428
00429 if(cpp_object)
00430 return RefPtr<T_CppObject>(cpp_object, src.refcount_ptr(), src.refmutex_ptr());
00431 else
00432 return RefPtr<T_CppObject>();
00433 }
00434
00435 template <class T_CppObject>
00436 template <class T_CastFrom>
00437 inline
00438 RefPtr<T_CppObject>
00439 RefPtr<T_CppObject>::cast_static(const RefPtr<T_CastFrom>& src)
00440 {
00441 T_CppObject *const cpp_object = static_cast<T_CppObject*>(src.operator->());
00442
00443 return RefPtr<T_CppObject>(cpp_object, src.refcount_ptr(), src.refmutex_ptr());
00444 }
00445
00446 template <class T_CppObject>
00447 template <class T_CastFrom>
00448 inline
00449 RefPtr<T_CppObject>
00450 RefPtr<T_CppObject>::cast_const(const RefPtr<T_CastFrom>& src)
00451 {
00452 T_CppObject *const cpp_object = const_cast<T_CppObject*>(src.operator->());
00453
00454 return RefPtr<T_CppObject>(cpp_object, src.refcount_ptr(), src.refmutex_ptr());
00455 }
00456
00457
00458
00459
00460
00461
00462
00463 template <class T_CppObject> inline
00464 void
00465 swap(RefPtr<T_CppObject>& lrp, RefPtr<T_CppObject>& rrp)
00466 {
00467 lrp.swap(rrp);
00468 }
00469
00470 }
00471
00472
00473 #endif