sp_counted_impl_p added for the pointer constructor

[SVN r27727]
This commit is contained in:
Peter Dimov
2005-03-17 23:30:47 +00:00
parent b0eb65b433
commit 09a0ba8c75
3 changed files with 116 additions and 66 deletions

View File

@ -19,21 +19,12 @@
//
#include <boost/config.hpp>
#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 <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/detail/bad_weak_ptr.hpp>
#include <boost/detail/sp_counted_base.hpp>
#include <boost/detail/sp_counted_impl.hpp>
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
#include <boost/detail/quick_allocator.hpp>
#endif
#include <memory> // std::auto_ptr, std::allocator
#include <functional> // std::less
#include <new> // std::bad_alloc
@ -79,6 +70,36 @@ public:
{
}
template<class Y> 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<Y>( p );
}
catch(...)
{
boost::checked_delete( p );
throw;
}
#else
pi_ = new sp_counted_impl_p<Y>( p );
if( pi_ == 0 )
{
boost::checked_delete( p );
boost::throw_exception( std::bad_alloc() );
}
#endif
}
template<class P, class D> 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<Y> is special cased to provide the strong guarantee
template<class Y>
explicit shared_count(std::auto_ptr<Y> & r): pi_(new sp_counted_impl_pd< Y *, checked_deleter<Y> >(r.get(), checked_deleter<Y>()))
explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( 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<sp_counted_base *>()(a.pi_, b.pi_);
return std::less<sp_counted_base *>()( 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

View File

@ -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 X> 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<X> 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<class T> void cbi_call_constructor_hook(sp_counted_base * pn, T * px, checked_deleter<T> 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<class T> void cbi_call_constructor_hook(sp_counted_base *, T * px, checked_array_deleter<T> const &, int)
{
boost::sp_array_constructor_hook(px);
}
virtual void * get_deleter( std::type_info const & )
{
return 0;
}
template<class P, class D> void cbi_call_constructor_hook(sp_counted_base *, P const &, D const &, long)
{
}
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
template<class T> void cbi_call_destructor_hook(sp_counted_base * pn, T * px, checked_deleter<T> const &, int)
{
boost::sp_scalar_destructor_hook(px, sizeof(T), pn);
}
void * operator new( std::size_t )
{
return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
}
template<class T> void cbi_call_destructor_hook(sp_counted_base *, T * px, checked_array_deleter<T> const &, int)
{
boost::sp_array_destructor_hook(px);
}
template<class P, class D> void cbi_call_destructor_hook(sp_counted_base *, P const &, D const &, long)
{
}
void operator delete( void * p )
{
std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
}
#endif
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
void * operator new( std::size_t )
{
return quick_allocator<this_type>::alloc();
}
void operator delete( void * p )
{
quick_allocator<this_type>::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<P, D> 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<this_type>().allocate(1, static_cast<this_type *>(0));
return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
}
void operator delete(void * p)
void operator delete( void * p )
{
std::allocator<this_type>().deallocate(static_cast<this_type *>(p), 1);
std::allocator<this_type>().deallocate( static_cast<this_type *>(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<this_type>::alloc();
}
void operator delete(void * p)
void operator delete( void * p )
{
quick_allocator<this_type>::dealloc(p);
quick_allocator<this_type>::dealloc( p );
}
#endif

View File

@ -121,7 +121,7 @@ public:
}
template<class Y>
explicit shared_ptr(Y * p): px(p), pn(p, checked_deleter<Y>()) // 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 );
}