#include #include using namespace lw; class SharedPointerTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE( SharedPointerTest ); CPPUNIT_TEST( testEmpty ); CPPUNIT_TEST( testNewShared ); CPPUNIT_TEST( testSwap ); CPPUNIT_TEST( testClear ); CPPUNIT_TEST( testClearEmpty ); CPPUNIT_TEST( testMoveCons ); CPPUNIT_TEST( testMoveConsCastC2P ); CPPUNIT_TEST( testMoveConsCastP2C ); CPPUNIT_TEST( testMoveConsCastBad ); CPPUNIT_TEST( testCopyCons ); CPPUNIT_TEST( testCopyConsCastC2P ); CPPUNIT_TEST( testCopyConsCastP2C ); CPPUNIT_TEST( testCopyConsCastBad ); CPPUNIT_TEST( testCopyAss ); CPPUNIT_TEST( testCopyAssCastC2P ); CPPUNIT_TEST( testCopyAssCastP2C ); CPPUNIT_TEST( testCopyAssCastBad ); CPPUNIT_TEST( testMoveAss ); CPPUNIT_TEST( testMoveAssCastC2P ); CPPUNIT_TEST( testMoveAssCastP2C ); CPPUNIT_TEST( testMoveAssCastBad ); CPPUNIT_TEST( testMakeOwnedEmpty ); CPPUNIT_TEST( testMakeOwnedOneRef ); CPPUNIT_TEST( testMakeOwnedManyRefs ); CPPUNIT_TEST_SUITE_END( ); public: void tearDown( ); void testEmpty( ); void testNewShared( ); void testSwap( ); void testClear( ); void testClearEmpty( ); void testMoveCons( ); void testMoveConsCastC2P( ); void testMoveConsCastP2C( ); void testMoveConsCastBad( ); void testCopyCons( ); void testCopyConsCastC2P( ); void testCopyConsCastP2C( ); void testCopyConsCastBad( ); void testCopyAss( ); void testCopyAssCastC2P( ); void testCopyAssCastP2C( ); void testCopyAssCastBad( ); void testMoveAss( ); void testMoveAssCastC2P( ); void testMoveAssCastP2C( ); void testMoveAssCastBad( ); void testMakeOwnedEmpty( ); void testMakeOwnedOneRef( ); void testMakeOwnedManyRefs( ); }; CPPUNIT_TEST_SUITE_REGISTRATION( SharedPointerTest ); /*----------------------------------------------------------------------------*/ #include "ptr-common.hh" using Ptr = T_SharedPtr< T_Test >; void SharedPointerTest::tearDown( ) { T_Test::dCalled = 0; } /*----------------------------------------------------------------------------*/ void SharedPointerTest::testEmpty( ) { { Ptr test; CPPUNIT_ASSERT( !test ); CPPUNIT_ASSERT_EQUAL( false , bool( test ) ); CPPUNIT_ASSERT_EQUAL( (T_Test *) nullptr , (T_Test *) test ); } CPPUNIT_ASSERT_EQUAL( 0 , T_Test::dCalled ); } void SharedPointerTest::testNewShared( ) { { Ptr test( NewShared< T_Test >( ) ); CPPUNIT_ASSERT( bool( test ) ); CPPUNIT_ASSERT_EQUAL( false , !test ); CPPUNIT_ASSERT( nullptr != (T_Test *) test ); CPPUNIT_ASSERT_EQUAL( -1 , test->field ); CPPUNIT_ASSERT_EQUAL( -1 , (*test).field ); } CPPUNIT_ASSERT_EQUAL( 1 , T_Test::dCalled ); } void SharedPointerTest::testSwap( ) { { Ptr test1( NewShared< T_Test >( 1 ) ); Ptr test2( NewShared< T_Test >( 2 ) ); swap( test1 , test2 ); CPPUNIT_ASSERT_EQUAL( 0 , T_Test::dCalled ); CPPUNIT_ASSERT_EQUAL( 1 , test2->field ); CPPUNIT_ASSERT_EQUAL( 2 , test1->field ); } CPPUNIT_ASSERT_EQUAL( 2 , T_Test::dCalled ); } void SharedPointerTest::testClear( ) { { Ptr test( NewShared< T_Test >( ) ); test.clear( ); CPPUNIT_ASSERT( !test ); CPPUNIT_ASSERT_EQUAL( 1 , T_Test::dCalled ); } CPPUNIT_ASSERT_EQUAL( 1 , T_Test::dCalled ); } void SharedPointerTest::testClearEmpty( ) { { Ptr test; test.clear( ); CPPUNIT_ASSERT( !test ); CPPUNIT_ASSERT_EQUAL( 0 , T_Test::dCalled ); } CPPUNIT_ASSERT_EQUAL( 0 , T_Test::dCalled ); } /*----------------------------------------------------------------------------*/ void SharedPointerTest::testMoveCons( ) { { Ptr test( NewShared< T_Test >( ) ); Ptr test2( std::move( test ) ); CPPUNIT_ASSERT( bool( test2 ) ); CPPUNIT_ASSERT( !test ); CPPUNIT_ASSERT_EQUAL( 0 , T_Test::dCalled ); } CPPUNIT_ASSERT_EQUAL( 1 , T_Test::dCalled ); } void SharedPointerTest::testMoveConsCastC2P( ) { T_SharedPtr< T_TestChild > source( NewShared< T_TestChild >( ) ); Ptr test( std::move( source ) ); CPPUNIT_ASSERT_EQUAL( 0 , T_Test::dCalled ); CPPUNIT_ASSERT( !source ); CPPUNIT_ASSERT( bool( test ) ); T_Test const& t( *test ); CPPUNIT_ASSERT( typeid( T_TestChild ) == typeid( t ) ); } void SharedPointerTest::testMoveConsCastP2C( ) { Ptr source( NewShared< T_TestChild >( ) ); T_SharedPtr< T_TestChild > test( std::move( source ) ); CPPUNIT_ASSERT_EQUAL( 0 , T_Test::dCalled ); CPPUNIT_ASSERT( !source ); CPPUNIT_ASSERT( bool( test ) ); } void SharedPointerTest::testMoveConsCastBad( ) { Ptr source( NewShared< T_OtherChild >( 123 , 456 ) ); try { T_SharedPtr< T_TestChild > test( std::move( source ) ); CPPUNIT_ASSERT( "std::bad_cast not thrown" ); } catch ( std::bad_cast const& ) { // OK } CPPUNIT_ASSERT_EQUAL( 0 , T_Test::dCalled ); CPPUNIT_ASSERT( source ); } /*----------------------------------------------------------------------------*/ void SharedPointerTest::testCopyCons( ) { { Ptr test( NewShared< T_Test >( ) ); { Ptr test2( test ); CPPUNIT_ASSERT( test == test2 ); CPPUNIT_ASSERT( (T_Test *) test == (T_Test *) test2 ); } CPPUNIT_ASSERT( bool( test ) ); } CPPUNIT_ASSERT_EQUAL( 1 , T_Test::dCalled ); } void SharedPointerTest::testCopyConsCastC2P( ) { T_SharedPtr< T_TestChild > source( NewShared< T_TestChild >( ) ); Ptr test( source ); CPPUNIT_ASSERT_EQUAL( 0 , T_Test::dCalled ); CPPUNIT_ASSERT( bool( source ) ); CPPUNIT_ASSERT( bool( test ) ); T_Test const& t( *test ); CPPUNIT_ASSERT( typeid( T_TestChild ) == typeid( t ) ); } void SharedPointerTest::testCopyConsCastP2C( ) { Ptr source( NewShared< T_TestChild >( ) ); T_SharedPtr< T_TestChild > test( source ); CPPUNIT_ASSERT_EQUAL( 0 , T_Test::dCalled ); CPPUNIT_ASSERT( bool( source ) ); CPPUNIT_ASSERT( bool( test ) ); } void SharedPointerTest::testCopyConsCastBad( ) { Ptr source( NewShared< T_OtherChild >( 123 , 456 ) ); try { T_SharedPtr< T_TestChild > test( source ); CPPUNIT_ASSERT( "std::bad_cast not thrown" ); } catch ( std::bad_cast const& ) { // OK } CPPUNIT_ASSERT_EQUAL( 0 , T_Test::dCalled ); CPPUNIT_ASSERT( source ); } /*----------------------------------------------------------------------------*/ void SharedPointerTest::testCopyAss( ) { { Ptr test1( NewShared< T_Test >( 1 ) ); Ptr test2( NewShared< T_Test >( 2 ) ); CPPUNIT_ASSERT( test1 != test2 ); test1 = test2; CPPUNIT_ASSERT_EQUAL( 1 , T_Test::dCalled ); CPPUNIT_ASSERT_EQUAL( 2 , test1->field ); CPPUNIT_ASSERT( test1 == test2 ); } CPPUNIT_ASSERT_EQUAL( 2 , T_Test::dCalled ); } void SharedPointerTest::testCopyAssCastC2P( ) { T_SharedPtr< T_TestChild > source( NewShared< T_TestChild >( ) ); Ptr test( NewShared< T_Test >( 123 ) ); CPPUNIT_ASSERT( test != source ); test = source; CPPUNIT_ASSERT_EQUAL( 1 , T_Test::dCalled ); CPPUNIT_ASSERT( bool( source ) ); CPPUNIT_ASSERT( bool( test ) ); T_Test const& t( *test ); CPPUNIT_ASSERT( typeid( T_TestChild ) == typeid( t ) ); } void SharedPointerTest::testCopyAssCastP2C( ) { Ptr source( NewShared< T_OtherChild >( 123 , 456 ) ); T_SharedPtr< T_OtherChild > test( NewShared< T_OtherChild >( 789 , 12 ) ); CPPUNIT_ASSERT( (void*)(T_OtherChild*)test != (void*)(T_Test*)source ); test = source; CPPUNIT_ASSERT_EQUAL( 1 , T_Test::dCalled ); CPPUNIT_ASSERT( bool( source ) ); CPPUNIT_ASSERT( bool( test ) ); } void SharedPointerTest::testCopyAssCastBad( ) { Ptr source( NewShared< T_OtherChild >( 123 , 456 ) ); T_SharedPtr< T_TestChild > test; try { test = source; CPPUNIT_ASSERT( "std::bad_cast not thrown" ); } catch ( std::bad_cast const& ) { // OK } CPPUNIT_ASSERT_EQUAL( 0 , T_Test::dCalled ); CPPUNIT_ASSERT( source ); CPPUNIT_ASSERT( !test ); } /*----------------------------------------------------------------------------*/ void SharedPointerTest::testMoveAss( ) { { Ptr test( NewShared< T_Test >( 1 ) ); test = NewShared< T_Test >( 2 ); CPPUNIT_ASSERT_EQUAL( 1 , T_Test::dCalled ); CPPUNIT_ASSERT_EQUAL( 2 , test->field ); } CPPUNIT_ASSERT_EQUAL( 2 , T_Test::dCalled ); } void SharedPointerTest::testMoveAssCastC2P( ) { T_SharedPtr< T_TestChild > source( NewShared< T_TestChild >( ) ); Ptr test( NewShared< T_Test >( 123 ) ); CPPUNIT_ASSERT( test != source ); test = std::move( source ); CPPUNIT_ASSERT_EQUAL( 1 , T_Test::dCalled ); CPPUNIT_ASSERT( bool( !source ) ); CPPUNIT_ASSERT( bool( test ) ); T_Test const& t( *test ); CPPUNIT_ASSERT( typeid( T_TestChild ) == typeid( t ) ); } void SharedPointerTest::testMoveAssCastP2C( ) { Ptr source( NewShared< T_OtherChild >( 123 , 456 ) ); T_SharedPtr< T_OtherChild > test( NewShared< T_OtherChild >( 789 , 12 ) ); CPPUNIT_ASSERT( (void*)(T_OtherChild*)test != (void*)(T_Test*)source ); test = std::move( source ); CPPUNIT_ASSERT_EQUAL( 1 , T_Test::dCalled ); CPPUNIT_ASSERT( bool( !source ) ); CPPUNIT_ASSERT( bool( test ) ); } void SharedPointerTest::testMoveAssCastBad( ) { Ptr source( NewShared< T_OtherChild >( 123 , 456 ) ); T_SharedPtr< T_TestChild > test; try { test = std::move( source ); CPPUNIT_ASSERT( "std::bad_cast not thrown" ); } catch ( std::bad_cast const& ) { // OK } CPPUNIT_ASSERT_EQUAL( 0 , T_Test::dCalled ); CPPUNIT_ASSERT( source ); CPPUNIT_ASSERT( !test ); } /*----------------------------------------------------------------------------*/ void SharedPointerTest::testMakeOwnedEmpty( ) { Ptr sp; T_OwnPtr< T_Test > op( sp.makeOwned( ) ); CPPUNIT_ASSERT( !op ); } void SharedPointerTest::testMakeOwnedOneRef( ) { Ptr sp( NewShared< T_Test >( 123 ) ); T_OwnPtr< T_Test > op( sp.makeOwned( ) ); CPPUNIT_ASSERT_EQUAL( 0 , T_Test::dCalled ); CPPUNIT_ASSERT( op ); CPPUNIT_ASSERT_EQUAL( 123 , op->field ); CPPUNIT_ASSERT( !sp ); } void SharedPointerTest::testMakeOwnedManyRefs( ) { Ptr sp( NewShared< T_Test >( 123 ) ); Ptr sp2( sp ); try { sp.makeOwned( ); CPPUNIT_FAIL( "X_TooManyReferences not thrown" ); } catch ( X_TooManyReferences const& ) { // OK } CPPUNIT_ASSERT_EQUAL( 0 , T_Test::dCalled ); CPPUNIT_ASSERT( sp && sp2 ); }