Improved reference-counted pointer

This commit is contained in:
Tsuda Kageyu
2013-04-29 20:15:05 +09:00
parent 82e616101a
commit 36ceaadfaa
17 changed files with 409 additions and 156 deletions

View File

@ -30,6 +30,7 @@ SET(test_runner_SRCS
main.cpp
test_list.cpp
test_map.cpp
test_smartptr.cpp
test_mpeg.cpp
test_synchdata.cpp
test_trueaudio.cpp

200
tests/test_smartptr.cpp Normal file
View File

@ -0,0 +1,200 @@
#include <trefcountptr.h>
#include <cppunit/extensions/HelperMacros.h>
#include "utils.h"
using namespace std;
using namespace TagLib;
bool baseDestructorCalled;
bool derivedDestructorCalled;
bool incompleteDestructorCalled;
class TestSmartptr : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestSmartptr);
CPPUNIT_TEST(testSharedptrBasic);
CPPUNIT_TEST(testDerivedClass);
CPPUNIT_TEST(testIncompleteClass);
CPPUNIT_TEST_SUITE_END();
private:
template<class T>
void ck( const T* v1, T v2 ) { CPPUNIT_ASSERT( *v1 == v2 ); }
public:
void testSharedptrBasic()
{
int * ip = new int;
TAGLIB_SHARED_PTR<int> cp ( ip );
CPPUNIT_ASSERT( ip == cp.get() );
CPPUNIT_ASSERT( cp.use_count() == 1 );
*cp = 54321;
CPPUNIT_ASSERT( *cp == 54321 );
CPPUNIT_ASSERT( *ip == 54321 );
ck( static_cast<int*>(cp.get()), 54321 );
ck( static_cast<int*>(ip), *cp );
TAGLIB_SHARED_PTR<int> cp2 ( cp );
CPPUNIT_ASSERT( ip == cp2.get() );
CPPUNIT_ASSERT( cp.use_count() == 2 );
CPPUNIT_ASSERT( cp2.use_count() == 2 );
CPPUNIT_ASSERT( *cp == 54321 );
CPPUNIT_ASSERT( *cp2 == 54321 );
ck( static_cast<int*>(cp2.get()), 54321 );
ck( static_cast<int*>(ip), *cp2 );
TAGLIB_SHARED_PTR<int> cp3 ( cp );
CPPUNIT_ASSERT( cp.use_count() == 3 );
CPPUNIT_ASSERT( cp2.use_count() == 3 );
CPPUNIT_ASSERT( cp3.use_count() == 3 );
cp.reset();
CPPUNIT_ASSERT( cp2.use_count() == 2 );
CPPUNIT_ASSERT( cp3.use_count() == 2 );
cp.reset( new int );
*cp = 98765;
CPPUNIT_ASSERT( *cp == 98765 );
*cp3 = 87654;
CPPUNIT_ASSERT( *cp3 == 87654 );
CPPUNIT_ASSERT( *cp2 == 87654 );
cp.swap( cp3 );
CPPUNIT_ASSERT( *cp == 87654 );
CPPUNIT_ASSERT( *cp2 == 87654 );
CPPUNIT_ASSERT( *cp3 == 98765 );
cp.swap( cp3 );
CPPUNIT_ASSERT( *cp == 98765 );
CPPUNIT_ASSERT( *cp2 == 87654 );
CPPUNIT_ASSERT( *cp3 == 87654 );
cp2 = cp2;
CPPUNIT_ASSERT( cp2.use_count() == 2 );
CPPUNIT_ASSERT( *cp2 == 87654 );
cp = cp2;
CPPUNIT_ASSERT( cp2.use_count() == 3 );
CPPUNIT_ASSERT( *cp2 == 87654 );
CPPUNIT_ASSERT( cp.use_count() == 3 );
CPPUNIT_ASSERT( *cp == 87654 );
TAGLIB_SHARED_PTR<int> cp4;
swap( cp2, cp4 );
CPPUNIT_ASSERT( cp4.use_count() == 3 );
CPPUNIT_ASSERT( *cp4 == 87654 );
CPPUNIT_ASSERT( cp2.get() == 0 );
std::set< TAGLIB_SHARED_PTR<int> > scp;
scp.insert(cp4);
CPPUNIT_ASSERT( scp.find(cp4) != scp.end() );
CPPUNIT_ASSERT( scp.find(cp4) == scp.find( TAGLIB_SHARED_PTR<int>(cp4) ) );
}
private:
class DummyBase
{
public:
DummyBase(int x) : value(x)
{
}
virtual ~DummyBase()
{
baseDestructorCalled = true;
}
int getValue() const
{
return value;
}
private:
int value;
};
class DummyDerived : public DummyBase
{
public:
DummyDerived(int x) : DummyBase(x)
{
}
virtual ~DummyDerived()
{
derivedDestructorCalled = true;
}
};
public:
void testDerivedClass()
{
baseDestructorCalled = false;
derivedDestructorCalled = false;
{
TAGLIB_SHARED_PTR<DummyBase> p1(new DummyDerived(100));
CPPUNIT_ASSERT(p1->getValue() == 100);
}
CPPUNIT_ASSERT(baseDestructorCalled);
CPPUNIT_ASSERT(derivedDestructorCalled);
baseDestructorCalled = false;
derivedDestructorCalled = false;
{
TAGLIB_SHARED_PTR<DummyDerived> p1(new DummyDerived(100));
TAGLIB_SHARED_PTR<DummyBase> p2 = p1;
CPPUNIT_ASSERT(p1->getValue() == 100);
CPPUNIT_ASSERT(p2->getValue() == 100);
}
CPPUNIT_ASSERT(baseDestructorCalled);
CPPUNIT_ASSERT(derivedDestructorCalled);
baseDestructorCalled = false;
derivedDestructorCalled = false;
{
TAGLIB_SHARED_PTR<DummyDerived> p1;
TAGLIB_SHARED_PTR<DummyBase> p2;
p1.reset(new DummyDerived(100));
p2 = p1;
CPPUNIT_ASSERT(p1->getValue() == 100);
CPPUNIT_ASSERT(p2->getValue() == 100);
}
CPPUNIT_ASSERT(baseDestructorCalled);
CPPUNIT_ASSERT(derivedDestructorCalled);
}
private:
class DummyIncomplete;
TAGLIB_SHARED_PTR<DummyIncomplete> pincomplete;
class DummyIncomplete
{
public:
~DummyIncomplete()
{
incompleteDestructorCalled = true;
}
int getValue() const { return 100; }
};
public:
void testIncompleteClass()
{
incompleteDestructorCalled = false;
pincomplete.reset(new DummyIncomplete());
CPPUNIT_ASSERT(pincomplete->getValue() == 100);
pincomplete.reset();
CPPUNIT_ASSERT(incompleteDestructorCalled);
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestSmartptr);