// // esft_regtest.cpp // // A regression test for enable_shared_from_this // // Copyright (c) 2008 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 class X: public boost::enable_shared_from_this< X > { private: int destroyed_; int deleted_; int expected_; private: X( X const& ); X& operator=( X const& ); public: static int instances; public: explicit X( int expected ): destroyed_( 0 ), deleted_( 0 ), expected_( expected ) { ++instances; } ~X() { BOOST_TEST( deleted_ == expected_ ); BOOST_TEST( destroyed_ == 0 ); ++destroyed_; --instances; } typedef void (*deleter_type)( X* ); static void deleter( X * px ) { ++px->deleted_; } static void deleter2( X * px ) { ++px->deleted_; delete px; } }; int X::instances = 0; void test() { BOOST_TEST( X::instances == 0 ); { X x( 0 ); BOOST_TEST( X::instances == 1 ); } BOOST_TEST( X::instances == 0 ); #if !defined( BOOST_NO_AUTO_PTR ) { std::auto_ptr px( new X( 0 ) ); BOOST_TEST( X::instances == 1 ); } #endif BOOST_TEST( X::instances == 0 ); { boost::shared_ptr px( new X( 0 ) ); BOOST_TEST( X::instances == 1 ); boost::weak_ptr wp( px ); BOOST_TEST( !wp.expired() ); px.reset(); BOOST_TEST( wp.expired() ); } BOOST_TEST( X::instances == 0 ); { X x( 1 ); boost::shared_ptr px( &x, X::deleter ); BOOST_TEST( X::instances == 1 ); X::deleter_type * pd = boost::get_deleter( px ); BOOST_TEST( pd != 0 && *pd == X::deleter ); boost::weak_ptr wp( px ); BOOST_TEST( !wp.expired() ); px.reset(); BOOST_TEST( wp.expired() ); } BOOST_TEST( X::instances == 0 ); { boost::shared_ptr px( new X( 1 ), X::deleter2 ); BOOST_TEST( X::instances == 1 ); X::deleter_type * pd = boost::get_deleter( px ); BOOST_TEST( pd != 0 && *pd == X::deleter2 ); boost::weak_ptr wp( px ); BOOST_TEST( !wp.expired() ); px.reset(); BOOST_TEST( wp.expired() ); } BOOST_TEST( X::instances == 0 ); } struct V: public boost::enable_shared_from_this { virtual ~V() {} std::string m_; }; struct V2 { virtual ~V2() {} std::string m2_; }; struct W: V2, V { }; void test2() { boost::shared_ptr p( new W ); } void test3() { V * p = new W; boost::shared_ptr pv( p ); BOOST_TEST( pv.get() == p ); BOOST_TEST( pv.use_count() == 1 ); } struct null_deleter { void operator()( void const* ) const {} }; void test4() { boost::shared_ptr pv( new V ); boost::shared_ptr pv2( pv.get(), null_deleter() ); BOOST_TEST( pv2.get() == pv.get() ); BOOST_TEST( pv2.use_count() == 1 ); } void test5() { V v; boost::shared_ptr p1( &v, null_deleter() ); BOOST_TEST( p1.get() == &v ); BOOST_TEST( p1.use_count() == 1 ); try { p1->shared_from_this(); } catch( ... ) { BOOST_ERROR( "p1->shared_from_this() failed" ); } p1.reset(); boost::shared_ptr p2( &v, null_deleter() ); BOOST_TEST( p2.get() == &v ); BOOST_TEST( p2.use_count() == 1 ); try { p2->shared_from_this(); } catch( ... ) { BOOST_ERROR( "p2->shared_from_this() failed" ); } } int main() { test(); test2(); test3(); test4(); test5(); return boost::report_errors(); }