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_SEQUENCE_HXX
21 #define INCLUDED_COMPHELPER_SEQUENCE_HXX
24 #include <com/sun/star/uno/Sequence.hxx>
25 #include <osl/diagnose.h>
26 #include <comphelper/comphelperdllapi.h>
32 /** search the given string within the given sequence, return the positions where it was found.
33 if _bOnlyFirst is sal_True, only the first occurrence will be returned.
35 COMPHELPER_DLLPUBLIC
css::uno::Sequence
<sal_Int16
> findValue(const css::uno::Sequence
< OUString
>& _rList
, const OUString
& _rValue
, bool _bOnlyFirst
);
40 inline void implCopySequence(const T
* _pSource
, T
*& _pDest
, sal_Int32 _nSourceLen
)
42 for (sal_Int32 i
=0; i
<_nSourceLen
; ++i
, ++_pSource
, ++_pDest
)
47 /// concat two sequences
49 inline css::uno::Sequence
<T
> concatSequences(const css::uno::Sequence
<T
>& _rLeft
, const css::uno::Sequence
<T
>& _rRight
)
51 sal_Int32
nLeft(_rLeft
.getLength()), nRight(_rRight
.getLength());
52 const T
* pLeft
= _rLeft
.getConstArray();
53 const T
* pRight
= _rRight
.getConstArray();
55 sal_Int32
nReturnLen(nLeft
+ nRight
);
56 css::uno::Sequence
<T
> aReturn(nReturnLen
);
57 T
* pReturn
= aReturn
.getArray();
59 internal::implCopySequence(pLeft
, pReturn
, nLeft
);
60 internal::implCopySequence(pRight
, pReturn
, nRight
);
65 /// concat additional elements from right sequence to left sequence
67 /// be aware that this takes time O(|left| * |right|)
68 template<typename T
> inline css::uno::Sequence
<T
> combineSequences(
69 css::uno::Sequence
<T
> const & left
, css::uno::Sequence
<T
> const & right
)
71 sal_Int32 n1
= left
.getLength();
72 css::uno::Sequence
<T
> ret(n1
+ right
.getLength());
73 //TODO: check for overflow
74 T
* p
= ret
.getArray();
75 internal::implCopySequence(left
.getConstArray(), p
, n1
);
77 for (sal_Int32 i
= 0; i
!= right
.getLength(); ++i
) {
79 for (sal_Int32 j
= 0; j
!= n1
; ++j
) {
80 if (right
[i
] == left
[j
]) {
93 /// concat three sequences
95 inline css::uno::Sequence
<T
> concatSequences(const css::uno::Sequence
<T
>& _rLeft
, const css::uno::Sequence
<T
>& _rMiddle
, const css::uno::Sequence
<T
>& _rRight
)
97 sal_Int32
nLeft(_rLeft
.getLength()), nMiddle(_rMiddle
.getLength()), nRight(_rRight
.getLength());
98 const T
* pLeft
= _rLeft
.getConstArray();
99 const T
* pMiddle
= _rMiddle
.getConstArray();
100 const T
* pRight
= _rRight
.getConstArray();
102 sal_Int32
nReturnLen(nLeft
+ nMiddle
+ nRight
);
103 css::uno::Sequence
<T
> aReturn(nReturnLen
);
104 T
* pReturn
= aReturn
.getArray();
106 internal::implCopySequence(pLeft
, pReturn
, nLeft
);
107 internal::implCopySequence(pMiddle
, pReturn
, nMiddle
);
108 internal::implCopySequence(pRight
, pReturn
, nRight
);
114 /// remove a specified element from a sequences
116 inline void removeElementAt(css::uno::Sequence
<T
>& _rSeq
, sal_Int32 _nPos
)
118 sal_Int32 nLength
= _rSeq
.getLength();
120 OSL_ENSURE(0 <= _nPos
&& _nPos
< nLength
, "invalid index");
122 for (sal_Int32 i
= _nPos
+ 1; i
< nLength
; ++i
)
124 _rSeq
[i
-1] = _rSeq
[i
];
127 _rSeq
.realloc(nLength
-1);
131 //= iterating through sequences
133 /** a helper class for iterating through a sequence
135 template <class TYPE
>
136 class OSequenceIterator
138 const TYPE
* m_pElements
;
140 const TYPE
* m_pCurrent
;
143 /** construct a sequence iterator from a sequence
145 OSequenceIterator(const css::uno::Sequence
< TYPE
>& _rSeq
);
146 /** construct a sequence iterator from a Any containing a sequence
148 OSequenceIterator(const css::uno::Any
& _rSequenceAny
);
150 bool hasMoreElements() const;
151 css::uno::Any
nextElement();
154 inline void construct(const css::uno::Sequence
< TYPE
>& _rSeq
);
158 template <class TYPE
>
159 inline OSequenceIterator
<TYPE
>::OSequenceIterator(const css::uno::Sequence
< TYPE
>& _rSeq
)
160 :m_pElements(nullptr)
168 template <class TYPE
>
169 inline OSequenceIterator
<TYPE
>::OSequenceIterator(const css::uno::Any
& _rSequenceAny
)
170 :m_pElements(nullptr)
174 css::uno::Sequence
< TYPE
> aContainer
;
175 bool bSuccess
= _rSequenceAny
>>= aContainer
;
176 OSL_ENSURE(bSuccess
, "OSequenceIterator::OSequenceIterator: invalid Any!");
178 construct(aContainer
);
182 template <class TYPE
>
183 void OSequenceIterator
<TYPE
>::construct(const css::uno::Sequence
< TYPE
>& _rSeq
)
185 m_pElements
= _rSeq
.getConstArray();
186 m_nLen
= _rSeq
.getLength();
187 m_pCurrent
= m_pElements
;
191 template <class TYPE
>
192 inline bool OSequenceIterator
<TYPE
>::hasMoreElements() const
194 return m_pCurrent
- m_pElements
< m_nLen
;
198 template <class TYPE
>
199 inline css::uno::Any OSequenceIterator
<TYPE
>::nextElement()
201 return css::uno::toAny(*m_pCurrent
++);
204 /** Copy from a plain C/C++ array into a Sequence.
207 Array element type. Must be assignable to DstType
210 Sequence element type. Must be assignable from SrcType
213 Valid pointer to at least num elements of type SrcType
216 Number of array elements to copy
218 @return the resulting Sequence
220 @attention when copying from e.g. a double array to a
221 Sequence<int>, no proper rounding will be performed, but the
222 values will be truncated. There's currently no measure to
223 prevent or detect precision loss, overflow or truncation.
225 template < typename DstType
, typename SrcType
>
226 inline css::uno::Sequence
< DstType
> arrayToSequence( const SrcType
* i_pArray
, sal_Int32 nNum
)
228 css::uno::Sequence
< DstType
> result( nNum
);
229 ::std::copy( i_pArray
, i_pArray
+nNum
, result
.getArray() );
234 /** Copy from a Sequence into a plain C/C++ array
237 Sequence element type. Must be assignable to DstType
240 Array element type. Must be assignable from SrcType
243 Valid pointer to at least i_Sequence.getLength() elements of
247 Reference to a Sequence of SrcType elements
249 @return a pointer to the array
251 @attention when copying from e.g. a Sequence<double> to an int
252 array, no proper rounding will be performed, but the values
253 will be truncated. There's currently no measure to prevent or
254 detect precision loss, overflow or truncation.
256 template < typename DstType
, typename SrcType
>
257 inline DstType
* sequenceToArray( DstType
* io_pArray
, const css::uno::Sequence
< SrcType
>& i_Sequence
)
259 ::std::copy( i_Sequence
.begin(), i_Sequence
.end(), io_pArray
);
264 /** Copy from a container into a Sequence
267 Container type. This type must fulfill the STL container
268 concept, in particular, the size(), begin() and end() methods
269 must be available and have the usual semantics.
272 Sequence element type. Must be assignable from SrcType's
276 Reference to the input contain with elements of type SrcType
278 @return the generated Sequence
280 @attention this function always performs a copy. Furthermore,
281 when copying from e.g. a vector<double> to a Sequence<int>, no
282 proper rounding will be performed, but the values will be
283 truncated. There's currently no measure to prevent or detect
284 precision loss, overflow or truncation.
286 template < typename DstType
, typename SrcType
>
287 inline css::uno::Sequence
< DstType
> containerToSequence( const SrcType
& i_Container
)
289 css::uno::Sequence
< DstType
> result( i_Container
.size() );
290 ::std::copy( i_Container
.begin(), i_Container
.end(), result
.getArray() );
294 // this one does better type deduction, but does not allow us to copy into a different element type
295 template < typename SrcType
>
296 inline css::uno::Sequence
< typename
SrcType::value_type
> containerToSequence( const SrcType
& i_Container
)
298 css::uno::Sequence
< typename
SrcType::value_type
> result( i_Container
.size() );
299 ::std::copy( i_Container
.begin(), i_Container
.end(), result
.getArray() );
303 template <typename T
>
304 inline css::uno::Sequence
<T
> containerToSequence(
305 ::std::vector
<T
> const& v
)
307 return css::uno::Sequence
<T
>(
308 v
.data(), static_cast<sal_Int32
>(v
.size()) );
312 /** Copy from a Sequence into a container
315 Sequence element type. Must be assignable to SrcType's
319 Container type. This type must fulfill the STL container and
320 sequence concepts, in particular, the begin(), end() and the
321 unary constructor DstType(int) methods must be available and
322 have the usual semantics.
325 Reference to a Sequence of SrcType elements
327 @return the generated container
329 @attention this function always performs a copy. Furthermore,
330 when copying from e.g. a Sequence<double> to a vector<int>, no
331 proper rounding will be performed, but the values will be
332 truncated. There's currently no measure to prevent or detect
333 precision loss, overflow or truncation.
335 template < typename DstType
, typename SrcType
>
336 inline DstType
sequenceToContainer( const css::uno::Sequence
< SrcType
>& i_Sequence
)
338 DstType
result( i_Sequence
.getLength() );
339 ::std::copy( i_Sequence
.begin(), i_Sequence
.end(), result
.begin() );
343 // this one does better type deduction, but does not allow us to copy into a different element type
344 template < typename DstType
>
345 inline DstType
sequenceToContainer( const css::uno::Sequence
< typename
DstType::value_type
>& i_Sequence
)
347 DstType
result( i_Sequence
.getLength() );
348 ::std::copy( i_Sequence
.begin(), i_Sequence
.end(), result
.begin() );
352 /** Copy from a Sequence into an existing container
354 This potentially saves a needless extra copy operation over
355 the whole container, as it passes the target object by
359 Sequence element type. Must be assignable to SrcType's
363 Container type. This type must fulfill the STL container and
364 sequence concepts, in particular, the begin(), end() and
365 resize(int) methods must be available and have the usual
369 Reference to the target container
372 Reference to a Sequence of SrcType elements
374 @return a non-const reference to the given container
376 @attention this function always performs a copy. Furthermore,
377 when copying from e.g. a Sequence<double> to a vector<int>, no
378 proper rounding will be performed, but the values will be
379 truncated. There's currently no measure to prevent or detect
380 precision loss, overflow or truncation.
382 template < typename DstType
, typename SrcType
>
383 inline DstType
& sequenceToContainer( DstType
& o_Output
, const css::uno::Sequence
< SrcType
>& i_Sequence
)
385 o_Output
.resize( i_Sequence
.getLength() );
386 ::std::copy( i_Sequence
.begin(), i_Sequence
.end(), o_Output
.begin() );
390 /** Copy (keys or values) from a associate container into a Sequence
392 @tpl M map container type eg. std::map/std::unordered_map
394 @return the generated Sequence
396 template < typename M
>
397 inline css::uno::Sequence
< typename
M::key_type
> mapKeysToSequence( M
const& map
)
399 css::uno::Sequence
< typename
M::key_type
> ret( static_cast<sal_Int32
>(map
.size()) );
400 typename
M::key_type
* pArray
= ret
.getArray();
401 for (const auto& i
: map
)
406 template < typename M
>
407 inline css::uno::Sequence
< typename
M::mapped_type
> mapValuesToSequence( M
const& map
)
409 css::uno::Sequence
< typename
M::mapped_type
> ret( static_cast<sal_Int32
>(map
.size()) );
410 typename
M::mapped_type
* pArray
= ret
.getArray();
411 for (const auto& i
: map
)
412 *pArray
++ = i
.second
;
416 } // namespace comphelper
419 #endif // INCLUDED_COMPHELPER_SEQUENCE_HXX
421 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */