LibreOffice Module comphelper (master)  1
enumerablemap.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 
21 #include <comphelper_module.hxx>
22 #include <comphelper_services.hxx>
26 
27 #include <com/sun/star/container/XEnumerableMap.hpp>
28 #include <com/sun/star/lang/NoSupportException.hpp>
29 #include <com/sun/star/lang/XInitialization.hpp>
30 #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
31 #include <com/sun/star/beans/IllegalTypeException.hpp>
32 #include <com/sun/star/beans/Pair.hpp>
33 #include <com/sun/star/lang/XServiceInfo.hpp>
34 
35 #include <cppuhelper/compbase3.hxx>
36 #include <cppuhelper/implbase.hxx>
38 #include <rtl/math.hxx>
39 #include <typelib/typedescription.hxx>
40 
41 #include <map>
42 #include <memory>
43 #include <utility>
44 
45 namespace comphelper
46 {
47 
48 
49  using ::com::sun::star::uno::Reference;
50  using ::com::sun::star::uno::XInterface;
51  using ::com::sun::star::uno::UNO_QUERY;
52  using ::com::sun::star::uno::RuntimeException;
53  using ::com::sun::star::uno::Any;
54  using ::com::sun::star::uno::Sequence;
55  using ::com::sun::star::uno::Type;
56  using ::com::sun::star::container::XEnumerableMap;
57  using ::com::sun::star::lang::NoSupportException;
58  using ::com::sun::star::beans::IllegalTypeException;
59  using ::com::sun::star::container::NoSuchElementException;
60  using ::com::sun::star::lang::IllegalArgumentException;
61  using ::com::sun::star::lang::XInitialization;
62  using ::com::sun::star::ucb::AlreadyInitializedException;
63  using ::com::sun::star::beans::Pair;
64  using ::com::sun::star::uno::TypeClass;
65  using ::com::sun::star::uno::TypeClass_VOID;
66  using ::com::sun::star::uno::TypeClass_UNKNOWN;
67  using ::com::sun::star::uno::TypeClass_ANY;
68  using ::com::sun::star::uno::TypeClass_EXCEPTION;
69  using ::com::sun::star::uno::TypeClass_STRUCT;
70  using ::com::sun::star::uno::TypeClass_FLOAT;
71  using ::com::sun::star::uno::TypeClass_DOUBLE;
72  using ::com::sun::star::uno::TypeClass_INTERFACE;
73  using ::com::sun::star::lang::XServiceInfo;
74  using ::com::sun::star::uno::XComponentContext;
75  using ::com::sun::star::container::XEnumeration;
76  using ::com::sun::star::uno::TypeDescription;
77  using ::com::sun::star::lang::DisposedException;
78 
79  namespace {
80 
81  class MapEnumerator;
82 
83  }
84 
85  typedef std::map< Any, Any, LessPredicateAdapter > KeyedValues;
86 
87  namespace {
88 
89  struct MapData
90  {
93  std::unique_ptr< KeyedValues > m_pValues;
94  std::shared_ptr< IKeyPredicateLess > m_pKeyCompare;
95  bool m_bMutable;
96  std::vector< MapEnumerator* > m_aModListeners;
97 
98  MapData()
99  :m_bMutable( true )
100  {
101  }
102 
103  MapData( const MapData& _source )
104  :m_aKeyType( _source.m_aKeyType )
105  ,m_aValueType( _source.m_aValueType )
106  ,m_pValues( new KeyedValues( *_source.m_pValues ) )
107  ,m_pKeyCompare( _source.m_pKeyCompare )
108  ,m_bMutable( false )
109  ,m_aModListeners()
110  {
111  }
112  private:
113  MapData& operator=( const MapData& _source ) = delete;
114  };
115 
116  }
117 
118  static void lcl_registerMapModificationListener( MapData& _mapData, MapEnumerator& _listener )
119  {
120  #if OSL_DEBUG_LEVEL > 0
121  for ( const MapEnumerator* lookup : _mapData.m_aModListeners )
122  {
123  OSL_ENSURE( lookup != &_listener, "lcl_registerMapModificationListener: this listener is already registered!" );
124  }
125  #endif
126  _mapData.m_aModListeners.push_back( &_listener );
127  }
128 
129 
130  static void lcl_revokeMapModificationListener( MapData& _mapData, MapEnumerator& _listener )
131  {
132  auto lookup = std::find(_mapData.m_aModListeners.begin(), _mapData.m_aModListeners.end(), &_listener);
133  if (lookup != _mapData.m_aModListeners.end())
134  {
135  _mapData.m_aModListeners.erase( lookup );
136  return;
137  }
138  OSL_FAIL( "lcl_revokeMapModificationListener: the listener is not registered!" );
139  }
140 
141 
142  static void lcl_notifyMapDataListeners_nothrow( const MapData& _mapData );
143 
144 
145  // EnumerableMap
146 
147  typedef ::cppu::WeakAggComponentImplHelper3 < XInitialization
148  , XEnumerableMap
149  , XServiceInfo
151 
152  namespace {
153 
154  class EnumerableMap: public Map_IFace, public ComponentBase
155  {
156  protected:
157  EnumerableMap();
158  virtual ~EnumerableMap() override;
159 
160  // XInitialization
161  virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) override;
162 
163  // XEnumerableMap
164  virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createKeyEnumeration( sal_Bool Isolated ) override;
165  virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createValueEnumeration( sal_Bool Isolated ) override;
166  virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createElementEnumeration( sal_Bool Isolated ) override;
167 
168  // XMap
169  virtual Type SAL_CALL getKeyType() override;
170  virtual Type SAL_CALL getValueType() override;
171  virtual void SAL_CALL clear( ) override;
172  virtual sal_Bool SAL_CALL containsKey( const Any& _key ) override;
173  virtual sal_Bool SAL_CALL containsValue( const Any& _value ) override;
174  virtual Any SAL_CALL get( const Any& _key ) override;
175  virtual Any SAL_CALL put( const Any& _key, const Any& _value ) override;
176  virtual Any SAL_CALL remove( const Any& _key ) override;
177 
178  // XElementAccess (base of XMap)
179  virtual Type SAL_CALL getElementType() override;
180  virtual sal_Bool SAL_CALL hasElements() override;
181 
182  // XServiceInfo
183  virtual OUString SAL_CALL getImplementationName( ) override;
184  virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
185  virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
186 
187  public:
188  // XServiceInfo, static version (used for component registration)
189  static OUString getImplementationName_static( );
190  static Sequence< OUString > getSupportedServiceNames_static( );
192 
193  private:
194  void impl_initValues_throw( const Sequence< Pair< Any, Any > >& _initialValues );
195 
197  void impl_checkValue_throw( const Any& _value ) const;
198  void impl_checkKey_throw( const Any& _key ) const;
199  void impl_checkNaN_throw( const Any& _keyOrValue, const Type& _keyOrValueType ) const;
200  void impl_checkMutable_throw() const;
201 
202  private:
203  ::osl::Mutex m_aMutex;
204  MapData m_aData;
205  };
206 
207  enum EnumerationType
208  {
209  eKeys, eValues, eBoth
210  };
211 
212  class MapEnumerator final
213  {
214  public:
215  MapEnumerator( ::cppu::OWeakObject& _rParent, MapData& _mapData, const EnumerationType _type )
216  :m_rParent( _rParent )
217  ,m_rMapData( _mapData )
218  ,m_eType( _type )
219  ,m_mapPos( _mapData.m_pValues->begin() )
220  ,m_disposed( false )
221  {
223  }
224 
225  ~MapEnumerator()
226  {
227  dispose();
228  }
229 
230  void dispose()
231  {
232  if ( !m_disposed )
233  {
235  m_disposed = true;
236  }
237  }
238 
239  // noncopyable
240  MapEnumerator(const MapEnumerator&) = delete;
241  const MapEnumerator& operator=(const MapEnumerator&) = delete;
242 
243  // XEnumeration equivalents
244  bool hasMoreElements();
245  Any nextElement();
246 
248  void mapModified();
249 
250  private:
252  MapData& m_rMapData;
253  const EnumerationType m_eType;
254  KeyedValues::const_iterator m_mapPos;
256  };
257 
258  }
259 
260  static void lcl_notifyMapDataListeners_nothrow( const MapData& _mapData )
261  {
262  for ( MapEnumerator* loop : _mapData.m_aModListeners )
263  {
264  loop->mapModified();
265  }
266  }
267 
268  typedef ::cppu::WeakImplHelper < XEnumeration
270 
271  namespace {
272 
273  class MapEnumeration :public ComponentBase
274  ,public MapEnumeration_Base
275  {
276  public:
277  MapEnumeration( ::cppu::OWeakObject& _parentMap, MapData& _mapData, ::cppu::OBroadcastHelper& _rBHelper,
278  const EnumerationType _type, const bool _isolated )
280  ,m_xKeepMapAlive( _parentMap )
281  ,m_pMapDataCopy( _isolated ? new MapData( _mapData ) : nullptr )
282  ,m_aEnumerator( *this, _isolated ? *m_pMapDataCopy : _mapData, _type )
283  {
284  }
285 
286  // XEnumeration
287  virtual sal_Bool SAL_CALL hasMoreElements( ) override;
288  virtual Any SAL_CALL nextElement( ) override;
289 
290  protected:
291  virtual ~MapEnumeration() override
292  {
293  acquire();
294  {
295  ::osl::MutexGuard aGuard( getMutex() );
296  m_aEnumerator.dispose();
297  m_pMapDataCopy.reset();
298  }
299  }
300 
301  private:
302  // since we share our mutex with the main map, we need to keep it alive as long as we live
304  std::unique_ptr< MapData > m_pMapDataCopy;
305  MapEnumerator m_aEnumerator;
306  };
307 
308  }
309 
310  EnumerableMap::EnumerableMap()
311  :Map_IFace( m_aMutex )
312  ,ComponentBase( Map_IFace::rBHelper )
313  {
314  }
315 
316 
317  EnumerableMap::~EnumerableMap()
318  {
319  if ( !impl_isDisposed() )
320  {
321  acquire();
322  dispose();
323  }
324  }
325 
326 
327  void SAL_CALL EnumerableMap::initialize( const Sequence< Any >& _arguments )
328  {
329  ComponentMethodGuard aGuard( *this, ComponentMethodGuard::MethodType::WithoutInit );
330  if ( impl_isInitialized_nothrow() )
331  throw AlreadyInitializedException();
332 
333  sal_Int32 nArgumentCount = _arguments.getLength();
334  if ( ( nArgumentCount != 2 ) && ( nArgumentCount != 3 ) )
335  throw IllegalArgumentException();
336 
337  Type aKeyType, aValueType;
338  if ( !( _arguments[0] >>= aKeyType ) )
339  throw IllegalArgumentException("com.sun.star.uno.Type expected.", *this, 1 );
340  if ( !( _arguments[1] >>= aValueType ) )
341  throw IllegalArgumentException("com.sun.star.uno.Type expected.", *this, 2 );
342 
343  Sequence< Pair< Any, Any > > aInitialValues;
344  bool bMutable = true;
345  if ( nArgumentCount == 3 )
346  {
347  if ( !( _arguments[2] >>= aInitialValues ) )
348  throw IllegalArgumentException("[]com.sun.star.beans.Pair<any,any> expected.", *this, 2 );
349  bMutable = false;
350  }
351 
352  // for the value, anything is allowed, except VOID
353  if ( ( aValueType.getTypeClass() == TypeClass_VOID ) || ( aValueType.getTypeClass() == TypeClass_UNKNOWN ) )
354  throw IllegalTypeException("Unsupported value type.", *this );
355 
356  // create the comparator for the KeyType, and throw if the type is not supported
357  std::unique_ptr< IKeyPredicateLess > pComparator( getStandardLessPredicate( aKeyType, nullptr ) );
358  if (!pComparator)
359  throw IllegalTypeException("Unsupported key type.", *this );
360 
361  // init members
362  m_aData.m_aKeyType = aKeyType;
363  m_aData.m_aValueType = aValueType;
364  m_aData.m_pKeyCompare = std::move(pComparator);
365  m_aData.m_pValues.reset( new KeyedValues( *m_aData.m_pKeyCompare ) );
366  m_aData.m_bMutable = bMutable;
367 
368  if ( aInitialValues.hasElements() )
369  impl_initValues_throw( aInitialValues );
370 
371  setInitialized();
372  }
373 
374 
375  void EnumerableMap::impl_initValues_throw( const Sequence< Pair< Any, Any > >& _initialValues )
376  {
377  OSL_PRECOND( m_aData.m_pValues.get() && m_aData.m_pValues->empty(), "EnumerableMap::impl_initValues_throw: illegal call!" );
378  if (!m_aData.m_pValues || !m_aData.m_pValues->empty())
379  throw RuntimeException();
380 
381  const Pair< Any, Any >* mapping = _initialValues.getConstArray();
382  const Pair< Any, Any >* mappingEnd = mapping + _initialValues.getLength();
383  for ( ; mapping != mappingEnd; ++mapping )
384  {
385  impl_checkValue_throw( mapping->Second );
386  (*m_aData.m_pValues)[ mapping->First ] = mapping->Second;
387  }
388  }
389 
390 
391  void EnumerableMap::impl_checkValue_throw( const Any& _value ) const
392  {
393  if ( !_value.hasValue() )
394  // nothing to do, NULL values are always allowed, regardless of the ValueType
395  return;
396 
397  TypeClass eAllowedTypeClass = m_aData.m_aValueType.getTypeClass();
398  bool bValid = false;
399 
400  switch ( eAllowedTypeClass )
401  {
402  default:
403  bValid = ( _value.getValueTypeClass() == eAllowedTypeClass );
404  break;
405  case TypeClass_ANY:
406  bValid = true;
407  break;
408  case TypeClass_INTERFACE:
409  {
410  // special treatment: _value might contain the proper type, but the interface
411  // might actually be NULL. Which is still valid ...
412  if ( m_aData.m_aValueType.isAssignableFrom( _value.getValueType() ) )
413  // this also catches the special case where XFoo is our value type,
414  // and _value contains a NULL-reference to XFoo, or a derived type
415  bValid = true;
416  else
417  {
418  Reference< XInterface > xValue( _value, UNO_QUERY );
419  if ( xValue.is() )
420  // XInterface is not-NULL, but is X(ValueType) not-NULL, too?
421  xValue.set( xValue->queryInterface( m_aData.m_aValueType ), UNO_QUERY );
422  bValid = xValue.is();
423  }
424  }
425  break;
426  case TypeClass_EXCEPTION:
427  case TypeClass_STRUCT:
428  {
429  // values are accepted if and only if their type equals, or is derived from, our value type
430 
431  if ( _value.getValueTypeClass() != eAllowedTypeClass )
432  bValid = false;
433  else
434  {
435  const TypeDescription aValueTypeDesc( _value.getValueType() );
436  const TypeDescription aRequiredTypeDesc( m_aData.m_aValueType );
437 
438  const _typelib_CompoundTypeDescription* pValueCompoundTypeDesc =
439  reinterpret_cast< const _typelib_CompoundTypeDescription* >( aValueTypeDesc.get() );
440 
441  while ( pValueCompoundTypeDesc )
442  {
443  if ( typelib_typedescription_equals( &pValueCompoundTypeDesc->aBase, aRequiredTypeDesc.get() ) )
444  break;
445  pValueCompoundTypeDesc = pValueCompoundTypeDesc->pBaseTypeDescription;
446  }
447  bValid = ( pValueCompoundTypeDesc != nullptr );
448  }
449  }
450  break;
451  }
452 
453  if ( !bValid )
454  {
455  throw IllegalTypeException(
456  "Incompatible value type. Found '" + _value.getValueTypeName()
457  + "', where '" + m_aData.m_aValueType.getTypeName()
458  + "' (or compatible type) is expected.",
459  *const_cast< EnumerableMap* >( this ) );
460  }
461 
462  impl_checkNaN_throw( _value, m_aData.m_aValueType );
463  }
464 
465 
466  void EnumerableMap::impl_checkNaN_throw( const Any& _keyOrValue, const Type& _keyOrValueType ) const
467  {
468  if ( ( _keyOrValueType.getTypeClass() == TypeClass_DOUBLE )
469  || ( _keyOrValueType.getTypeClass() == TypeClass_FLOAT )
470  )
471  {
472  double nValue(0);
473  if ( _keyOrValue >>= nValue )
474  if ( ::rtl::math::isNan( nValue ) )
475  throw IllegalArgumentException(
476  "NaN (not-a-number) not supported by this implementation.",
477  *const_cast< EnumerableMap* >( this ), 0 );
478  // (note that the case of _key not containing a float/double value is handled in the
479  // respective IKeyPredicateLess implementation, so there's no need to handle this here.)
480  }
481  }
482 
483 
484  void EnumerableMap::impl_checkKey_throw( const Any& _key ) const
485  {
486  if ( !_key.hasValue() )
487  throw IllegalArgumentException(
488  "NULL keys not supported by this implementation.",
489  *const_cast< EnumerableMap* >( this ), 0 );
490 
491  impl_checkNaN_throw( _key, m_aData.m_aKeyType );
492  }
493 
494 
495  void EnumerableMap::impl_checkMutable_throw() const
496  {
497  if ( !m_aData.m_bMutable )
498  throw NoSupportException(
499  "The map is immutable.",
500  *const_cast< EnumerableMap* >( this ) );
501  }
502 
503 
504  Reference< XEnumeration > SAL_CALL EnumerableMap::createKeyEnumeration( sal_Bool Isolated )
505  {
506  ComponentMethodGuard aGuard( *this );
507  return new MapEnumeration( *this, m_aData, getBroadcastHelper(), eKeys, Isolated );
508  }
509 
510 
511  Reference< XEnumeration > SAL_CALL EnumerableMap::createValueEnumeration( sal_Bool Isolated )
512  {
513  ComponentMethodGuard aGuard( *this );
514  return new MapEnumeration( *this, m_aData, getBroadcastHelper(), eValues, Isolated );
515  }
516 
517 
518  Reference< XEnumeration > SAL_CALL EnumerableMap::createElementEnumeration( sal_Bool Isolated )
519  {
520  ComponentMethodGuard aGuard( *this );
521  return new MapEnumeration( *this, m_aData, getBroadcastHelper(), eBoth, Isolated );
522  }
523 
524 
525  Type SAL_CALL EnumerableMap::getKeyType()
526  {
527  ComponentMethodGuard aGuard( *this );
528  return m_aData.m_aKeyType;
529  }
530 
531 
532  Type SAL_CALL EnumerableMap::getValueType()
533  {
534  ComponentMethodGuard aGuard( *this );
535  return m_aData.m_aValueType;
536  }
537 
538 
539  void SAL_CALL EnumerableMap::clear( )
540  {
541  ComponentMethodGuard aGuard( *this );
542  impl_checkMutable_throw();
543 
544  m_aData.m_pValues->clear();
545 
547  }
548 
549 
550  sal_Bool SAL_CALL EnumerableMap::containsKey( const Any& _key )
551  {
552  ComponentMethodGuard aGuard( *this );
553  impl_checkKey_throw( _key );
554 
555  KeyedValues::const_iterator pos = m_aData.m_pValues->find( _key );
556  return ( pos != m_aData.m_pValues->end() );
557  }
558 
559 
560  sal_Bool SAL_CALL EnumerableMap::containsValue( const Any& _value )
561  {
562  ComponentMethodGuard aGuard( *this );
563  impl_checkValue_throw( _value );
564  for (auto const& value : *m_aData.m_pValues)
565  {
566  if ( value.second == _value )
567  return true;
568  }
569  return false;
570  }
571 
572 
573  Any SAL_CALL EnumerableMap::get( const Any& _key )
574  {
575  ComponentMethodGuard aGuard( *this );
576  impl_checkKey_throw( _key );
577 
578  KeyedValues::const_iterator pos = m_aData.m_pValues->find( _key );
579  if ( pos == m_aData.m_pValues->end() )
580  throw NoSuchElementException( anyToString( _key ), *this );
581 
582  return pos->second;
583  }
584 
585 
586  Any SAL_CALL EnumerableMap::put( const Any& _key, const Any& _value )
587  {
588  ComponentMethodGuard aGuard( *this );
589  impl_checkMutable_throw();
590  impl_checkKey_throw( _key );
591  impl_checkValue_throw( _value );
592 
593  Any previousValue;
594 
595  KeyedValues::iterator pos = m_aData.m_pValues->find( _key );
596  if ( pos != m_aData.m_pValues->end() )
597  {
598  previousValue = pos->second;
599  pos->second = _value;
600  }
601  else
602  {
603  (*m_aData.m_pValues)[ _key ] = _value;
604  }
605 
607 
608  return previousValue;
609  }
610 
611 
612  Any SAL_CALL EnumerableMap::remove( const Any& _key )
613  {
614  ComponentMethodGuard aGuard( *this );
615  impl_checkMutable_throw();
616  impl_checkKey_throw( _key );
617 
618  Any previousValue;
619 
620  KeyedValues::iterator pos = m_aData.m_pValues->find( _key );
621  if ( pos != m_aData.m_pValues->end() )
622  {
623  previousValue = pos->second;
624  m_aData.m_pValues->erase( pos );
625  }
626 
628 
629  return previousValue;
630  }
631 
632 
633  Type SAL_CALL EnumerableMap::getElementType()
634  {
635  return ::cppu::UnoType< Pair< Any, Any > >::get();
636  }
637 
638 
639  sal_Bool SAL_CALL EnumerableMap::hasElements()
640  {
641  ComponentMethodGuard aGuard( *this );
642  return m_aData.m_pValues->empty();
643  }
644 
645 
646  OUString SAL_CALL EnumerableMap::getImplementationName( )
647  {
648  return getImplementationName_static();
649  }
650 
651  sal_Bool SAL_CALL EnumerableMap::supportsService( const OUString& _serviceName )
652  {
653  return cppu::supportsService(this, _serviceName);
654  }
655 
656 
657  Sequence< OUString > SAL_CALL EnumerableMap::getSupportedServiceNames( )
658  {
659  return getSupportedServiceNames_static();
660  }
661 
662 
663  OUString EnumerableMap::getImplementationName_static( )
664  {
665  return "org.openoffice.comp.comphelper.EnumerableMap";
666  }
667 
668 
669  Sequence< OUString > EnumerableMap::getSupportedServiceNames_static( )
670  {
671  Sequence< OUString > aServiceNames { "com.sun.star.container.EnumerableMap" };
672  return aServiceNames;
673  }
674 
675 
676  Reference< XInterface > EnumerableMap::Create( SAL_UNUSED_PARAMETER const Reference< XComponentContext >& )
677  {
678  return *new EnumerableMap;
679  }
680 
681 
682  bool MapEnumerator::hasMoreElements()
683  {
684  if ( m_disposed )
685  throw DisposedException( OUString(), m_rParent );
686  return m_mapPos != m_rMapData.m_pValues->end();
687  }
688 
689 
690  Any MapEnumerator::nextElement()
691  {
692  if ( m_disposed )
693  throw DisposedException( OUString(), m_rParent );
694  if ( m_mapPos == m_rMapData.m_pValues->end() )
695  throw NoSuchElementException("No more elements.", m_rParent );
696 
697  Any aNextElement;
698  switch ( m_eType )
699  {
700  case eKeys: aNextElement = m_mapPos->first; break;
701  case eValues: aNextElement = m_mapPos->second; break;
702  case eBoth: aNextElement <<= Pair< Any, Any >( m_mapPos->first, m_mapPos->second ); break;
703  }
704  ++m_mapPos;
705  return aNextElement;
706  }
707 
708 
709  void MapEnumerator::mapModified()
710  {
711  m_disposed = true;
712  }
713 
714 
715  sal_Bool SAL_CALL MapEnumeration::hasMoreElements( )
716  {
717  ComponentMethodGuard aGuard( *this );
718  return m_aEnumerator.hasMoreElements();
719  }
720 
721 
722  Any SAL_CALL MapEnumeration::nextElement( )
723  {
724  ComponentMethodGuard aGuard( *this );
725  return m_aEnumerator.nextElement();
726  }
727 
728 
729 } // namespace comphelper
730 
731 
733 {
735 }
736 
737 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Type
std::unique_ptr< KeyedValues > m_pValues
std::unique_ptr< MapData > m_pMapDataCopy
::osl::Mutex m_aMutex
void Create(SwFormatVertOrient &rItem, SvStream &rStrm, sal_uInt16 nVersionAbusedAsSize)
OUStringBuffer & remove(OUStringBuffer &rIn, sal_Unicode c)
Removes all occurrences of a character from within the source string.
Definition: string.hxx:60
std::shared_ptr< IKeyPredicateLess > m_pKeyCompare
OUString getImplementationName()
Sequence< OUString > aServiceNames
std::map< Any, Any, LessPredicateAdapter > KeyedValues
static void lcl_notifyMapDataListeners_nothrow(const MapData &_mapData)
Sequence< PropertyValue > aArguments
enumrange< T >::Iterator begin(enumrange< T >)
size_t pos
MapData m_aData
MapEnumerator m_aEnumerator
sal_Int16 const nValue
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
KeyedValues::const_iterator m_mapPos
sal_Bool SAL_CALL typelib_typedescription_equals(const typelib_TypeDescription *p1, const typelib_TypeDescription *p2) SAL_THROW_EXTERN_C()
::cppu::OWeakObject & m_rParent
::cppu::WeakImplHelper< XEnumeration > MapEnumeration_Base
css::uno::Sequence< OUString > getSupportedServiceNames()
MapData & m_rMapData
unsigned char sal_Bool
::cppu::WeakAggComponentImplHelper3< XInitialization, XEnumerableMap, XServiceInfo > Map_IFace
void createRegistryInfo_Map()
bool m_disposed
Type m_aValueType
bool m_bMutable
Reference< XInterface > m_xKeepMapAlive
std::vector< MapEnumerator * > m_aModListeners
Any value
std::unique_ptr< IKeyPredicateLess > getStandardLessPredicate(Type const &i_type, Reference< XCollator > const &i_collator)
Definition: anycompare.cxx:165
Type m_aKeyType
const EnumerationType m_eType
void dispose()
static void lcl_revokeMapModificationListener(MapData &_mapData, MapEnumerator &_listener)
static void lcl_registerMapModificationListener(MapData &_mapData, MapEnumerator &_listener)
OUString anyToString(uno::Any const &value)
::osl::Mutex & getMutex()