Skip to content

Commit

Permalink
return and use std::vector from OInterfaceContainerHelper
Browse files Browse the repository at this point in the history
since most of the time we don’t need a heavyweight uno::Sequence.
Adds a new method getElementsAsVector().

Change-Id: I9e72bef0c0c723ffd0dd7d4152db5baec6784a7a
Reviewed-on: https://gerrit.libreoffice.org/15747
Reviewed-by: Noel Grandin <[email protected]>
Tested-by: Noel Grandin <[email protected]>
  • Loading branch information
grandinj committed Jun 29, 2015
1 parent 3712006 commit e57314f
Show file tree
Hide file tree
Showing 18 changed files with 148 additions and 202 deletions.
5 changes: 2 additions & 3 deletions chart2/source/model/main/ChartModel.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,9 @@ bool ChartModel::impl_isControllerConnected( const uno::Reference< frame::XContr
{
try
{
uno::Sequence< uno::Reference<uno::XInterface> > aSeq = m_aControllers.getElements();
for( sal_Int32 nN = aSeq.getLength(); nN--; )
for( uno::Reference<uno::XInterface> & rInterface : m_aControllers.getElements() )
{
if( aSeq[nN] == xController )
if( rInterface == xController )
return true;
}
}
Expand Down
13 changes: 5 additions & 8 deletions comphelper/source/misc/accessibleeventnotifier.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ namespace comphelper

void AccessibleEventNotifier::addEvent( const TClientId _nClient, const AccessibleEventObject& _rEvent )
{
Sequence< Reference< XInterface > > aListeners;
std::vector< Reference< XInterface > > aListeners;

// --- <mutex lock> -------------------------------
{
Expand All @@ -267,25 +267,22 @@ namespace comphelper
return;

// since we're synchronous, again, we want to notify immediately
aListeners = aClientPos->second->getElements();
aListeners = aClientPos->second->getElementsAsVector();
}
// --- </mutex lock> ------------------------------

// default handling: loop through all listeners, and notify them
const Reference< XInterface >* pListeners = aListeners.getConstArray();
const Reference< XInterface >* pListenersEnd = pListeners + aListeners.getLength();
while ( pListeners != pListenersEnd )
// default handling: loop through all listeners, and notify them
for ( const Reference< XInterface > & rL : aListeners )
{
try
{
static_cast< XAccessibleEventListener* >( pListeners->get() )->notifyEvent( _rEvent );
static_cast< XAccessibleEventListener* >( rL.get() )->notifyEvent( _rEvent );
}
catch( const Exception& )
{
// no assertion, because a broken access remote bridge or something like this
// can cause this exception
}
++pListeners;
}
}

Expand Down
19 changes: 9 additions & 10 deletions cppuhelper/qa/ifcontainer/cppu_ifcontainer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,11 @@ namespace cppu_ifcontainer
pContainer->addInterface(xRef);
aListeners.push_back(xRef);
}
Sequence< Reference< XInterface > > aElements;
aElements = pContainer->getElements();
std::vector< Reference< XInterface > > aElements = pContainer->getElementsAsVector();

CPPUNIT_ASSERT_MESSAGE("query contents",
(int)aElements.getLength() == nTests);
if ((int)aElements.getLength() == nTests)
(int)aElements.size() == nTests);
if ((int)aElements.size() == nTests)
{
for (i = 0; i < nTests; i++)
{
Expand Down Expand Up @@ -157,8 +156,8 @@ namespace cppu_ifcontainer
pHelper = pContainer->getContainer(pTypes[i]);

CPPUNIT_ASSERT_MESSAGE("no helper", pHelper != NULL);
Sequence<Reference< XInterface > > aSeq = pHelper->getElements();
CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq.getLength() == 2);
std::vector<Reference< XInterface > > aSeq = pHelper->getElementsAsVector();
CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq.size() == 2);
CPPUNIT_ASSERT_MESSAGE("match", aSeq[0] == xRefs[i*2]);
CPPUNIT_ASSERT_MESSAGE("match", aSeq[1] == xRefs[i*2+1]);
}
Expand All @@ -175,8 +174,8 @@ namespace cppu_ifcontainer
pHelper = pContainer->getContainer(pTypes[i]);

CPPUNIT_ASSERT_MESSAGE("no helper", pHelper != NULL);
Sequence<Reference< XInterface > > aSeq = pHelper->getElements();
CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq.getLength() == 1);
std::vector<Reference< XInterface > > aSeq = pHelper->getElementsAsVector();
CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq.size() == 1);
CPPUNIT_ASSERT_MESSAGE("match", aSeq[0] == xRefs[i*2]);
}

Expand All @@ -191,8 +190,8 @@ namespace cppu_ifcontainer

pHelper = pContainer->getContainer(pTypes[i]);
CPPUNIT_ASSERT_MESSAGE("no helper", pHelper != NULL);
Sequence<Reference< XInterface > > aSeq = pHelper->getElements();
CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq.getLength() == 0);
std::vector<Reference< XInterface > > aSeq = pHelper->getElementsAsVector();
CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq.size() == 0);
}

