1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_COMPHELPER_SEQUENCEASHASHMAP_HXX
21 #define INCLUDED_COMPHELPER_SEQUENCEASHASHMAP_HXX
23 #include <unordered_map>
24 #include <com/sun/star/uno/Sequence.hxx>
26 #include <comphelper/comphelperdllapi.h>
28 namespace com::sun::star::beans
{ struct NamedValue
; }
29 namespace com::sun::star::beans
{ struct PropertyValue
; }
34 /** @short Implements a stl hash map on top of some
35 specialized sequence from type PropertyValue
38 @descr That provides the possibility to modify
39 such name sequences very easy ...
42 /** Cache the hash code since calculating it for every comparison adds up */
43 struct OUStringAndHashCode
48 OUStringAndHashCode(OUString s
) : maString(std::move(s
)), mnHashCode(maString
.hashCode()) {}
50 struct OUStringAndHashCodeEqual
52 bool operator()(const OUStringAndHashCode
& lhs
, const OUStringAndHashCode
& rhs
) const
54 return lhs
.mnHashCode
== rhs
.mnHashCode
&& lhs
.maString
== rhs
.maString
;
57 struct OUStringAndHashCodeHash
59 size_t operator()(const OUStringAndHashCode
& i
) const
64 using SequenceAsHashMapBase
= std::unordered_map
<OUStringAndHashCode
, css::uno::Any
, OUStringAndHashCodeHash
, OUStringAndHashCodeEqual
>;
66 class SAL_WARN_UNUSED COMPHELPER_DLLPUBLIC SequenceAsHashMap
72 /** @short creates an empty hash map.
77 /** @see operator<<(const css::uno::Any&)
79 SequenceAsHashMap(const css::uno::Any
& aSource
);
82 /** @see operator<<(const css::uno::Sequence< css::uno::Any >&)
84 SequenceAsHashMap(const css::uno::Sequence
< css::uno::Any
>& lSource
);
87 /** @see operator<<(const css::uno::Sequence< css::beans::PropertyValue >&)
89 SequenceAsHashMap(const css::uno::Sequence
< css::beans::PropertyValue
>& lSource
);
92 /** @see operator<<(const css::uno::Sequence< css::beans::NamedValue >&)
94 SequenceAsHashMap(const css::uno::Sequence
< css::beans::NamedValue
>& lSource
);
97 /** @short fill this map from the given
98 Any, which of course must contain
99 a suitable sequence of element types
100 "css.beans.PropertyValue" or "css.beans.NamedValue".
102 @attention If the given Any is an empty one
103 (if it's set to VOID), no exception
104 is thrown. In such case this instance will
105 be created as an empty one too!
108 contains the new items for this map.
110 @throw A css::lang::IllegalArgumentException
111 is thrown, if the given Any does not contain a suitable sequence ...
112 but not if it's a VOID Any!
114 void operator<<(const css::uno::Any
& aSource
);
117 /** @short fill this map from the given
118 sequence, where every Any must contain
119 an item from type "css.beans.PropertyValue"
120 "css.beans.NamedValue".
123 contains the new items for this map.
125 @throw A css::lang::IllegalArgumentException
126 is thrown, if the given Any sequence
127 uses wrong types for its items. VOID Any will be ignored!
129 void operator<<(const css::uno::Sequence
< css::uno::Any
>& lSource
);
132 /** @short fill this map from the given
133 PropertyValue sequence.
136 contains the new items for this map.
138 void operator<<(const css::uno::Sequence
< css::beans::PropertyValue
>& lSource
);
141 /** @short fill this map from the given
145 contains the new items for this map.
147 void operator<<(const css::uno::Sequence
< css::beans::NamedValue
>& lSource
);
150 /** @short converts this map instance to an
151 PropertyValue sequence.
154 target sequence for converting.
156 void operator>>(css::uno::Sequence
< css::beans::PropertyValue
>& lDestination
) const;
159 /** @short converts this map instance to an
163 target sequence for converting.
165 void operator>>(css::uno::Sequence
< css::beans::NamedValue
>& lDestination
) const;
168 /** @short return this map instance as an
170 used in const environments only.
172 @descr It's made const to prevent using of the
173 return value directly as an in/out parameter!
174 usage: myMethod(stlDequeAdapter.getAsAnyList());
176 @param bAsPropertyValue
177 switch between using of PropertyValue or NamedValue as
180 @return A const Any, which
181 contains all items of this map.
183 css::uno::Any
getAsConstAny(bool bAsPropertyValue
) const;
186 /** @short return this map instance to as a
187 NamedValue sequence, which can be
188 used in const environments only.
190 @descr It's made const to prevent using of the
191 return value directly as an in/out parameter!
192 usage: myMethod(stlDequeAdapter.getAsNamedValueList());
194 @return A const sequence of type NamedValue, which
195 contains all items of this map.
197 css::uno::Sequence
< css::beans::NamedValue
> getAsConstNamedValueList() const;
200 /** @short return this map instance to as a
201 PropertyValue sequence, which can be
202 used in const environments only.
204 @descr It's made const to prevent using of the
205 return value directly as an in/out parameter!
206 usage: myMethod(stlDequeAdapter.getAsPropertyValueList());
208 @return A const sequence of type PropertyValue, which
209 contains all items of this map.
211 css::uno::Sequence
< css::beans::PropertyValue
> getAsConstPropertyValueList() const;
214 /** @short check if the specified item exists
215 and return its (unpacked!) value or it returns the
216 specified default value otherwise.
218 @descr If a value should be extracted only in case
219 the requested property exists really (without creating
220 of new items as it the index operator of a
221 hash map does!) this method can be used.
224 key name of the item.
227 the default value, which is returned
228 if the specified item could not
231 @return The (unpacked!) value of the specified property or
232 the given default value otherwise.
234 @attention "unpacked" means the Any content of every iterator->second!
236 template< class TValueType
>
237 TValueType
getUnpackedValueOrDefault(const OUString
& sKey
,
238 const TValueType
& aDefault
) const
240 auto pIt
= m_aMap
.find(sKey
);
241 if (pIt
== m_aMap
.end())
244 TValueType aValue
= TValueType();
245 if (!(pIt
->second
>>= aValue
))
251 /** @short check if the specified item exists
252 and return its value or it returns
253 an empty css::uno::Any.
255 @descr If a value should be extracted only in case
256 the requested property exists really (without creating
257 of new items as the index operator of a
258 hash map does!) this method can be used.
261 key name of the item.
263 @return The value of the specified property or
264 an empty css::uno::Any.
266 css::uno::Any
getValue(const OUString
& sKey
) const
268 auto pIt
= m_aMap
.find(sKey
);
269 if (pIt
== m_aMap
.end())
270 return css::uno::Any();
276 /** @short creates a new item with the specified
277 name and value only in case such item name
278 does not already exist.
280 @descr To check if the property already exists only
281 its name is used for compare. Its value isn't
285 key name of the property.
288 the new (unpacked!) value.
289 Note: This value will be transformed to an Any
290 internally, because only Any values can be
291 part of a PropertyValue or NamedValue structure.
293 @return TRUE if this property was added as new item;
294 FALSE if it already exists.
296 template< class TValueType
>
297 bool createItemIfMissing(const OUString
& sKey
,
298 const TValueType
& aValue
)
300 if (!m_aMap
.contains(sKey
))
302 (*this)[sKey
] = css::uno::toAny(aValue
);
310 /** @short check if all items of given map
311 exists in these called map also.
313 @descr Every item of the given map must exists
314 with same name and value inside these map.
315 But these map can contain additional items
316 which are not part of the search-map.
319 the map containing all items for checking.
322 TRUE if all items of Rcheck could be found
323 in these map; FALSE otherwise.
325 bool match(const SequenceAsHashMap
& rCheck
) const;
328 /** @short merge all values from the given map into
331 @descr Existing items will be overwritten ...
332 missing items will be created new ...
333 but non specified items will stay alive !
336 the map containing all items for the update.
338 void update(const SequenceAsHashMap
& rSource
);
340 css::uno::Any
& operator[](const OUString
& rKey
)
345 css::uno::Any
& operator[](const OUStringAndHashCode
& rKey
)
350 using iterator
= SequenceAsHashMapBase::iterator
;
351 using const_iterator
= SequenceAsHashMapBase::const_iterator
;
360 return m_aMap
.size();
365 return m_aMap
.empty();
370 return m_aMap
.begin();
373 const_iterator
begin() const
375 return m_aMap
.begin();
383 const_iterator
end() const
388 iterator
find(const OUString
& rKey
)
390 return m_aMap
.find(rKey
);
393 const_iterator
find(const OUString
& rKey
) const
395 return m_aMap
.find(rKey
);
398 iterator
find(const OUStringAndHashCode
& rKey
)
400 return m_aMap
.find(rKey
);
403 const_iterator
find(const OUStringAndHashCode
& rKey
) const
405 return m_aMap
.find(rKey
);
408 bool contains(const OUString
& rKey
) const
410 return m_aMap
.contains(rKey
);
413 iterator
erase(iterator it
)
415 return m_aMap
.erase(it
);
418 size_t erase(const OUString
& rKey
)
420 return m_aMap
.erase(rKey
);
424 SequenceAsHashMapBase m_aMap
;
427 } // namespace comphelper
429 #endif // INCLUDED_COMPHELPER_SEQUENCEASHASHMAP_HXX
431 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */