// // sp_bml_unique_ptr_test.cpp // // Copyright (c) 2012, 2015 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt // #include #include #include #include #include #include #include struct X: public boost::enable_shared_from_this< X > { static int instances; X() { ++instances; } ~X() { --instances; } private: X( X const & ); X & operator=( X const & ); }; int X::instances = 0; struct Y { static int instances; bool deleted_; Y(): deleted_( false ) { ++instances; } ~Y() { BOOST_TEST( deleted_ ); --instances; } private: Y( Y const & ); Y & operator=( Y const & ); }; int Y::instances = 0; struct YD { void operator()( Y* p ) const { if( p ) { p->deleted_ = true; delete p; } else { BOOST_ERROR( "YD::operator()(0) called" ); } } }; template static void test_null_unique_ptr( boost::movelib::unique_ptr p1, boost::movelib::unique_ptr p2 ) { BOOST_TEST( T::instances == 0 ); boost::shared_ptr sp( boost::move( p1 ) ); BOOST_TEST( sp.get() == 0 ); BOOST_TEST( sp.use_count() == 0 ); sp.reset( new T, typename boost::remove_reference::type() ); BOOST_TEST( sp.get() != 0 ); BOOST_TEST( sp.use_count() == 1 ); BOOST_TEST( T::instances == 1 ); sp = boost::move( p2 ); BOOST_TEST( sp.get() == 0 ); BOOST_TEST( sp.use_count() == 0 ); BOOST_TEST( T::instances == 0 ); } int main() { { BOOST_TEST( X::instances == 0 ); boost::movelib::unique_ptr p( new X ); BOOST_TEST( X::instances == 1 ); boost::shared_ptr p2( boost::move( p ) ); BOOST_TEST( X::instances == 1 ); BOOST_TEST( p.get() == 0 ); boost::shared_ptr p3 = p2->shared_from_this(); BOOST_TEST( p2 == p3 ); BOOST_TEST( !(p2 < p3) && !(p3 < p2) ); p2.reset(); p3.reset(); BOOST_TEST( X::instances == 0 ); p2 = boost::movelib::unique_ptr( new X ); BOOST_TEST( X::instances == 1 ); p2 = boost::movelib::unique_ptr( new X ); BOOST_TEST( X::instances == 1 ); p3 = p2->shared_from_this(); BOOST_TEST( p2 == p3 ); BOOST_TEST( !(p2 < p3) && !(p3 < p2) ); p2.reset(); p3.reset(); BOOST_TEST( X::instances == 0 ); } { BOOST_TEST( X::instances == 0 ); boost::movelib::unique_ptr p( new X ); BOOST_TEST( X::instances == 1 ); boost::shared_ptr p2( boost::move( p ) ); BOOST_TEST( X::instances == 1 ); BOOST_TEST( p.get() == 0 ); boost::shared_ptr p3 = p2->shared_from_this(); BOOST_TEST( p2 == p3 ); BOOST_TEST( !(p2 < p3) && !(p3 < p2) ); p2.reset(); p3.reset(); BOOST_TEST( X::instances == 0 ); p2 = boost::movelib::unique_ptr( new X ); BOOST_TEST( X::instances == 1 ); p2 = boost::movelib::unique_ptr( new X ); BOOST_TEST( X::instances == 1 ); p3 = p2->shared_from_this(); BOOST_TEST( p2 == p3 ); BOOST_TEST( !(p2 < p3) && !(p3 < p2) ); p2.reset(); p3.reset(); BOOST_TEST( X::instances == 0 ); } { BOOST_TEST( X::instances == 0 ); boost::movelib::unique_ptr p( new X ); BOOST_TEST( X::instances == 1 ); boost::shared_ptr p2( boost::move( p ) ); BOOST_TEST( X::instances == 1 ); BOOST_TEST( p.get() == 0 ); p2.reset(); BOOST_TEST( X::instances == 0 ); p2 = boost::movelib::unique_ptr( new X ); BOOST_TEST( X::instances == 1 ); p2 = boost::movelib::unique_ptr( new X ); BOOST_TEST( X::instances == 1 ); p2.reset(); BOOST_TEST( X::instances == 0 ); } { BOOST_TEST( Y::instances == 0 ); boost::movelib::unique_ptr p( new Y, YD() ); BOOST_TEST( Y::instances == 1 ); boost::shared_ptr p2( boost::move( p ) ); BOOST_TEST( Y::instances == 1 ); BOOST_TEST( p.get() == 0 ); p2.reset(); BOOST_TEST( Y::instances == 0 ); p2 = boost::movelib::unique_ptr( new Y, YD() ); BOOST_TEST( Y::instances == 1 ); p2 = boost::movelib::unique_ptr( new Y, YD() ); BOOST_TEST( Y::instances == 1 ); p2.reset(); BOOST_TEST( Y::instances == 0 ); } { BOOST_TEST( Y::instances == 0 ); YD yd; boost::movelib::unique_ptr p( new Y, yd ); BOOST_TEST( Y::instances == 1 ); boost::shared_ptr p2( boost::move( p ) ); BOOST_TEST( Y::instances == 1 ); BOOST_TEST( p.get() == 0 ); p2.reset(); BOOST_TEST( Y::instances == 0 ); p2 = boost::movelib::unique_ptr( new Y, yd ); BOOST_TEST( Y::instances == 1 ); p2 = boost::movelib::unique_ptr( new Y, yd ); BOOST_TEST( Y::instances == 1 ); p2.reset(); BOOST_TEST( Y::instances == 0 ); } { BOOST_TEST( Y::instances == 0 ); YD yd; boost::movelib::unique_ptr p( new Y, yd ); BOOST_TEST( Y::instances == 1 ); boost::shared_ptr p2( boost::move( p ) ); BOOST_TEST( Y::instances == 1 ); BOOST_TEST( p.get() == 0 ); p2.reset(); BOOST_TEST( Y::instances == 0 ); p2 = boost::movelib::unique_ptr( new Y, yd ); BOOST_TEST( Y::instances == 1 ); p2 = boost::movelib::unique_ptr( new Y, yd ); BOOST_TEST( Y::instances == 1 ); p2.reset(); BOOST_TEST( Y::instances == 0 ); } { test_null_unique_ptr( boost::movelib::unique_ptr(), boost::movelib::unique_ptr() ); test_null_unique_ptr( boost::movelib::unique_ptr(), boost::movelib::unique_ptr() ); test_null_unique_ptr( boost::movelib::unique_ptr(), boost::movelib::unique_ptr() ); test_null_unique_ptr( boost::movelib::unique_ptr(), boost::movelib::unique_ptr() ); } { test_null_unique_ptr( boost::movelib::unique_ptr( 0, YD() ), boost::movelib::unique_ptr( 0, YD() ) ); test_null_unique_ptr( boost::movelib::unique_ptr( 0, YD() ), boost::movelib::unique_ptr( 0, YD() ) ); test_null_unique_ptr( boost::movelib::unique_ptr( 0, YD() ), boost::movelib::unique_ptr( 0, YD() ) ); test_null_unique_ptr( boost::movelib::unique_ptr( 0, YD() ), boost::movelib::unique_ptr( 0, YD() ) ); } { YD yd; test_null_unique_ptr( boost::movelib::unique_ptr( 0, yd ), boost::movelib::unique_ptr( 0, yd ) ); test_null_unique_ptr( boost::movelib::unique_ptr( 0, yd ), boost::movelib::unique_ptr( 0, yd ) ); test_null_unique_ptr( boost::movelib::unique_ptr( 0, yd ), boost::movelib::unique_ptr( 0, yd ) ); test_null_unique_ptr( boost::movelib::unique_ptr( 0, yd ), boost::movelib::unique_ptr( 0, yd ) ); } return boost::report_errors(); }