SGSharedPtr: add unit tests
Add unit tests for move ctor and move assignment operator, as well for a few other SGSharedPtr methods.
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
// Unit tests for reference counting and smart pointer classes
|
||||
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
#include <cstdlib> // EXIT_SUCCESS
|
||||
|
||||
#include <simgear/misc/test_macros.hxx>
|
||||
@@ -37,6 +39,7 @@ void test_SGSharedPtr()
|
||||
SG_CHECK_EQUAL( ReferenceCounted::count(ptr.get()), 1 );
|
||||
SG_CHECK_EQUAL( ptr.getNumRefs(), 1 );
|
||||
|
||||
// Test SGSharedPtr's copy assignment operator
|
||||
RefPtr ptr2 = ptr;
|
||||
SG_CHECK_EQUAL( ptr.getNumRefs(), 2 );
|
||||
SG_CHECK_EQUAL( ptr2.getNumRefs(), 2 );
|
||||
@@ -44,6 +47,7 @@ void test_SGSharedPtr()
|
||||
SG_CHECK_EQUAL( ptr, ptr2 );
|
||||
SG_CHECK_EQUAL( ptr.get(), ptr2.get() );
|
||||
|
||||
// Test SGSharedPtr::reset() with no argument
|
||||
ptr.reset();
|
||||
SG_CHECK_IS_NULL( ptr.get() );
|
||||
SG_CHECK_EQUAL( ptr.getNumRefs(), 0 );
|
||||
@@ -55,6 +59,121 @@ void test_SGSharedPtr()
|
||||
SG_CHECK_EQUAL( ptr.getNumRefs(), 0 );
|
||||
SG_CHECK_EQUAL( ptr2.getNumRefs(), 0 );
|
||||
SG_CHECK_EQUAL( instance_count, 0) ;
|
||||
|
||||
// Test operator==() and operator!=() for SGSharedPtr
|
||||
{
|
||||
RefPtr ptrA(new ReferenceCounted());
|
||||
RefPtr ptrB(ptrA);
|
||||
RefPtr ptrC(new ReferenceCounted());
|
||||
RefPtr emptyPtr{};
|
||||
SG_CHECK_EQUAL( ptrA, ptrB );
|
||||
SG_CHECK_EQUAL( ptrA.get(), ptrB.get() ); // same thing by definition
|
||||
SG_CHECK_NE( ptrA, ptrC );
|
||||
SG_CHECK_NE( ptrA.get(), ptrC.get() );
|
||||
SG_CHECK_NE( ptrB, ptrC );
|
||||
SG_CHECK_NE( ptrA, emptyPtr );
|
||||
SG_CHECK_EQUAL( emptyPtr, emptyPtr );
|
||||
}
|
||||
|
||||
// Test SGSharedPtr::reset(T* p) and SGSharedPtr::operator T*()
|
||||
{
|
||||
RefPtr ptrA(new ReferenceCounted());
|
||||
SG_CHECK_EQUAL( ptrA.getNumRefs(), 1 );
|
||||
|
||||
RefPtr ptrB(new ReferenceCounted());
|
||||
SG_CHECK_NE( ptrA, ptrB );
|
||||
ptrB.reset(ptrA);
|
||||
SG_CHECK_EQUAL( ptrA, ptrB );
|
||||
SG_CHECK_EQUAL( ptrA.getNumRefs(), 2 );
|
||||
SG_CHECK_EQUAL( ptrB.getNumRefs(), 2 );
|
||||
|
||||
RefPtr ptrC(new ReferenceCounted());
|
||||
SG_CHECK_NE( ptrA, ptrC );
|
||||
SG_CHECK_EQUAL( ptrC.getNumRefs(), 1 );
|
||||
// ptrA is implicit converted to ReferenceCounted*
|
||||
ptrC.reset(ptrA);
|
||||
SG_CHECK_EQUAL( ptrA.getNumRefs(), 3 );
|
||||
SG_CHECK_EQUAL( ptrB.getNumRefs(), 3 );
|
||||
SG_CHECK_EQUAL( ptrC.getNumRefs(), 3 );
|
||||
SG_CHECK_EQUAL( ptrA, ptrB );
|
||||
SG_CHECK_EQUAL( ptrB, ptrC );
|
||||
}
|
||||
|
||||
// Test SGSharedPtr's copy constructor
|
||||
{
|
||||
RefPtr ptrA(new ReferenceCounted());
|
||||
SG_CHECK_EQUAL( ptrA.getNumRefs(), 1 );
|
||||
|
||||
RefPtr ptrB(ptrA);
|
||||
SG_CHECK_EQUAL( ptrA.getNumRefs(), 2 );
|
||||
SG_CHECK_EQUAL( ptrB.getNumRefs(), 2 );
|
||||
SG_CHECK_EQUAL( ptrA, ptrB );
|
||||
}
|
||||
|
||||
// Test SGSharedPtr's move constructor
|
||||
{
|
||||
RefPtr ptrA(new ReferenceCounted());
|
||||
RefPtr ptrB(ptrA);
|
||||
RefPtr ptrC(std::move(ptrA));
|
||||
|
||||
SG_CHECK_EQUAL( ptrB.getNumRefs(), 2 );
|
||||
SG_CHECK_EQUAL( ptrC.getNumRefs(), 2 );
|
||||
SG_CHECK_EQUAL( ptrB, ptrC );
|
||||
// Although our implementation has these two properties, they are
|
||||
// absolutely *not* guaranteed by the C++ move semantics:
|
||||
SG_CHECK_EQUAL( ptrA.getNumRefs(), 0 );
|
||||
SG_CHECK_IS_NULL( ptrA.get() );
|
||||
}
|
||||
|
||||
// Test SGSharedPtr's move assignment operator: self-move, supposedly
|
||||
// undefined behavior but certainly safer as a no-op---which the
|
||||
// copy-and-swap idiom offers for free.
|
||||
{
|
||||
RefPtr ptrA(new ReferenceCounted());
|
||||
RefPtr ptrB(ptrA);
|
||||
|
||||
ptrA = std::move(ptrA);
|
||||
SG_CHECK_EQUAL( ptrA.getNumRefs(), 2 );
|
||||
SG_CHECK_EQUAL( ptrB.getNumRefs(), 2 );
|
||||
SG_CHECK_IS_NOT_NULL( ptrA.get() );
|
||||
SG_CHECK_EQUAL( ptrA, ptrB );
|
||||
}
|
||||
|
||||
// Test SGSharedPtr's move assignment operator: move to an empty SGSharedPtr
|
||||
{
|
||||
RefPtr ptrA;
|
||||
RefPtr ptrB(new ReferenceCounted());
|
||||
|
||||
ptrA = std::move(ptrB);
|
||||
SG_CHECK_EQUAL( ptrA.getNumRefs(), 1 );
|
||||
SG_CHECK_IS_NOT_NULL( ptrA.get() );
|
||||
// Implementation detail that is *not* guaranteed by the C++ move
|
||||
// semantics:
|
||||
SG_CHECK_EQUAL( ptrB.getNumRefs(), 0 );
|
||||
SG_CHECK_IS_NULL( ptrB.get() );
|
||||
}
|
||||
|
||||
// Test SGSharedPtr's move assignment operator: move to a non-empty
|
||||
// SGSharedPtr
|
||||
{
|
||||
RefPtr ptrA(new ReferenceCounted());
|
||||
RefPtr ptrB(ptrA);
|
||||
RefPtr ptrC(new ReferenceCounted());
|
||||
|
||||
SG_CHECK_EQUAL( ptrA.getNumRefs(), 2 );
|
||||
SG_CHECK_EQUAL( ptrB.getNumRefs(), 2 );
|
||||
SG_CHECK_EQUAL( ptrC.getNumRefs(), 1 );
|
||||
SG_CHECK_EQUAL( ptrA, ptrB );
|
||||
SG_CHECK_NE( ptrA, ptrC );
|
||||
|
||||
ptrA = std::move(ptrC);
|
||||
SG_CHECK_EQUAL( ptrA.getNumRefs(), 1 );
|
||||
SG_CHECK_EQUAL( ptrB.getNumRefs(), 1 );
|
||||
SG_CHECK_NE( ptrA, ptrB );
|
||||
// Implementation detail that is *not* guaranteed by the C++ move
|
||||
// semantics:
|
||||
SG_CHECK_IS_NULL( ptrC.get() );
|
||||
}
|
||||
}
|
||||
|
||||
class Base1:
|
||||
|
||||
Reference in New Issue
Block a user