Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions include/boost/smart_ptr/detail/shared_count.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ class shared_count
{
}

#if !defined(BOOST_SP_EMBEDDED)
template<class Y> explicit shared_count( Y * p ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
Expand Down Expand Up @@ -163,7 +164,19 @@ class shared_count

#endif
}
#endif

template<class Y> explicit shared_count( Y * p, sp_nothrow_tag ) noexcept : pi_(0)
{
pi_ = new (std::nothrow) sp_counted_impl_p<Y>( p );

if( pi_ == 0 )
{
boost::checked_delete( p );
}
}

#if !defined(BOOST_SP_EMBEDDED)
template<class P, class D> shared_count( P p, D d ): pi_(0)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
Expand Down Expand Up @@ -193,7 +206,22 @@ class shared_count

#endif
}
#endif

template<class P, class D> shared_count( P p, D d, sp_nothrow_tag ) noexcept : pi_(0)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
pi_ = new (std::nothrow) sp_counted_impl_pd<P, D>(p, d);

if(pi_ == 0)
{
d(p); // delete p
}
}

#if !defined(BOOST_SP_EMBEDDED)
template< class P, class D > shared_count( P p, sp_inplace_tag<D> ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
Expand Down Expand Up @@ -223,7 +251,22 @@ class shared_count

#endif // #ifndef BOOST_NO_EXCEPTIONS
}
#endif

template< class P, class D > shared_count( P p, sp_inplace_tag<D>, sp_nothrow_tag ) noexcept : pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
pi_ = new sp_counted_impl_pd< P, D >( p );

if( pi_ == 0 )
{
D::operator_fn( p ); // delete p
}
}

#if !defined(BOOST_SP_EMBEDDED)
template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
Expand Down Expand Up @@ -270,7 +313,9 @@ class shared_count

#endif
}
#endif

#if !defined(BOOST_SP_EMBEDDED)
template< class P, class D, class A > shared_count( P p, sp_inplace_tag< D >, A a ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
Expand Down Expand Up @@ -317,11 +362,13 @@ class shared_count

#endif // #ifndef BOOST_NO_EXCEPTIONS
}
#endif

#ifndef BOOST_NO_AUTO_PTR

// auto_ptr<Y> is special cased to provide the strong guarantee

#if !defined(BOOST_SP_EMBEDDED)
template<class 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)
Expand All @@ -339,9 +386,22 @@ class shared_count

r.release();
}
#endif

template<class Y>
shared_count( std::auto_ptr<Y> & r, sp_nothrow_tag ): pi_( new(std::nothrow) sp_counted_impl_p<Y>( r.get() ) )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
if( pi_ != 0 )
{
r.release();
}
}
#endif

#if !defined(BOOST_SP_EMBEDDED)
template<class Y, class D>
explicit shared_count( std::unique_ptr<Y, D> & r ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
Expand All @@ -364,7 +424,26 @@ class shared_count

r.release();
}
#endif

template<class Y, class D>
shared_count( std::unique_ptr<Y, D> & r, sp_nothrow_tag ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
typedef typename sp_convert_reference<D>::type D2;

D2 d2( static_cast<D&&>( r.get_deleter() ) );
pi_ = new (std::nothrow) sp_counted_impl_pd< typename std::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );

if( pi_ != 0 )
{
r.release();
}
}

#if !defined(BOOST_SP_EMBEDDED)
template<class Y, class D>
explicit shared_count( boost::movelib::unique_ptr<Y, D> & r ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
Expand All @@ -387,6 +466,24 @@ class shared_count

r.release();
}
#endif

template<class Y, class D>
shared_count( boost::movelib::unique_ptr<Y, D> & r, sp_nothrow_tag ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
typedef typename sp_convert_reference<D>::type D2;

D2 d2( r.get_deleter() );
pi_ = new (std::nothrow) sp_counted_impl_pd< typename boost::movelib::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );

if( pi_ != 0 )
{
r.release();
}
}

~shared_count() /*noexcept*/
{
Expand All @@ -412,7 +509,9 @@ class shared_count
r.pi_ = 0;
}

#if !defined(BOOST_SP_EMBEDDED)
explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
#endif
shared_count( weak_count const & r, sp_nothrow_tag ) noexcept; // constructs an empty *this when r.use_count() == 0

shared_count & operator= (shared_count const & r) noexcept
Expand Down Expand Up @@ -613,6 +712,7 @@ class weak_count
}
};

#if !defined(BOOST_SP_EMBEDDED)
inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
Expand All @@ -623,6 +723,7 @@ inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
boost::throw_exception( boost::bad_weak_ptr() );
}
}
#endif

inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ) noexcept: pi_( r.pi_ )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
Expand Down
8 changes: 4 additions & 4 deletions include/boost/smart_ptr/detail/sp_counted_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ template<class X> class BOOST_SYMBOL_VISIBLE sp_counted_impl_p: public sp_counte
return 0;
}

#if defined(BOOST_SP_USE_STD_ALLOCATOR)
#if defined(BOOST_SP_USE_STD_ALLOCATOR) && !defined(BOOST_SP_EMBEDDED)

