o3tl: add another unit test to cow_wrapper
Add unit tests to cow_wrapper for the move ctor and move assignment. Change-Id: I82a5886ca7ae110985c7202125699cf95b6466d8 Reviewed-on: https://gerrit.libreoffice.org/18108 Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de> Tested-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
This commit is contained in:
committed by
Thorsten Behrens
parent
77a0897e60
commit
311e77440f
@@ -113,9 +113,11 @@ class cow_wrapper_client
|
|||||||
public:
|
public:
|
||||||
cow_wrapper_client();
|
cow_wrapper_client();
|
||||||
cow_wrapper_client( const cow_wrapper_client& );
|
cow_wrapper_client( const cow_wrapper_client& );
|
||||||
|
cow_wrapper_client( cow_wrapper_client&& );
|
||||||
~cow_wrapper_client();
|
~cow_wrapper_client();
|
||||||
|
|
||||||
cow_wrapper_client& operator=( const cow_wrapper_client& );
|
cow_wrapper_client& operator=( const cow_wrapper_client& );
|
||||||
|
cow_wrapper_client& operator=( cow_wrapper_client&& );
|
||||||
|
|
||||||
void modify( int nVal );
|
void modify( int nVal );
|
||||||
int queryUnmodified() const;
|
int queryUnmodified() const;
|
||||||
@@ -144,6 +146,10 @@ cow_wrapper_client::cow_wrapper_client( const cow_wrapper_client& rSrc ) :
|
|||||||
maImpl( rSrc.maImpl )
|
maImpl( rSrc.maImpl )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
cow_wrapper_client::cow_wrapper_client( cow_wrapper_client& rSrc ) :
|
||||||
|
maImpl( std::move( rSrc.maImpl ) )
|
||||||
|
{
|
||||||
|
}
|
||||||
cow_wrapper_client::~cow_wrapper_client()
|
cow_wrapper_client::~cow_wrapper_client()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -152,6 +158,11 @@ cow_wrapper_client& cow_wrapper_client::operator=( const cow_wrapper_client& rSr
|
|||||||
maImpl = rSrc.maImpl;
|
maImpl = rSrc.maImpl;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
cow_wrapper_client& cow_wrapper_client::operator=( cow_wrapper_client&& rSrc )
|
||||||
|
{
|
||||||
|
maImpl = std::move( rSrc.maImpl );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
void cow_wrapper_client::modify( int nVal )
|
void cow_wrapper_client::modify( int nVal )
|
||||||
{
|
{
|
||||||
maImpl->setValue( nVal );
|
maImpl->setValue( nVal );
|
||||||
@@ -272,13 +283,13 @@ int cow_wrapper_client::queryUnmodified() const
|
|||||||
/// true, if not shared with any other cow_wrapper instance
|
/// true, if not shared with any other cow_wrapper instance
|
||||||
bool is_unique() const // nothrow
|
bool is_unique() const // nothrow
|
||||||
{
|
{
|
||||||
return m_pimpl->m_ref_count == 1;
|
return m_pimpl ? m_pimpl->m_ref_count == 1 : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return number of shared instances (1 for unique object)
|
/// return number of shared instances (1 for unique object)
|
||||||
typename MTPolicy::ref_count_t use_count() const // nothrow
|
typename MTPolicy::ref_count_t use_count() const // nothrow
|
||||||
{
|
{
|
||||||
return m_pimpl->m_ref_count;
|
return m_pimpl ? m_pimpl->m_ref_count : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(cow_wrapper& r) // never throws
|
void swap(cow_wrapper& r) // never throws
|
||||||
|
@@ -219,6 +219,56 @@ bool cow_wrapper_client4::operator<( const cow_wrapper_client4& rRHS ) const
|
|||||||
return maImpl < rRHS.maImpl;
|
return maImpl < rRHS.maImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BogusRefCountPolicy::s_bShouldIncrement = 0;
|
||||||
|
bool BogusRefCountPolicy::s_bShouldDecrement = 0;
|
||||||
|
sal_uInt32 BogusRefCountPolicy::s_nEndOfScope = 0;
|
||||||
|
|
||||||
|
cow_wrapper_client5::cow_wrapper_client5() :
|
||||||
|
maImpl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
cow_wrapper_client5::cow_wrapper_client5(int nX) :
|
||||||
|
maImpl(nX)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
cow_wrapper_client5::cow_wrapper_client5( const cow_wrapper_client5& rSrc ) :
|
||||||
|
maImpl( rSrc.maImpl )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
cow_wrapper_client5::cow_wrapper_client5( cow_wrapper_client5&& rSrc ) :
|
||||||
|
maImpl( std::move( rSrc.maImpl ) )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
cow_wrapper_client5::~cow_wrapper_client5()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
cow_wrapper_client5& cow_wrapper_client5::operator=( const cow_wrapper_client5& rSrc )
|
||||||
|
{
|
||||||
|
maImpl = rSrc.maImpl;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
cow_wrapper_client5& cow_wrapper_client5::operator=( cow_wrapper_client5&& rSrc )
|
||||||
|
{
|
||||||
|
maImpl = std::move( rSrc.maImpl );
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cow_wrapper_client5::operator==( const cow_wrapper_client5& rSrc ) const {
|
||||||
|
return maImpl == rSrc.maImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cow_wrapper_client5::operator!=( const cow_wrapper_client5& rSrc ) const {
|
||||||
|
return maImpl != rSrc.maImpl;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace o3tltests
|
} // namespace o3tltests
|
||||||
|
|
||||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
#define INCLUDED_O3TL_QA_COW_WRAPPER_CLIENTS_HXX
|
#define INCLUDED_O3TL_QA_COW_WRAPPER_CLIENTS_HXX
|
||||||
|
|
||||||
#include "o3tl/cow_wrapper.hxx"
|
#include "o3tl/cow_wrapper.hxx"
|
||||||
|
#include "cppunit/extensions/HelperMacros.h"
|
||||||
|
|
||||||
/* Definition of Cow_Wrapper_Clients classes */
|
/* Definition of Cow_Wrapper_Clients classes */
|
||||||
|
|
||||||
@@ -139,6 +140,61 @@ private:
|
|||||||
o3tl::cow_wrapper< int > maImpl;
|
o3tl::cow_wrapper< int > maImpl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// singleton ref-counting policy used to keep track of when
|
||||||
|
// incrementing and decrementing occurs
|
||||||
|
struct BogusRefCountPolicy
|
||||||
|
{
|
||||||
|
static bool s_bShouldIncrement;
|
||||||
|
static bool s_bShouldDecrement;
|
||||||
|
static sal_uInt32 s_nEndOfScope;
|
||||||
|
typedef sal_uInt32 ref_count_t;
|
||||||
|
static void incrementCount( ref_count_t& rCount ) {
|
||||||
|
if(s_bShouldIncrement)
|
||||||
|
{
|
||||||
|
++rCount;
|
||||||
|
s_bShouldIncrement = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CPPUNIT_FAIL("Ref-counting policy incremented when it should not have.");
|
||||||
|
}
|
||||||
|
static bool decrementCount( ref_count_t& rCount ) {
|
||||||
|
if(s_nEndOfScope)
|
||||||
|
{
|
||||||
|
--rCount;
|
||||||
|
--s_nEndOfScope;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(s_bShouldDecrement)
|
||||||
|
{
|
||||||
|
--rCount;
|
||||||
|
s_bShouldDecrement = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CPPUNIT_FAIL("Ref-counting policy decremented when it should not have.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class cow_wrapper_client5
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cow_wrapper_client5();
|
||||||
|
explicit cow_wrapper_client5(int);
|
||||||
|
~cow_wrapper_client5();
|
||||||
|
|
||||||
|
cow_wrapper_client5( const cow_wrapper_client5& );
|
||||||
|
cow_wrapper_client5( cow_wrapper_client5&& );
|
||||||
|
cow_wrapper_client5& operator=( const cow_wrapper_client5& );
|
||||||
|
cow_wrapper_client5& operator=( cow_wrapper_client5&& );
|
||||||
|
|
||||||
|
sal_uInt32 use_count() const { return maImpl.use_count(); }
|
||||||
|
|
||||||
|
bool operator==( const cow_wrapper_client5& rRHS ) const;
|
||||||
|
bool operator!=( const cow_wrapper_client5& rRHS ) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
o3tl::cow_wrapper< int, BogusRefCountPolicy > maImpl;
|
||||||
|
};
|
||||||
} // namespace o3tltests
|
} // namespace o3tltests
|
||||||
|
|
||||||
#endif // INCLUDED_O3TL_QA_COW_WRAPPER_CLIENTS_HXX
|
#endif // INCLUDED_O3TL_QA_COW_WRAPPER_CLIENTS_HXX
|
||||||
|
@@ -161,6 +161,89 @@ public:
|
|||||||
!aTestObj1.is_default() );
|
!aTestObj1.is_default() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void testRefCounting()
|
||||||
|
{
|
||||||
|
// add scope to ensure appropriate number of calls to
|
||||||
|
// the reference counting policy have been made
|
||||||
|
{
|
||||||
|
// if any incrementing/decrementing occurs a failure
|
||||||
|
// will occur
|
||||||
|
cow_wrapper_client5 aTestObj1(1);
|
||||||
|
cow_wrapper_client5 aTestObj2( std::move( aTestObj1 ) );
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("aTestObj2.use_count() == 1",
|
||||||
|
aTestObj2.use_count() == 1 );
|
||||||
|
|
||||||
|
// the following should increment
|
||||||
|
BogusRefCountPolicy::s_bShouldIncrement = 1;
|
||||||
|
cow_wrapper_client5 aTestObj3( aTestObj2 );
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("s_bShouldIncrement == 0",
|
||||||
|
BogusRefCountPolicy::s_bShouldIncrement == 0 );
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("aTestObj3.use_count() == 2",
|
||||||
|
aTestObj3.use_count() == 2 );
|
||||||
|
{
|
||||||
|
cow_wrapper_client5 aTestObj4;
|
||||||
|
// the following should decrement the lvalue and then increment the rvalue
|
||||||
|
BogusRefCountPolicy::s_bShouldIncrement = 1;
|
||||||
|
BogusRefCountPolicy::s_bShouldDecrement = 1;
|
||||||
|
aTestObj4 = aTestObj2;
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("s_bShouldIncrement == 0",
|
||||||
|
BogusRefCountPolicy::s_bShouldIncrement == 0 );
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("s_bShouldDecrement == 0",
|
||||||
|
BogusRefCountPolicy::s_bShouldDecrement == 0 );
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("aTestObj2.use_count() == 3",
|
||||||
|
aTestObj2.use_count() == 3 );
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("aTestObj3.use_count() == 3",
|
||||||
|
aTestObj3.use_count() == 3 );
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("aTestObj4.use_count() == 3",
|
||||||
|
aTestObj4.use_count() == 3 );
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("aTestObj2 == aTestObj3",
|
||||||
|
aTestObj2 == aTestObj3 );
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("aTestObj3 == aTestObj4",
|
||||||
|
aTestObj3 == aTestObj4 );
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("aTestObj2 == aTestObj4",
|
||||||
|
aTestObj2 == aTestObj4 );
|
||||||
|
|
||||||
|
// only decrement the lvalue before assignment
|
||||||
|
BogusRefCountPolicy::s_bShouldDecrement = 1;
|
||||||
|
aTestObj4 = cow_wrapper_client5( 4 );
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("s_bShouldIncrement == 0",
|
||||||
|
BogusRefCountPolicy::s_bShouldIncrement == 0 );
|
||||||
|
|
||||||
|
// only one call should be made to the ref counting policy's
|
||||||
|
// decrementing function at the end of the scope
|
||||||
|
BogusRefCountPolicy::s_bShouldDecrement = 1;
|
||||||
|
}
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("s_bShouldDecrement == 0",
|
||||||
|
BogusRefCountPolicy::s_bShouldDecrement == 0 );
|
||||||
|
|
||||||
|
// self assignment
|
||||||
|
// aTestObj2 is defunct afterwards, one decrement happens
|
||||||
|
BogusRefCountPolicy::s_bShouldDecrement = 1;
|
||||||
|
aTestObj3 = std::move( aTestObj2 );
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("aTestObj2.use_count() == 0",
|
||||||
|
aTestObj2.use_count() == 0 );
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("aTestObj3.use_count() == 1",
|
||||||
|
aTestObj3.use_count() == 1 );
|
||||||
|
|
||||||
|
cow_wrapper_client5 aTestObj5;
|
||||||
|
|
||||||
|
// only decrement the lvalue before assignment
|
||||||
|
BogusRefCountPolicy::s_bShouldDecrement = 1;
|
||||||
|
aTestObj3 = std::move( aTestObj5 );
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("s_bShouldDecrement == 0",
|
||||||
|
BogusRefCountPolicy::s_bShouldDecrement == 0);
|
||||||
|
|
||||||
|
// one call should be made to the ref-counting policy's
|
||||||
|
// decrementing function at the end of the scope. Only
|
||||||
|
// aTestObj3 still holds a valid instance
|
||||||
|
BogusRefCountPolicy::s_nEndOfScope = 1;
|
||||||
|
}
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("s_EndOfScope == 0",
|
||||||
|
BogusRefCountPolicy::s_nEndOfScope == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
// Change the following lines only, if you add, remove or rename
|
// Change the following lines only, if you add, remove or rename
|
||||||
// member functions of the current class,
|
// member functions of the current class,
|
||||||
// because these macros are need by auto register mechanism.
|
// because these macros are need by auto register mechanism.
|
||||||
@@ -168,6 +251,7 @@ public:
|
|||||||
CPPUNIT_TEST_SUITE(cow_wrapper_test);
|
CPPUNIT_TEST_SUITE(cow_wrapper_test);
|
||||||
CPPUNIT_TEST(testCowWrapper);
|
CPPUNIT_TEST(testCowWrapper);
|
||||||
CPPUNIT_TEST(testStaticDefault);
|
CPPUNIT_TEST(testStaticDefault);
|
||||||
|
CPPUNIT_TEST(testRefCounting);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user