shared_count.hpp

Go to the documentation of this file.
00001 #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
00002 #define BOOST_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 <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>           // std::auto_ptr, std::allocator
00033 #include <functional>       // std::less
00034 #include <new>              // std::bad_alloc
00035 #include <typeinfo>         // std::type_info in get_deleter
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) // nothrow
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); // delete 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); // delete p
00127             boost::throw_exception(std::bad_alloc());
00128         }
00129 
00130 #endif
00131     }
00132 
00133 #ifndef BOOST_NO_AUTO_PTR
00134 
00135     // auto_ptr<Y> is special cased to provide the strong guarantee
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() // nothrow
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_) // nothrow
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); // throws bad_weak_ptr when r.use_count() == 0
00174 
00175     shared_count & operator= (shared_count const & r) // nothrow
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) // nothrow
00190     {
00191         sp_counted_base * tmp = r.pi_;
00192         r.pi_ = pi_;
00193         pi_ = tmp;
00194     }
00195 
00196     long use_count() const // nothrow
00197     {
00198         return pi_ != 0? pi_->use_count(): 0;
00199     }
00200 
00201     bool unique() const // nothrow
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) // nothrow
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_) // nothrow
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_) // nothrow
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() // nothrow
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) // nothrow
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) // nothrow
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) // nothrow
00289     {
00290         sp_counted_base * tmp = r.pi_;
00291         r.pi_ = pi_;
00292         pi_ = tmp;
00293     }
00294 
00295     long use_count() const // nothrow
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 } // namespace detail
00323 
00324 } // namespace boost
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

Generated on Wed Jan 21 15:32:10 2009 for SystemC by  doxygen 1.5.5