#include #include using namespace ebcl; class RefCountTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE( RefCountTest ); CPPUNIT_TEST( testStackInstance ); CPPUNIT_TEST( testEmpty ); CPPUNIT_TEST( testConstruct ); CPPUNIT_TEST( testCopyCons ); CPPUNIT_TEST( testCopyAss ); CPPUNIT_TEST( testMoveCons ); CPPUNIT_TEST( testMoveAss ); CPPUNIT_TEST_SUITE_END( ); public: void setUp( ) override; void testStackInstance( ); void testEmpty( ); void testConstruct( ); void testCopyCons( ); void testCopyAss( ); void testMoveCons( ); void testMoveAss( ); }; CPPUNIT_TEST_SUITE_REGISTRATION( RefCountTest ); /*----------------------------------------------------------------------------*/ namespace { #define M_MKTESTDECL_( CLS , ATOMIC ) \ class T_ ##CLS : public T_ReferenceCountedClass< ATOMIC > \ { \ public: \ static uint32_t cNew; \ static uint32_t cDel; \ T_ ##CLS( ) noexcept { cNew ++; } \ ~T_ ##CLS( ) noexcept { cDel ++; } \ }; \ uint32_t T_ ##CLS::cNew = 0; \ uint32_t T_ ##CLS::cDel = 0; \ using P_ ##CLS = T_RcPtr< T_ ##CLS > M_MKTESTDECL_( Atomic , true ); M_MKTESTDECL_( Simple , false ); class T_Child : public T_Simple { }; using P_Child = T_RcPtr< T_Child >; } // namespace /*----------------------------------------------------------------------------*/ void RefCountTest::setUp( ) { T_Atomic::cNew = T_Atomic::cDel = 0; T_Simple::cNew = T_Simple::cDel = 0; } /*----------------------------------------------------------------------------*/ void RefCountTest::testStackInstance( ) { { T_Atomic t1; T_Simple t2; CPPUNIT_ASSERT_EQUAL( 1u , T_Atomic::cNew ); CPPUNIT_ASSERT_EQUAL( 1u , T_Simple::cNew ); CPPUNIT_ASSERT_EQUAL( 0u , t1.getReferenceCount( ) ); CPPUNIT_ASSERT_EQUAL( 0u , t2.getReferenceCount( ) ); } CPPUNIT_ASSERT_EQUAL( 1u , T_Atomic::cDel ); CPPUNIT_ASSERT_EQUAL( 1u , T_Simple::cDel ); } /*----------------------------------------------------------------------------*/ void RefCountTest::testEmpty( ) { { P_Atomic p1; P_Simple p2; CPPUNIT_ASSERT_EQUAL( 0u , T_Atomic::cNew ); CPPUNIT_ASSERT_EQUAL( 0u , T_Simple::cNew ); CPPUNIT_ASSERT_EQUAL( false , bool{ p1 } ); CPPUNIT_ASSERT_EQUAL( false , bool{ p2 } ); CPPUNIT_ASSERT_EQUAL( true , !p1 ); CPPUNIT_ASSERT_EQUAL( true , !p2 ); CPPUNIT_ASSERT_EQUAL( (T_Atomic*) nullptr , p1.get( ) ); CPPUNIT_ASSERT_EQUAL( (T_Simple*) nullptr , p2.get( ) ); CPPUNIT_ASSERT_EQUAL( (T_Atomic*) nullptr , (T_Atomic*) p1 ); CPPUNIT_ASSERT_EQUAL( (T_Simple*) nullptr , (T_Simple*) p2 ); } CPPUNIT_ASSERT_EQUAL( 0u , T_Atomic::cDel ); CPPUNIT_ASSERT_EQUAL( 0u , T_Simple::cDel ); } void RefCountTest::testConstruct( ) { { P_Atomic p1{ P_Atomic::New( ) }; P_Simple p2{ P_Simple::New( ) }; CPPUNIT_ASSERT_EQUAL( 1u , T_Atomic::cNew ); CPPUNIT_ASSERT_EQUAL( 1u , T_Simple::cNew ); CPPUNIT_ASSERT_EQUAL( true , bool{ p1 } ); CPPUNIT_ASSERT_EQUAL( true , bool{ p2 } ); CPPUNIT_ASSERT_EQUAL( false , !p1 ); CPPUNIT_ASSERT_EQUAL( false , !p2 ); CPPUNIT_ASSERT( (T_Atomic*) nullptr != p1.get( ) ); CPPUNIT_ASSERT( (T_Simple*) nullptr != p2.get( ) ); CPPUNIT_ASSERT( (T_Atomic*) nullptr != (T_Atomic*) p1 ); CPPUNIT_ASSERT( (T_Simple*) nullptr != (T_Simple*) p2 ); CPPUNIT_ASSERT_EQUAL( 1u , p1->getReferenceCount( ) ); CPPUNIT_ASSERT_EQUAL( 1u , p2->getReferenceCount( ) ); CPPUNIT_ASSERT_EQUAL( 1u , (*p1).getReferenceCount( ) ); CPPUNIT_ASSERT_EQUAL( 1u , (*p2).getReferenceCount( ) ); } CPPUNIT_ASSERT_EQUAL( 1u , T_Atomic::cDel ); CPPUNIT_ASSERT_EQUAL( 1u , T_Simple::cDel ); } /*----------------------------------------------------------------------------*/ void RefCountTest::testCopyCons( ) { { P_Atomic p1{ P_Atomic::New( ) }; P_Simple p2{ P_Simple::New( ) }; { P_Atomic c1{ p1 }; P_Simple c2{ p2 }; CPPUNIT_ASSERT_EQUAL( 1u , T_Atomic::cNew ); CPPUNIT_ASSERT_EQUAL( 1u , T_Simple::cNew ); CPPUNIT_ASSERT( c1 ); CPPUNIT_ASSERT( c2 ); CPPUNIT_ASSERT( p1.get( ) == c1.get( ) ); CPPUNIT_ASSERT( p2.get( ) == c2.get( ) ); CPPUNIT_ASSERT_EQUAL( 2u , p1->getReferenceCount( ) ); CPPUNIT_ASSERT_EQUAL( 2u , p2->getReferenceCount( ) ); } CPPUNIT_ASSERT_EQUAL( 0u , T_Atomic::cDel ); CPPUNIT_ASSERT_EQUAL( 0u , T_Simple::cDel ); CPPUNIT_ASSERT_EQUAL( 1u , p1->getReferenceCount( ) ); CPPUNIT_ASSERT_EQUAL( 1u , p2->getReferenceCount( ) ); } CPPUNIT_ASSERT_EQUAL( 1u , T_Atomic::cDel ); CPPUNIT_ASSERT_EQUAL( 1u , T_Simple::cDel ); } void RefCountTest::testCopyAss( ) { { P_Atomic p1{ P_Atomic::New( ) }; P_Simple p2{ P_Simple::New( ) }; { P_Atomic c1; P_Simple c2; CPPUNIT_ASSERT( !c1 ); CPPUNIT_ASSERT( !c2 ); c1 = p1; c2 = p2; CPPUNIT_ASSERT_EQUAL( 1u , T_Atomic::cNew ); CPPUNIT_ASSERT_EQUAL( 1u , T_Simple::cNew ); CPPUNIT_ASSERT( c1 ); CPPUNIT_ASSERT( c2 ); CPPUNIT_ASSERT( p1.get( ) == c1.get( ) ); CPPUNIT_ASSERT( p2.get( ) == c2.get( ) ); CPPUNIT_ASSERT_EQUAL( 2u , p1->getReferenceCount( ) ); CPPUNIT_ASSERT_EQUAL( 2u , p2->getReferenceCount( ) ); } CPPUNIT_ASSERT_EQUAL( 0u , T_Atomic::cDel ); CPPUNIT_ASSERT_EQUAL( 0u , T_Simple::cDel ); CPPUNIT_ASSERT_EQUAL( 1u , p1->getReferenceCount( ) ); CPPUNIT_ASSERT_EQUAL( 1u , p2->getReferenceCount( ) ); } CPPUNIT_ASSERT_EQUAL( 1u , T_Atomic::cDel ); CPPUNIT_ASSERT_EQUAL( 1u , T_Simple::cDel ); } void RefCountTest::testMoveCons( ) { P_Atomic p1{ P_Atomic::New( ) }; P_Simple p2{ P_Simple::New( ) }; { P_Atomic c1{ std::move( p1 ) }; P_Simple c2{ std::move( p2 ) }; CPPUNIT_ASSERT_EQUAL( 1u , T_Atomic::cNew ); CPPUNIT_ASSERT_EQUAL( 1u , T_Simple::cNew ); CPPUNIT_ASSERT_EQUAL( 0u , T_Atomic::cDel ); CPPUNIT_ASSERT_EQUAL( 0u , T_Simple::cDel ); CPPUNIT_ASSERT( c1 ); CPPUNIT_ASSERT( c2 ); CPPUNIT_ASSERT( !p1 ); CPPUNIT_ASSERT( !p2 ); CPPUNIT_ASSERT_EQUAL( 1u , c1->getReferenceCount( ) ); CPPUNIT_ASSERT_EQUAL( 1u , c2->getReferenceCount( ) ); } CPPUNIT_ASSERT_EQUAL( 1u , T_Atomic::cDel ); CPPUNIT_ASSERT_EQUAL( 1u , T_Simple::cDel ); } void RefCountTest::testMoveAss( ) { P_Atomic p1{ P_Atomic::New( ) }; P_Simple p2{ P_Simple::New( ) }; { P_Atomic c1; P_Simple c2; CPPUNIT_ASSERT( !c1 ); CPPUNIT_ASSERT( !c2 ); c1 = std::move( p1 ); c2 = std::move( p2 ); CPPUNIT_ASSERT_EQUAL( 1u , T_Atomic::cNew ); CPPUNIT_ASSERT_EQUAL( 1u , T_Simple::cNew ); CPPUNIT_ASSERT_EQUAL( 0u , T_Atomic::cDel ); CPPUNIT_ASSERT_EQUAL( 0u , T_Simple::cDel ); CPPUNIT_ASSERT( c1 ); CPPUNIT_ASSERT( c2 ); CPPUNIT_ASSERT( !p1 ); CPPUNIT_ASSERT( !p2 ); CPPUNIT_ASSERT_EQUAL( 1u , c1->getReferenceCount( ) ); CPPUNIT_ASSERT_EQUAL( 1u , c2->getReferenceCount( ) ); } CPPUNIT_ASSERT_EQUAL( 1u , T_Atomic::cDel ); CPPUNIT_ASSERT_EQUAL( 1u , T_Simple::cDel ); }