From 334654de06fb38a5d89a303966d106b9cfce54f2 Mon Sep 17 00:00:00 2001 From: Jonathan Wang Date: Sun, 15 Mar 2015 20:17:55 -0400 Subject: [PATCH 1/4] intrusive_ptr: add converting ctor for intrusive_ptr with move semantics. Analagous to template intrusive_ptr(intrusive_ptr const&) --- include/boost/smart_ptr/intrusive_ptr.hpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index e5db609..0b02eba 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -122,6 +122,20 @@ public: return *this; } +#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES) + template friend class intrusive_ptr; + template +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + intrusive_ptr(intrusive_ptr && rhs, typename boost::detail::sp_enable_if_convertible::type = boost::detail::sp_empty()) +#else + intrusive_ptr(intrusive_ptr && rhs) +#endif + : px( rhs.px ) + { + rhs.px = 0; + } +#endif + #endif intrusive_ptr & operator=(intrusive_ptr const & rhs) From a7ade6f062eaa41424b86e57afe7b0de92f17fdf Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 17 May 2016 18:34:18 +0300 Subject: [PATCH 2/4] Remove unnecessary #ifdef --- include/boost/smart_ptr/intrusive_ptr.hpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index ba3f30b..dceb817 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -122,19 +122,22 @@ public: return *this; } -#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES) template friend class intrusive_ptr; + template #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + intrusive_ptr(intrusive_ptr && rhs, typename boost::detail::sp_enable_if_convertible::type = boost::detail::sp_empty()) + #else + intrusive_ptr(intrusive_ptr && rhs) + #endif : px( rhs.px ) { rhs.px = 0; } -#endif #endif From b7f99ceba6b7b528b4d3e99e8b7d29a11514b145 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 17 May 2016 18:36:50 +0300 Subject: [PATCH 3/4] Update intrusive_ptr_move_test with converting move construction. --- test/intrusive_ptr_move_test.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/intrusive_ptr_move_test.cpp b/test/intrusive_ptr_move_test.cpp index 0e89764..c97bd11 100644 --- a/test/intrusive_ptr_move_test.cpp +++ b/test/intrusive_ptr_move_test.cpp @@ -143,6 +143,18 @@ int main() BOOST_TEST( N::base::instances == 0 ); } + { + boost::intrusive_ptr p( new Y ); + BOOST_TEST( N::base::instances == 1 ); + + boost::intrusive_ptr p2( std::move( p ) ); + BOOST_TEST( N::base::instances == 1 ); + BOOST_TEST( p.get() == 0 ); + + p2.reset(); + BOOST_TEST( N::base::instances == 0 ); + } + { boost::intrusive_ptr p( new X ); BOOST_TEST( N::base::instances == 1 ); From e52905cf3c264ee454ca5978d7986bfd58bcb573 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 17 May 2016 18:43:41 +0300 Subject: [PATCH 4/4] Add intrusive_ptr converting move assignment. --- include/boost/smart_ptr/intrusive_ptr.hpp | 7 ++++++ test/intrusive_ptr_move_test.cpp | 27 +++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index dceb817..1e93397 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -139,6 +139,13 @@ public: rhs.px = 0; } + template + intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_NOEXCEPT + { + this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this); + return *this; + } + #endif intrusive_ptr & operator=(intrusive_ptr const & rhs) diff --git a/test/intrusive_ptr_move_test.cpp b/test/intrusive_ptr_move_test.cpp index c97bd11..2f2f652 100644 --- a/test/intrusive_ptr_move_test.cpp +++ b/test/intrusive_ptr_move_test.cpp @@ -182,6 +182,33 @@ int main() BOOST_TEST( N::base::instances == 0 ); } + { + boost::intrusive_ptr p( new Y ); + BOOST_TEST( N::base::instances == 1 ); + + boost::intrusive_ptr p2; + p2 = std::move( p ); + BOOST_TEST( N::base::instances == 1 ); + BOOST_TEST( p.get() == 0 ); + + p2.reset(); + BOOST_TEST( N::base::instances == 0 ); + } + + { + boost::intrusive_ptr p( new Y ); + BOOST_TEST( N::base::instances == 1 ); + + boost::intrusive_ptr p2( new X ); + BOOST_TEST( N::base::instances == 2 ); + p2 = std::move( p ); + BOOST_TEST( N::base::instances == 1 ); + BOOST_TEST( p.get() == 0 ); + + p2.reset(); + BOOST_TEST( N::base::instances == 0 ); + } + return boost::report_errors(); }