From b55166d266f31caf7bd85e54a59c7e8b49204b16 Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Mon, 29 Jun 2015 10:11:53 +0200 Subject: Revert "return and use std::vector from OInterfaceContainerHelper" This reverts commit e57314f61f67b093510c5a8a8f34a62126ba8734. --- cppuhelper/qa/ifcontainer/cppu_ifcontainer.cxx | 19 ++--- cppuhelper/source/gcc3.map | 6 -- cppuhelper/source/interfacecontainer.cxx | 108 ++++++++++++++----------- 3 files changed, 73 insertions(+), 60 deletions(-) (limited to 'cppuhelper') diff --git a/cppuhelper/qa/ifcontainer/cppu_ifcontainer.cxx b/cppuhelper/qa/ifcontainer/cppu_ifcontainer.cxx index e98aab205adc..ff7c7925276c 100644 --- a/cppuhelper/qa/ifcontainer/cppu_ifcontainer.cxx +++ b/cppuhelper/qa/ifcontainer/cppu_ifcontainer.cxx @@ -112,11 +112,12 @@ namespace cppu_ifcontainer pContainer->addInterface(xRef); aListeners.push_back(xRef); } - std::vector< Reference< XInterface > > aElements = pContainer->getElementsAsVector(); + Sequence< Reference< XInterface > > aElements; + aElements = pContainer->getElements(); CPPUNIT_ASSERT_MESSAGE("query contents", - (int)aElements.size() == nTests); - if ((int)aElements.size() == nTests) + (int)aElements.getLength() == nTests); + if ((int)aElements.getLength() == nTests) { for (i = 0; i < nTests; i++) { @@ -156,8 +157,8 @@ namespace cppu_ifcontainer pHelper = pContainer->getContainer(pTypes[i]); CPPUNIT_ASSERT_MESSAGE("no helper", pHelper != NULL); - std::vector > aSeq = pHelper->getElementsAsVector(); - CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq.size() == 2); + Sequence > aSeq = pHelper->getElements(); + CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq.getLength() == 2); CPPUNIT_ASSERT_MESSAGE("match", aSeq[0] == xRefs[i*2]); CPPUNIT_ASSERT_MESSAGE("match", aSeq[1] == xRefs[i*2+1]); } @@ -174,8 +175,8 @@ namespace cppu_ifcontainer pHelper = pContainer->getContainer(pTypes[i]); CPPUNIT_ASSERT_MESSAGE("no helper", pHelper != NULL); - std::vector > aSeq = pHelper->getElementsAsVector(); - CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq.size() == 1); + Sequence > aSeq = pHelper->getElements(); + CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq.getLength() == 1); CPPUNIT_ASSERT_MESSAGE("match", aSeq[0] == xRefs[i*2]); } @@ -190,8 +191,8 @@ namespace cppu_ifcontainer pHelper = pContainer->getContainer(pTypes[i]); CPPUNIT_ASSERT_MESSAGE("no helper", pHelper != NULL); - std::vector > aSeq = pHelper->getElementsAsVector(); - CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq.size() == 0); + Sequence > aSeq = pHelper->getElements(); + CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq.getLength() == 0); } delete pContainer; diff --git a/cppuhelper/source/gcc3.map b/cppuhelper/source/gcc3.map index 1a15f35be3ff..12c29834ab16 100644 --- a/cppuhelper/source/gcc3.map +++ b/cppuhelper/source/gcc3.map @@ -430,12 +430,6 @@ global: _ZN4cppu15supportsServiceEPN3com3sun4star4lang12XServiceInfoERKN3rtl8OUStringE; # cppu::supportsService(com::sun::star::lang::XServiceInfo*, rtl::OUString const&) } UDK_3.8; - -PRIVATE_cppuhelper.1 { # LibreOffice 5.1 - global: - _ZNK4cppu25OInterfaceContainerHelper19getElementsAsVectorEv; # std::vector< Reference > OInterfaceContainerHelper::getElementsAsVector() const -}; - # Unique libstdc++ symbols: GLIBCXX_3.4 { global: diff --git a/cppuhelper/source/interfacecontainer.cxx b/cppuhelper/source/interfacecontainer.cxx index 93a38363f8a6..5bd20a442128 100644 --- a/cppuhelper/source/interfacecontainer.cxx +++ b/cppuhelper/source/interfacecontainer.cxx @@ -28,7 +28,6 @@ #include #include -#include using namespace osl; @@ -37,6 +36,32 @@ using namespace com::sun::star::lang; namespace cppu { +/** + * Reallocate the sequence. + */ +static void realloc( Sequence< Reference< XInterface > > & rSeq, sal_Int32 nNewLen ) +{ + rSeq.realloc( nNewLen ); +} + +/** + * Remove an element from an interface sequence. + */ +static void sequenceRemoveElementAt( Sequence< Reference< XInterface > > & rSeq, sal_Int32 index ) +{ + sal_Int32 nNewLen = rSeq.getLength() - 1; + + Sequence< Reference< XInterface > > aDestSeq( rSeq.getLength() - 1 ); + // getArray on a const sequence is faster + const Reference< XInterface > * pSource = ((const Sequence< Reference< XInterface > > &)rSeq).getConstArray(); + Reference< XInterface > * pDest = aDestSeq.getArray(); + sal_Int32 i = 0; + for( ; i < index; i++ ) + pDest[i] = pSource[i]; + for( sal_Int32 j = i ; j < nNewLen; j++ ) + pDest[j] = pSource[j+1]; + rSeq = aDestSeq; +} #ifdef _MSC_VER #pragma warning( disable: 4786 ) @@ -54,7 +79,7 @@ OInterfaceIteratorHelper::OInterfaceIteratorHelper( OInterfaceContainerHelper & if( bIsList ) { rCont.bInUse = sal_True; - nRemain = aData.pAsVector->size(); + nRemain = aData.pAsSequence->getLength(); } else if( aData.pAsInterface ) { @@ -71,7 +96,7 @@ OInterfaceIteratorHelper::~OInterfaceIteratorHelper() { MutexGuard aGuard( rCont.rMutex ); // bResetInUse protect the iterator against recursion - bShared = aData.pAsVector == rCont.aData.pAsVector && rCont.bIsList; + bShared = aData.pAsSequence == rCont.aData.pAsSequence && rCont.bIsList; if( bShared ) { OSL_ENSURE( rCont.bInUse, "OInterfaceContainerHelper must be in use" ); @@ -83,7 +108,7 @@ OInterfaceIteratorHelper::~OInterfaceIteratorHelper() { if( bIsList ) // Sequence owned by the iterator - delete aData.pAsVector; + delete aData.pAsSequence; else if( aData.pAsInterface ) // Interface is acquired by the iterator aData.pAsInterface->release(); @@ -96,7 +121,8 @@ XInterface * OInterfaceIteratorHelper::next() { nRemain--; if( bIsList ) - return (*aData.pAsVector)[nRemain].get(); + // typecase to const,so the getArray method is faster + return aData.pAsSequence->getConstArray()[nRemain].get(); else if( aData.pAsInterface ) return aData.pAsInterface; } @@ -109,8 +135,8 @@ void OInterfaceIteratorHelper::remove() if( bIsList ) { OSL_ASSERT( nRemain >= 0 && - nRemain < static_cast(aData.pAsVector->size()) ); - XInterface * p = (*aData.pAsVector)[nRemain].get(); + nRemain < aData.pAsSequence->getLength() ); + XInterface * p = aData.pAsSequence->getConstArray()[nRemain].get(); rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >( &p ) ); } else @@ -131,7 +157,7 @@ OInterfaceContainerHelper::~OInterfaceContainerHelper() { OSL_ENSURE( !bInUse, "~OInterfaceContainerHelper but is in use" ); if( bIsList ) - delete aData.pAsVector; + delete aData.pAsSequence; else if( aData.pAsInterface ) aData.pAsInterface->release(); } @@ -140,30 +166,17 @@ sal_Int32 OInterfaceContainerHelper::getLength() const { MutexGuard aGuard( rMutex ); if( bIsList ) - return aData.pAsVector->size(); + return aData.pAsSequence->getLength(); else if( aData.pAsInterface ) return 1; return 0; } -std::vector< Reference > OInterfaceContainerHelper::getElementsAsVector() const -{ - MutexGuard aGuard( rMutex ); - if( bIsList ) - return *aData.pAsVector; - else if( aData.pAsInterface ) - { - Reference x( aData.pAsInterface ); - return { x }; - } - return std::vector< Reference< XInterface > >(); -} - -css::uno::Sequence< Reference > OInterfaceContainerHelper::getElements() const +Sequence< Reference > OInterfaceContainerHelper::getElements() const { MutexGuard aGuard( rMutex ); if( bIsList ) - return css::uno::Sequence< Reference >( aData.pAsVector->data(), static_cast(aData.pAsVector->size()) ); + return *aData.pAsSequence; else if( aData.pAsInterface ) { Reference x( aData.pAsInterface ); @@ -180,7 +193,7 @@ void OInterfaceContainerHelper::copyAndResetInUse() // this should be the worst case. If a iterator is active // and a new Listener is added. if( bIsList ) - aData.pAsVector = new std::vector< Reference< XInterface > >( *aData.pAsVector ); + aData.pAsSequence = new Sequence< Reference< XInterface > >( *aData.pAsSequence ); else if( aData.pAsInterface ) aData.pAsInterface->acquire(); @@ -197,16 +210,19 @@ sal_Int32 OInterfaceContainerHelper::addInterface( const Reference & if( bIsList ) { - aData.pAsVector->push_back( rListener ); - return aData.pAsVector->size(); + sal_Int32 nLen = aData.pAsSequence->getLength(); + realloc( *aData.pAsSequence, nLen +1 ); + aData.pAsSequence->getArray()[ nLen ] = rListener; + return nLen +1; } else if( aData.pAsInterface ) { - std::vector< Reference< XInterface > > * pSeq = new std::vector< Reference< XInterface > >( 2 ); - (*pSeq)[0] = aData.pAsInterface; - (*pSeq)[1] = rListener; + Sequence< Reference< XInterface > > * pSeq = new Sequence< Reference< XInterface > >( 2 ); + Reference * pArray = pSeq->getArray(); + pArray[0] = aData.pAsInterface; + pArray[1] = rListener; aData.pAsInterface->release(); - aData.pAsVector = pSeq; + aData.pAsSequence = pSeq; bIsList = sal_True; return 2; } @@ -228,41 +244,43 @@ sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference * pL = aData.pAsSequence->getConstArray(); + sal_Int32 nLen = aData.pAsSequence->getLength(); + sal_Int32 i; + for( i = 0; i < nLen; i++ ) { - if( (*it).get() == rListener.get() ) + // It is not valid to compare the pointer directly, but it's faster. + if( pL[i].get() == rListener.get() ) { - aData.pAsVector->erase(it); - bFound = true; + sequenceRemoveElementAt( *aData.pAsSequence, i ); break; } } - if (!bFound) + + if( i == nLen ) { // interface not found, use the correct compare method - for( auto it = std::begin(*aData.pAsVector); it != std::end(*aData.pAsVector); ++it ) + for( i = 0; i < nLen; i++ ) { - if( *it == rListener ) + if( pL[i] == rListener ) { - aData.pAsVector->erase(it); + sequenceRemoveElementAt(*aData.pAsSequence, i ); break; } } } - if( aData.pAsVector->size() == 1 ) + if( aData.pAsSequence->getLength() == 1 ) { - XInterface * p = (*aData.pAsVector)[0].get(); + XInterface * p = aData.pAsSequence->getConstArray()[0].get(); p->acquire(); - delete aData.pAsVector; + delete aData.pAsSequence; aData.pAsInterface = p; bIsList = sal_False; return 1; } else - return aData.pAsVector->size(); + return aData.pAsSequence->getLength(); } else if( aData.pAsInterface && Reference( aData.pAsInterface ) == rListener ) { -- cgit