summaryrefslogtreecommitdiff
path: root/o3tl
diff options
context:
space:
mode:
authorDaniel Robertson <danlrobertson89@gmail.com>2015-08-27 17:55:55 -0400
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2015-08-29 22:47:38 +0000
commit311e77440f11dbe8e49d75b09a4ae0f850ce00c5 (patch)
treef93c323d2e102f6258eadbdd9b71b310970331f4 /o3tl
parent77a0897e6000990666d6f4dad54d549b0b7fda27 (diff)
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>
Diffstat (limited to 'o3tl')
-rw-r--r--o3tl/qa/cow_wrapper_clients.cxx50
-rw-r--r--o3tl/qa/cow_wrapper_clients.hxx56
-rw-r--r--o3tl/qa/test-cow_wrapper.cxx84
3 files changed, 190 insertions, 0 deletions
diff --git a/o3tl/qa/cow_wrapper_clients.cxx b/o3tl/qa/cow_wrapper_clients.cxx
index d49dd092865b..3cea25766c84 100644
--- a/o3tl/qa/cow_wrapper_clients.cxx
+++ b/o3tl/qa/cow_wrapper_clients.cxx
@@ -219,6 +219,56 @@ bool cow_wrapper_client4::operator<( const cow_wrapper_client4& rRHS ) const
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
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/o3tl/qa/cow_wrapper_clients.hxx b/o3tl/qa/cow_wrapper_clients.hxx
index 30dd5e043732..f438c06a20ab 100644
--- a/o3tl/qa/cow_wrapper_clients.hxx
+++ b/o3tl/qa/cow_wrapper_clients.hxx
@@ -21,6 +21,7 @@
#define INCLUDED_O3TL_QA_COW_WRAPPER_CLIENTS_HXX
#include "o3tl/cow_wrapper.hxx"
+#include "cppunit/extensions/HelperMacros.h"
/* Definition of Cow_Wrapper_Clients classes */
@@ -139,6 +140,61 @@ private:
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
#endif // INCLUDED_O3TL_QA_COW_WRAPPER_CLIENTS_HXX
diff --git a/o3tl/qa/test-cow_wrapper.cxx b/o3tl/qa/test-cow_wrapper.cxx
index 82bc2be8d91b..71003551907e 100644
--- a/o3tl/qa/test-cow_wrapper.cxx
+++ b/o3tl/qa/test-cow_wrapper.cxx
@@ -161,6 +161,89 @@ public:
!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
// member functions of the current class,
// because these macros are need by auto register mechanism.
@@ -168,6 +251,7 @@ public:
CPPUNIT_TEST_SUITE(cow_wrapper_test);
CPPUNIT_TEST(testCowWrapper);
CPPUNIT_TEST(testStaticDefault);
+ CPPUNIT_TEST(testRefCounting);
CPPUNIT_TEST_SUITE_END();
};