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