diff --git a/include/boost/smart_ptr/local_shared_ptr.hpp b/include/boost/smart_ptr/local_shared_ptr.hpp index 21cae2e..0f42550 100644 --- a/include/boost/smart_ptr/local_shared_ptr.hpp +++ b/include/boost/smart_ptr/local_shared_ptr.hpp @@ -141,10 +141,16 @@ public: #if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) template< class Y, class D > - local_shared_ptr( std::unique_ptr< Y, D > && r ) - : px( r.get() ), pn( new boost::detail::local_counted_impl( shared_ptr( std::move(r) ) ) ) + local_shared_ptr( std::unique_ptr< Y, D > && r, + typename boost::detail::sp_enable_if_convertible::type = boost::detail::sp_empty() ) + : px( r.get() ), pn( 0 ) { boost::detail::sp_assert_convertible< Y, T >(); + + if( px ) + { + pn = new boost::detail::local_counted_impl( shared_ptr( std::move(r) ) ); + } } #endif diff --git a/test/local_sp_test.cpp b/test/local_sp_test.cpp index fbe441d..69cbb30 100644 --- a/test/local_sp_test.cpp +++ b/test/local_sp_test.cpp @@ -790,6 +790,119 @@ static void shared_ptr_move_constructor() #endif +// unique_ptr_constructor + +#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + +template static void test_null_unique_ptr( std::unique_ptr && p1 ) +{ + boost::local_shared_ptr p2( std::move( p1 ) ); + + BOOST_TEST( p1.get() == 0 ); + + BOOST_TEST( p2.get() == 0 ); + BOOST_TEST( p2.local_use_count() == 0 ); +} + +template static void null_unique_ptr_test() +{ + test_null_unique_ptr( std::unique_ptr() ); + + test_null_unique_ptr( std::unique_ptr() ); + test_null_unique_ptr( std::unique_ptr() ); + test_null_unique_ptr( std::unique_ptr() ); + + test_null_unique_ptr( std::unique_ptr() ); + test_null_unique_ptr( std::unique_ptr() ); + test_null_unique_ptr( std::unique_ptr() ); + + test_null_unique_ptr( std::unique_ptr() ); + + test_null_unique_ptr( std::unique_ptr() ); + test_null_unique_ptr( std::unique_ptr() ); + test_null_unique_ptr( std::unique_ptr() ); + + test_null_unique_ptr( std::unique_ptr() ); + test_null_unique_ptr( std::unique_ptr() ); + test_null_unique_ptr( std::unique_ptr() ); +} + +template static void test_nonempty_unique_ptr( std::unique_ptr && p1 ) +{ + U * q = p1.get(); + + boost::local_shared_ptr p2( std::move(p1) ); + + BOOST_TEST( p2.get() == q ); + BOOST_TEST( p2.local_use_count() == 1 ); + + BOOST_TEST( p1.get() == 0 ); +} + +template static void new_unique_ptr_test() +{ + test_nonempty_unique_ptr( std::unique_ptr( new T() ) ); + + test_nonempty_unique_ptr( std::unique_ptr( new T() ) ); + test_nonempty_unique_ptr( std::unique_ptr( new T() ) ); + test_nonempty_unique_ptr( std::unique_ptr( new T() ) ); + + test_nonempty_unique_ptr( std::unique_ptr( new T() ) ); + test_nonempty_unique_ptr( std::unique_ptr( new T() ) ); + test_nonempty_unique_ptr( std::unique_ptr( new T() ) ); + + test_nonempty_unique_ptr( std::unique_ptr( new T() ) ); + + test_nonempty_unique_ptr( std::unique_ptr( new T() ) ); + test_nonempty_unique_ptr( std::unique_ptr( new T() ) ); + test_nonempty_unique_ptr( std::unique_ptr( new T() ) ); + + test_nonempty_unique_ptr( std::unique_ptr( new T() ) ); + test_nonempty_unique_ptr( std::unique_ptr( new T() ) ); + test_nonempty_unique_ptr( std::unique_ptr( new T() ) ); +} + +template static void test_deleter_unique_ptr() +{ + m = 0; + + test_nonempty_unique_ptr( std::unique_ptr( &m, deleter2 ) ); + + BOOST_TEST( m == 1 ); +} + +template static void deleter_unique_ptr_test() +{ + test_deleter_unique_ptr(); + test_deleter_unique_ptr(); + test_deleter_unique_ptr(); + test_deleter_unique_ptr(); +} + +static void unique_ptr_constructor() +{ + null_unique_ptr_test(); + null_unique_ptr_test(); + + BOOST_TEST( X::instances == 0 ); + + new_unique_ptr_test(); + new_unique_ptr_test(); + + BOOST_TEST( X::instances == 0 ); + + deleter_unique_ptr_test(); + deleter_unique_ptr_test(); +} + +#else + +static void unique_ptr_constructor() +{ +} + +#endif + // copy assignment template static void empty_copy_assign_test() @@ -1139,7 +1252,7 @@ int main() nullptr_allocator_constructor(); shared_ptr_copy_constructor(); shared_ptr_move_constructor(); - // unique_ptr_constructor(); + unique_ptr_constructor(); copy_assignment(); move_assignment();