mirror of
https://github.com/boostorg/smart_ptr.git
synced 2025-07-31 21:24:40 +02:00
Embed local_counted_base in the deleter in the pointer case
This commit is contained in:
@@ -32,7 +32,6 @@ class local_counted_base
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
local_counted_base( local_counted_base const & );
|
|
||||||
local_counted_base & operator= ( local_counted_base const & );
|
local_counted_base & operator= ( local_counted_base const & );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -48,11 +47,17 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~local_counted_base() /*BOOST_NOEXCEPT*/
|
BOOST_CONSTEXPR local_counted_base( local_counted_base const & ) BOOST_SP_NOEXCEPT: local_use_count_( initial_ )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_ref()
|
virtual ~local_counted_base() /*BOOST_SP_NOEXCEPT*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void destroy() BOOST_SP_NOEXCEPT = 0;
|
||||||
|
|
||||||
|
void add_ref() BOOST_SP_NOEXCEPT
|
||||||
{
|
{
|
||||||
#if defined( __has_builtin )
|
#if defined( __has_builtin )
|
||||||
# if __has_builtin( __builtin_assume )
|
# if __has_builtin( __builtin_assume )
|
||||||
@@ -65,13 +70,13 @@ public:
|
|||||||
local_use_count_ = static_cast<count_type>( local_use_count_ + 1 );
|
local_use_count_ = static_cast<count_type>( local_use_count_ + 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void release()
|
void release() BOOST_SP_NOEXCEPT
|
||||||
{
|
{
|
||||||
local_use_count_ = static_cast<count_type>( local_use_count_ - 1 );
|
local_use_count_ = static_cast<count_type>( local_use_count_ - 1 );
|
||||||
|
|
||||||
if( local_use_count_ == 0 )
|
if( local_use_count_ == 0 )
|
||||||
{
|
{
|
||||||
delete this;
|
destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +88,10 @@ public:
|
|||||||
|
|
||||||
class local_counted_impl: public local_counted_base
|
class local_counted_impl: public local_counted_base
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
local_counted_impl( local_counted_impl const & );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
boost::shared_ptr<void const volatile> pn_;
|
boost::shared_ptr<void const volatile> pn_;
|
||||||
@@ -100,6 +109,23 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
virtual void destroy() BOOST_SP_NOEXCEPT
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class local_counted_impl_em: public local_counted_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
boost::shared_ptr<void const volatile> pn_;
|
||||||
|
|
||||||
|
virtual void destroy() BOOST_SP_NOEXCEPT
|
||||||
|
{
|
||||||
|
pn_.reset();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
@@ -17,9 +17,86 @@
|
|||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template<class T> class local_shared_ptr;
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template<class D> class local_sp_deleter: public local_counted_impl_em
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
D d_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
local_sp_deleter(): d_()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit local_sp_deleter( D const& d ) BOOST_SP_NOEXCEPT: d_( d )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
|
explicit local_sp_deleter( D&& d ) BOOST_SP_NOEXCEPT: d_( std::move(d) )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class Y> void operator()( Y* p ) const BOOST_SP_NOEXCEPT
|
||||||
|
{
|
||||||
|
d_( p );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class E, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E > * ppx, Y * p, boost::detail::local_counted_base * & pn )
|
||||||
|
{
|
||||||
|
boost::detail::sp_assert_convertible< Y, E >();
|
||||||
|
|
||||||
|
typedef boost::detail::local_sp_deleter< boost::checked_deleter<Y> > D;
|
||||||
|
|
||||||
|
boost::shared_ptr<E> p2( p, D() );
|
||||||
|
|
||||||
|
D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
|
||||||
|
|
||||||
|
pd->pn_ = p2;
|
||||||
|
|
||||||
|
pn = pd;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class E, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E[] > * ppx, Y * p, boost::detail::local_counted_base * & pn )
|
||||||
|
{
|
||||||
|
boost::detail::sp_assert_convertible< Y[], E[] >();
|
||||||
|
|
||||||
|
typedef boost::detail::local_sp_deleter< boost::checked_array_deleter<E> > D;
|
||||||
|
|
||||||
|
boost::shared_ptr<E[]> p2( p, D() );
|
||||||
|
|
||||||
|
D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
|
||||||
|
|
||||||
|
pd->pn_ = p2;
|
||||||
|
|
||||||
|
pn = pd;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class E, std::size_t N, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E[N] > * ppx, Y * p, boost::detail::local_counted_base * & pn )
|
||||||
|
{
|
||||||
|
boost::detail::sp_assert_convertible< Y[N], E[N] >();
|
||||||
|
|
||||||
|
typedef boost::detail::local_sp_deleter< boost::checked_array_deleter<E> > D;
|
||||||
|
|
||||||
|
boost::shared_ptr<E[N]> p2( p, D() );
|
||||||
|
|
||||||
|
D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
|
||||||
|
|
||||||
|
pd->pn_ = p2;
|
||||||
|
|
||||||
|
pn = pd;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -73,9 +150,9 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
explicit local_shared_ptr( Y * p ): px( p ),
|
explicit local_shared_ptr( Y * p ): px( p ), pn( 0 )
|
||||||
pn( new boost::detail::local_counted_impl( shared_ptr<T>( p ) ) )
|
|
||||||
{
|
{
|
||||||
|
boost::detail::lsp_pointer_construct( this, p, pn );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Y, class D> local_shared_ptr( Y * p, D d ): px( p ),
|
template<class Y, class D> local_shared_ptr( Y * p, D d ): px( p ),
|
||||||
|
Reference in New Issue
Block a user