diff options
author | Daniel Robertson <danlrobertson89@gmail.com> | 2015-11-03 09:47:36 -0500 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2015-11-06 15:19:29 +0000 |
commit | f15d11a9f8d6c783fd8c937256fa3372f8e4fe01 (patch) | |
tree | ae3cd96514c43899b17b32f1f7ba62bc254ef665 /sal | |
parent | c460ddb98317f1be0368eb197e338a4f8b44322d (diff) |
rtl::Reference Add move construction/assignment
Add move constructor and appropriately overloaded assignment operator to
rtl::Reference, and add basic unit tests for the reference counting of
rtl::Reference.
Change-Id: Ia7ff5d786bdf3b17709cec06608c91e22379746c
Reviewed-on: https://gerrit.libreoffice.org/19762
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'sal')
-rw-r--r-- | sal/CppunitTest_sal_rtl_ref.mk | 22 | ||||
-rw-r--r-- | sal/Module_sal.mk | 1 | ||||
-rw-r--r-- | sal/qa/rtl/ref/rtl_ref.cxx | 112 |
3 files changed, 135 insertions, 0 deletions
diff --git a/sal/CppunitTest_sal_rtl_ref.mk b/sal/CppunitTest_sal_rtl_ref.mk new file mode 100644 index 000000000000..f42bf92e95a7 --- /dev/null +++ b/sal/CppunitTest_sal_rtl_ref.mk @@ -0,0 +1,22 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_CppunitTest_CppunitTest,sal_rtl_ref)) + +$(eval $(call gb_CppunitTest_add_exception_objects,sal_rtl_ref,\ + sal/qa/rtl/ref/rtl_ref \ +)) + +$(eval $(call gb_CppunitTest_use_libraries,sal_rtl_ref,\ + sal \ + $(gb_UWINAPI) \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/sal/Module_sal.mk b/sal/Module_sal.mk index 192da9319d84..0b021034be17 100644 --- a/sal/Module_sal.mk +++ b/sal/Module_sal.mk @@ -54,6 +54,7 @@ $(eval $(call gb_Module_add_check_targets,sal,\ CppunitTest_sal_rtl_oustring \ CppunitTest_sal_rtl_oustringbuffer \ CppunitTest_sal_rtl_process \ + CppunitTest_sal_rtl_ref \ CppunitTest_sal_rtl_strings \ CppunitTest_sal_rtl_textenc \ CppunitTest_sal_rtl_uri \ diff --git a/sal/qa/rtl/ref/rtl_ref.cxx b/sal/qa/rtl/ref/rtl_ref.cxx new file mode 100644 index 000000000000..66d54e654dd6 --- /dev/null +++ b/sal/qa/rtl/ref/rtl_ref.cxx @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <rtl/ref.hxx> +#include <sal/types.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/plugin/TestPlugIn.h> + +namespace rtl_ref +{ + +class MoveTestClass +{ +private: + bool m_bIncFlag; + long m_nRef; +public: + MoveTestClass(): m_bIncFlag(false), m_nRef(0) { } + + // There should never be more than two references to this class as it + // is used as a test class for move functions. One reference being the + // original reference and the second being the test reference + void acquire() + { + if(m_bIncFlag) + { + ++m_nRef; + m_bIncFlag = false; + } + else + CPPUNIT_FAIL("RC was incremented when in should not have been"); + } + + void release() { --m_nRef; } + + long use_count() { return m_nRef; } + + void set_inc_flag() { m_bIncFlag = true; } +}; + +rtl::Reference< MoveTestClass > get_reference( MoveTestClass* pcTestClass ) +{ + // constructor will increment the reference count + pcTestClass->set_inc_flag(); + rtl::Reference< MoveTestClass > tmp(pcTestClass); + return tmp; +} + +class TestReferenceRefCounting : public CppUnit::TestFixture +{ + void testMove() + { + MoveTestClass cTestClass; + + // constructor will increment the reference count + cTestClass.set_inc_flag(); + rtl::Reference< MoveTestClass > test1( &cTestClass ); + + // move should not increment the reference count + rtl::Reference< MoveTestClass > test2( std::move(test1) ); + CPPUNIT_ASSERT_MESSAGE("test2.use_count() == 1", + test2->use_count() == 1); + + // test1 now contains a null pointer + CPPUNIT_ASSERT_MESSAGE("!test1.is()", + !test1.is()); + + // function return should move the reference + test2 = get_reference( &cTestClass ); + CPPUNIT_ASSERT_MESSAGE("test2.use_count() == 1", + test2->use_count() == 1); + + // normal copy + test2->set_inc_flag(); + test1 = test2; + CPPUNIT_ASSERT_MESSAGE("test2.use_count() == 2", + test2->use_count() == 2); + + // use count should decrement + test2 = rtl::Reference< MoveTestClass >(nullptr); + CPPUNIT_ASSERT_MESSAGE("test1.use_count() == 1", + test1->use_count() == 1); + + // move of a null pointer should not cause an error + test1 = std::move(test2); + + CPPUNIT_ASSERT_MESSAGE("!test1.is()", + !test1.is()); + CPPUNIT_ASSERT_MESSAGE("!test2.is()", + !test2.is()); + + CPPUNIT_ASSERT_MESSAGE("cTestClass.use_count() == 0", + cTestClass.use_count() == 0); + } + + CPPUNIT_TEST_SUITE(TestReferenceRefCounting); + CPPUNIT_TEST(testMove); + CPPUNIT_TEST_SUITE_END(); +}; + +} // namespace rtl_ref +CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ref::TestReferenceRefCounting); +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |