00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00032
00033 #ifndef GROOVX_RUTZ_SHARED_PTR_H_UTC20070412044942_DEFINED
00034 #define GROOVX_RUTZ_SHARED_PTR_H_UTC20070412044942_DEFINED
00035
00036 #include "rutz/atomic.h"
00037 #include "rutz/traits.h"
00038
00040 namespace rutz
00041 {
00042 namespace shared_ptr_aux
00043 {
00045 typedef void (ptr_check_function)(const void*);
00046
00048
00054 ptr_check_function* set_check_function(ptr_check_function* func);
00055
00057 void check_ptr(const void* p);
00058 }
00059
00060 template <class T> class shared_ptr;
00061 }
00062
00064
00079 template<class T>
00080 class rutz::shared_ptr
00081 {
00082 public:
00084
00093 explicit inline shared_ptr(T* p =0);
00094
00096 inline shared_ptr(const shared_ptr& r) throw();
00097
00099
00101 inline ~shared_ptr();
00102
00104 inline shared_ptr& operator=(const shared_ptr& r);
00105
00107
00110 template<class TT>
00111 inline shared_ptr(const shared_ptr<TT>& r) throw();
00112
00114
00117 template<class TT>
00118 inline shared_ptr& operator=(const shared_ptr<TT>& r);
00119
00121
00156 template <class TT>
00157 inline shared_ptr& dyn_cast_from(const shared_ptr<TT>& r);
00158
00159 template <class TT>
00160 inline shared_ptr& dynCastFrom(const shared_ptr<TT>& r)
00161 { return this->dyn_cast_from(r); }
00162
00164 inline void reset(T* p=0);
00165
00167 inline T& operator*() const throw() { return *px; }
00168
00170 inline T* operator->() const throw() { return px; }
00171
00173 inline T* get() const throw() { return px; }
00174
00176 bool is_valid() const throw() { return px != 0; }
00177
00179 bool is_invalid() const throw() { return px == 0; }
00180
00182 inline int use_count() const throw() { return pn->atomic_get(); }
00183
00185 inline bool unique() const throw() { return use_count() == 1; }
00186
00188 inline void swap(shared_ptr<T>& that) throw();
00189
00190 private:
00191 T* px;
00192 rutz::atomic_int_t* pn;
00193
00194 template<class TT> friend class shared_ptr;
00195 };
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 namespace rutz
00206 {
00207
00209 template<class T, class U>
00210 inline bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b)
00211 {
00212 return a.get() == b.get();
00213 }
00214
00216 template<class T, class U>
00217 inline bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b)
00218 {
00219 return a.get() != b.get();
00220 }
00221
00223 template <class T>
00224 inline shared_ptr<T> make_shared(T* t) { return shared_ptr<T>(t); }
00225
00227 template <class Dst, class Src>
00228 inline shared_ptr<Dst> dyn_cast(const shared_ptr<Src>& src)
00229 {
00230 shared_ptr<Dst> dst;
00231 dst.dyn_cast_from(src);
00232 return dst;
00233 }
00234
00236 template <class Dst, class Src>
00237 inline void dyn_cast_to_from(shared_ptr<Dst>& dst, const shared_ptr<Src>& src)
00238 {
00239 dst.dyn_cast_from(src);
00240 }
00241
00243 template <class Dst, class Src>
00244 inline shared_ptr<Dst> dynCast(const shared_ptr<Src>& src)
00245 { return dyn_cast<Dst,Src>(src); }
00246
00248 template <class Dst, class Src>
00249 inline void dynCastToFrom(shared_ptr<Dst>& dst, const shared_ptr<Src>& src)
00250 { dyn_cast_to_from<Dst,Src>(dst, src); }
00251
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261 template <class T> inline
00262 rutz::shared_ptr<T>::shared_ptr(T* p) :
00263 px(p), pn(0)
00264 {
00265 #if defined(GVX_MEM_DEBUG)
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 rutz::shared_ptr_aux::check_ptr(rutz::full_object_cast(p));
00278 #endif
00279
00280
00281 try { pn = new rutz::atomic_int_t; pn->atomic_set(1); }
00282 catch (...) { delete p; throw; }
00283 }
00284
00285
00286 template <class T> inline
00287 rutz::shared_ptr<T>::shared_ptr(const shared_ptr<T>& r) throw() :
00288 px(r.px), pn(r.pn)
00289 {
00290 pn->atomic_incr();
00291 }
00292
00293
00294 template <class T> inline
00295 rutz::shared_ptr<T>::~shared_ptr()
00296 {
00297 if (pn->atomic_decr_test_zero())
00298 {
00299 delete px; px = 0;
00300 delete pn; pn = 0;
00301 }
00302 }
00303
00304
00305 template <class T> inline
00306 rutz::shared_ptr<T>&
00307 rutz::shared_ptr<T>::operator=(const rutz::shared_ptr<T>& r)
00308 {
00309 shared_ptr(r).swap(*this);
00310 return *this;
00311 }
00312
00313
00314 template <class T>
00315 template<class TT> inline
00316 rutz::shared_ptr<T>::shared_ptr(const rutz::shared_ptr<TT>& r) throw() :
00317 px(r.px), pn(r.pn)
00318 {
00319 pn->atomic_incr();
00320 }
00321
00322
00323 template <class T>
00324 template<class TT> inline
00325 rutz::shared_ptr<T>&
00326 rutz::shared_ptr<T>::operator=(const rutz::shared_ptr<TT>& r)
00327 {
00328 shared_ptr(r).swap(*this);
00329 return *this;
00330 }
00331
00332
00333 template <class T>
00334 template<class TT> inline
00335 rutz::shared_ptr<T>&
00336 rutz::shared_ptr<T>::dyn_cast_from(const rutz::shared_ptr<TT>& r)
00337 {
00338
00339
00340 if (pn->atomic_decr_test_zero())
00341 {
00342 delete px; px = 0;
00343 delete pn; pn = 0;
00344 }
00345
00346
00347 T* const new_px = dynamic_cast<T*>(r.px);
00348
00349 if (new_px == 0 && r.px != 0)
00350 {
00351
00352
00353
00354
00355
00356 pn = new rutz::atomic_int_t; pn->atomic_set(1);
00357 }
00358 else
00359 {
00360
00361 pn = r.pn;
00362
00363
00364 pn->atomic_incr();
00365
00366
00367 px = new_px;
00368 }
00369 return *this;
00370 }
00371
00372
00373 template <class T> inline
00374 void rutz::shared_ptr<T>::reset(T* p)
00375 {
00376 shared_ptr(p).swap(*this);
00377 }
00378
00379
00380 template <class T> inline
00381 void rutz::shared_ptr<T>::swap(shared_ptr<T>& that) throw()
00382 {
00383 T* that_px = that.px; that.px = this->px; this->px = that_px;
00384 rutz::atomic_int_t* that_pn = that.pn; that.pn = this->pn; this->pn = that_pn;
00385 }
00386
00387
00388
00389
00390
00391
00392
00393 static const char __attribute__((used)) vcid_groovx_rutz_shared_ptr_h_utc20070412044942[] = "$Id: shared_ptr.h 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00394 #endif // !GROOVX_RUTZ_SHARED_PTR_H_UTC20070412044942DEFINED