From f901988e57137f05afac20e2985d366144131192 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 20 Jun 2017 21:38:03 +0300 Subject: [PATCH] Store shared_count in local_counted_base, not shared_ptr --- .../smart_ptr/detail/local_counted_base.hpp | 21 ++++++++++--------- include/boost/smart_ptr/local_shared_ptr.hpp | 21 ++++++++++--------- .../smart_ptr/make_local_shared_object.hpp | 4 ++-- include/boost/smart_ptr/shared_ptr.hpp | 21 +++++++++++++++++++ 4 files changed, 45 insertions(+), 22 deletions(-) diff --git a/include/boost/smart_ptr/detail/local_counted_base.hpp b/include/boost/smart_ptr/detail/local_counted_base.hpp index b9a3911..2e5f6ae 100644 --- a/include/boost/smart_ptr/detail/local_counted_base.hpp +++ b/include/boost/smart_ptr/detail/local_counted_base.hpp @@ -17,6 +17,7 @@ // // See http://www.boost.org/libs/smart_ptr/ for documentation. +#include #include #include #include @@ -56,7 +57,7 @@ public: virtual void local_cb_destroy() BOOST_SP_NOEXCEPT = 0; - virtual boost::shared_ptr 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 { @@ -95,17 +96,17 @@ private: private: - boost::shared_ptr pn_; + shared_count pn_; public: - template explicit local_counted_impl( boost::shared_ptr const& pn ): pn_( pn ) + explicit local_counted_impl( shared_count const& pn ): pn_( pn ) { } #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) - template explicit local_counted_impl( boost::shared_ptr&& pn ): pn_( std::move(pn) ) + explicit local_counted_impl( shared_count && pn ): pn_( std::move(pn) ) { } @@ -116,9 +117,9 @@ public: delete this; } - virtual boost::shared_ptr 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( pn_ ); + return pn_; } }; @@ -126,16 +127,16 @@ class local_counted_impl_em: public local_counted_base { public: - boost::shared_ptr pn_; + shared_count pn_; virtual void local_cb_destroy() BOOST_SP_NOEXCEPT { - pn_.reset(); + shared_count().swap( pn_ ); } - virtual boost::shared_ptr 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( pn_ ); + return pn_; } }; diff --git a/include/boost/smart_ptr/local_shared_ptr.hpp b/include/boost/smart_ptr/local_shared_ptr.hpp index 2c0d2ab..2e3b8bf 100644 --- a/include/boost/smart_ptr/local_shared_ptr.hpp +++ b/include/boost/smart_ptr/local_shared_ptr.hpp @@ -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() ); - pd->pn_ = p2; + pd->pn_ = p2._internal_count(); 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() ); - pd->pn_ = p2; + pd->pn_ = p2._internal_count(); 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() ); - pd->pn_ = p2; + pd->pn_ = p2._internal_count(); 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() ); - pd->pn_ = p2; + pd->pn_ = p2._internal_count(); 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() ); - pd->pn_ = p2; + pd->pn_ = p2._internal_count(); pn = pd; } @@ -197,7 +197,7 @@ public: 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 ) { - 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 ) { - pn = new boost::detail::local_counted_impl( shared_ptr( std::move(r) ) ); + pn = new boost::detail::local_counted_impl( shared_ptr( std::move(r) )._internal_count() ); } } @@ -453,7 +454,7 @@ public: if( pn ) { - return static_pointer_cast( pn->local_cb_get_shared_ptr() ); + return shared_ptr( boost::detail::sp_internal_constructor_tag(), px, pn->local_cb_get_shared_count() ); } else { @@ -471,7 +472,7 @@ public: if( pn ) { - return static_pointer_cast( pn->local_cb_get_shared_ptr() ); + return shared_ptr( boost::detail::sp_internal_constructor_tag(), px, pn->local_cb_get_shared_count() ); } else { diff --git a/include/boost/smart_ptr/make_local_shared_object.hpp b/include/boost/smart_ptr/make_local_shared_object.hpp index 46426b5..518c24d 100644 --- a/include/boost/smart_ptr/make_local_shared_object.hpp +++ b/include/boost/smart_ptr/make_local_shared_object.hpp @@ -146,7 +146,7 @@ template typename boost::detail::lsp_if_not_arr T * pt2 = static_cast< T* >( pv ); boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - pd->pn_ = boost::shared_ptr( pt, pt2 ); + pd->pn_ = pt._internal_count(); return boost::local_shared_ptr( boost::detail::lsp_internal_constructor_tag(), pt2, pd ); } @@ -179,7 +179,7 @@ template typename boost::detail::lsp_if_not_array::type all T * pt2 = static_cast< T* >( pv ); boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - pd->pn_ = boost::shared_ptr( pt, pt2 ); + pd->pn_ = pt._internal_count(); return boost::local_shared_ptr( boost::detail::lsp_internal_constructor_tag(), pt2, pd ); } diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index a735062..e8a302c 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -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 ) +struct sp_internal_constructor_tag +{ +}; + } // 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 template @@ -781,6 +797,11 @@ public: 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 // to work in the absence of member template friends. (Matthew Langston)