00001 #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
00002 #define BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
00003
00004
00005
00006 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
00007 # pragma once
00008 #endif
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef __BORLANDC__
00022 # pragma warn -8027 // Functions containing try are not expanded inline
00023 #endif
00024
00025 #include <sysc/packages/boost/config.hpp>
00026 #include <sysc/packages/boost/checked_delete.hpp>
00027 #include <sysc/packages/boost/throw_exception.hpp>
00028 #include <sysc/packages/boost/detail/bad_weak_ptr.hpp>
00029 #include <sysc/packages/boost/detail/sp_counted_base.hpp>
00030 #include <sysc/packages/boost/detail/sp_counted_impl.hpp>
00031
00032 #include <memory>
00033 #include <functional>
00034 #include <new>
00035 #include <typeinfo>
00036
00037 namespace boost
00038 {
00039
00040 namespace detail
00041 {
00042
00043 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00044
00045 int const shared_count_id = 0x2C35F101;
00046 int const weak_count_id = 0x298C38A4;
00047
00048 #endif
00049
00050 class weak_count;
00051
00052 class shared_count
00053 {
00054 private:
00055
00056 sp_counted_base * pi_;
00057
00058 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00059 int id_;
00060 #endif
00061
00062 friend class weak_count;
00063
00064 public:
00065
00066 shared_count(): pi_(0)
00067 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00068 , id_(shared_count_id)
00069 #endif
00070 {
00071 }
00072
00073 template<class Y> explicit shared_count( Y * p ): pi_( 0 )
00074 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00075 , id_(shared_count_id)
00076 #endif
00077 {
00078 #ifndef BOOST_NO_EXCEPTIONS
00079
00080 try
00081 {
00082 pi_ = new sp_counted_impl_p<Y>( p );
00083 }
00084 catch(...)
00085 {
00086 boost::checked_delete( p );
00087 throw;
00088 }
00089
00090 #else
00091
00092 pi_ = new sp_counted_impl_p<Y>( p );
00093
00094 if( pi_ == 0 )
00095 {
00096 boost::checked_delete( p );
00097 boost::throw_exception( std::bad_alloc() );
00098 }
00099
00100 #endif
00101 }
00102
00103 template<class P, class D> shared_count(P p, D d): pi_(0)
00104 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00105 , id_(shared_count_id)
00106 #endif
00107 {
00108 #ifndef BOOST_NO_EXCEPTIONS
00109
00110 try
00111 {
00112 pi_ = new sp_counted_impl_pd<P, D>(p, d);
00113 }
00114 catch(...)
00115 {
00116 d(p);
00117 throw;
00118 }
00119
00120 #else
00121
00122 pi_ = new sp_counted_impl_pd<P, D>(p, d);
00123
00124 if(pi_ == 0)
00125 {
00126 d(p);
00127 boost::throw_exception(std::bad_alloc());
00128 }
00129
00130 #endif
00131 }
00132
00133 #ifndef BOOST_NO_AUTO_PTR
00134
00135
00136
00137 template<class Y>
00138 explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) )
00139 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00140 , id_(shared_count_id)
00141 #endif
00142 {
00143 #ifdef BOOST_NO_EXCEPTIONS
00144
00145 if( pi_ == 0 )
00146 {
00147 boost::throw_exception(std::bad_alloc());
00148 }
00149
00150 #endif
00151
00152 r.release();
00153 }
00154
00155 #endif
00156
00157 ~shared_count()
00158 {
00159 if( pi_ != 0 ) pi_->release();
00160 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00161 id_ = 0;
00162 #endif
00163 }
00164
00165 shared_count(shared_count const & r): pi_(r.pi_)
00166 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00167 , id_(shared_count_id)
00168 #endif
00169 {
00170 if( pi_ != 0 ) pi_->add_ref_copy();
00171 }
00172
00173 explicit shared_count(weak_count const & r);
00174
00175 shared_count & operator= (shared_count const & r)
00176 {
00177 sp_counted_base * tmp = r.pi_;
00178
00179 if( tmp != pi_ )
00180 {
00181 if( tmp != 0 ) tmp->add_ref_copy();
00182 if( pi_ != 0 ) pi_->release();
00183 pi_ = tmp;
00184 }
00185
00186 return *this;
00187 }
00188
00189 void swap(shared_count & r)
00190 {
00191 sp_counted_base * tmp = r.pi_;
00192 r.pi_ = pi_;
00193 pi_ = tmp;
00194 }
00195
00196 long use_count() const
00197 {
00198 return pi_ != 0? pi_->use_count(): 0;
00199 }
00200
00201 bool unique() const
00202 {
00203 return use_count() == 1;
00204 }
00205
00206 friend inline bool operator==(shared_count const & a, shared_count const & b)
00207 {
00208 return a.pi_ == b.pi_;
00209 }
00210
00211 friend inline bool operator<(shared_count const & a, shared_count const & b)
00212 {
00213 return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
00214 }
00215
00216 void * get_deleter(std::type_info const & ti) const
00217 {
00218 return pi_? pi_->get_deleter( ti ): 0;
00219 }
00220 };
00221
00222
00223 class weak_count
00224 {
00225 private:
00226
00227 sp_counted_base * pi_;
00228
00229 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00230 int id_;
00231 #endif
00232
00233 friend class shared_count;
00234
00235 public:
00236
00237 weak_count(): pi_(0)
00238 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00239 , id_(weak_count_id)
00240 #endif
00241 {
00242 }
00243
00244 weak_count(shared_count const & r): pi_(r.pi_)
00245 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00246 , id_(shared_count_id)
00247 #endif
00248 {
00249 if(pi_ != 0) pi_->weak_add_ref();
00250 }
00251
00252 weak_count(weak_count const & r): pi_(r.pi_)
00253 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00254 , id_(shared_count_id)
00255 #endif
00256 {
00257 if(pi_ != 0) pi_->weak_add_ref();
00258 }
00259
00260 ~weak_count()
00261 {
00262 if(pi_ != 0) pi_->weak_release();
00263 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00264 id_ = 0;
00265 #endif
00266 }
00267
00268 weak_count & operator= (shared_count const & r)
00269 {
00270 sp_counted_base * tmp = r.pi_;
00271 if(tmp != 0) tmp->weak_add_ref();
00272 if(pi_ != 0) pi_->weak_release();
00273 pi_ = tmp;
00274
00275 return *this;
00276 }
00277
00278 weak_count & operator= (weak_count const & r)
00279 {
00280 sp_counted_base * tmp = r.pi_;
00281 if(tmp != 0) tmp->weak_add_ref();
00282 if(pi_ != 0) pi_->weak_release();
00283 pi_ = tmp;
00284
00285 return *this;
00286 }
00287
00288 void swap(weak_count & r)
00289 {
00290 sp_counted_base * tmp = r.pi_;
00291 r.pi_ = pi_;
00292 pi_ = tmp;
00293 }
00294
00295 long use_count() const
00296 {
00297 return pi_ != 0? pi_->use_count(): 0;
00298 }
00299
00300 friend inline bool operator==(weak_count const & a, weak_count const & b)
00301 {
00302 return a.pi_ == b.pi_;
00303 }
00304
00305 friend inline bool operator<(weak_count const & a, weak_count const & b)
00306 {
00307 return std::less<sp_counted_base *>()(a.pi_, b.pi_);
00308 }
00309 };
00310
00311 inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
00312 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00313 , id_(shared_count_id)
00314 #endif
00315 {
00316 if( pi_ == 0 || !pi_->add_ref_lock() )
00317 {
00318 boost::throw_exception( boost::bad_weak_ptr() );
00319 }
00320 }
00321
00322 }
00323
00324 }
00325
00326 #ifdef __BORLANDC__
00327 # pragma warn .8027 // Functions containing try are not expanded inline
00328 #endif
00329
00330 #endif // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED