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
24
25#include <com/sun/star/container/XEnumerableMap.hpp>
26#include <com/sun/star/lang/NoSupportException.hpp>
27#include <com/sun/star/lang/XInitialization.hpp>
28#include <com/sun/star/ucb/AlreadyInitializedException.hpp>
29#include <com/sun/star/beans/IllegalTypeException.hpp>
30#include <com/sun/star/beans/Pair.hpp>
31#include <com/sun/star/lang/XServiceInfo.hpp>
32#include <com/sun/star/uno/XComponentContext.hpp>
33
37#include <typelib/typedescription.hxx>
38
39#include <cmath>
40#include <map>
41#include <memory>
42#include <optional>
43#include <utility>
44
45namespace 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::optional< KeyedValues > m_pValues;
94 std::shared_ptr< IKeyPredicateLess > m_pKeyCompare;
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_pKeyCompare( _source.m_pKeyCompare )
107 ,m_bMutable( false )
108 {
109 m_pValues.emplace( *_source.m_pValues );
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
297 Reference< XInterface > m_xKeepMapAlive;
298 std::unique_ptr< MapData > m_pMapDataCopy;
299 MapEnumerator m_aEnumerator;
300 };
301
302 }
303
304 EnumerableMap::EnumerableMap()
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("wrong number of args", static_cast<cppu::OWeakObject*>(this), 1);
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.emplace( *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
706extern "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: */
Any value
::cppu::OWeakObject & m_rParent
MapData m_aData
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * org_openoffice_comp_comphelper_EnumerableMap(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
std::unique_ptr< MapData > m_pMapDataCopy
std::optional< KeyedValues > m_pValues
bool m_disposed
Type m_aKeyType
MapData & m_rMapData
Reference< XInterface > m_xKeepMapAlive
std::vector< MapEnumerator * > m_aModListeners
KeyedValues::const_iterator m_mapPos
::osl::Mutex m_aMutex
MapEnumerator m_aEnumerator
const EnumerationType m_eType
std::shared_ptr< IKeyPredicateLess > m_pKeyCompare
bool m_bMutable
Type m_aValueType
sal_Int16 nValue
Sequence< PropertyValue > aArguments
OUStringBuffer & remove(OUStringBuffer &rIn, sal_Unicode c)
Removes all occurrences of a character from within the source string.
Definition: string.hxx:49
OUString anyToString(uno::Any const &value)
::cppu::WeakImplHelper< XEnumeration > MapEnumeration_Base
std::map< Any, Any, LessPredicateAdapter > KeyedValues
std::unique_ptr< IKeyPredicateLess > getStandardLessPredicate(Type const &i_type, Reference< XCollator > const &i_collator)
Definition: anycompare.cxx:378
static void lcl_notifyMapDataListeners_nothrow(const MapData &_mapData)
static void lcl_revokeMapModificationListener(MapData &_mapData, MapEnumerator &_listener)
static void lcl_registerMapModificationListener(MapData &_mapData, MapEnumerator &_listener)
::cppu::WeakAggComponentImplHelper3< XInitialization, XEnumerableMap, XServiceInfo > Map_IFace
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
Type
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
::osl::Mutex & getMutex()
enumrange< T >::Iterator begin(enumrange< T >)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
void dispose()
static PropertyMapEntry const * find(const rtl::Reference< PropertySetInfo > &mxInfo, const OUString &aName) noexcept
sal_Bool SAL_CALL typelib_typedescription_equals(const typelib_TypeDescription *p1, const typelib_TypeDescription *p2) SAL_THROW_EXTERN_C()
unsigned char sal_Bool
size_t pos