android: Update app-specific/MIME type icons
[LibreOffice.git] / include / comphelper / sequence.hxx
blobbc67559dfbeeed1597b40697499ff9c388dea59a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
26 #include <algorithm>
27 #include <vector>
29 namespace comphelper
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)
41 return i;
44 return -1;
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)));
55 return aReturn;
58 /// concat additional elements from right sequence to left sequence
59 ///
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);
69 sal_Int32 n2 = n1;
70 for (sal_Int32 i = 0; i != right.getLength(); ++i) {
71 bool found = false;
72 for (sal_Int32 j = 0; j != n1; ++j) {
73 if (right[i] == left[j]) {
74 found = true;
75 break;
78 if (!found) {
79 pRet[n2++] = right[i];
82 ret.realloc(n2);
83 return ret;
86 /// remove a specified element from a sequences
87 template<class T>
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.
102 @tpl SrcType
103 Array element type. Must be assignable to DstType
105 @tpl DstType
106 Sequence element type. Must be assignable from SrcType
108 @param i_pArray
109 Valid pointer to at least num elements of type SrcType
111 @param nNum
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 );
128 else
130 css::uno::Sequence< DstType > result( nNum );
131 ::std::copy( i_pArray, i_pArray+nNum, result.getArray() );
132 return result;
137 /** Copy from a Sequence into a plain C/C++ array
139 @tpl SrcType
140 Sequence element type. Must be assignable to DstType
142 @tpl DstType
143 Array element type. Must be assignable from SrcType
145 @param io_pArray
146 Valid pointer to at least i_Sequence.getLength() elements of
147 type DstType
149 @param i_Sequence
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 );
163 return io_pArray;
167 /** Copy from a container into a Sequence
169 @tpl SrcType
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.
174 @tpl DstType
175 Sequence element type. Must be assignable from SrcType's
176 elements
178 @param i_Container
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() );
195 return result;
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);
205 // handle arrays
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
223 @tpl SrcType
224 Sequence element type. Must be assignable to SrcType's
225 elements
227 @tpl DstType
228 Container type. This type must have a constructor taking a pair
229 of iterators defining a range to copy from
231 @param i_Sequence
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
259 reference.
261 @tpl SrcType
262 Sequence element type. Must be assignable to SrcType's
263 elements
265 @tpl DstType
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
269 semantics.
271 @param o_Output
272 Reference to the target container
274 @param i_Sequence
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() );
290 return o_Output;
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; });
305 return ret;
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; });
314 return ret;
317 } // namespace comphelper
320 #endif // INCLUDED_COMPHELPER_SEQUENCE_HXX
322 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */