Merge branch 'feature/local_get_deleter' into feature/local_shared_ptr

This commit is contained in:
Peter Dimov
2017-06-20 21:38:44 +03:00
4 changed files with 45 additions and 22 deletions

View File

@ -17,6 +17,7 @@
// //
// See http://www.boost.org/libs/smart_ptr/ for documentation. // See http://www.boost.org/libs/smart_ptr/ for documentation.
#include <boost/smart_ptr/detail/shared_count.hpp>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <utility> #include <utility>
#include <climits> #include <climits>
@ -56,7 +57,7 @@ public:
virtual void local_cb_destroy() BOOST_SP_NOEXCEPT = 0; virtual void local_cb_destroy() BOOST_SP_NOEXCEPT = 0;
virtual boost::shared_ptr<void> local_cb_get_shared_ptr() const BOOST_SP_NOEXCEPT = 0; virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT = 0;
void add_ref() BOOST_SP_NOEXCEPT void add_ref() BOOST_SP_NOEXCEPT
{ {
@ -95,17 +96,17 @@ private:
private: private:
boost::shared_ptr<void const volatile> pn_; shared_count pn_;
public: public:
template<class T> explicit local_counted_impl( boost::shared_ptr<T> const& pn ): pn_( pn ) explicit local_counted_impl( shared_count const& pn ): pn_( pn )
{ {
} }
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class T> explicit local_counted_impl( boost::shared_ptr<T>&& pn ): pn_( std::move(pn) ) explicit local_counted_impl( shared_count && pn ): pn_( std::move(pn) )
{ {
} }
@ -116,9 +117,9 @@ public:
delete this; delete this;
} }
virtual boost::shared_ptr<void> local_cb_get_shared_ptr() const BOOST_SP_NOEXCEPT virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT
{ {
return const_pointer_cast<void>( pn_ ); return pn_;
} }
}; };
@ -126,16 +127,16 @@ class local_counted_impl_em: public local_counted_base
{ {
public: public:
boost::shared_ptr<void const volatile> pn_; shared_count pn_;
virtual void local_cb_destroy() BOOST_SP_NOEXCEPT virtual void local_cb_destroy() BOOST_SP_NOEXCEPT
{ {
pn_.reset(); shared_count().swap( pn_ );
} }
virtual boost::shared_ptr<void> local_cb_get_shared_ptr() const BOOST_SP_NOEXCEPT virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT
{ {
return const_pointer_cast<void>( pn_ ); return pn_;
} }
}; };

View File

@ -31,7 +31,7 @@ template< class E, class Y > inline void lsp_pointer_construct( boost::local_sha
D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() ); D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
pd->pn_ = p2; pd->pn_ = p2._internal_count();
pn = pd; pn = pd;
} }
@ -46,7 +46,7 @@ template< class E, class Y > inline void lsp_pointer_construct( boost::local_sha
D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() ); D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
pd->pn_ = p2; pd->pn_ = p2._internal_count();
pn = pd; pn = pd;
} }
@ -61,7 +61,7 @@ template< class E, std::size_t N, class Y > inline void lsp_pointer_construct( b
D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() ); D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
pd->pn_ = p2; pd->pn_ = p2._internal_count();
pn = pd; pn = pd;
} }
@ -74,7 +74,7 @@ template< class E, class P, class D > inline void lsp_deleter_construct( boost::
D2 * pd = static_cast< D2 * >( p2._internal_get_untyped_deleter() ); D2 * pd = static_cast< D2 * >( p2._internal_get_untyped_deleter() );
pd->pn_ = p2; pd->pn_ = p2._internal_count();
pn = pd; pn = pd;
} }
@ -87,7 +87,7 @@ template< class E, class P, class D, class A > inline void lsp_allocator_constru
D2 * pd = static_cast< D2 * >( p2._internal_get_untyped_deleter() ); D2 * pd = static_cast< D2 * >( p2._internal_get_untyped_deleter() );
pd->pn_ = p2; pd->pn_ = p2._internal_count();
pn = pd; pn = pd;
} }
@ -197,7 +197,7 @@ public:
if( r.use_count() != 0 ) if( r.use_count() != 0 )
{ {
pn = new boost::detail::local_counted_impl( r ); pn = new boost::detail::local_counted_impl( r._internal_count() );
} }
} }
@ -211,7 +211,8 @@ public:
if( r.use_count() != 0 ) if( r.use_count() != 0 )
{ {
pn = new boost::detail::local_counted_impl( std::move(r) ); pn = new boost::detail::local_counted_impl( r._internal_count() );
r.reset();
} }
} }
@ -230,7 +231,7 @@ public:
if( px ) if( px )
{ {
pn = new boost::detail::local_counted_impl( shared_ptr<T>( std::move(r) ) ); pn = new boost::detail::local_counted_impl( shared_ptr<T>( std::move(r) )._internal_count() );
} }
} }
@ -453,7 +454,7 @@ public:
if( pn ) if( pn )
{ {
return static_pointer_cast<Y>( pn->local_cb_get_shared_ptr() ); return shared_ptr<Y>( boost::detail::sp_internal_constructor_tag(), px, pn->local_cb_get_shared_count() );
} }
else else
{ {
@ -471,7 +472,7 @@ public:
if( pn ) if( pn )
{ {
return static_pointer_cast<Y>( pn->local_cb_get_shared_ptr() ); return shared_ptr<Y>( boost::detail::sp_internal_constructor_tag(), px, pn->local_cb_get_shared_count() );
} }
else else
{ {

View File

@ -146,7 +146,7 @@ template<class T, class A, class... Args> typename boost::detail::lsp_if_not_arr
T * pt2 = static_cast< T* >( pv ); T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
pd->pn_ = boost::shared_ptr<T>( pt, pt2 ); pd->pn_ = pt._internal_count();
return boost::local_shared_ptr<T>( boost::detail::lsp_internal_constructor_tag(), pt2, pd ); return boost::local_shared_ptr<T>( boost::detail::lsp_internal_constructor_tag(), pt2, pd );
} }
@ -179,7 +179,7 @@ template<class T, class A> typename boost::detail::lsp_if_not_array<T>::type all
T * pt2 = static_cast< T* >( pv ); T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
pd->pn_ = boost::shared_ptr<T>( pt, pt2 ); pd->pn_ = pt._internal_count();
return boost::local_shared_ptr<T>( boost::detail::lsp_internal_constructor_tag(), pt2, pd ); return boost::local_shared_ptr<T>( boost::detail::lsp_internal_constructor_tag(), pt2, pd );
} }

View File

@ -323,6 +323,10 @@ template< class T, std::size_t N, class Y > inline void sp_deleter_construct( bo
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
struct sp_internal_constructor_tag
{
};
} // namespace detail } // namespace detail
@ -355,6 +359,18 @@ public:
{ {
} }
#endif
BOOST_CONSTEXPR shared_ptr( boost::detail::sp_internal_constructor_tag, element_type * px_, boost::detail::shared_count const & pn_ ) BOOST_SP_NOEXCEPT : px( px_ ), pn( pn_ )
{
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
BOOST_CONSTEXPR shared_ptr( boost::detail::sp_internal_constructor_tag, element_type * px_, boost::detail::shared_count && pn_ ) BOOST_SP_NOEXCEPT : px( px_ ), pn( std::move( pn_ ) )
{
}
#endif #endif
template<class Y> template<class Y>
@ -781,6 +797,11 @@ public:
return px == r.px && pn == r.pn; return px == r.px && pn == r.pn;
} }
boost::detail::shared_count _internal_count() const BOOST_NOEXCEPT
{
return pn;
}
// Tasteless as this may seem, making all members public allows member templates // Tasteless as this may seem, making all members public allows member templates
// to work in the absence of member template friends. (Matthew Langston) // to work in the absence of member template friends. (Matthew Langston)