CppUnit project page | CppUnit home page |
00001 #ifndef CPPTL_INTRUSIVEPTR_H_INCLUDED 00002 # define CPPTL_INTRUSIVEPTR_H_INCLUDED 00003 00004 # include <cpptl/forwards.h> 00005 # include <cpptl/atomiccounter.h> 00006 00007 // We use inheritance instead of the typedef in a struct to 00008 // simulate the template typedef because the typedef in a struct 00009 // trick does not support type deduction in template functions. 00010 00011 00012 // If CPPTL_USE_BOOST_INTRUSIVE_PTR is defined, then we use boost::intrusive_ptr 00013 // as our smart_pointer, otherwise we use a simple implementation 00014 // of our own. 00015 00016 namespace CppTL 00017 { 00019 class IntrusiveCount 00020 { 00021 public: 00022 virtual ~IntrusiveCount() 00023 { 00024 } 00025 00026 void incrementReferenceCount() 00027 { 00028 count_.increment(); 00029 } 00030 00031 void releaseReferenceCount() 00032 { 00033 if ( !count_.decrement() ) 00034 delete this; 00035 } 00036 00037 private: 00038 mutable AtomicCounter count_; 00039 }; 00040 00041 } 00042 00043 # ifndef CPPTL_USE_BOOST_SHARED_PTR 00044 namespace CppTL 00045 { 00046 inline void instrusivePtrAddRef( IntrusiveCount *p ) 00047 { 00048 p->incrementReferenceCount(); 00049 } 00050 00051 inline void intrusivePtrRelease( IntrusiveCount *p ) 00052 { 00053 p->releaseReferenceCount(); 00054 } 00055 00056 template<class PointeeType> 00057 class IntrusivePtr 00058 { 00059 public: 00060 typedef IntrusivePtr<PointeeType> ThisType; 00061 00062 IntrusivePtr() 00063 : p_( 0 ) 00064 { 00065 } 00066 00067 IntrusivePtr( PointeeType *p ) 00068 : p_( p ) 00069 { 00070 if ( p ) 00071 instrusivePtrAddRef( p ); 00072 } 00073 00074 IntrusivePtr( const ThisType &other ) 00075 : p_( other.p_ ) 00076 { 00077 if ( p_ ) 00078 instrusivePtrAddRef( p_ ); 00079 } 00080 00081 ~IntrusivePtr() 00082 { 00083 if ( p_ ) 00084 intrusivePtrRelease( p_ ); 00085 } 00086 00087 void reset() 00088 { 00089 IntrusivePtr tmp; 00090 tmp.swap( *this ); 00091 } 00092 00093 void reset( PointeeType *p ) 00094 { 00095 IntrusivePtr tmp( p ); 00096 tmp.swap( *this ); 00097 } 00098 00099 PointeeType *get() const 00100 { 00101 return p_; 00102 } 00103 00104 void swap( ThisType &other ) 00105 { 00106 CppTL::swap( p_, other.p_ ); 00107 } 00108 00109 ThisType &operator =( const ThisType &other ) 00110 { 00111 ThisType tmp( other ); 00112 swap( tmp ); 00113 return *this; 00114 } 00115 00116 PointeeType &operator *() const 00117 { 00118 CPPTL_ASSERT_MESSAGE( p_ != 0, "Attempting to dereference a null pointer with operator *." ); 00119 return *p_; 00120 } 00121 00122 PointeeType *operator ->() const 00123 { 00124 CPPTL_ASSERT_MESSAGE( p_ != 0, "Attempting to use a null pointer with operator ->." ); 00125 return p_; 00126 } 00127 00128 operator bool() const 00129 { 00130 return p_ != 0; 00131 } 00132 00133 bool operator !() const 00134 { 00135 return p_ == 0; 00136 } 00137 00138 bool operator ==( const ThisType &other ) const 00139 { 00140 return p_ == other.p_; 00141 } 00142 00143 bool operator !=( const ThisType &other ) const 00144 { 00145 return !(*this == other ); 00146 } 00147 00148 bool operator <( const ThisType &other ) const 00149 { 00150 return p_ < other.p_; 00151 } 00152 00153 bool operator <=( const ThisType &other ) const 00154 { 00155 return p_ <= other.p_; 00156 } 00157 00158 bool operator >=( const ThisType &other ) const 00159 { 00160 return p_ >= other.p_; 00161 } 00162 00163 bool operator >( const ThisType &other ) const 00164 { 00165 return p_ > other.p_; 00166 } 00167 00168 private: 00169 PointeeType *p_; 00170 }; 00171 00172 00173 template<class T, class U> 00174 IntrusivePtr<T> 00175 staticPointerCast( const IntrusivePtr<U> & r) 00176 { 00177 return IntrusivePtr<T>( static_cast<T*>( r.get() ) ); 00178 } 00179 00180 } // namespace CppTL 00181 00182 # else // ifndef CPPTL_USE_BOOST_SHARED_PTR 00183 00184 # include <boost/shared_ptr.hpp> 00185 00186 namespace CppTL 00187 { 00188 00189 template<class PointeeType> 00190 class IntrusivePtr : public ::boost::intrusive_ptr<PointeeType> 00191 { 00192 public: 00193 typedef IntrusivePtr<PointeeType> ThisType; 00194 00195 IntrusivePtr() 00196 { 00197 } 00198 00199 IntrusivePtr( PointeeType *p ) 00200 : ::boost::intrusive_ptr( p ) 00201 { 00202 } 00203 00204 IntrusivePtr( const ::boost::intrusive_ptr<PointeeType> &other ) 00205 : ::boost::intrusive_ptr( other ) 00206 { 00207 } 00208 00209 ThisType &operator =( const ::boost::intrusive_ptr<PointeeType> &other ) 00210 { 00211 return ::boost::intrusive_ptr<PointeeType>::operator =( other ); 00212 } 00213 }; 00214 00215 00216 template<class T, class U> 00217 IntrusivePtr<T> 00218 staticPointerCast( const ::boost::intrusive_ptr<U> & r) 00219 { 00220 return IntrusivePtr<T>( ::boost::static_pointer_cast<T>( r ) ); 00221 } 00222 00223 } // namespace CppTL 00224 00225 namespace boost { 00226 inline void intrusive_ptr_add_ref( CppTL::IntrusiveCount *p ) 00227 { 00228 p->incrementReferenceCount(); 00229 } 00230 00231 inline void intrusive_ptr_release( CppTL::IntrusiveCount *p ) 00232 { 00233 p->releaseReferenceCount(); 00234 } 00235 } // namespace boost 00236 00237 # endif // ifndef CPPTL_USE_BOOST_SHARED_PTR 00238 00239 00240 namespace CppTL { 00241 00242 template<class DataType> 00243 class SharedDataPtr 00244 { 00245 public: 00246 typedef SharedDataPtr<DataType> ThisType; 00247 typedef DataType Data; 00248 00249 SharedDataPtr() 00250 { 00251 } 00252 00253 SharedDataPtr( const Data &data ) 00254 : shared_( new CountedData( data ) ) 00255 { 00256 } 00257 00258 SharedDataPtr( const ThisType &other ) 00259 : shared_( other.shared_ ) 00260 { 00261 } 00262 00263 ~SharedDataPtr() 00264 { 00265 } 00266 00267 Data *get() const 00268 { 00269 CountedData *data = shared_.get(); 00270 return data ? &(data->data_) : 0; 00271 } 00272 00273 void swap( ThisType &other ) 00274 { 00275 shared_.swap( other.shared_ ); 00276 } 00277 00278 ThisType &operator =( const ThisType &other ) 00279 { 00280 ThisType tmp( other ); 00281 swap( tmp ); 00282 return *this; 00283 } 00284 00285 DataType &operator *() const 00286 { 00287 // assert( p_ != 0 ) 00288 return shared_->data_; 00289 } 00290 00291 DataType *operator ->() const 00292 { 00293 return &(shared_->data_); 00294 } 00295 00296 operator bool() const 00297 { 00298 return shared_; 00299 } 00300 00301 bool operator !() const 00302 { 00303 return !shared_; 00304 } 00305 00306 private: 00307 class CountedData : public IntrusiveCount 00308 { 00309 public: 00310 CountedData( const Data &data ) 00311 : data_( data ) 00312 { 00313 } 00314 00315 Data data_; 00316 }; 00317 00318 IntrusivePtr<CountedData> shared_; 00319 }; 00320 00321 00322 } // namespace CppTL 00323 00324 00325 #endif // CPPTL_INTRUSIVEPTR_H_INCLUDED 00326
hosts this site. |
Send comments to: CppUnit Developers |