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 inline T_CppObject* operator->() const;
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 inline operator bool() const;
00139
00140
00141 inline void clear();
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 template <class T_CastFrom>
00154 static inline RefPtr<T_CppObject> cast_dynamic(const RefPtr<T_CastFrom>& src);
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 template <class T_CastFrom>
00166 static inline RefPtr<T_CppObject> cast_static(const RefPtr<T_CastFrom>& src);
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 template <class T_CastFrom>
00178 static inline RefPtr<T_CppObject> cast_const(const RefPtr<T_CastFrom>& src);
00179
00180
00181
00182
00183
00184
00185 explicit inline RefPtr(T_CppObject *cpp_object, int *refcount, Mutex *refmutex);
00186
00187
00188
00189
00190
00191
00192
00193 inline int * refcount_ptr() const { return __ref_count; }
00194
00195
00196
00197
00198
00199 inline Mutex * refmutex_ptr() const { return __ref_mutex; }
00200
00201 private:
00202
00203 T_CppObject *__cpp_object;
00204 mutable int *__ref_count;
00205 mutable Mutex *__ref_mutex;
00206
00207 };
00208
00209
00210
00211
00212
00213 template <class T_CppObject> inline
00214 T_CppObject* RefPtr<T_CppObject>::operator->() const
00215 {
00216 return __cpp_object;
00217 }
00218
00219 template <class T_CppObject> inline
00220 RefPtr<T_CppObject>::RefPtr()
00221 :
00222 __cpp_object(0),
00223 __ref_count(0),
00224 __ref_mutex(0)
00225 {}
00226
00227 template <class T_CppObject> inline
00228 RefPtr<T_CppObject>::~RefPtr()
00229 {
00230 if(__ref_count && __ref_mutex)
00231 {
00232 __ref_mutex->lock();
00233
00234 --(*__ref_count);
00235
00236 if(*__ref_count == 0)
00237 {
00238 if(__cpp_object)
00239 {
00240 delete __cpp_object;
00241 __cpp_object = 0;
00242 }
00243
00244 delete __ref_count;
00245 delete __ref_mutex;
00246 __ref_count = 0;
00247 __ref_mutex = 0;
00248 } else {
00249 __ref_mutex->unlock();
00250 }
00251 }
00252 }
00253
00254
00255 template <class T_CppObject> inline
00256 RefPtr<T_CppObject>::RefPtr(T_CppObject* cpp_object)
00257 :
00258 __cpp_object(cpp_object),
00259 __ref_count(0),
00260 __ref_mutex(0)
00261 {
00262 if(cpp_object)
00263 {
00264 __ref_count = new int;
00265 __ref_mutex = new Mutex();
00266 *__ref_count = 1;
00267 }
00268 }
00269
00270
00271 template <class T_CppObject> inline
00272 RefPtr<T_CppObject>::RefPtr(T_CppObject* cpp_object, int* refcount, Mutex *refmutex)
00273 :
00274 __cpp_object(cpp_object),
00275 __ref_count(refcount),
00276 __ref_mutex(refmutex)
00277 {
00278 if(__cpp_object && __ref_count && __ref_mutex) {
00279 __ref_mutex->lock();
00280 ++(*__ref_count);
00281 __ref_mutex->unlock();
00282 }
00283 }
00284
00285 template <class T_CppObject> inline
00286 RefPtr<T_CppObject>::RefPtr(const RefPtr<T_CppObject>& src)
00287 :
00288 __cpp_object (src.__cpp_object),
00289 __ref_count(src.__ref_count),
00290 __ref_mutex(src.__ref_mutex)
00291 {
00292 if(__cpp_object && __ref_count && __ref_mutex)
00293 {
00294 __ref_mutex->lock();
00295 ++(*__ref_count);
00296 __ref_mutex->unlock();
00297 }
00298 }
00299
00300
00301
00302
00303 template <class T_CppObject>
00304 template <class T_CastFrom>
00305 inline
00306 RefPtr<T_CppObject>::RefPtr(const RefPtr<T_CastFrom>& src)
00307 :
00308
00309
00310
00311 __cpp_object (src.operator->()),
00312 __ref_count(src.refcount_ptr()),
00313 __ref_mutex(src.refmutex_ptr())
00314 {
00315 if(__cpp_object && __ref_count && __ref_mutex) {
00316 __ref_mutex->lock();
00317 ++(*__ref_count);
00318 __ref_mutex->unlock();
00319 }
00320 }
00321
00322 template <class T_CppObject> inline
00323 void
00324 RefPtr<T_CppObject>::swap(RefPtr<T_CppObject>& other)
00325 {
00326 T_CppObject *const temp = __cpp_object;
00327 int *temp_count = __ref_count;
00328 Mutex *temp_mutex = __ref_mutex;
00329
00330 __cpp_object = other.__cpp_object;
00331 __ref_count = other.__ref_count;
00332 __ref_mutex = other.__ref_mutex;
00333
00334 other.__cpp_object = temp;
00335 other.__ref_count = temp_count;
00336 other.__ref_mutex = temp_mutex;
00337 }
00338
00339 template <class T_CppObject> inline
00340 RefPtr<T_CppObject>&
00341 RefPtr<T_CppObject>::operator=(const RefPtr<T_CppObject>& src)
00342 {
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 RefPtr<T_CppObject> temp (src);
00368 this->swap(temp);
00369 return *this;
00370 }
00371
00372 template <class T_CppObject> inline
00373 RefPtr<T_CppObject>&
00374 RefPtr<T_CppObject>::operator=(T_CppObject *ptr)
00375 {
00376 RefPtr<T_CppObject> temp(ptr);
00377 this->swap(temp);
00378 return *this;
00379 }
00380
00381
00382 template <class T_CppObject>
00383 template <class T_CastFrom>
00384 inline
00385 RefPtr<T_CppObject>&
00386 RefPtr<T_CppObject>::operator=(const RefPtr<T_CastFrom>& src)
00387 {
00388 RefPtr<T_CppObject> temp (src);
00389 this->swap(temp);
00390 return *this;
00391 }
00392
00393 template <class T_CppObject> inline
00394 bool
00395 RefPtr<T_CppObject>::operator==(const RefPtr<T_CppObject>& src) const
00396 {
00397 return (__cpp_object == src.__cpp_object);
00398 }
00399
00400 template <class T_CppObject> inline
00401 bool
00402 RefPtr<T_CppObject>::operator!=(const RefPtr<T_CppObject>& src) const
00403 {
00404 return (__cpp_object != src.__cpp_object);
00405 }
00406
00407 template <class T_CppObject> inline
00408 RefPtr<T_CppObject>::operator bool() const
00409 {
00410 return (__cpp_object != 0);
00411 }
00412
00413 template <class T_CppObject> inline
00414 void RefPtr<T_CppObject>::clear()
00415 {
00416 RefPtr<T_CppObject> temp;
00417 this->swap(temp);
00418 }
00419
00420 template <class T_CppObject>
00421 template <class T_CastFrom>
00422 inline
00423 RefPtr<T_CppObject>
00424 RefPtr<T_CppObject>::cast_dynamic(const RefPtr<T_CastFrom>& src)
00425 {
00426 T_CppObject *const cpp_object = dynamic_cast<T_CppObject*>(src.operator->());
00427
00428 if(cpp_object)
00429 return RefPtr<T_CppObject>(cpp_object, src.refcount_ptr(), src.refmutex_ptr());
00430 else
00431 return RefPtr<T_CppObject>();
00432 }
00433
00434 template <class T_CppObject>
00435 template <class T_CastFrom>
00436 inline
00437 RefPtr<T_CppObject>
00438 RefPtr<T_CppObject>::cast_static(const RefPtr<T_CastFrom>& src)
00439 {
00440 T_CppObject *const cpp_object = static_cast<T_CppObject*>(src.operator->());
00441
00442 return RefPtr<T_CppObject>(cpp_object, src.refcount_ptr(), src.refmutex_ptr());
00443 }
00444
00445 template <class T_CppObject>
00446 template <class T_CastFrom>
00447 inline
00448 RefPtr<T_CppObject>
00449 RefPtr<T_CppObject>::cast_const(const RefPtr<T_CastFrom>& src)
00450 {
00451 T_CppObject *const cpp_object = const_cast<T_CppObject*>(src.operator->());
00452
00453 return RefPtr<T_CppObject>(cpp_object, src.refcount_ptr(), src.refmutex_ptr());
00454 }
00455
00456
00457
00458
00459
00460
00461
00462 template <class T_CppObject> inline
00463 void
00464 swap(RefPtr<T_CppObject>& lrp, RefPtr<T_CppObject>& rrp)
00465 {
00466 lrp.swap(rrp);
00467 }
00468
00469 }
00470
00471
00472 #endif