diff --git a/include/boost/smart_ptr/detail/sp_counted_impl.hpp b/include/boost/smart_ptr/detail/sp_counted_impl.hpp index 26628cc..b21685e 100644 --- a/include/boost/smart_ptr/detail/sp_counted_impl.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_impl.hpp @@ -228,7 +228,7 @@ template class BOOST_SYMBOL_VISIBLE sp_counted_impl_p private: P p_; // copy constructor must not throw - D d_; // copy constructor must not throw + D d_; // copy/move constructor must not throw A a_; // copy constructor must not throw sp_counted_impl_pda( sp_counted_impl_pda const & ); @@ -240,10 +240,20 @@ public: // pre: d( p ) must not throw +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + + sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( static_cast< D&& >( d ) ), a_( a ) + { + } + +#else + sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a ) { } +#endif + sp_counted_impl_pda( P p, A a ): p_( p ), d_( a ), a_( a ) { } diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 38dce70..e3f3142 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -405,11 +405,22 @@ public: // As above, but with allocator. A's copy constructor shall not throw. +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + + template shared_ptr( Y * p, D d, A a ): px( p ), pn( p, static_cast< D&& >( d ), a ) + { + boost::detail::sp_deleter_construct( this, p ); + } + +#else + template shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a ) { boost::detail::sp_deleter_construct( this, p ); } +#endif + #if !defined( BOOST_NO_CXX11_NULLPTR ) template shared_ptr( boost::detail::sp_nullptr_t p, D d, A a ): px( p ), pn( p, d, a ) @@ -711,6 +722,11 @@ public: this_type( p, static_cast< D&& >( d ) ).swap( *this ); } + template void reset( Y * p, D d, A a ) + { + this_type( p, static_cast< D&& >( d ), a ).swap( *this ); + } + #else template void reset( Y * p, D d ) @@ -718,13 +734,13 @@ public: this_type( p, d ).swap( *this ); } -#endif - template void reset( Y * p, D d, A a ) { this_type( p, d, a ).swap( *this ); } +#endif + template void reset( shared_ptr const & r, element_type * p ) BOOST_SP_NOEXCEPT { this_type( r, p ).swap( *this ); diff --git a/test/sp_move_only_deleter.cpp b/test/sp_move_only_deleter.cpp index d879b7b..08cd576 100644 --- a/test/sp_move_only_deleter.cpp +++ b/test/sp_move_only_deleter.cpp @@ -100,6 +100,31 @@ int main() BOOST_TEST( Y::instances == 0 ); } + { + YD del; + boost::shared_ptr p( new Y, std::move( del ), std::allocator() ); + + BOOST_TEST( Y::instances == 1 ); + BOOST_TEST( del.moved_ ); + + p.reset( new Y, YD(), std::allocator() ); + + BOOST_TEST( Y::instances == 1 ); + + p = boost::shared_ptr( new Y, YD(), std::allocator() ); + + BOOST_TEST( Y::instances == 1 ); + + YD del2; + p.reset( new Y, std::move( del2 ), std::allocator() ); + + BOOST_TEST( Y::instances == 1 ); + BOOST_TEST( del2.moved_ ); + + p.reset(); + BOOST_TEST( Y::instances == 0 ); + } + return boost::report_errors(); }