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
23 #include <com/sun/star/uno/Sequence.hxx>
24 #include <osl/diagnose.h>
31 /** Search the given value within the given sequence, return the position of the first occurrence.
32 Returns -1 if nothing found.
34 template <class T1
, class T2
>
35 inline sal_Int32
findValue(const css::uno::Sequence
<T1
>& _rList
, const T2
& _rValue
)
37 // at which position do I find the value?
38 for (sal_Int32 i
= 0; i
< _rList
.getLength(); ++i
)
40 if (_rList
[i
] == _rValue
)
47 /// concat several sequences
48 template <class T
, class... Ss
>
49 inline css::uno::Sequence
<T
> concatSequences(const css::uno::Sequence
<T
>& rS1
, const Ss
&... rSn
)
51 // unary fold to disallow empty parameter pack: at least have one sequence in rSn
52 css::uno::Sequence
<T
> aReturn(std::size(rS1
) + (... + std::size(rSn
)));
53 T
* pReturn
= std::copy(std::begin(rS1
), std::end(rS1
), aReturn
.begin());
54 (..., (pReturn
= std::copy(std::begin(rSn
), std::end(rSn
), pReturn
)));
58 /// concat additional elements from right sequence to left sequence
60 /// be aware that this takes time O(|left| * |right|)
61 template<typename T
> inline css::uno::Sequence
<T
> combineSequences(
62 css::uno::Sequence
<T
> const & left
, css::uno::Sequence
<T
> const & right
)
64 sal_Int32 n1
= left
.getLength();
65 css::uno::Sequence
<T
> ret(n1
+ right
.getLength());
66 //TODO: check for overflow
67 std::copy_n(left
.getConstArray(), n1
, ret
.getArray());
69 for (sal_Int32 i
= 0; i
!= right
.getLength(); ++i
) {
71 for (sal_Int32 j
= 0; j
!= n1
; ++j
) {
72 if (right
[i
] == left
[j
]) {
85 /// remove a specified element from a sequences
87 inline void removeElementAt(css::uno::Sequence
<T
>& _rSeq
, sal_Int32 _nPos
)
89 sal_Int32 nLength
= _rSeq
.getLength();
91 OSL_ENSURE(0 <= _nPos
&& _nPos
< nLength
, "invalid index");
93 T
* pPos
= _rSeq
.getArray() + _nPos
;
94 std::move(pPos
+ 1, pPos
+ nLength
- _nPos
, pPos
);
96 _rSeq
.realloc(nLength
-1);
99 /** Copy from a plain C/C++ array into a Sequence.
102 Array element type. Must be assignable to DstType
105 Sequence element type. Must be assignable from SrcType
108 Valid pointer to at least num elements of type SrcType
111 Number of array elements to copy
113 @return the resulting Sequence
115 @attention when copying from e.g. a double array to a
116 Sequence<int>, no proper rounding will be performed, but the
117 values will be truncated. There's currently no measure to
118 prevent or detect precision loss, overflow or truncation.
120 template < typename DstType
, typename SrcType
>
121 inline css::uno::Sequence
< DstType
> arrayToSequence( const SrcType
* i_pArray
, sal_Int32 nNum
)
123 css::uno::Sequence
< DstType
> result( nNum
);
124 ::std::copy( i_pArray
, i_pArray
+nNum
, result
.getArray() );
129 /** Copy from a Sequence into a plain C/C++ array
132 Sequence element type. Must be assignable to DstType
135 Array element type. Must be assignable from SrcType
138 Valid pointer to at least i_Sequence.getLength() elements of
142 Reference to a Sequence of SrcType elements
144 @return a pointer to the array
146 @attention when copying from e.g. a Sequence<double> to an int
147 array, no proper rounding will be performed, but the values
148 will be truncated. There's currently no measure to prevent or
149 detect precision loss, overflow or truncation.
151 template < typename DstType
, typename SrcType
>
152 inline DstType
* sequenceToArray( DstType
* io_pArray
, const css::uno::Sequence
< SrcType
>& i_Sequence
)
154 ::std::copy( i_Sequence
.begin(), i_Sequence
.end(), io_pArray
);
159 /** Copy from a container into a Sequence
162 Container type. This type must fulfill the STL container
163 concept, in particular, the size(), begin() and end() methods
164 must be available and have the usual semantics.
167 Sequence element type. Must be assignable from SrcType's
171 Reference to the input contain with elements of type SrcType
173 @return the generated Sequence
175 @attention this function always performs a copy. Furthermore,
176 when copying from e.g. a vector<double> to a Sequence<int>, no
177 proper rounding will be performed, but the values will be
178 truncated. There's currently no measure to prevent or detect
179 precision loss, overflow or truncation.
181 template < typename DstElementType
, typename SrcType
>
182 inline css::uno::Sequence
< DstElementType
> containerToSequence( const SrcType
& i_Container
)
184 css::uno::Sequence
< DstElementType
> result( i_Container
.size() );
185 ::std::copy( i_Container
.begin(), i_Container
.end(), result
.getArray() );
189 // this one does better type deduction, but does not allow us to copy into a different element type
190 template < typename SrcType
>
191 inline css::uno::Sequence
< typename
SrcType::value_type
> containerToSequence( const SrcType
& i_Container
)
193 css::uno::Sequence
< typename
SrcType::value_type
> result( i_Container
.size() );
194 ::std::copy( i_Container
.begin(), i_Container
.end(), result
.getArray() );
199 template<typename ElementType
, std::size_t SrcSize
>
200 inline css::uno::Sequence
< ElementType
> containerToSequence( ElementType
const (&i_Array
)[ SrcSize
] )
202 return css::uno::Sequence
< ElementType
>( i_Array
, SrcSize
);
205 template <typename T
>
206 inline css::uno::Sequence
<T
> containerToSequence(
207 ::std::vector
<T
> const& v
)
209 return css::uno::Sequence
<T
>(
210 v
.data(), static_cast<sal_Int32
>(v
.size()) );
214 /** Copy from a Sequence into a container
217 Sequence element type. Must be assignable to SrcType's
221 Container type. This type must have a constructor taking a pair
222 of iterators defining a range to copy from
225 Reference to a Sequence of SrcType elements
227 @return the generated container. C++17 copy elision rules apply
229 @attention this function always performs a copy. Furthermore,
230 when copying from e.g. a Sequence<double> to a vector<int>, no
231 proper rounding will be performed, but the values will be
232 truncated. There's currently no measure to prevent or detect
233 precision loss, overflow or truncation.
235 template < typename DstType
, typename SrcType
>
236 inline DstType
sequenceToContainer( const css::uno::Sequence
< SrcType
>& i_Sequence
)
238 return DstType(i_Sequence
.begin(), i_Sequence
.end());
241 // this one does better type deduction, but does not allow us to copy into a different element type
242 template < typename DstType
>
243 inline DstType
sequenceToContainer( const css::uno::Sequence
< typename
DstType::value_type
>& i_Sequence
)
245 return DstType(i_Sequence
.begin(), i_Sequence
.end());
248 /** Copy from a Sequence into an existing container
250 This potentially saves a needless extra copy operation over
251 the whole container, as it passes the target object by
255 Sequence element type. Must be assignable to SrcType's
259 Container type. This type must fulfill the STL container and
260 sequence concepts, in particular, the begin(), end() and
261 resize(int) methods must be available and have the usual
265 Reference to the target container
268 Reference to a Sequence of SrcType elements
270 @return a non-const reference to the given container
272 @attention this function always performs a copy. Furthermore,
273 when copying from e.g. a Sequence<double> to a vector<int>, no
274 proper rounding will be performed, but the values will be
275 truncated. There's currently no measure to prevent or detect
276 precision loss, overflow or truncation.
278 template < typename DstType
, typename SrcType
>
279 inline DstType
& sequenceToContainer( DstType
& o_Output
, const css::uno::Sequence
< SrcType
>& i_Sequence
)
281 o_Output
.resize( i_Sequence
.getLength() );
282 ::std::copy( i_Sequence
.begin(), i_Sequence
.end(), o_Output
.begin() );
286 /** Copy (keys or values) from an associate container into a Sequence
288 @tpl M map container type eg. std::map/std::unordered_map
290 @return the generated Sequence
292 template < typename M
>
293 inline css::uno::Sequence
< typename
M::key_type
> mapKeysToSequence( M
const& map
)
295 css::uno::Sequence
< typename
M::key_type
> ret( static_cast<sal_Int32
>(map
.size()) );
296 typename
M::key_type
* pArray
= ret
.getArray();
297 for (const auto& i
: map
)
302 template < typename M
>
303 inline css::uno::Sequence
< typename
M::mapped_type
> mapValuesToSequence( M
const& map
)
305 css::uno::Sequence
< typename
M::mapped_type
> ret( static_cast<sal_Int32
>(map
.size()) );
306 typename
M::mapped_type
* pArray
= ret
.getArray();
307 for (const auto& i
: map
)
308 *pArray
++ = i
.second
;
312 } // namespace comphelper
315 #endif // INCLUDED_COMPHELPER_SEQUENCE_HXX
317 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */