234 lines
6.7 KiB
C++
234 lines
6.7 KiB
C++
|
#include <ebcl/RefCount.hh>
|
||
|
#include <cppunit/extensions/HelperMacros.h>
|
||
|
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 );
|
||
|
}
|