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
.getArray());
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 auto pRet
= ret
.getArray();
68 std::copy_n(left
.getConstArray(), n1
, pRet
);
70 for (sal_Int32 i
= 0; i
!= right
.getLength(); ++i
) {
72 for (sal_Int32 j
= 0; j
!= n1
; ++j
) {
73 if (right
[i
] == left
[j
]) {
79 pRet
[n2
++] = right
[i
];
86 /// remove a specified element from a sequences
88 inline void removeElementAt(css::uno::Sequence
<T
>& _rSeq
, sal_Int32 _nPos
)
90 sal_Int32 nLength
= _rSeq
.getLength();
92 OSL_ENSURE(0 <= _nPos
&& _nPos
< nLength
, "invalid index");
94 T
* pPos
= _rSeq
.getArray() + _nPos
;
95 std::move(pPos
+ 1, pPos
+ nLength
- _nPos
, pPos
);
97 _rSeq
.realloc(nLength
-1);
100 /** Copy from a plain C/C++ array into a Sequence.
103 Array element type. Must be assignable to DstType
106 Sequence element type. Must be assignable from SrcType
109 Valid pointer to at least num elements of type SrcType
112 Number of array elements to copy
114 @return the resulting Sequence
116 @attention when copying from e.g. a double array to a
117 Sequence<int>, no proper rounding will be performed, but the
118 values will be truncated. There's currently no measure to
119 prevent or detect precision loss, overflow or truncation.
121 template < typename DstType
, typename SrcType
>
122 inline css::uno::Sequence
< DstType
> arrayToSequence( const SrcType
* i_pArray
, sal_Int32 nNum
)
124 if constexpr (std::is_same_v
< DstType
, SrcType
>)
126 return css::uno::Sequence
< DstType
>( i_pArray
, nNum
);
130 css::uno::Sequence
< DstType
> result( nNum
);
131 ::std::copy( i_pArray
, i_pArray
+nNum
, result
.getArray() );
137 /** Copy from a Sequence into a plain C/C++ array
140 Sequence element type. Must be assignable to DstType
143 Array element type. Must be assignable from SrcType
146 Valid pointer to at least i_Sequence.getLength() elements of
150 Reference to a Sequence of SrcType elements
152 @return a pointer to the array
154 @attention when copying from e.g. a Sequence<double> to an int
155 array, no proper rounding will be performed, but the values
156 will be truncated. There's currently no measure to prevent or
157 detect precision loss, overflow or truncation.
159 template < typename DstType
, typename SrcType
>
160 inline DstType
* sequenceToArray( DstType
* io_pArray
, const css::uno::Sequence
< SrcType
>& i_Sequence
)
162 ::std::copy( i_Sequence
.begin(), i_Sequence
.end(), io_pArray
);
167 /** Copy from a container into a Sequence
170 Container type. This type must fulfill the STL container
171 concept, in particular, the size(), begin() and end() methods
172 must be available and have the usual semantics.
175 Sequence element type. Must be assignable from SrcType's
179 Reference to the input contain with elements of type SrcType
181 @return the generated Sequence
183 @attention this function always performs a copy. Furthermore,
184 when copying from e.g. a vector<double> to a Sequence<int>, no
185 proper rounding will be performed, but the values will be
186 truncated. There's currently no measure to prevent or detect
187 precision loss, overflow or truncation.
189 template < typename DstElementType
, typename SrcType
>
190 inline css::uno::Sequence
< DstElementType
> containerToSequence( const SrcType
& i_Container
)
192 using ::std::size
, ::std::begin
, ::std::end
;
193 css::uno::Sequence
< DstElementType
> result( size(i_Container
) );
194 ::std::copy( begin(i_Container
), end(i_Container
), result
.getArray() );
198 // this one does better type deduction, but does not allow us to copy into a different element type
199 template < typename SrcType
>
200 inline css::uno::Sequence
< typename
SrcType::value_type
> containerToSequence( const SrcType
& i_Container
)
202 return containerToSequence
<typename
SrcType::value_type
, SrcType
>(i_Container
);
206 template<typename ElementType
, std::size_t SrcSize
>
207 inline css::uno::Sequence
< ElementType
> containerToSequence( ElementType
const (&i_Array
)[ SrcSize
] )
209 return css::uno::Sequence
< ElementType
>( i_Array
, SrcSize
);
212 template <typename T
>
213 inline css::uno::Sequence
<T
> containerToSequence(
214 ::std::vector
<T
> const& v
)
216 return css::uno::Sequence
<T
>(
217 v
.data(), static_cast<sal_Int32
>(v
.size()) );
221 /** Copy from a Sequence into a container
224 Sequence element type. Must be assignable to SrcType's
228 Container type. This type must have a constructor taking a pair
229 of iterators defining a range to copy from
232 Reference to a Sequence of SrcType elements
234 @return the generated container. C++17 copy elision rules apply
236 @attention this function always performs a copy. Furthermore,
237 when copying from e.g. a Sequence<double> to a vector<int>, no
238 proper rounding will be performed, but the values will be
239 truncated. There's currently no measure to prevent or detect
240 precision loss, overflow or truncation.
242 template < typename DstType
, typename SrcType
>
243 inline DstType
sequenceToContainer( const css::uno::Sequence
< SrcType
>& i_Sequence
)
245 return DstType(i_Sequence
.begin(), i_Sequence
.end());
248 // this one does better type deduction, but does not allow us to copy into a different element type
249 template < typename DstType
>
250 inline DstType
sequenceToContainer( const css::uno::Sequence
< typename
DstType::value_type
>& i_Sequence
)
252 return DstType(i_Sequence
.begin(), i_Sequence
.end());
255 /** Copy from a Sequence into an existing container
257 This potentially saves a needless extra copy operation over
258 the whole container, as it passes the target object by
262 Sequence element type. Must be assignable to SrcType's
266 Container type. This type must fulfill the STL container and
267 sequence concepts, in particular, the begin(), end() and
268 resize(int) methods must be available and have the usual
272 Reference to the target container
275 Reference to a Sequence of SrcType elements
277 @return a non-const reference to the given container
279 @attention this function always performs a copy. Furthermore,
280 when copying from e.g. a Sequence<double> to a vector<int>, no
281 proper rounding will be performed, but the values will be
282 truncated. There's currently no measure to prevent or detect
283 precision loss, overflow or truncation.
285 template < typename DstType
, typename SrcType
>
286 inline DstType
& sequenceToContainer( DstType
& o_Output
, const css::uno::Sequence
< SrcType
>& i_Sequence
)
288 o_Output
.resize( i_Sequence
.getLength() );
289 ::std::copy( i_Sequence
.begin(), i_Sequence
.end(), o_Output
.begin() );
293 /** Copy (keys or values) from an associate container into a Sequence
295 @tpl M map container type eg. std::map/std::unordered_map
297 @return the generated Sequence
299 template < typename M
>
300 inline css::uno::Sequence
< typename
M::key_type
> mapKeysToSequence( M
const& map
)
302 css::uno::Sequence
< typename
M::key_type
> ret( static_cast<sal_Int32
>(map
.size()) );
303 std::transform(map
.begin(), map
.end(), ret
.getArray(),
304 [](const auto& i
) { return i
.first
; });
308 template < typename M
>
309 inline css::uno::Sequence
< typename
M::mapped_type
> mapValuesToSequence( M
const& map
)
311 css::uno::Sequence
< typename
M::mapped_type
> ret( static_cast<sal_Int32
>(map
.size()) );
312 std::transform(map
.begin(), map
.end(), ret
.getArray(),
313 [](const auto& i
) { return i
.second
; });
317 } // namespace comphelper
320 #endif // INCLUDED_COMPHELPER_SEQUENCE_HXX
322 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */