bump product version to 5.0.4.1
[LibreOffice.git] / comphelper / source / container / enumerablemap.cxx
blob9338d711f80768ff20a8ae8af6009ee6c25f1436
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
41 #include <map>
42 #include <memory>
43 #include <utility>
45 #include <boost/noncopyable.hpp>
47 namespace comphelper
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;
90 struct MapData
92 Type m_aKeyType;
93 Type m_aValueType;
94 ::std::unique_ptr< KeyedValues > m_pValues;
95 ::std::shared_ptr< IKeyPredicateLess > m_pKeyCompare;
96 bool m_bMutable;
97 MapListeners m_aModListeners;
99 MapData()
100 :m_bMutable( true )
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 )
109 ,m_bMutable( false )
110 ,m_aModListeners()
113 private:
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
122 public:
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();
135 ++lookup
138 OSL_ENSURE( *lookup != &_listener, "lcl_registerMapModificationListener: this listener is already registered!" );
140 #endif
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();
149 ++lookup
152 if ( *lookup == &_listener )
154 _mapData.m_aModListeners.erase( lookup );
155 return;
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();
166 ++loop
169 (*loop)->mapModified();
174 // EnumerableMap
176 typedef ::cppu::WeakAggComponentImplHelper3 < XInitialization
177 , XEnumerableMap
178 , XServiceInfo
179 > Map_IFace;
181 class COMPHELPER_DLLPRIVATE EnumerableMap :public Map_IFace
182 ,public ComponentBase
184 protected:
185 EnumerableMap();
186 virtual ~EnumerableMap();
188 // XInitialization
189 virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
191 // XEnumerableMap
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;
196 // XMap
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;
210 // XServiceInfo
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;
215 public:
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 >& );
221 private:
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;
230 private:
231 ::osl::Mutex m_aMutex;
232 MapData m_aData;
234 ::std::vector< ::com::sun::star::uno::WeakReference< XInterface > >
235 m_aDependentComponents;
239 enum EnumerationType
241 eKeys, eValues, eBoth
245 class MapEnumerator:
246 public IMapModificationListener, private boost::noncopyable
248 public:
249 MapEnumerator( ::cppu::OWeakObject& _rParent, MapData& _mapData, const EnumerationType _type )
250 :m_rParent( _rParent )
251 ,m_rMapData( _mapData )
252 ,m_eType( _type )
253 ,m_mapPos( _mapData.m_pValues->begin() )
254 ,m_disposed( false )
256 lcl_registerMapModificationListener( m_rMapData, *this );
259 virtual ~MapEnumerator()
261 dispose();
264 void dispose()
266 if ( !m_disposed )
268 lcl_revokeMapModificationListener( m_rMapData, *this );
269 m_disposed = true;
273 // XEnumeration equivalents
274 bool hasMoreElements();
275 Any nextElement();
277 // IMapModificationListener
278 virtual void mapModified() SAL_OVERRIDE;
280 private:
281 ::cppu::OWeakObject& m_rParent;
282 MapData& m_rMapData;
283 const EnumerationType m_eType;
284 KeyedValues::const_iterator m_mapPos;
285 bool m_disposed;
289 typedef ::cppu::WeakImplHelper1 < XEnumeration
290 > MapEnumeration_Base;
291 class MapEnumeration :public ComponentBase
292 ,public MapEnumeration_Base
294 public:
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 )
304 // XEnumeration
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;
308 protected:
309 virtual ~MapEnumeration()
311 acquire();
313 ::osl::MutexGuard aGuard( getMutex() );
314 m_aEnumerator.dispose();
315 m_pMapDataCopy.reset();
319 private:
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() )
338 acquire();
339 dispose();
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 );
366 bMutable = false;
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 );
378 // init members
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 );
388 setInitialized();
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
412 return;
414 TypeClass eAllowedTypeClass = m_aData.m_aValueType.getTypeClass();
415 bool bValid = false;
417 switch ( eAllowedTypeClass )
419 default:
420 bValid = ( _value.getValueTypeClass() == eAllowedTypeClass );
421 break;
422 case TypeClass_ANY:
423 bValid = true;
424 break;
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
432 bValid = true;
433 else
435 Reference< XInterface > xValue( _value, UNO_QUERY );
436 if ( xValue.is() )
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();
442 break;
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 )
449 bValid = false;
450 else
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() ) )
461 break;
462 pValueCompoundTypeDesc = pValueCompoundTypeDesc->pBaseTypeDescription;
464 bValid = ( pValueCompoundTypeDesc != NULL );
467 break;
470 if ( !bValid )
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 )
491 double nValue(0);
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();
586 ++mapping
589 if ( mapping->second == _value )
590 return sal_True;
592 return sal_False;
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 );
605 return pos->second;
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 );
616 Any previousValue;
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;
624 else
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 );
641 Any previousValue;
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()
708 if ( m_disposed )
709 throw DisposedException( OUString(), m_rParent );
710 return m_mapPos != m_rMapData.m_pValues->end();
714 Any MapEnumerator::nextElement()
716 if ( m_disposed )
717 throw DisposedException( OUString(), m_rParent );
718 if ( m_mapPos == m_rMapData.m_pValues->end() )
719 throw NoSuchElementException("No more elements.", m_rParent );
721 Any aNextElement;
722 switch ( m_eType )
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;
728 ++m_mapPos;
729 return aNextElement;
733 void MapEnumerator::mapModified()
735 m_disposed = true;
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: */