void * operator new( std::size_t )
{
Expand All @@ -118,7 +118,7 @@ template<class X> class BOOST_SYMBOL_VISIBLE sp_counted_impl_p: public sp_counte

#endif

#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) && !defined(BOOST_SP_EMBEDDED)

void * operator new( std::size_t )
{
Expand Down Expand Up @@ -177,7 +177,7 @@ template<class P, class D> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pd: public
return &reinterpret_cast<char&>( del );
}

#if defined(BOOST_SP_USE_STD_ALLOCATOR)
#if defined(BOOST_SP_USE_STD_ALLOCATOR) && !defined(BOOST_SP_EMBEDDED)

void * operator new( std::size_t )
{
Expand All @@ -191,7 +191,7 @@ template<class P, class D> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pd: public

#endif

#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) && !defined(BOOST_SP_EMBEDDED)

void * operator new( std::size_t )
{
Expand Down
11 changes: 10 additions & 1 deletion include/boost/smart_ptr/enable_shared_from.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,24 @@ class enable_shared_from: public enable_shared_from_this<enable_shared_from>
{
private:

#if !defined(BOOST_SP_EMBEDDED)
using enable_shared_from_this<enable_shared_from>::shared_from_this;
#endif
using enable_shared_from_this<enable_shared_from>::try_shared_from_this;
using enable_shared_from_this<enable_shared_from>::weak_from_this;
};


#if !defined(BOOST_SP_EMBEDDED)
template<class T> shared_ptr<T> shared_from( T * p )
{
return shared_ptr<T>( p->enable_shared_from_this<enable_shared_from>::shared_from_this(), p );
}
#endif

template<class T> shared_ptr<T> try_shared_from( T * p ) noexcept
{
return shared_ptr<T>( p->enable_shared_from_this<enable_shared_from>::try_shared_from_this(), p );
}

template<class T> weak_ptr<T> weak_from( T * p ) noexcept
{
Expand Down
14 changes: 14 additions & 0 deletions include/boost/smart_ptr/enable_shared_from_this.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,33 @@ template<class T> class enable_shared_from_this

public:

#if !defined(BOOST_SP_EMBEDDED)
shared_ptr<T> shared_from_this()
{
shared_ptr<T> p( weak_this_ );
BOOST_ASSERT( p.get() == this );
return p;
}
#endif

shared_ptr<T> try_shared_from_this() noexcept
{
return shared_ptr<T>( weak_this_, boost::detail::sp_nothrow_tag() );
}

#if !defined(BOOST_SP_EMBEDDED)
shared_ptr<T const> shared_from_this() const
{
shared_ptr<T const> p( weak_this_ );
BOOST_ASSERT( p.get() == this );
return p;
}
#endif

shared_ptr<T const> try_shared_from_this() const noexcept
{
return shared_ptr<T const>( weak_this_, boost::detail::sp_nothrow_tag() );
}

weak_ptr<T> weak_from_this() noexcept
{
Expand Down
2 changes: 2 additions & 0 deletions include/boost/smart_ptr/make_shared_array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Distributed under the Boost Software License, Version 1.0.

namespace boost {

#if !defined(BOOST_SP_EMBEDDED)
template<class T>
inline typename std::enable_if<detail::sp_is_bounded_array<T>::value, shared_ptr<T> >::type
make_shared()
Expand Down Expand Up @@ -62,6 +63,7 @@ make_shared_noinit(std::size_t size)
return boost::allocate_shared_noinit<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>(), size);
}
#endif

} /* boost */

Expand Down
48 changes: 48 additions & 0 deletions include/boost/smart_ptr/make_shared_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ template< class T, std::size_t N > struct sp_if_not_array< T[N] >

// _noinit versions

#if !defined(BOOST_SP_EMBEDDED)
template< class T > typename boost::detail::sp_if_not_array< T >::type make_shared_noinit()
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
Expand All @@ -199,7 +200,29 @@ template< class T > typename boost::detail::sp_if_not_array< T >::type make_shar
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
#endif

template< class T > typename boost::detail::sp_if_not_array< T >::type try_make_shared_noinit() noexcept
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), boost::detail::sp_nothrow_tag() );

if ( pt._internal_count_ref().empty() )
return boost::shared_ptr< T >();

boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );

void * pv = pd->address();

::new( pv ) T;
pd->set_initialized();

T * pt2 = static_cast< T* >( pv );

boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}

#if !defined(BOOST_SP_EMBEDDED)
template< class T, class A > typename boost::detail::sp_if_not_array< T >::type allocate_shared_noinit( A const & a )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
Expand All @@ -216,9 +239,11 @@ template< class T, class A > typename boost::detail::sp_if_not_array< T >::type
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
#endif

//

#if !defined(BOOST_SP_EMBEDDED)
template< class T, class... Args > typename boost::detail::sp_if_not_array< T >::type make_shared( Args && ... args )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
Expand All @@ -235,7 +260,29 @@ template< class T, class... Args > typename boost::detail::sp_if_not_array< T >:
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
#endif

template< class T, class... Args > typename boost::detail::sp_if_not_array< T >::type try_make_shared( Args && ... args ) noexcept
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), sp_nothrow_tag() );

if ( pt._internal_count_ref().empty() )
return boost::shared_ptr< T >();

boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );

void * pv = pd->address();

::new( pv ) T( std::forward<Args>( args )... );
pd->set_initialized();

T * pt2 = static_cast< T* >( pv );

boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}

#if !defined(BOOST_SP_EMBEDDED)
template< class T, class A, class... Args > typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, Args && ... args )
{
typedef typename std::allocator_traits<A>::template rebind_alloc<T> A2;
Expand All @@ -257,6 +304,7 @@ template< class T, class A, class... Args > typename boost::detail::sp_if_not_ar
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
#endif

#undef BOOST_SP_MSD

Expand Down
Loading