build fix
[LibreOffice.git] / include / comphelper / sequence.hxx
blob68c361c6282fe6ffe96a8eb85e71f535100947e4
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 <algorithm>
24 #include <com/sun/star/uno/Sequence.hxx>
25 #include <osl/diagnose.h>
26 #include <comphelper/comphelperdllapi.h>
28 #include <vector>
30 namespace comphelper
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);
37 namespace internal
39 template <class T>
40 inline void implCopySequence(const T* _pSource, T*& _pDest, sal_Int32 _nSourceLen)
42 for (sal_Int32 i=0; i<_nSourceLen; ++i, ++_pSource, ++_pDest)
43 *_pDest = *_pSource;
47 /// concat two sequences
48 template <class T>
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);
62 return aReturn;
65 /// concat additional elements from right sequence to left sequence
66 ///
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);
76 sal_Int32 n2 = n1;
77 for (sal_Int32 i = 0; i != right.getLength(); ++i) {
78 bool found = false;
79 for (sal_Int32 j = 0; j != n1; ++j) {
80 if (right[i] == left[j]) {
81 found = true;
82 break;
85 if (!found) {
86 ret[n2++] = right[i];
89 ret.realloc(n2);
90 return ret;
93 /// concat three sequences
94 template <class T>
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);
110 return aReturn;
114 /// remove a specified element from a sequences
115 template<class T>
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;
139 sal_Int32 m_nLen;
140 const TYPE* m_pCurrent;
142 public:
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();
153 private:
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)
161 ,m_nLen(0)
162 ,m_pCurrent(nullptr)
164 construct(_rSeq);
168 template <class TYPE>
169 inline OSequenceIterator<TYPE>::OSequenceIterator(const css::uno::Any& _rSequenceAny)
170 :m_pElements(nullptr)
171 ,m_nLen(0)
172 ,m_pCurrent(nullptr)
174 css::uno::Sequence< TYPE > aContainer;
175 bool bSuccess = _rSequenceAny >>= aContainer;
176 OSL_ENSURE(bSuccess, "OSequenceIterator::OSequenceIterator: invalid Any!");
177 (void)bSuccess;
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.
206 @tpl SrcType
207 Array element type. Must be assignable to DstType
209 @tpl DstType
210 Sequence element type. Must be assignable from SrcType
212 @param i_pArray
213 Valid pointer to at least num elements of type SrcType
215 @param nNum
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() );
230 return result;
234 /** Copy from a Sequence into a plain C/C++ array
236 @tpl SrcType
237 Sequence element type. Must be assignable to DstType
239 @tpl DstType
240 Array element type. Must be assignable from SrcType
242 @param io_pArray
243 Valid pointer to at least i_Sequence.getLength() elements of
244 type DstType
246 @param i_Sequence
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 );
260 return io_pArray;
264 /** Copy from a container into a Sequence
266 @tpl SrcType
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.
271 @tpl DstType
272 Sequence element type. Must be assignable from SrcType's
273 elements
275 @param i_Container
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() );
291 return result;
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() );
300 return result;
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
314 @tpl SrcType
315 Sequence element type. Must be assignable to SrcType's
316 elements
318 @tpl DstType
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.
324 @param i_Sequence
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() );
340 return result;
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() );
349 return result;
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
356 reference.
358 @tpl SrcType
359 Sequence element type. Must be assignable to SrcType's
360 elements
362 @tpl DstType
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
366 semantics.
368 @param o_Output
369 Reference to the target container
371 @param i_Sequence
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() );
387 return o_Output;
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)
402 *pArray++ = i.first;
403 return ret;
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;
413 return ret;
416 } // namespace comphelper
419 #endif // INCLUDED_COMPHELPER_SEQUENCE_HXX
421 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */