diff --git a/tests/list.mk b/tests/list.mk index 2c0cec6..78e7aab 100644 --- a/tests/list.mk +++ b/tests/list.mk @@ -26,6 +26,7 @@ TESTS = \ key-value-table \ object-table \ fs-path \ + ref-count \ srd-mem-target \ srd-lexer \ srd-text-writer \ diff --git a/tests/ref-count.cc b/tests/ref-count.cc index 186274d..740b32f 100644 --- a/tests/ref-count.cc +++ b/tests/ref-count.cc @@ -2,8 +2,21 @@ #include using namespace ebcl; +template< bool Atomic > class RefCountTest : public CppUnit::TestFixture { + public: + class T_Test : public T_ReferenceCountedClass< Atomic > \ + { + public: + static uint32_t cNew; + static uint32_t cDel; + T_Test( ) noexcept { cNew ++; } + ~T_Test( ) noexcept { cDel ++; } + }; + using P_Test = T_RcPtr< T_Test >; + + private: CPPUNIT_TEST_SUITE( RefCountTest ); CPPUNIT_TEST( testStackInstance ); @@ -14,6 +27,8 @@ class RefCountTest : public CppUnit::TestFixture CPPUNIT_TEST( testCopyAss ); CPPUNIT_TEST( testMoveCons ); CPPUNIT_TEST( testMoveAss ); + + CPPUNIT_TEST( testSwap ); CPPUNIT_TEST_SUITE_END( ); public: @@ -28,206 +43,165 @@ class RefCountTest : public CppUnit::TestFixture void testCopyAss( ); void testMoveCons( ); void testMoveAss( ); + + void testSwap( ); }; -CPPUNIT_TEST_SUITE_REGISTRATION( RefCountTest ); +CPPUNIT_TEST_SUITE_REGISTRATION( RefCountTest< true > ); +CPPUNIT_TEST_SUITE_REGISTRATION( RefCountTest< false > ); + +template<> uint32_t RefCountTest< true >::T_Test::cNew = 0; +template<> uint32_t RefCountTest< true >::T_Test::cDel = 0; +template<> uint32_t RefCountTest< false >::T_Test::cNew = 0; +template<> uint32_t RefCountTest< false >::T_Test::cDel = 0; /*----------------------------------------------------------------------------*/ -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( ) +template< bool A > +void RefCountTest< A >::setUp( ) { - T_Atomic::cNew = T_Atomic::cDel = 0; - T_Simple::cNew = T_Simple::cDel = 0; + T_Test::cNew = T_Test::cDel = 0; } /*----------------------------------------------------------------------------*/ -void RefCountTest::testStackInstance( ) +template< bool A > +void RefCountTest< A >::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( ) ); + T_Test t; + CPPUNIT_ASSERT_EQUAL( 1u , T_Test::cNew ); + CPPUNIT_ASSERT_EQUAL( 0u , t.getReferenceCount( ) ); } - CPPUNIT_ASSERT_EQUAL( 1u , T_Atomic::cDel ); - CPPUNIT_ASSERT_EQUAL( 1u , T_Simple::cDel ); + CPPUNIT_ASSERT_EQUAL( 1u , T_Test::cDel ); } /*----------------------------------------------------------------------------*/ -void RefCountTest::testEmpty( ) +template< bool A > +void RefCountTest< A >::testEmpty( ) { { - P_Atomic p1; - P_Simple p2; - CPPUNIT_ASSERT_EQUAL( 0u , T_Atomic::cNew ); - CPPUNIT_ASSERT_EQUAL( 0u , T_Simple::cNew ); + P_Test p1; + CPPUNIT_ASSERT_EQUAL( 0u , T_Test::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( (T_Test*) nullptr , p1.get( ) ); + CPPUNIT_ASSERT_EQUAL( (T_Test*) nullptr , (T_Test*) p1 ); } - CPPUNIT_ASSERT_EQUAL( 0u , T_Atomic::cDel ); - CPPUNIT_ASSERT_EQUAL( 0u , T_Simple::cDel ); + CPPUNIT_ASSERT_EQUAL( 0u , T_Test::cDel ); } -void RefCountTest::testConstruct( ) +template< bool A > +void RefCountTest< A >::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 ); + P_Test p1{ P_Test::New( ) }; + CPPUNIT_ASSERT_EQUAL( 1u , T_Test::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( (T_Test*) nullptr != p1.get( ) ); + CPPUNIT_ASSERT( (T_Test*) nullptr != (T_Test*) p1 ); 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 ); + CPPUNIT_ASSERT_EQUAL( 1u , T_Test::cDel ); } /*----------------------------------------------------------------------------*/ -void RefCountTest::testCopyCons( ) +template< bool A > +void RefCountTest< A >::testCopyCons( ) { { - P_Atomic p1{ P_Atomic::New( ) }; - P_Simple p2{ P_Simple::New( ) }; + P_Test p1{ P_Test::New( ) }; { - P_Atomic c1{ p1 }; - P_Simple c2{ p2 }; - CPPUNIT_ASSERT_EQUAL( 1u , T_Atomic::cNew ); - CPPUNIT_ASSERT_EQUAL( 1u , T_Simple::cNew ); + P_Test c1{ p1 }; + CPPUNIT_ASSERT_EQUAL( 1u , T_Test::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( 0u , T_Test::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 ); + CPPUNIT_ASSERT_EQUAL( 1u , T_Test::cDel ); } -void RefCountTest::testCopyAss( ) +template< bool A > +void RefCountTest< A >::testCopyAss( ) { { - P_Atomic p1{ P_Atomic::New( ) }; - P_Simple p2{ P_Simple::New( ) }; + P_Test p1{ P_Test::New( ) }; { - P_Atomic c1; - P_Simple c2; + P_Test c1; 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_EQUAL( 1u , T_Test::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( 0u , T_Test::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 ); + CPPUNIT_ASSERT_EQUAL( 1u , T_Test::cDel ); } -void RefCountTest::testMoveCons( ) +template< bool A > +void RefCountTest< A >::testMoveCons( ) { - P_Atomic p1{ P_Atomic::New( ) }; - P_Simple p2{ P_Simple::New( ) }; + P_Test p1{ P_Test::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 ); + P_Test c1{ std::move( p1 ) }; + CPPUNIT_ASSERT_EQUAL( 1u , T_Test::cNew ); + CPPUNIT_ASSERT_EQUAL( 0u , T_Test::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 ); + CPPUNIT_ASSERT_EQUAL( 1u , T_Test::cDel ); } -void RefCountTest::testMoveAss( ) +template< bool A > +void RefCountTest< A >::testMoveAss( ) { - P_Atomic p1{ P_Atomic::New( ) }; - P_Simple p2{ P_Simple::New( ) }; + P_Test p1{ P_Test::New( ) }; { - P_Atomic c1; - P_Simple c2; + P_Test c1; 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_EQUAL( 1u , T_Test::cNew ); + CPPUNIT_ASSERT_EQUAL( 0u , T_Test::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 ); + CPPUNIT_ASSERT_EQUAL( 1u , T_Test::cDel ); +} + +/*----------------------------------------------------------------------------*/ + +template< bool A > +void RefCountTest< A >::testSwap( ) +{ + { + P_Test p1{ P_Test::New( ) }; + P_Test p2{ }; + CPPUNIT_ASSERT_EQUAL( 1u , T_Test::cNew ); + CPPUNIT_ASSERT_EQUAL( 0u , T_Test::cDel ); + CPPUNIT_ASSERT( p1 ); + CPPUNIT_ASSERT( !p2 ); + CPPUNIT_ASSERT_EQUAL( 1u , p1->getReferenceCount( ) ); + + p1.swap( p2 ); + CPPUNIT_ASSERT( !p1 ); + CPPUNIT_ASSERT( p2 ); + CPPUNIT_ASSERT_EQUAL( 1u , p2->getReferenceCount( ) ); + + p1.swap( p2 ); + CPPUNIT_ASSERT( p1 ); + CPPUNIT_ASSERT( !p2 ); + CPPUNIT_ASSERT_EQUAL( 1u , p1->getReferenceCount( ) ); + } + CPPUNIT_ASSERT_EQUAL( 1u , T_Test::cDel ); }