shared_count.hpp
Go to the documentation of this file.
00001 #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
00002 #define BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
00003 
00004 // MS compatible compilers support #pragma once
00005 
00006 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
00007 # pragma once
00008 #endif
00009 
00010 //
00011 //  detail/shared_count.hpp
00012 //
00013 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
00014 //  Copyright 2004-2005 Peter Dimov
00015 //
00016 // Distributed under the Boost Software License, Version 1.0. (See
00017 // accompanying file LICENSE_1_0.txt or copy at
00018 // http://www.boost.org/LICENSE_1_0.txt)
00019 //
00020 
00021 #ifdef __BORLANDC__
00022 # pragma warn -8027     // Functions containing try are not expanded inline
00023 #endif
00024 
00025 #include <boost/config.hpp>
00026 #include <boost/checked_delete.hpp>
00027 #include <boost/throw_exception.hpp>
00028 #include <boost/smart_ptr/bad_weak_ptr.hpp>
00029 #include <boost/smart_ptr/detail/sp_counted_base.hpp>
00030 #include <boost/smart_ptr/detail/sp_counted_impl.hpp>
00031 #include <boost/detail/workaround.hpp>
00032 // In order to avoid circular dependencies with Boost.TR1
00033 // we make sure that our include of <memory> doesn't try to
00034 // pull in the TR1 headers: that's why we use this header 
00035 // rather than including <memory> directly:
00036 #include <boost/config/no_tr1/memory.hpp>  // std::auto_ptr
00037 #include <functional>       // std::less
00038 #include <new>              // std::bad_alloc
00039 
00040 namespace boost
00041 {
00042 
00043 namespace detail
00044 {
00045 
00046 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00047 
00048 int const shared_count_id = 0x2C35F101;
00049 int const   weak_count_id = 0x298C38A4;
00050 
00051 #endif
00052 
00053 struct sp_nothrow_tag {};
00054 
00055 class weak_count;
00056 
00057 class shared_count
00058 {
00059 private:
00060 
00061     sp_counted_base * pi_;
00062 
00063 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00064     int id_;
00065 #endif
00066 
00067     friend class weak_count;
00068 
00069 public:
00070 
00071     shared_count(): pi_(0) // nothrow
00072 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00073         , id_(shared_count_id)
00074 #endif
00075     {
00076     }
00077 
00078     template<class Y> explicit shared_count( Y * p ): pi_( 0 )
00079 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00080         , id_(shared_count_id)
00081 #endif
00082     {
00083 #ifndef BOOST_NO_EXCEPTIONS
00084 
00085         try
00086         {
00087             pi_ = new sp_counted_impl_p<Y>( p );
00088         }
00089         catch(...)
00090         {
00091             boost::checked_delete( p );
00092             throw;
00093         }
00094 
00095 #else
00096 
00097         pi_ = new sp_counted_impl_p<Y>( p );
00098 
00099         if( pi_ == 0 )
00100         {
00101             boost::checked_delete( p );
00102             boost::throw_exception( std::bad_alloc() );
00103         }
00104 
00105 #endif
00106     }
00107 
00108 #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
00109     template<class Y, class D> shared_count( Y * p, D d ): pi_(0)
00110 #else
00111     template<class P, class D> shared_count( P p, D d ): pi_(0)
00112 #endif
00113 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00114         , id_(shared_count_id)
00115 #endif
00116     {
00117 #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
00118         typedef Y* P;
00119 #endif
00120 #ifndef BOOST_NO_EXCEPTIONS
00121 
00122         try
00123         {
00124             pi_ = new sp_counted_impl_pd<P, D>(p, d);
00125         }
00126         catch(...)
00127         {
00128             d(p); // delete p
00129             throw;
00130         }
00131 
00132 #else
00133 
00134         pi_ = new sp_counted_impl_pd<P, D>(p, d);
00135 
00136         if(pi_ == 0)
00137         {
00138             d(p); // delete p
00139             boost::throw_exception(std::bad_alloc());
00140         }
00141 
00142 #endif
00143     }
00144 
00145     template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
00146 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00147         , id_(shared_count_id)
00148 #endif
00149     {
00150         typedef sp_counted_impl_pda<P, D, A> impl_type;
00151         typedef typename A::template rebind< impl_type >::other A2;
00152 
00153         A2 a2( a );
00154 
00155 #ifndef BOOST_NO_EXCEPTIONS
00156 
00157         try
00158         {
00159             pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
00160             new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
00161         }
00162         catch(...)
00163         {
00164             d( p );
00165 
00166             if( pi_ != 0 )
00167             {
00168                 a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
00169             }
00170 
00171             throw;
00172         }
00173 
00174 #else
00175 
00176         pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
00177 
00178         if( pi_ != 0 )
00179         {
00180             new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
00181         }
00182         else
00183         {
00184             d( p );
00185             boost::throw_exception( std::bad_alloc() );
00186         }
00187 
00188 #endif
00189     }
00190 
00191 #ifndef BOOST_NO_AUTO_PTR
00192 
00193     // auto_ptr<Y> is special cased to provide the strong guarantee
00194 
00195     template<class Y>
00196     explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) )
00197 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00198         , id_(shared_count_id)
00199 #endif
00200     {
00201 #ifdef BOOST_NO_EXCEPTIONS
00202 
00203         if( pi_ == 0 )
00204         {
00205             boost::throw_exception(std::bad_alloc());
00206         }
00207 
00208 #endif
00209 
00210         r.release();
00211     }
00212 
00213 #endif 
00214 
00215     ~shared_count() // nothrow
00216     {
00217         if( pi_ != 0 ) pi_->release();
00218 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00219         id_ = 0;
00220 #endif
00221     }
00222 
00223     shared_count(shared_count const & r): pi_(r.pi_) // nothrow
00224 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00225         , id_(shared_count_id)
00226 #endif
00227     {
00228         if( pi_ != 0 ) pi_->add_ref_copy();
00229     }
00230 
00231 #if defined( BOOST_HAS_RVALUE_REFS )
00232 
00233     shared_count(shared_count && r): pi_(r.pi_) // nothrow
00234 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00235         , id_(shared_count_id)
00236 #endif
00237     {
00238         r.pi_ = 0;
00239     }
00240 
00241 #endif
00242 
00243     explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
00244     shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0
00245 
00246     shared_count & operator= (shared_count const & r) // nothrow
00247     {
00248         sp_counted_base * tmp = r.pi_;
00249 
00250         if( tmp != pi_ )
00251         {
00252             if( tmp != 0 ) tmp->add_ref_copy();
00253             if( pi_ != 0 ) pi_->release();
00254             pi_ = tmp;
00255         }
00256 
00257         return *this;
00258     }
00259 
00260     void swap(shared_count & r) // nothrow
00261     {
00262         sp_counted_base * tmp = r.pi_;
00263         r.pi_ = pi_;
00264         pi_ = tmp;
00265     }
00266 
00267     long use_count() const // nothrow
00268     {
00269         return pi_ != 0? pi_->use_count(): 0;
00270     }
00271 
00272     bool unique() const // nothrow
00273     {
00274         return use_count() == 1;
00275     }
00276 
00277     bool empty() const // nothrow
00278     {
00279         return pi_ == 0;
00280     }
00281 
00282     friend inline bool operator==(shared_count const & a, shared_count const & b)
00283     {
00284         return a.pi_ == b.pi_;
00285     }
00286 
00287     friend inline bool operator<(shared_count const & a, shared_count const & b)
00288     {
00289         return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
00290     }
00291 
00292     void * get_deleter( sp_typeinfo const & ti ) const
00293     {
00294         return pi_? pi_->get_deleter( ti ): 0;
00295     }
00296 };
00297 
00298 
00299 class weak_count
00300 {
00301 private:
00302 
00303     sp_counted_base * pi_;
00304 
00305 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00306     int id_;
00307 #endif
00308 
00309     friend class shared_count;
00310 
00311 public:
00312 
00313     weak_count(): pi_(0) // nothrow
00314 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00315         , id_(weak_count_id)
00316 #endif
00317     {
00318     }
00319 
00320     weak_count(shared_count const & r): pi_(r.pi_) // nothrow
00321 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00322         , id_(weak_count_id)
00323 #endif
00324     {
00325         if(pi_ != 0) pi_->weak_add_ref();
00326     }
00327 
00328     weak_count(weak_count const & r): pi_(r.pi_) // nothrow
00329 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00330         , id_(weak_count_id)
00331 #endif
00332     {
00333         if(pi_ != 0) pi_->weak_add_ref();
00334     }
00335 
00336     ~weak_count() // nothrow
00337     {
00338         if(pi_ != 0) pi_->weak_release();
00339 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00340         id_ = 0;
00341 #endif
00342     }
00343 
00344     weak_count & operator= (shared_count const & r) // nothrow
00345     {
00346         sp_counted_base * tmp = r.pi_;
00347 
00348         if( tmp != pi_ )
00349         {
00350             if(tmp != 0) tmp->weak_add_ref();
00351             if(pi_ != 0) pi_->weak_release();
00352             pi_ = tmp;
00353         }
00354 
00355         return *this;
00356     }
00357 
00358     weak_count & operator= (weak_count const & r) // nothrow
00359     {
00360         sp_counted_base * tmp = r.pi_;
00361 
00362         if( tmp != pi_ )
00363         {
00364             if(tmp != 0) tmp->weak_add_ref();
00365             if(pi_ != 0) pi_->weak_release();
00366             pi_ = tmp;
00367         }
00368 
00369         return *this;
00370     }
00371 
00372     void swap(weak_count & r) // nothrow
00373     {
00374         sp_counted_base * tmp = r.pi_;
00375         r.pi_ = pi_;
00376         pi_ = tmp;
00377     }
00378 
00379     long use_count() const // nothrow
00380     {
00381         return pi_ != 0? pi_->use_count(): 0;
00382     }
00383 
00384     bool empty() const // nothrow
00385     {
00386         return pi_ == 0;
00387     }
00388 
00389     friend inline bool operator==(weak_count const & a, weak_count const & b)
00390     {
00391         return a.pi_ == b.pi_;
00392     }
00393 
00394     friend inline bool operator<(weak_count const & a, weak_count const & b)
00395     {
00396         return std::less<sp_counted_base *>()(a.pi_, b.pi_);
00397     }
00398 };
00399 
00400 inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
00401 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00402         , id_(shared_count_id)
00403 #endif
00404 {
00405     if( pi_ == 0 || !pi_->add_ref_lock() )
00406     {
00407         boost::throw_exception( boost::bad_weak_ptr() );
00408     }
00409 }
00410 
00411 inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ )
00412 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00413         , id_(shared_count_id)
00414 #endif
00415 {
00416     if( pi_ != 0 && !pi_->add_ref_lock() )
00417     {
00418         pi_ = 0;
00419     }
00420 }
00421 
00422 } // namespace detail
00423 
00424 } // namespace boost
00425 
00426 #ifdef __BORLANDC__
00427 # pragma warn .8027     // Functions containing try are not expanded inline
00428 #endif
00429 
00430 #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED


appl
Author(s): petercai
autogenerated on Tue Jan 7 2014 11:02:29