Go to the documentation of this file.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
00027
00028 #ifndef _Reference_Counted_Pointer_
00029 #define _Reference_Counted_Pointer_
00030
00031
00032 #if defined (DEBUG)
00033
00034 #define DEBUG_ALL -1
00035 #define DEBUG_RCP (1 << 14)
00036
00037
00038 #if (DEBUG +0 == DEBUG_RCP)
00039 #define RCP_DEBUG DEBUG_RCP
00040 #endif
00041 #if (DEBUG +0 == DEBUG_ALL)
00042 #define RCP_DEBUG -1
00043 #endif
00044
00045 #include <iostream>
00046 #include <iomanip>
00047 using std::clog;
00048 using std::endl;
00049 #endif // DEBUG
00050
00051
00052 namespace PIRL
00053 {
00118 template <class T>
00119 class Reference_Counted_Pointer
00120 {
00121 private:
00122 T
00123 *Pointer;
00124 long
00125 *Counter;
00126
00127
00128 public:
00129
00146 explicit Reference_Counted_Pointer (T* pointer = 0)
00147 : Pointer (pointer),
00148 Counter (new long (1))
00149 {
00150 #ifdef RCP_DEBUG
00151 clog << ">-< Reference_Counted_Pointer @ " << (void*)this
00152 << " (@" << (void*)Pointer << '#' << *Counter
00153 << ") Constructed from pointer" << endl;
00154 #endif
00155 }
00156
00165 Reference_Counted_Pointer (const Reference_Counted_Pointer<T>& RCP)
00166 : Pointer (RCP.Pointer),
00167 Counter (RCP.Counter)
00168 {
00169 ++*Counter;
00170 #ifdef RCP_DEBUG
00171 clog << ">-< Reference_Counted_Pointer @ " << (void*)this
00172 << " (@" << (void*)Pointer << '#' << *Counter
00173 << ") Copy of RCP @ " << (void*)&RCP << endl;
00174 #endif
00175 }
00176
00184 ~Reference_Counted_Pointer ()
00185 {dispose ();}
00186
00221 Reference_Counted_Pointer<T>& operator=
00222 (const Reference_Counted_Pointer<T>& RCP)
00223 {
00224 #ifdef RCP_DEBUG
00225 clog << ">>> Reference_Counted_Pointer @ " << (void*)this
00226 << " (@" << (void*)Pointer << '#' << *Counter
00227 << ")::operator= (RCP& @ " << (void*)&RCP
00228 << " (@" << (void*)RCP.Pointer << '#' << *RCP.Counter << "))" << endl;
00229 #endif
00230 if (this != &RCP)
00231 {
00232 if (Pointer != RCP.Pointer)
00233 {
00234
00235 #ifdef RCP_DEBUG
00236 clog << " normal assignment" << endl;
00237 #endif
00238 dispose ();
00239 Pointer = RCP.Pointer;
00240 }
00241 else
00242 if (Counter != RCP.Counter)
00243 {
00244
00245
00246
00247
00248
00249
00250
00251 if (--*Counter == 0)
00252 delete Counter;
00253 #ifdef RCP_DEBUG
00254 clog << " same Pointer, different Counters!" << endl;
00255 #endif
00256 }
00257 Counter = RCP.Counter;
00258 ++*Counter;
00259 #ifdef RCP_DEBUG
00260 clog << " Counter = " << *Counter << endl;
00261 #endif
00262 }
00263 #ifdef RCP_DEBUG
00264 clog << "<<< Reference_Counted_Pointer operator= (RCP&)" << endl;
00265 #endif
00266 return *this;
00267 }
00268
00295 Reference_Counted_Pointer<T>& operator= (T* pointer)
00296 {
00297 #ifdef RCP_DEBUG
00298 clog << ">>> Reference_Counted_Pointer @ " << (void*)this
00299 << " (@" << (void*)Pointer << '#' << *Counter
00300 << ")::operator= (T* " << (void*)pointer << ")" << endl;
00301 #endif
00302 if (Pointer != pointer)
00303 {
00304 dispose ();
00305 Pointer = pointer;
00306 Counter = new long (1);
00307 #ifdef RCP_DEBUG
00308 clog << " reset Pointer and Counter" << endl;
00309 #endif
00310 }
00311 #ifdef RCP_DEBUG
00312 else
00313 clog << " same Pointer" << endl;
00314 clog << "<<< Reference_Counted_Pointer::operator= (T*)" << endl;
00315 #endif
00316 return *this;
00317 }
00318
00324 T& operator* () const
00325 {
00326 #if defined (RCP_DEBUG) && (RCP_DEBUG == DEBUG_ALL)
00327 clog << ">-< Reference_Counted_Pointer @ " << (void*)this
00328 << " (@" << (void*)Pointer << '#' << *Counter
00329 << ")::operator*" << endl;
00330 #endif
00331 return *Pointer;
00332 }
00333
00339 T* operator-> () const
00340 {
00341 #if defined (RCP_DEBUG) && (RCP_DEBUG == DEBUG_ALL)
00342 clog << ">-< Reference_Counted_Pointer @ " << (void*)this
00343 << " (@" << (void*)Pointer << '#' << *Counter
00344 << ")::operator->" << endl;
00345 #endif
00346 return Pointer;
00347 }
00348
00354 operator T* () const
00355 {return Pointer;}
00356
00363 operator bool () const
00364 {return Pointer != 0;}
00365
00366
00381 bool operator== (const Reference_Counted_Pointer& RCP) const
00382 {return Pointer == RCP.Pointer;}
00383
00384
00396 bool operator!= (const Reference_Counted_Pointer& RCP) const
00397 {return Pointer != RCP.Pointer;}
00398
00423 bool is_distinct_from (const Reference_Counted_Pointer& RCP) const
00424 {return Pointer != RCP.Pointer || Counter != RCP.Counter;}
00425
00426
00431 long reference_count () const
00432 {return *Counter;}
00433
00434
00435 protected:
00441 void dispose ()
00442 {
00443 #ifdef RCP_DEBUG
00444 clog << ">-< Reference_Counted_Pointer @ " << (void*)this
00445 << " (@" << (void*)Pointer << '#' << *Counter << ")::dispose" << endl;
00446 #endif
00447 if (--*Counter == 0)
00448 {
00449 delete Counter;
00450 if (Pointer)
00451 {
00452 #ifdef RCP_DEBUG
00453 clog << " delete object @ " << (void*)Pointer << endl;
00454 #endif
00455 delete Pointer;
00456 Pointer = 0;
00457 }
00458 }
00459 }
00460 };
00461
00462
00463 }
00464 #endif // _Reference_Counted_Pointer_