delete pContainer;
Expand Down
6 changes: 6 additions & 0 deletions cppuhelper/source/gcc3.map
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,12 @@ 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<XInterface> > OInterfaceContainerHelper::getElementsAsVector() const
};

# Unique libstdc++ symbols:
GLIBCXX_3.4 {
global:
Expand Down
108 changes: 45 additions & 63 deletions cppuhelper/source/interfacecontainer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <memory>

#include <com/sun/star/lang/XEventListener.hpp>
#include <iterator>


using namespace osl;
Expand All @@ -36,32 +37,6 @@ 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 )
Expand All @@ -79,7 +54,7 @@ OInterfaceIteratorHelper::OInterfaceIteratorHelper( OInterfaceContainerHelper &
if( bIsList )
{
rCont.bInUse = sal_True;
nRemain = aData.pAsSequence->getLength();
nRemain = aData.pAsVector->size();
}
else if( aData.pAsInterface )
{
Expand All @@ -96,7 +71,7 @@ OInterfaceIteratorHelper::~OInterfaceIteratorHelper()
{
MutexGuard aGuard( rCont.rMutex );
// bResetInUse protect the iterator against recursion
bShared = aData.pAsSequence == rCont.aData.pAsSequence && rCont.bIsList;
bShared = aData.pAsVector == rCont.aData.pAsVector && rCont.bIsList;
if( bShared )
{
OSL_ENSURE( rCont.bInUse, "OInterfaceContainerHelper must be in use" );
Expand All @@ -108,7 +83,7 @@ OInterfaceIteratorHelper::~OInterfaceIteratorHelper()
{
if( bIsList )
// Sequence owned by the iterator
delete aData.pAsSequence;
delete aData.pAsVector;
else if( aData.pAsInterface )
// Interface is acquired by the iterator
aData.pAsInterface->release();
Expand All @@ -121,8 +96,7 @@ XInterface * OInterfaceIteratorHelper::next()
{
nRemain--;
if( bIsList )
// typecase to const,so the getArray method is faster
return aData.pAsSequence->getConstArray()[nRemain].get();
return (*aData.pAsVector)[nRemain].get();
else if( aData.pAsInterface )
return aData.pAsInterface;
}
Expand All @@ -135,8 +109,8 @@ void OInterfaceIteratorHelper::remove()
if( bIsList )
{
OSL_ASSERT( nRemain >= 0 &&
nRemain < aData.pAsSequence->getLength() );
XInterface * p = aData.pAsSequence->getConstArray()[nRemain].get();
nRemain < static_cast<sal_Int32>(aData.pAsVector->size()) );
XInterface * p = (*aData.pAsVector)[nRemain].get();
rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >( &p ) );
}
else
Expand All @@ -157,7 +131,7 @@ OInterfaceContainerHelper::~OInterfaceContainerHelper()
{
OSL_ENSURE( !bInUse, "~OInterfaceContainerHelper but is in use" );
if( bIsList )
delete aData.pAsSequence;
delete aData.pAsVector;
else if( aData.pAsInterface )
aData.pAsInterface->release();
}
Expand All @@ -166,17 +140,30 @@ sal_Int32 OInterfaceContainerHelper::getLength() const
{
MutexGuard aGuard( rMutex );
if( bIsList )
return aData.pAsSequence->getLength();
return aData.pAsVector->size();
else if( aData.pAsInterface )
return 1;
return 0;
}

Sequence< Reference<XInterface> > OInterfaceContainerHelper::getElements() const
std::vector< Reference<XInterface> > OInterfaceContainerHelper::getElementsAsVector() const
{
MutexGuard aGuard( rMutex );
if( bIsList )
return *aData.pAsVector;
else if( aData.pAsInterface )
{
Reference<XInterface> x( aData.pAsInterface );
return { x };
}
return std::vector< Reference< XInterface > >();
}

css::uno::Sequence< Reference<XInterface> > OInterfaceContainerHelper::getElements() const
{
MutexGuard aGuard( rMutex );
if( bIsList )
return *aData.pAsSequence;
return css::uno::Sequence< Reference<XInterface> >( aData.pAsVector->data(), static_cast<sal_Int32>(aData.pAsVector->size()) );
else if( aData.pAsInterface )
{
Reference<XInterface> x( aData.pAsInterface );
Expand All @@ -193,7 +180,7 @@ void OInterfaceContainerHelper::copyAndResetInUse()
// this should be the worst case. If a iterator is active
// and a new Listener is added.
if( bIsList )
aData.pAsSequence = new Sequence< Reference< XInterface > >( *aData.pAsSequence );
aData.pAsVector = new std::vector< Reference< XInterface > >( *aData.pAsVector );
else if( aData.pAsInterface )
aData.pAsInterface->acquire();

Expand All @@ -210,19 +197,16 @@ sal_Int32 OInterfaceContainerHelper::addInterface( const Reference<XInterface> &

if( bIsList )
{
sal_Int32 nLen = aData.pAsSequence->getLength();
realloc( *aData.pAsSequence, nLen +1 );
aData.pAsSequence->getArray()[ nLen ] = rListener;
return nLen +1;
aData.pAsVector->push_back( rListener );
return aData.pAsVector->size();
}
else if( aData.pAsInterface )
{
Sequence< Reference< XInterface > > * pSeq = new Sequence< Reference< XInterface > >( 2 );
Reference<XInterface> * pArray = pSeq->getArray();
pArray[0] = aData.pAsInterface;
pArray[1] = rListener;
std::vector< Reference< XInterface > > * pSeq = new std::vector< Reference< XInterface > >( 2 );
(*pSeq)[0] = aData.pAsInterface;
(*pSeq)[1] = rListener;
aData.pAsInterface->release();
aData.pAsSequence = pSeq;
aData.pAsVector = pSeq;
bIsList = sal_True;
return 2;
}
Expand All @@ -244,43 +228,41 @@ sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference<XInterface

if( bIsList )
{
const Reference<XInterface> * pL = aData.pAsSequence->getConstArray();
sal_Int32 nLen = aData.pAsSequence->getLength();
sal_Int32 i;
for( i = 0; i < nLen; i++ )
// It is not valid to compare the pointer directly, but it's faster.
bool bFound = false;
for( auto it = std::begin(*aData.pAsVector); it != std::end(*aData.pAsVector); ++it )
{
// It is not valid to compare the pointer directly, but it's faster.
if( pL[i].get() == rListener.get() )
if( (*it).get() == rListener.get() )
{
sequenceRemoveElementAt( *aData.pAsSequence, i );
aData.pAsVector->erase(it);
bFound = true;
break;
}
}

if( i == nLen )
if (!bFound)
{
// interface not found, use the correct compare method
for( i = 0; i < nLen; i++ )
for( auto it = std::begin(*aData.pAsVector); it != std::end(*aData.pAsVector); ++it )
{
if( pL[i] == rListener )
if( *it == rListener )
{
sequenceRemoveElementAt(*aData.pAsSequence, i );
aData.pAsVector->erase(it);
break;
}
}
}

if( aData.pAsSequence->getLength() == 1 )
if( aData.pAsVector->size() == 1 )
{
XInterface * p = aData.pAsSequence->getConstArray()[0].get();
XInterface * p = (*aData.pAsVector)[0].get();
p->acquire();
delete aData.pAsSequence;
delete aData.pAsVector;
aData.pAsInterface = p;
bIsList = sal_False;
return 1;
}
else
return aData.pAsSequence->getLength();
return aData.pAsVector->size();
}
else if( aData.pAsInterface && Reference<XInterface>( aData.pAsInterface ) == rListener )
{
Expand Down
13 changes: 3 additions & 10 deletions dbaccess/source/core/api/RowSet.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -104,22 +104,15 @@ com_sun_star_comp_dba_ORowSet_get_implementation(css::uno::XComponentContext* co
}

#define NOTIFY_LISTERNERS_CHECK(_rListeners,T,method) \
Sequence< Reference< XInterface > > aListenerSeq = _rListeners.getElements(); \
\
const Reference< XInterface >* pxIntBegin = aListenerSeq.getConstArray(); \
const Reference< XInterface >* pxInt = pxIntBegin + aListenerSeq.getLength(); \
std::vector< Reference< XInterface > > aListenerSeq = _rListeners.getElementsAsVector(); \
\
_rGuard.clear(); \
bool bCheck = true; \
while( pxInt > pxIntBegin && bCheck ) \
for( auto iter = aListenerSeq.rbegin(); iter != aListenerSeq.rend() && bCheck; ++iter ) \
{ \
try \
{ \
while( pxInt > pxIntBegin && bCheck ) \
{ \
--pxInt; \
bCheck = static_cast< T* >( pxInt->get() )->method(aEvt); \
} \
bCheck = static_cast< T* >( (*iter).get() )->method(aEvt); \
} \
catch( RuntimeException& ) \
{ \
Expand Down
13 changes: 3 additions & 10 deletions dbaccess/source/inc/apitools.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -328,21 +328,14 @@ public:
return new ::cppu::OPropertyArrayHelper(aDescriptor);

#define NOTIFY_LISTERNERS(_rListeners,T,method) \
Sequence< Reference< XInterface > > aListenerSeq = _rListeners.getElements(); \
\
const Reference< XInterface >* pxIntBegin = aListenerSeq.getConstArray(); \
const Reference< XInterface >* pxInt = pxIntBegin + aListenerSeq.getLength(); \
std::vector< Reference< XInterface > > aListenerSeq = _rListeners.getElementsAsVector(); \
\
_rGuard.clear(); \
while( pxInt > pxIntBegin ) \
for( auto iter = aListenerSeq.rbegin(); iter != aListenerSeq.rend(); ++iter ) \
{ \
try \
{ \
while( pxInt > pxIntBegin ) \
{ \
--pxInt; \
static_cast< T* >( pxInt->get() )->method(aEvt); \
} \
static_cast< T* >( (*iter).get() )->method(aEvt); \
} \
catch( RuntimeException& ) \
{ \
Expand Down
Loading

0 comments on commit e57314f

Please sign in to comment.