sl@0: #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED sl@0: #define BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED sl@0: sl@0: // MS compatible compilers support #pragma once sl@0: sl@0: #if defined(_MSC_VER) && (_MSC_VER >= 1020) sl@0: # pragma once sl@0: #endif sl@0: sl@0: // sl@0: // detail/shared_count.hpp sl@0: // sl@0: // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. sl@0: // Copyright 2004-2005 Peter Dimov sl@0: // sl@0: // Distributed under the Boost Software License, Version 1.0. (See sl@0: // accompanying file LICENSE_1_0.txt or copy at sl@0: // http://www.boost.org/LICENSE_1_0.txt) sl@0: // sl@0: sl@0: #ifdef __BORLANDC__ sl@0: # pragma warn -8027 // Functions containing try are not expanded inline sl@0: #endif sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #include // std::auto_ptr sl@0: #include // std::less sl@0: #include // std::bad_alloc sl@0: #include // std::type_info in get_deleter sl@0: sl@0: namespace boost sl@0: { sl@0: sl@0: namespace detail sl@0: { sl@0: sl@0: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) sl@0: sl@0: int const shared_count_id = 0x2C35F101; sl@0: int const weak_count_id = 0x298C38A4; sl@0: sl@0: #endif sl@0: sl@0: class weak_count; sl@0: sl@0: class shared_count sl@0: { sl@0: private: sl@0: sl@0: sp_counted_base * pi_; sl@0: sl@0: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) sl@0: int id_; sl@0: #endif sl@0: sl@0: friend class weak_count; sl@0: sl@0: public: sl@0: sl@0: shared_count(): pi_(0) // nothrow sl@0: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) sl@0: , id_(shared_count_id) sl@0: #endif sl@0: { sl@0: } sl@0: sl@0: template explicit shared_count( Y * p ): pi_( 0 ) sl@0: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) sl@0: , id_(shared_count_id) sl@0: #endif sl@0: { sl@0: #ifndef BOOST_NO_EXCEPTIONS sl@0: sl@0: try sl@0: { sl@0: pi_ = new sp_counted_impl_p( p ); sl@0: } sl@0: catch(...) sl@0: { sl@0: boost::checked_delete( p ); sl@0: throw; sl@0: } sl@0: sl@0: #else sl@0: sl@0: pi_ = new sp_counted_impl_p( p ); sl@0: sl@0: if( pi_ == 0 ) sl@0: { sl@0: boost::checked_delete( p ); sl@0: boost::throw_exception( std::bad_alloc() ); sl@0: } sl@0: sl@0: #endif sl@0: } sl@0: sl@0: template shared_count(P p, D d): pi_(0) sl@0: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) sl@0: , id_(shared_count_id) sl@0: #endif sl@0: { sl@0: #ifndef BOOST_NO_EXCEPTIONS sl@0: sl@0: try sl@0: { sl@0: pi_ = new sp_counted_impl_pd(p, d); sl@0: } sl@0: catch(...) sl@0: { sl@0: d(p); // delete p sl@0: throw; sl@0: } sl@0: sl@0: #else sl@0: sl@0: pi_ = new sp_counted_impl_pd(p, d); sl@0: sl@0: if(pi_ == 0) sl@0: { sl@0: d(p); // delete p sl@0: boost::throw_exception(std::bad_alloc()); sl@0: } sl@0: sl@0: #endif sl@0: } sl@0: sl@0: template shared_count( P p, D d, A a ): pi_( 0 ) sl@0: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) sl@0: , id_(shared_count_id) sl@0: #endif sl@0: { sl@0: typedef sp_counted_impl_pda impl_type; sl@0: typedef typename A::template rebind< impl_type >::other A2; sl@0: sl@0: A2 a2( a ); sl@0: sl@0: #ifndef BOOST_NO_EXCEPTIONS sl@0: sl@0: try sl@0: { sl@0: pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); sl@0: new( static_cast< void* >( pi_ ) ) impl_type( p, d, a ); sl@0: } sl@0: catch(...) sl@0: { sl@0: d( p ); sl@0: sl@0: if( pi_ != 0 ) sl@0: { sl@0: a2.deallocate( static_cast< impl_type* >( pi_ ), 1 ); sl@0: } sl@0: sl@0: throw; sl@0: } sl@0: sl@0: #else sl@0: sl@0: pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); sl@0: sl@0: if( pi_ != 0 ) sl@0: { sl@0: new( static_cast< void* >( pi_ ) ) impl_type( p, d, a ); sl@0: } sl@0: else sl@0: { sl@0: d( p ); sl@0: boost::throw_exception( std::bad_alloc() ); sl@0: } sl@0: sl@0: #endif sl@0: } sl@0: sl@0: #ifndef BOOST_NO_AUTO_PTR sl@0: sl@0: // auto_ptr is special cased to provide the strong guarantee sl@0: sl@0: template sl@0: explicit shared_count( std::auto_ptr & r ): pi_( new sp_counted_impl_p( r.get() ) ) sl@0: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) sl@0: , id_(shared_count_id) sl@0: #endif sl@0: { sl@0: #ifdef BOOST_NO_EXCEPTIONS sl@0: sl@0: if( pi_ == 0 ) sl@0: { sl@0: boost::throw_exception(std::bad_alloc()); sl@0: } sl@0: sl@0: #endif sl@0: sl@0: r.release(); sl@0: } sl@0: sl@0: #endif sl@0: sl@0: ~shared_count() // nothrow sl@0: { sl@0: if( pi_ != 0 ) pi_->release(); sl@0: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) sl@0: id_ = 0; sl@0: #endif sl@0: } sl@0: sl@0: shared_count(shared_count const & r): pi_(r.pi_) // nothrow sl@0: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) sl@0: , id_(shared_count_id) sl@0: #endif sl@0: { sl@0: if( pi_ != 0 ) pi_->add_ref_copy(); sl@0: } sl@0: sl@0: explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0 sl@0: sl@0: shared_count & operator= (shared_count const & r) // nothrow sl@0: { sl@0: sp_counted_base * tmp = r.pi_; sl@0: sl@0: if( tmp != pi_ ) sl@0: { sl@0: if( tmp != 0 ) tmp->add_ref_copy(); sl@0: if( pi_ != 0 ) pi_->release(); sl@0: pi_ = tmp; sl@0: } sl@0: sl@0: return *this; sl@0: } sl@0: sl@0: void swap(shared_count & r) // nothrow sl@0: { sl@0: sp_counted_base * tmp = r.pi_; sl@0: r.pi_ = pi_; sl@0: pi_ = tmp; sl@0: } sl@0: sl@0: long use_count() const // nothrow sl@0: { sl@0: return pi_ != 0? pi_->use_count(): 0; sl@0: } sl@0: sl@0: bool unique() const // nothrow sl@0: { sl@0: return use_count() == 1; sl@0: } sl@0: sl@0: friend inline bool operator==(shared_count const & a, shared_count const & b) sl@0: { sl@0: return a.pi_ == b.pi_; sl@0: } sl@0: sl@0: friend inline bool operator<(shared_count const & a, shared_count const & b) sl@0: { sl@0: return std::less()( a.pi_, b.pi_ ); sl@0: } sl@0: sl@0: void * get_deleter(std::type_info const & ti) const sl@0: { sl@0: return pi_? pi_->get_deleter( ti ): 0; sl@0: } sl@0: }; sl@0: sl@0: sl@0: class weak_count sl@0: { sl@0: private: sl@0: sl@0: sp_counted_base * pi_; sl@0: sl@0: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) sl@0: int id_; sl@0: #endif sl@0: sl@0: friend class shared_count; sl@0: sl@0: public: sl@0: sl@0: weak_count(): pi_(0) // nothrow sl@0: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) sl@0: , id_(weak_count_id) sl@0: #endif sl@0: { sl@0: } sl@0: sl@0: weak_count(shared_count const & r): pi_(r.pi_) // nothrow sl@0: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) sl@0: , id_(shared_count_id) sl@0: #endif sl@0: { sl@0: if(pi_ != 0) pi_->weak_add_ref(); sl@0: } sl@0: sl@0: weak_count(weak_count const & r): pi_(r.pi_) // nothrow sl@0: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) sl@0: , id_(shared_count_id) sl@0: #endif sl@0: { sl@0: if(pi_ != 0) pi_->weak_add_ref(); sl@0: } sl@0: sl@0: ~weak_count() // nothrow sl@0: { sl@0: if(pi_ != 0) pi_->weak_release(); sl@0: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) sl@0: id_ = 0; sl@0: #endif sl@0: } sl@0: sl@0: weak_count & operator= (shared_count const & r) // nothrow sl@0: { sl@0: sp_counted_base * tmp = r.pi_; sl@0: if(tmp != 0) tmp->weak_add_ref(); sl@0: if(pi_ != 0) pi_->weak_release(); sl@0: pi_ = tmp; sl@0: sl@0: return *this; sl@0: } sl@0: sl@0: weak_count & operator= (weak_count const & r) // nothrow sl@0: { sl@0: sp_counted_base * tmp = r.pi_; sl@0: if(tmp != 0) tmp->weak_add_ref(); sl@0: if(pi_ != 0) pi_->weak_release(); sl@0: pi_ = tmp; sl@0: sl@0: return *this; sl@0: } sl@0: sl@0: void swap(weak_count & r) // nothrow sl@0: { sl@0: sp_counted_base * tmp = r.pi_; sl@0: r.pi_ = pi_; sl@0: pi_ = tmp; sl@0: } sl@0: sl@0: long use_count() const // nothrow sl@0: { sl@0: return pi_ != 0? pi_->use_count(): 0; sl@0: } sl@0: sl@0: friend inline bool operator==(weak_count const & a, weak_count const & b) sl@0: { sl@0: return a.pi_ == b.pi_; sl@0: } sl@0: sl@0: friend inline bool operator<(weak_count const & a, weak_count const & b) sl@0: { sl@0: return std::less()(a.pi_, b.pi_); sl@0: } sl@0: }; sl@0: sl@0: inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ ) sl@0: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) sl@0: , id_(shared_count_id) sl@0: #endif sl@0: { sl@0: if( pi_ == 0 || !pi_->add_ref_lock() ) sl@0: { sl@0: boost::throw_exception( boost::bad_weak_ptr() ); sl@0: } sl@0: } sl@0: sl@0: } // namespace detail sl@0: sl@0: } // namespace boost sl@0: sl@0: #ifdef __BORLANDC__ sl@0: # pragma warn .8027 // Functions containing try are not expanded inline sl@0: #endif sl@0: sl@0: #endif // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED