sharedptr.h
Go to the documentation of this file.00001 #ifndef CPPTL_SHAREDPTR_H_INCLUDED
00002 # define CPPTL_SHAREDPTR_H_INCLUDED
00003
00004 # include <cpptl/forwards.h>
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 # ifndef CPPTL_USE_BOOST_SHARED_PTR
00015
00016 # include <cpptl/atomiccounter.h>
00017
00018 namespace CppTL
00019 {
00020
00022 namespace Impl {
00023
00024 struct StaticPointerCastTag {};
00025
00027 class SharedPtrBase
00028 {
00029 public:
00030 long use_count() const
00031 {
00032 if ( count_ )
00033 return count_->count();
00034 return 0;
00035 }
00036
00037 bool unique() const
00038 {
00039 return use_count() == 1;
00040 }
00041
00042 operator bool() const
00043 {
00044 return p_ != 0;
00045 }
00046
00047 bool operator !() const
00048 {
00049 return p_ == 0;
00050 }
00051 protected:
00052 SharedPtrBase()
00053 : p_( 0 )
00054 , count_( 0 )
00055 {
00056 }
00057 explicit SharedPtrBase( void *p )
00058 : p_( p )
00059 , count_( p ? new AtomicCounter( 1 ) : 0 )
00060 {
00061 }
00062
00063 SharedPtrBase( void *p,
00064 AtomicCounter *count,
00065 StaticPointerCastTag )
00066 : p_( p )
00067 , count_( count )
00068 {
00069 count_->increment();
00070 }
00071
00072 SharedPtrBase( const SharedPtrBase &other )
00073 : p_( other.p_ )
00074 , count_( other.count_ )
00075 {
00076 if ( p_ )
00077 count_->increment();
00078 }
00079
00080 ~SharedPtrBase()
00081 {
00082
00083 }
00084
00085 bool releaseCount()
00086 {
00087 if ( count_ && count_->decrement() == 0 )
00088 {
00089 delete count_;
00090 return true;
00091 }
00092 return false;
00093 }
00094
00095 void swap( SharedPtrBase &other )
00096 {
00097 void *tmpP = p_;
00098 AtomicCounter *tmpCount = count_;
00099 p_ = other.p_;
00100 count_ = other.count_;
00101 other.p_ = tmpP;
00102 other.count_ = tmpCount;
00103 }
00104
00105 void *get() const
00106 {
00107 return p_;
00108 }
00109
00110 void *deref() const
00111 {
00112
00113 return p_;
00114 }
00115
00116
00117
00118 public:
00119 void *p_;
00120 AtomicCounter *count_;
00121 };
00122
00123 }
00125
00126 template<class PointeeType>
00127 class SharedPtr : public Impl::SharedPtrBase
00128 {
00129 public:
00130 typedef SharedPtr<PointeeType> ThisType;
00131 typedef Impl::SharedPtrBase SuperClass;
00132
00133 SharedPtr()
00134 {
00135 }
00136
00137 explicit SharedPtr( PointeeType *p )
00138 : Impl::SharedPtrBase( p )
00139 {
00140 }
00141
00142 SharedPtr( PointeeType *p,
00143 AtomicCounter *count,
00144 Impl::StaticPointerCastTag )
00145 : Impl::SharedPtrBase( p, count, Impl::StaticPointerCastTag() )
00146 {
00147 }
00148
00149 SharedPtr( const ThisType &other )
00150 : Impl::SharedPtrBase( other )
00151 {
00152 }
00153
00154 ~SharedPtr()
00155 {
00156 if ( releaseCount() )
00157 checkedDelete( static_cast<PointeeType *>( p_ ) );
00158 }
00159
00160 void reset()
00161 {
00162 SharedPtr tmp;
00163 tmp.swap( *this );
00164 }
00165
00166 void reset( PointeeType *p )
00167 {
00168 SharedPtr tmp( p );
00169 tmp.swap( *this );
00170 }
00171
00172 PointeeType *get() const
00173 {
00174 return static_cast<PointeeType *>( SharedPtrBase::get() );
00175 }
00176
00177 void swap( SharedPtr &other )
00178 {
00179 SuperClass::swap( other );
00180 }
00181
00182 ThisType &operator =( const SharedPtr &other )
00183 {
00184 ThisType tmp( other );
00185 swap( tmp );
00186 return *this;
00187 }
00188
00189 PointeeType &operator *() const
00190 {
00191
00192 return *( static_cast<PointeeType *>( p_ ) );
00193 }
00194
00195 PointeeType *operator ->() const
00196 {
00197 return static_cast<PointeeType *>( SuperClass::deref() );
00198 }
00199 };
00200
00201
00202 template<class TargetType, class SourceType>
00203 SharedPtr<TargetType>
00204 staticPointerCast( const SharedPtr<SourceType> &p )
00205 {
00206 TargetType *target = static_cast<TargetType *>( p.p_ );
00207 return SharedPtr<TargetType>( target, p.count_,
00208 Impl::StaticPointerCastTag() );
00209 }
00210
00211 }
00212
00213 # else // ifndef CPPTL_USE_BOOST_SHARED_PTR
00214
00215 # include <boost/shared_ptr.hpp>
00216
00217 namespace CppTL
00218 {
00219
00220 template<class PointeeType>
00221 class SharedPtr : public ::boost::shared_ptr<PointeeType>
00222 {
00223 public:
00224 typedef SharedPtr<PointeeType> ThisType;
00225
00226 SharedPtr()
00227 {
00228 }
00229
00230 explicit SharedPtr( PointeeType *p )
00231 : ::boost::shared_ptr( p )
00232 {
00233 }
00234
00235 SharedPtr( const ::boost::shared_ptr<PointeeType> &other )
00236 : ::boost::shared_ptr( other )
00237 {
00238 }
00239
00240 ThisType &operator =( const ::boost::shared_ptr<PointeeType> &other )
00241 {
00242 return ::boost::shared_ptr<PointeeType>::operator =( other );
00243 }
00244 };
00245
00246
00247 template<class T, class U>
00248 SharedPtr<T>
00249 staticPointerCast( const ::boost::shared_ptr<U> & r)
00250 {
00251 return SharedPtr<T>( ::boost::static_pointer_cast<T>( r ) );
00252 }
00253
00254 }
00255
00256 # endif // ifndef CPPTL_USE_BOOST_SHARED_PTR
00257
00258
00259
00260 #endif // CPPTL_SHAREDPTR_H_INCLUDED
00261