1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "comphelper_module.hxx"
22 #include "comphelper_services.hxx"
23 #include <comphelper/anytostring.hxx>
24 #include <comphelper/anycompare.hxx>
25 #include <comphelper/componentbase.hxx>
26 #include <comphelper/extract.hxx>
28 #include <com/sun/star/container/XEnumerableMap.hpp>
29 #include <com/sun/star/lang/XInitialization.hpp>
30 #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
31 #include <com/sun/star/beans/Pair.hpp>
32 #include <com/sun/star/lang/XServiceInfo.hpp>
34 #include <cppuhelper/compbase3.hxx>
35 #include <cppuhelper/implbase1.hxx>
36 #include <cppuhelper/supportsservice.hxx>
37 #include <rtl/math.hxx>
38 #include <rtl/ustrbuf.hxx>
39 #include <typelib/typedescription.hxx>
45 #include <boost/noncopyable.hpp>
51 using ::com::sun::star::uno::Reference
;
52 using ::com::sun::star::uno::XInterface
;
53 using ::com::sun::star::uno::UNO_QUERY
;
54 using ::com::sun::star::uno::UNO_QUERY_THROW
;
55 using ::com::sun::star::uno::UNO_SET_THROW
;
56 using ::com::sun::star::uno::Exception
;
57 using ::com::sun::star::uno::RuntimeException
;
58 using ::com::sun::star::uno::Any
;
59 using ::com::sun::star::uno::makeAny
;
60 using ::com::sun::star::uno::Sequence
;
61 using ::com::sun::star::uno::Type
;
62 using ::com::sun::star::container::XEnumerableMap
;
63 using ::com::sun::star::lang::NoSupportException
;
64 using ::com::sun::star::beans::IllegalTypeException
;
65 using ::com::sun::star::container::NoSuchElementException
;
66 using ::com::sun::star::lang::IllegalArgumentException
;
67 using ::com::sun::star::lang::XInitialization
;
68 using ::com::sun::star::ucb::AlreadyInitializedException
;
69 using ::com::sun::star::beans::Pair
;
70 using ::com::sun::star::uno::TypeClass
;
71 using ::com::sun::star::uno::TypeClass_VOID
;
72 using ::com::sun::star::uno::TypeClass_UNKNOWN
;
73 using ::com::sun::star::uno::TypeClass_ANY
;
74 using ::com::sun::star::uno::TypeClass_EXCEPTION
;
75 using ::com::sun::star::uno::TypeClass_STRUCT
;
76 using ::com::sun::star::uno::TypeClass_FLOAT
;
77 using ::com::sun::star::uno::TypeClass_DOUBLE
;
78 using ::com::sun::star::uno::TypeClass_INTERFACE
;
79 using ::com::sun::star::lang::XServiceInfo
;
80 using ::com::sun::star::uno::XComponentContext
;
81 using ::com::sun::star::container::XEnumeration
;
82 using ::com::sun::star::uno::TypeDescription
;
83 using ::com::sun::star::lang::WrappedTargetException
;
84 using ::com::sun::star::lang::DisposedException
;
86 class IMapModificationListener
;
87 typedef ::std::vector
< IMapModificationListener
* > MapListeners
;
89 typedef ::std::map
< Any
, Any
, LessPredicateAdapter
> KeyedValues
;
94 ::std::unique_ptr
< KeyedValues
> m_pValues
;
95 ::std::shared_ptr
< IKeyPredicateLess
> m_pKeyCompare
;
97 MapListeners m_aModListeners
;
104 MapData( const MapData
& _source
)
105 :m_aKeyType( _source
.m_aKeyType
)
106 ,m_aValueType( _source
.m_aValueType
)
107 ,m_pValues( new KeyedValues( *_source
.m_pValues
) )
108 ,m_pKeyCompare( _source
.m_pKeyCompare
)
114 MapData
& operator=( const MapData
& _source
) SAL_DELETED_FUNCTION
;
118 /** implemented by components who want to be notified of modifications in the MapData they work with
120 class SAL_NO_VTABLE IMapModificationListener
123 /// called when the map was modified
124 virtual void mapModified() = 0;
125 virtual ~IMapModificationListener()
130 static void lcl_registerMapModificationListener( MapData
& _mapData
, IMapModificationListener
& _listener
)
132 #if OSL_DEBUG_LEVEL > 0
133 for ( MapListeners::const_iterator lookup
= _mapData
.m_aModListeners
.begin();
134 lookup
!= _mapData
.m_aModListeners
.end();
138 OSL_ENSURE( *lookup
!= &_listener
, "lcl_registerMapModificationListener: this listener is already registered!" );
141 _mapData
.m_aModListeners
.push_back( &_listener
);
145 static void lcl_revokeMapModificationListener( MapData
& _mapData
, IMapModificationListener
& _listener
)
147 for ( MapListeners::iterator lookup
= _mapData
.m_aModListeners
.begin();
148 lookup
!= _mapData
.m_aModListeners
.end();
152 if ( *lookup
== &_listener
)
154 _mapData
.m_aModListeners
.erase( lookup
);
158 OSL_FAIL( "lcl_revokeMapModificationListener: the listener is not registered!" );
162 static void lcl_notifyMapDataListeners_nothrow( const MapData
& _mapData
)
164 for ( MapListeners::const_iterator loop
= _mapData
.m_aModListeners
.begin();
165 loop
!= _mapData
.m_aModListeners
.end();
169 (*loop
)->mapModified();
176 typedef ::cppu::WeakAggComponentImplHelper3
< XInitialization
181 class COMPHELPER_DLLPRIVATE EnumerableMap
:public Map_IFace
182 ,public ComponentBase
186 virtual ~EnumerableMap();
189 virtual void SAL_CALL
initialize( const Sequence
< Any
>& aArguments
) throw (Exception
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
192 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::container::XEnumeration
> SAL_CALL
createKeyEnumeration( sal_Bool _Isolated
) throw (::com::sun::star::lang::NoSupportException
, ::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
193 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::container::XEnumeration
> SAL_CALL
createValueEnumeration( sal_Bool _Isolated
) throw (::com::sun::star::lang::NoSupportException
, ::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
194 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::container::XEnumeration
> SAL_CALL
createElementEnumeration( sal_Bool _Isolated
) throw (::com::sun::star::lang::NoSupportException
, ::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
197 virtual Type SAL_CALL
getKeyType() throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
198 virtual Type SAL_CALL
getValueType() throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
199 virtual void SAL_CALL
clear( ) throw (NoSupportException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
200 virtual sal_Bool SAL_CALL
containsKey( const Any
& _key
) throw (IllegalTypeException
, IllegalArgumentException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
201 virtual sal_Bool SAL_CALL
containsValue( const Any
& _value
) throw (IllegalTypeException
, IllegalArgumentException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
202 virtual Any SAL_CALL
get( const Any
& _key
) throw (IllegalTypeException
, IllegalArgumentException
, NoSuchElementException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
203 virtual Any SAL_CALL
put( const Any
& _key
, const Any
& _value
) throw (NoSupportException
, IllegalTypeException
, IllegalArgumentException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
204 virtual Any SAL_CALL
remove( const Any
& _key
) throw (NoSupportException
, IllegalTypeException
, IllegalArgumentException
, NoSuchElementException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
206 // XElementAccess (base of XMap)
207 virtual Type SAL_CALL
getElementType() throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
208 virtual sal_Bool SAL_CALL
hasElements() throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
211 virtual OUString SAL_CALL
getImplementationName( ) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
212 virtual sal_Bool SAL_CALL
supportsService( const OUString
& ServiceName
) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
213 virtual Sequence
< OUString
> SAL_CALL
getSupportedServiceNames( ) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
216 // XServiceInfo, static version (used for component registration)
217 static OUString SAL_CALL
getImplementationName_static( );
218 static Sequence
< OUString
> SAL_CALL
getSupportedServiceNames_static( );
219 static Reference
< XInterface
> SAL_CALL
Create( const Reference
< XComponentContext
>& );
222 void impl_initValues_throw( const Sequence
< Pair
< Any
, Any
> >& _initialValues
);
224 /// throws a IllegalTypeException if the given value is not compatible with our ValueType
225 void impl_checkValue_throw( const Any
& _value
) const;
226 void impl_checkKey_throw( const Any
& _key
) const;
227 void impl_checkNaN_throw( const Any
& _keyOrValue
, const Type
& _keyOrValueType
) const;
228 void impl_checkMutable_throw() const;
231 ::osl::Mutex m_aMutex
;
234 ::std::vector
< ::com::sun::star::uno::WeakReference
< XInterface
> >
235 m_aDependentComponents
;
241 eKeys
, eValues
, eBoth
246 public IMapModificationListener
, private boost::noncopyable
249 MapEnumerator( ::cppu::OWeakObject
& _rParent
, MapData
& _mapData
, const EnumerationType _type
)
250 :m_rParent( _rParent
)
251 ,m_rMapData( _mapData
)
253 ,m_mapPos( _mapData
.m_pValues
->begin() )
256 lcl_registerMapModificationListener( m_rMapData
, *this );
259 virtual ~MapEnumerator()
268 lcl_revokeMapModificationListener( m_rMapData
, *this );
273 // XEnumeration equivalents
274 bool hasMoreElements();
277 // IMapModificationListener
278 virtual void mapModified() SAL_OVERRIDE
;
281 ::cppu::OWeakObject
& m_rParent
;
283 const EnumerationType m_eType
;
284 KeyedValues::const_iterator m_mapPos
;
289 typedef ::cppu::WeakImplHelper1
< XEnumeration
290 > MapEnumeration_Base
;
291 class MapEnumeration
:public ComponentBase
292 ,public MapEnumeration_Base
295 MapEnumeration( ::cppu::OWeakObject
& _parentMap
, MapData
& _mapData
, ::cppu::OBroadcastHelper
& _rBHelper
,
296 const EnumerationType _type
, const bool _isolated
)
297 :ComponentBase( _rBHelper
, ComponentBase::NoInitializationNeeded() )
298 ,m_xKeepMapAlive( _parentMap
)
299 ,m_pMapDataCopy( _isolated
? new MapData( _mapData
) : NULL
)
300 ,m_aEnumerator( *this, _isolated
? *m_pMapDataCopy
: _mapData
, _type
)
305 virtual sal_Bool SAL_CALL
hasMoreElements( ) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
306 virtual Any SAL_CALL
nextElement( ) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
309 virtual ~MapEnumeration()
313 ::osl::MutexGuard
aGuard( getMutex() );
314 m_aEnumerator
.dispose();
315 m_pMapDataCopy
.reset();
320 // since we share our mutex with the main map, we need to keep it alive as long as we live
321 Reference
< XInterface
> m_xKeepMapAlive
;
322 ::std::unique_ptr
< MapData
> m_pMapDataCopy
;
323 MapEnumerator m_aEnumerator
;
327 EnumerableMap::EnumerableMap()
328 :Map_IFace( m_aMutex
)
329 ,ComponentBase( Map_IFace::rBHelper
)
334 EnumerableMap::~EnumerableMap()
336 if ( !impl_isDisposed() )
344 void SAL_CALL
EnumerableMap::initialize( const Sequence
< Any
>& _arguments
) throw (Exception
, RuntimeException
, std::exception
)
346 ComponentMethodGuard
aGuard( *this, ComponentMethodGuard::WithoutInit
);
347 if ( impl_isInitialized_nothrow() )
348 throw AlreadyInitializedException();
350 sal_Int32 nArgumentCount
= _arguments
.getLength();
351 if ( ( nArgumentCount
!= 2 ) && ( nArgumentCount
!= 3 ) )
352 throw IllegalArgumentException();
354 Type aKeyType
, aValueType
;
355 if ( !( _arguments
[0] >>= aKeyType
) )
356 throw IllegalArgumentException("com.sun.star.uno.Type expected.", *this, 1 );
357 if ( !( _arguments
[1] >>= aValueType
) )
358 throw IllegalArgumentException("com.sun.star.uno.Type expected.", *this, 2 );
360 Sequence
< Pair
< Any
, Any
> > aInitialValues
;
361 bool bMutable
= true;
362 if ( nArgumentCount
== 3 )
364 if ( !( _arguments
[2] >>= aInitialValues
) )
365 throw IllegalArgumentException("[]com.sun.star.beans.Pair<any,any> expected.", *this, 2 );
369 // for the value, anything is allowed, except VOID
370 if ( ( aValueType
.getTypeClass() == TypeClass_VOID
) || ( aValueType
.getTypeClass() == TypeClass_UNKNOWN
) )
371 throw IllegalTypeException("Unsupported value type.", *this );
373 // create the comparator for the KeyType, and throw if the type is not supported
374 ::std::unique_ptr
< IKeyPredicateLess
> pComparator( getStandardLessPredicate( aKeyType
, NULL
) );
375 if ( !pComparator
.get() )
376 throw IllegalTypeException("Unsupported key type.", *this );
379 m_aData
.m_aKeyType
= aKeyType
;
380 m_aData
.m_aValueType
= aValueType
;
381 m_aData
.m_pKeyCompare
= std::move(pComparator
);
382 m_aData
.m_pValues
.reset( new KeyedValues( *m_aData
.m_pKeyCompare
) );
383 m_aData
.m_bMutable
= bMutable
;
385 if ( aInitialValues
.getLength() )
386 impl_initValues_throw( aInitialValues
);
392 void EnumerableMap::impl_initValues_throw( const Sequence
< Pair
< Any
, Any
> >& _initialValues
)
394 OSL_PRECOND( m_aData
.m_pValues
.get() && m_aData
.m_pValues
->empty(), "EnumerableMap::impl_initValues_throw: illegal call!" );
395 if ( !m_aData
.m_pValues
.get() || !m_aData
.m_pValues
->empty() )
396 throw RuntimeException();
398 const Pair
< Any
, Any
>* mapping
= _initialValues
.getConstArray();
399 const Pair
< Any
, Any
>* mappingEnd
= mapping
+ _initialValues
.getLength();
400 for ( ; mapping
!= mappingEnd
; ++mapping
)
402 impl_checkValue_throw( mapping
->Second
);
403 (*m_aData
.m_pValues
)[ mapping
->First
] = mapping
->Second
;
408 void EnumerableMap::impl_checkValue_throw( const Any
& _value
) const
410 if ( !_value
.hasValue() )
411 // nothing to do, NULL values are always allowed, regardless of the ValueType
414 TypeClass eAllowedTypeClass
= m_aData
.m_aValueType
.getTypeClass();
417 switch ( eAllowedTypeClass
)
420 bValid
= ( _value
.getValueTypeClass() == eAllowedTypeClass
);
425 case TypeClass_INTERFACE
:
427 // special treatment: _value might contain the proper type, but the interface
428 // might actually be NULL. Which is still valid ...
429 if ( m_aData
.m_aValueType
.isAssignableFrom( _value
.getValueType() ) )
430 // this also catches the special case where XFoo is our value type,
431 // and _value contains a NULL-reference to XFoo, or a derived type
435 Reference
< XInterface
> xValue( _value
, UNO_QUERY
);
437 // XInterface is not-NULL, but is X(ValueType) not-NULL, too?
438 xValue
.set( xValue
->queryInterface( m_aData
.m_aValueType
), UNO_QUERY
);
439 bValid
= xValue
.is();
443 case TypeClass_EXCEPTION
:
444 case TypeClass_STRUCT
:
446 // values are accepted if and only if their type equals, or is derived from, our value type
448 if ( _value
.getValueTypeClass() != eAllowedTypeClass
)
452 const TypeDescription
aValueTypeDesc( _value
.getValueType() );
453 const TypeDescription
aRequiredTypeDesc( m_aData
.m_aValueType
);
455 const _typelib_CompoundTypeDescription
* pValueCompoundTypeDesc
=
456 reinterpret_cast< const _typelib_CompoundTypeDescription
* >( aValueTypeDesc
.get() );
458 while ( pValueCompoundTypeDesc
)
460 if ( typelib_typedescription_equals( &pValueCompoundTypeDesc
->aBase
, aRequiredTypeDesc
.get() ) )
462 pValueCompoundTypeDesc
= pValueCompoundTypeDesc
->pBaseTypeDescription
;
464 bValid
= ( pValueCompoundTypeDesc
!= NULL
);
472 OUStringBuffer aMessage
;
473 aMessage
.appendAscii( "Incompatible value type. Found '" );
474 aMessage
.append( _value
.getValueTypeName() );
475 aMessage
.appendAscii( "', where '" );
476 aMessage
.append( m_aData
.m_aValueType
.getTypeName() );
477 aMessage
.appendAscii( "' (or compatible type) is expected." );
478 throw IllegalTypeException( aMessage
.makeStringAndClear(), *const_cast< EnumerableMap
* >( this ) );
481 impl_checkNaN_throw( _value
, m_aData
.m_aValueType
);
485 void EnumerableMap::impl_checkNaN_throw( const Any
& _keyOrValue
, const Type
& _keyOrValueType
) const
487 if ( ( _keyOrValueType
.getTypeClass() == TypeClass_DOUBLE
)
488 || ( _keyOrValueType
.getTypeClass() == TypeClass_FLOAT
)
492 if ( _keyOrValue
>>= nValue
)
493 if ( ::rtl::math::isNan( nValue
) )
494 throw IllegalArgumentException(
495 "NaN (not-a-number) not supported by this implementation.",
496 *const_cast< EnumerableMap
* >( this ), 0 );
497 // (note that the case of _key not containing a float/double value is handled in the
498 // respective IKeyPredicateLess implementation, so there's no need to handle this here.)
503 void EnumerableMap::impl_checkKey_throw( const Any
& _key
) const
505 if ( !_key
.hasValue() )
506 throw IllegalArgumentException(
507 "NULL keys not supported by this implementation.",
508 *const_cast< EnumerableMap
* >( this ), 0 );
510 impl_checkNaN_throw( _key
, m_aData
.m_aKeyType
);
514 void EnumerableMap::impl_checkMutable_throw() const
516 if ( !m_aData
.m_bMutable
)
517 throw NoSupportException(
518 "The map is immutable.",
519 *const_cast< EnumerableMap
* >( this ) );
523 Reference
< XEnumeration
> SAL_CALL
EnumerableMap::createKeyEnumeration( sal_Bool _Isolated
) throw (NoSupportException
, RuntimeException
, std::exception
)
525 ComponentMethodGuard
aGuard( *this );
526 return new MapEnumeration( *this, m_aData
, getBroadcastHelper(), eKeys
, _Isolated
);
530 Reference
< XEnumeration
> SAL_CALL
EnumerableMap::createValueEnumeration( sal_Bool _Isolated
) throw (NoSupportException
, RuntimeException
, std::exception
)
532 ComponentMethodGuard
aGuard( *this );
533 return new MapEnumeration( *this, m_aData
, getBroadcastHelper(), eValues
, _Isolated
);
537 Reference
< XEnumeration
> SAL_CALL
EnumerableMap::createElementEnumeration( sal_Bool _Isolated
) throw (NoSupportException
, RuntimeException
, std::exception
)
539 ComponentMethodGuard
aGuard( *this );
540 return new MapEnumeration( *this, m_aData
, getBroadcastHelper(), eBoth
, _Isolated
);
544 Type SAL_CALL
EnumerableMap::getKeyType() throw (RuntimeException
, std::exception
)
546 ComponentMethodGuard
aGuard( *this );
547 return m_aData
.m_aKeyType
;
551 Type SAL_CALL
EnumerableMap::getValueType() throw (RuntimeException
, std::exception
)
553 ComponentMethodGuard
aGuard( *this );
554 return m_aData
.m_aValueType
;
558 void SAL_CALL
EnumerableMap::clear( ) throw (NoSupportException
, RuntimeException
, std::exception
)
560 ComponentMethodGuard
aGuard( *this );
561 impl_checkMutable_throw();
563 m_aData
.m_pValues
->clear();
565 lcl_notifyMapDataListeners_nothrow( m_aData
);
569 sal_Bool SAL_CALL
EnumerableMap::containsKey( const Any
& _key
) throw (IllegalTypeException
, IllegalArgumentException
, RuntimeException
, std::exception
)
571 ComponentMethodGuard
aGuard( *this );
572 impl_checkKey_throw( _key
);
574 KeyedValues::const_iterator pos
= m_aData
.m_pValues
->find( _key
);
575 return ( pos
!= m_aData
.m_pValues
->end() );
579 sal_Bool SAL_CALL
EnumerableMap::containsValue( const Any
& _value
) throw (IllegalTypeException
, IllegalArgumentException
, RuntimeException
, std::exception
)
581 ComponentMethodGuard
aGuard( *this );
582 impl_checkValue_throw( _value
);
584 for ( KeyedValues::const_iterator mapping
= m_aData
.m_pValues
->begin();
585 mapping
!= m_aData
.m_pValues
->end();
589 if ( mapping
->second
== _value
)
596 Any SAL_CALL
EnumerableMap::get( const Any
& _key
) throw (IllegalTypeException
, IllegalArgumentException
, NoSuchElementException
, RuntimeException
, std::exception
)
598 ComponentMethodGuard
aGuard( *this );
599 impl_checkKey_throw( _key
);
601 KeyedValues::const_iterator pos
= m_aData
.m_pValues
->find( _key
);
602 if ( pos
== m_aData
.m_pValues
->end() )
603 throw NoSuchElementException( anyToString( _key
), *this );
609 Any SAL_CALL
EnumerableMap::put( const Any
& _key
, const Any
& _value
) throw (NoSupportException
, IllegalTypeException
, IllegalArgumentException
, RuntimeException
, std::exception
)
611 ComponentMethodGuard
aGuard( *this );
612 impl_checkMutable_throw();
613 impl_checkKey_throw( _key
);
614 impl_checkValue_throw( _value
);
618 KeyedValues::iterator pos
= m_aData
.m_pValues
->find( _key
);
619 if ( pos
!= m_aData
.m_pValues
->end() )
621 previousValue
= pos
->second
;
622 pos
->second
= _value
;
626 (*m_aData
.m_pValues
)[ _key
] = _value
;
629 lcl_notifyMapDataListeners_nothrow( m_aData
);
631 return previousValue
;
635 Any SAL_CALL
EnumerableMap::remove( const Any
& _key
) throw (NoSupportException
, IllegalTypeException
, IllegalArgumentException
, NoSuchElementException
, RuntimeException
, std::exception
)
637 ComponentMethodGuard
aGuard( *this );
638 impl_checkMutable_throw();
639 impl_checkKey_throw( _key
);
643 KeyedValues::iterator pos
= m_aData
.m_pValues
->find( _key
);
644 if ( pos
!= m_aData
.m_pValues
->end() )
646 previousValue
= pos
->second
;
647 m_aData
.m_pValues
->erase( pos
);
650 lcl_notifyMapDataListeners_nothrow( m_aData
);
652 return previousValue
;
656 Type SAL_CALL
EnumerableMap::getElementType() throw (RuntimeException
, std::exception
)
658 return ::cppu::UnoType
< Pair
< Any
, Any
> >::get();
662 sal_Bool SAL_CALL
EnumerableMap::hasElements() throw (RuntimeException
, std::exception
)
664 ComponentMethodGuard
aGuard( *this );
665 return m_aData
.m_pValues
->empty();
669 OUString SAL_CALL
EnumerableMap::getImplementationName( ) throw (RuntimeException
, std::exception
)
671 return getImplementationName_static();
674 sal_Bool SAL_CALL
EnumerableMap::supportsService( const OUString
& _serviceName
) throw (RuntimeException
, std::exception
)
676 return cppu::supportsService(this, _serviceName
);
680 Sequence
< OUString
> SAL_CALL
EnumerableMap::getSupportedServiceNames( ) throw (RuntimeException
, std::exception
)
682 return getSupportedServiceNames_static();
686 OUString SAL_CALL
EnumerableMap::getImplementationName_static( )
688 return OUString( "org.openoffice.comp.comphelper.EnumerableMap" );
692 Sequence
< OUString
> SAL_CALL
EnumerableMap::getSupportedServiceNames_static( )
694 Sequence
< OUString
> aServiceNames(1);
695 aServiceNames
[0] = "com.sun.star.container.EnumerableMap";
696 return aServiceNames
;
700 Reference
< XInterface
> SAL_CALL
EnumerableMap::Create( SAL_UNUSED_PARAMETER
const Reference
< XComponentContext
>& )
702 return *new EnumerableMap
;
706 bool MapEnumerator::hasMoreElements()
709 throw DisposedException( OUString(), m_rParent
);
710 return m_mapPos
!= m_rMapData
.m_pValues
->end();
714 Any
MapEnumerator::nextElement()
717 throw DisposedException( OUString(), m_rParent
);
718 if ( m_mapPos
== m_rMapData
.m_pValues
->end() )
719 throw NoSuchElementException("No more elements.", m_rParent
);
724 case eKeys
: aNextElement
= m_mapPos
->first
; break;
725 case eValues
: aNextElement
= m_mapPos
->second
; break;
726 case eBoth
: aNextElement
<<= Pair
< Any
, Any
>( m_mapPos
->first
, m_mapPos
->second
); break;
733 void MapEnumerator::mapModified()
739 sal_Bool SAL_CALL
MapEnumeration::hasMoreElements( ) throw (RuntimeException
, std::exception
)
741 ComponentMethodGuard
aGuard( *this );
742 return m_aEnumerator
.hasMoreElements();
746 Any SAL_CALL
MapEnumeration::nextElement( ) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
, std::exception
)
748 ComponentMethodGuard
aGuard( *this );
749 return m_aEnumerator
.nextElement();
753 } // namespace comphelper
756 void createRegistryInfo_Map()
758 ::comphelper::module::OAutoRegistration
< ::comphelper::EnumerableMap
> aAutoRegistration
;
761 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */