Kaydet (Commit) f15d11a9 authored tarafından Daniel Robertson's avatar Daniel Robertson Kaydeden (comit) Stephan Bergmann

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/19762Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarStephan Bergmann <sbergman@redhat.com>
üst c460ddb9
...@@ -72,6 +72,15 @@ public: ...@@ -72,6 +72,15 @@ public:
m_pBody->acquire(); m_pBody->acquire();
} }
#ifdef LIBO_INTERNAL_ONLY
/** Move constructor...
*/
inline Reference (Reference<reference_type> && handle)
: m_pBody (handle.m_pBody)
{
handle.m_pBody = nullptr;
}
#endif
/** Destructor... /** Destructor...
*/ */
...@@ -106,6 +115,24 @@ public: ...@@ -106,6 +115,24 @@ public:
return set( handle.m_pBody ); return set( handle.m_pBody );
} }
#ifdef LIBO_INTERNAL_ONLY
/** Assignment.
* Unbinds this instance from its body (if bound),
* bind it to the body represented by the handle, and
* set the body represented by the handle to nullptr.
*/
inline Reference<reference_type> &
SAL_CALL operator= (Reference<reference_type> && handle)
{
// self-movement guts ourself
if (m_pBody)
m_pBody->release();
m_pBody = handle.m_pBody;
handle.m_pBody = nullptr;
return *this;
}
#endif
/** Assignment... /** Assignment...
*/ */
inline Reference<reference_type> & inline Reference<reference_type> &
......
# -*- 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:
...@@ -54,6 +54,7 @@ $(eval $(call gb_Module_add_check_targets,sal,\ ...@@ -54,6 +54,7 @@ $(eval $(call gb_Module_add_check_targets,sal,\
CppunitTest_sal_rtl_oustring \ CppunitTest_sal_rtl_oustring \
CppunitTest_sal_rtl_oustringbuffer \ CppunitTest_sal_rtl_oustringbuffer \
CppunitTest_sal_rtl_process \ CppunitTest_sal_rtl_process \
CppunitTest_sal_rtl_ref \
CppunitTest_sal_rtl_strings \ CppunitTest_sal_rtl_strings \
CppunitTest_sal_rtl_textenc \ CppunitTest_sal_rtl_textenc \
CppunitTest_sal_rtl_uri \ CppunitTest_sal_rtl_uri \
......
/* -*- 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: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment