diff --git a/include/boost/detail/shared_count.hpp b/include/boost/detail/shared_count.hpp index 106428d..133e54e 100644 --- a/include/boost/detail/shared_count.hpp +++ b/include/boost/detail/shared_count.hpp @@ -19,21 +19,12 @@ // #include - -#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR) -# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible. -#endif - #include #include #include #include #include -#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) -#include -#endif - #include // std::auto_ptr, std::allocator #include // std::less #include // std::bad_alloc @@ -79,6 +70,36 @@ public: { } + template explicit shared_count( Y * p ): pi_( 0 ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { +#ifndef BOOST_NO_EXCEPTIONS + + try + { + pi_ = new sp_counted_impl_p( p ); + } + catch(...) + { + boost::checked_delete( p ); + throw; + } + +#else + + pi_ = new sp_counted_impl_p( p ); + + if( pi_ == 0 ) + { + boost::checked_delete( p ); + boost::throw_exception( std::bad_alloc() ); + } + +#endif + } + template shared_count(P p, D d): pi_(0) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) , id_(shared_count_id) @@ -114,11 +135,20 @@ public: // auto_ptr is special cased to provide the strong guarantee template - explicit shared_count(std::auto_ptr & r): pi_(new sp_counted_impl_pd< Y *, checked_deleter >(r.get(), checked_deleter())) + explicit shared_count( std::auto_ptr & r ): pi_( new sp_counted_impl_p( r.get() ) ) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) , id_(shared_count_id) #endif { +#ifdef BOOST_NO_EXCEPTIONS + + if( pi_ == 0 ) + { + boost::throw_exception(std::bad_alloc()); + } + +#endif + r.release(); } @@ -126,7 +156,7 @@ public: ~shared_count() // nothrow { - if(pi_ != 0) pi_->release(); + if( pi_ != 0 ) pi_->release(); #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) id_ = 0; #endif @@ -137,7 +167,7 @@ public: , id_(shared_count_id) #endif { - if(pi_ != 0) pi_->add_ref_copy(); + if( pi_ != 0 ) pi_->add_ref_copy(); } explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0 @@ -146,10 +176,10 @@ public: { sp_counted_base * tmp = r.pi_; - if(tmp != pi_) + if( tmp != pi_ ) { - if(tmp != 0) tmp->add_ref_copy(); - if(pi_ != 0) pi_->release(); + if( tmp != 0 ) tmp->add_ref_copy(); + if( pi_ != 0 ) pi_->release(); pi_ = tmp; } @@ -180,12 +210,12 @@ public: friend inline bool operator<(shared_count const & a, shared_count const & b) { - return std::less()(a.pi_, b.pi_); + return std::less()( a.pi_, b.pi_ ); } void * get_deleter(std::type_info const & ti) const { - return pi_? pi_->get_deleter(ti): 0; + return pi_? pi_->get_deleter( ti ): 0; } }; @@ -278,7 +308,7 @@ public: } }; -inline shared_count::shared_count(weak_count const & r): pi_(r.pi_) +inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ ) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) , id_(shared_count_id) #endif diff --git a/include/boost/detail/sp_counted_impl.hpp b/include/boost/detail/sp_counted_impl.hpp index 8d3c8c7..51093b5 100644 --- a/include/boost/detail/sp_counted_impl.hpp +++ b/include/boost/detail/sp_counted_impl.hpp @@ -38,52 +38,78 @@ namespace boost { -// Debug hooks - #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) -void sp_scalar_constructor_hook(void * px, std::size_t size, void * pn); -void sp_array_constructor_hook(void * px); -void sp_scalar_destructor_hook(void * px, std::size_t size, void * pn); -void sp_array_destructor_hook(void * px); +void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn ); +void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn ); #endif namespace detail { +template class sp_counted_impl_p: public sp_counted_base +{ +private: + + X * px_; + + sp_counted_impl_p( sp_counted_impl_p const & ); + sp_counted_impl_p & operator= ( sp_counted_impl_p const & ); + + typedef sp_counted_impl_p this_type; + +public: + + explicit sp_counted_impl_p( X * px ): px_( px ) + { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + boost::sp_scalar_constructor_hook( px, sizeof(X), this ); +#endif + } -template void cbi_call_constructor_hook(sp_counted_base * pn, T * px, checked_deleter const &, int) -{ - boost::sp_scalar_constructor_hook(px, sizeof(T), pn); -} + virtual void dispose() // nothrow + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + boost::sp_scalar_destructor_hook( px_, sizeof(X), this ); +#endif + boost::checked_delete( px_ ); + } -template void cbi_call_constructor_hook(sp_counted_base *, T * px, checked_array_deleter const &, int) -{ - boost::sp_array_constructor_hook(px); -} + virtual void * get_deleter( std::type_info const & ) + { + return 0; + } -template void cbi_call_constructor_hook(sp_counted_base *, P const &, D const &, long) -{ -} +#if defined(BOOST_SP_USE_STD_ALLOCATOR) -template void cbi_call_destructor_hook(sp_counted_base * pn, T * px, checked_deleter const &, int) -{ - boost::sp_scalar_destructor_hook(px, sizeof(T), pn); -} + void * operator new( std::size_t ) + { + return std::allocator().allocate( 1, static_cast(0) ); + } -template void cbi_call_destructor_hook(sp_counted_base *, T * px, checked_array_deleter const &, int) -{ - boost::sp_array_destructor_hook(px); -} - -template void cbi_call_destructor_hook(sp_counted_base *, P const &, D const &, long) -{ -} + void operator delete( void * p ) + { + std::allocator().deallocate( static_cast(p), 1 ); + } #endif +#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) + + void * operator new( std::size_t ) + { + return quick_allocator::alloc(); + } + + void operator delete( void * p ) + { + quick_allocator::dealloc( p ); + } + +#endif +}; + // // Borland's Codeguard trips up over the -Vx- option here: // @@ -98,8 +124,8 @@ private: P ptr; // copy constructor must not throw D del; // copy constructor must not throw - sp_counted_impl_pd(sp_counted_impl_pd const &); - sp_counted_impl_pd & operator= (sp_counted_impl_pd const &); + sp_counted_impl_pd( sp_counted_impl_pd const & ); + sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & ); typedef sp_counted_impl_pd this_type; @@ -107,50 +133,44 @@ public: // pre: d(p) must not throw - sp_counted_impl_pd(P p, D d): ptr(p), del(d) + sp_counted_impl_pd( P p, D d ): ptr(p), del(d) { -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - detail::cbi_call_constructor_hook(this, p, d, 0); -#endif } virtual void dispose() // nothrow { -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - detail::cbi_call_destructor_hook(this, ptr, del, 0); -#endif - del(ptr); + del( ptr ); } - virtual void * get_deleter(std::type_info const & ti) + virtual void * get_deleter( std::type_info const & ti ) { return ti == typeid(D)? &del: 0; } #if defined(BOOST_SP_USE_STD_ALLOCATOR) - void * operator new(std::size_t) + void * operator new( std::size_t ) { - return std::allocator().allocate(1, static_cast(0)); + return std::allocator().allocate( 1, static_cast(0) ); } - void operator delete(void * p) + void operator delete( void * p ) { - std::allocator().deallocate(static_cast(p), 1); + std::allocator().deallocate( static_cast(p), 1 ); } #endif #if defined(BOOST_SP_USE_QUICK_ALLOCATOR) - void * operator new(std::size_t) + void * operator new( std::size_t ) { return quick_allocator::alloc(); } - void operator delete(void * p) + void operator delete( void * p ) { - quick_allocator::dealloc(p); + quick_allocator::dealloc( p ); } #endif diff --git a/include/boost/shared_ptr.hpp b/include/boost/shared_ptr.hpp index 474bf4f..800e539 100644 --- a/include/boost/shared_ptr.hpp +++ b/include/boost/shared_ptr.hpp @@ -121,7 +121,7 @@ public: } template - explicit shared_ptr(Y * p): px(p), pn(p, checked_deleter()) // Y must be complete + explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete { detail::sp_enable_shared_from_this( pn, p, p ); }