Reference counting helpers - Progress, tests
* Assignment copy/move operators * Boolean conversion / ! operator * Content access
This commit is contained in:
parent
f0e46da2f5
commit
ddaa46867d
3 changed files with 419 additions and 12 deletions
|
@ -41,6 +41,9 @@ class T_ReferenceCountedClass
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
T_ReferenceCountedClass( ) noexcept;
|
T_ReferenceCountedClass( ) noexcept;
|
||||||
|
|
||||||
|
public:
|
||||||
|
uint32_t getReferenceCount( ) const noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Shortcuts
|
// Shortcuts
|
||||||
|
@ -72,6 +75,7 @@ class T_RcPtr
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T_Target* target_;
|
T_Target* target_;
|
||||||
|
void setTarget_( T_Target* t ) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -80,27 +84,58 @@ class T_RcPtr
|
||||||
T_RcPtr( ) noexcept;
|
T_RcPtr( ) noexcept;
|
||||||
~T_RcPtr( ) noexcept;
|
~T_RcPtr( ) noexcept;
|
||||||
|
|
||||||
|
// Constructor function
|
||||||
|
template< typename... AT >
|
||||||
|
static T_RcPtr< Type > New( AT&& ... arguments );
|
||||||
|
|
||||||
void clear( ) noexcept;
|
void clear( ) noexcept;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// Copy constructors
|
// Copy constructors and operators
|
||||||
|
|
||||||
T_RcPtr( T_Self const& other ) noexcept;
|
T_RcPtr( T_Self const& other ) noexcept;
|
||||||
|
T_Self& operator= ( T_Self const& other ) noexcept;
|
||||||
|
|
||||||
template< typename Q , T_EnableForChild< Type , Q > = true >
|
template< typename Q , T_EnableForChild< Type , Q > = true >
|
||||||
T_RcPtr( T_RcPtr< Q > const& source ) noexcept;
|
T_RcPtr( T_RcPtr< Q > const& source ) noexcept;
|
||||||
template< typename Q , T_EnableForParent< Type , Q > = false >
|
template< typename Q , T_EnableForParent< Type , Q > = false >
|
||||||
explicit T_RcPtr( T_RcPtr< Q > const& source );
|
explicit T_RcPtr( T_RcPtr< Q > const& source );
|
||||||
|
|
||||||
|
template< typename Q , T_EnableForChild< Type , Q > = true >
|
||||||
|
T_Self& operator= ( T_RcPtr< Q > const& other ) noexcept;
|
||||||
|
template< typename Q , T_EnableForParent< Type , Q > = false >
|
||||||
|
T_Self& operator= ( T_RcPtr< Q > const& other );
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// Move constructors
|
// Move constructors and operators
|
||||||
|
|
||||||
template< typename Q , T_EnableForChild< Type , Q > = true >
|
template< typename Q , T_EnableForChild< Type , Q > = true >
|
||||||
T_RcPtr( T_RcPtr< Q >&& other ) noexcept;
|
T_RcPtr( T_RcPtr< Q >&& other ) noexcept;
|
||||||
|
|
||||||
template< typename Q , T_EnableForParent< Type , Q > = false >
|
template< typename Q , T_EnableForParent< Type , Q > = false >
|
||||||
explicit T_RcPtr( T_RcPtr< Q >&& other );
|
explicit T_RcPtr( T_RcPtr< Q >&& other );
|
||||||
};
|
|
||||||
|
|
||||||
|
template< typename Q , T_EnableForChild< Type , Q > = true >
|
||||||
|
T_Self& operator= ( T_RcPtr< Q >&& other ) noexcept;
|
||||||
|
template< typename Q , T_EnableForParent< Type , Q > = false >
|
||||||
|
T_Self& operator= ( T_RcPtr< Q >&& other );
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Boolean conversion
|
||||||
|
|
||||||
|
operator bool ( ) const noexcept;
|
||||||
|
bool operator! ( ) const noexcept;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Content access
|
||||||
|
|
||||||
|
// Access the actual pointer
|
||||||
|
Type * get( ) const noexcept;
|
||||||
|
explicit operator Type* ( ) const noexcept;
|
||||||
|
|
||||||
|
// Access the object; undefined behavior if get() == nullptr.
|
||||||
|
Type* operator -> ( ) const;
|
||||||
|
Type& operator * ( ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -27,6 +27,12 @@ inline bool T_ReferenceCountedClass< B >::decreaseReferences_( ) noexcept
|
||||||
return ( -- referenceCounter_ ) == 0;
|
return ( -- referenceCounter_ ) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< bool B >
|
||||||
|
inline uint32_t T_ReferenceCountedClass< B >::getReferenceCount( ) const noexcept
|
||||||
|
{
|
||||||
|
return uint32_t{ referenceCounter_ };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*= T_RcPtr ==================================================================*/
|
/*= T_RcPtr ==================================================================*/
|
||||||
|
|
||||||
|
@ -41,6 +47,30 @@ inline T_RcPtr< T >::~T_RcPtr( ) noexcept
|
||||||
clear( );
|
clear( );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
template< typename... AT >
|
||||||
|
inline T_RcPtr< T > T_RcPtr< T >::New(
|
||||||
|
AT&& ... arguments )
|
||||||
|
{
|
||||||
|
T* const obj{ new T( std::forward< AT >( arguments ) ... ) };
|
||||||
|
T_RcPtr< T > ptr;
|
||||||
|
ptr.setTarget_( obj );
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
inline void T_RcPtr< T >::setTarget_(
|
||||||
|
T_Target* t ) noexcept
|
||||||
|
{
|
||||||
|
assert( target_ == nullptr );
|
||||||
|
if ( t ) {
|
||||||
|
t->increaseReferences_( );
|
||||||
|
}
|
||||||
|
target_ = t;
|
||||||
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
inline void T_RcPtr< T >::clear( ) noexcept
|
inline void T_RcPtr< T >::clear( ) noexcept
|
||||||
{
|
{
|
||||||
|
@ -55,11 +85,9 @@ inline void T_RcPtr< T >::clear( ) noexcept
|
||||||
template< typename T >
|
template< typename T >
|
||||||
inline T_RcPtr< T >::T_RcPtr(
|
inline T_RcPtr< T >::T_RcPtr(
|
||||||
T_RcPtr< T > const& other ) noexcept
|
T_RcPtr< T > const& other ) noexcept
|
||||||
: target_{ other.target_ }
|
: target_{ nullptr }
|
||||||
{
|
{
|
||||||
if ( target_ ) {
|
setTarget_( other.target_ );
|
||||||
target_->increaseReferences_( );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
|
@ -68,11 +96,9 @@ template<
|
||||||
T_EnableForChild< T , Q >
|
T_EnableForChild< T , Q >
|
||||||
> inline T_RcPtr< T >::T_RcPtr(
|
> inline T_RcPtr< T >::T_RcPtr(
|
||||||
T_RcPtr< Q > const& other ) noexcept
|
T_RcPtr< Q > const& other ) noexcept
|
||||||
: target_{ other.target_ }
|
: target_{ nullptr }
|
||||||
{
|
{
|
||||||
if ( target_ ) {
|
setTarget_( other.target_ );
|
||||||
target_->increaseReferences_( );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
|
@ -93,6 +119,45 @@ template<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
inline T_RcPtr< T >& T_RcPtr< T >::operator= (
|
||||||
|
T_Self const& other ) noexcept
|
||||||
|
{
|
||||||
|
clear( );
|
||||||
|
setTarget_( other.target_ );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
template<
|
||||||
|
typename Q ,
|
||||||
|
T_EnableForChild< T , Q >
|
||||||
|
> inline T_RcPtr< T >& T_RcPtr< T >::operator= (
|
||||||
|
T_RcPtr< Q > const& other ) noexcept
|
||||||
|
{
|
||||||
|
clear( );
|
||||||
|
setTarget_( other.target_ );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
template<
|
||||||
|
typename Q ,
|
||||||
|
T_EnableForParent< T , Q >
|
||||||
|
> inline T_RcPtr< T >& T_RcPtr< T >::operator= (
|
||||||
|
T_RcPtr< Q > const& other )
|
||||||
|
{
|
||||||
|
clear( );
|
||||||
|
if ( other.target_ ) {
|
||||||
|
T* const nt{ dynamic_cast< T* >( other.target_ ) };
|
||||||
|
if ( nt == nullptr ) {
|
||||||
|
throw std::bad_cast( );
|
||||||
|
}
|
||||||
|
setTarget_( nt );
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
|
@ -124,6 +189,80 @@ template<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
template<
|
||||||
|
typename Q ,
|
||||||
|
T_EnableForChild< T , Q >
|
||||||
|
> inline T_RcPtr< T >& T_RcPtr< T >::operator= (
|
||||||
|
T_RcPtr< Q >&& other ) noexcept
|
||||||
|
{
|
||||||
|
clear( );
|
||||||
|
target_ = other.target_;
|
||||||
|
other.target_ = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
template<
|
||||||
|
typename Q ,
|
||||||
|
T_EnableForParent< T , Q >
|
||||||
|
> inline T_RcPtr< T >& T_RcPtr< T >::operator= (
|
||||||
|
T_RcPtr< Q >&& other )
|
||||||
|
{
|
||||||
|
clear( );
|
||||||
|
if ( other.target_ ) {
|
||||||
|
T* const nt{ dynamic_cast< T* >( other.target_ ) };
|
||||||
|
if ( nt == nullptr ) {
|
||||||
|
throw std::bad_cast( );
|
||||||
|
}
|
||||||
|
other.target_ = nullptr;
|
||||||
|
target_ = nt;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
inline T_RcPtr< T >::operator bool ( ) const noexcept
|
||||||
|
{
|
||||||
|
return target_ != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
inline bool T_RcPtr< T >::operator! ( ) const noexcept
|
||||||
|
{
|
||||||
|
return target_ == nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
inline T_RcPtr< T >::operator T* ( ) const noexcept
|
||||||
|
{
|
||||||
|
return target_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
inline T* T_RcPtr< T >::get( ) const noexcept
|
||||||
|
{
|
||||||
|
return target_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
inline T* T_RcPtr< T >::operator -> ( ) const
|
||||||
|
{
|
||||||
|
assert( target_ != nullptr );
|
||||||
|
return target_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
inline T& T_RcPtr< T >::operator * ( ) const
|
||||||
|
{
|
||||||
|
assert( target_ != nullptr );
|
||||||
|
return *target_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace ebcl
|
} // namespace ebcl
|
||||||
#endif // _H_EBCL_INLINE_REFCOUNT
|
#endif // _H_EBCL_INLINE_REFCOUNT
|
||||||
|
|
233
tests/ref-count.cc
Normal file
233
tests/ref-count.cc
Normal file
|
@ -0,0 +1,233 @@
|
||||||
|
#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 );
|
||||||
|
}
|
Loading…
Reference in a new issue