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
= false);
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 /** contrcuct a sequence iterator from a sequence
145 OSequenceIterator(const ::com::sun::star::uno::Sequence
< TYPE
>& _rSeq
);
146 /** contrcuct a sequence iterator from a Any containing a sequence
148 OSequenceIterator(const ::com::sun::star::uno::Any
& _rSequenceAny
);
150 bool hasMoreElements() const;
151 ::com::sun::star::uno::Any
nextElement();
154 inline void construct(const ::com::sun::star::uno::Sequence
< TYPE
>& _rSeq
);
158 template <class TYPE
>
159 inline OSequenceIterator
<TYPE
>::OSequenceIterator(const ::com::sun::star::uno::Sequence
< TYPE
>& _rSeq
)
168 template <class TYPE
>
169 inline OSequenceIterator
<TYPE
>::OSequenceIterator(const ::com::sun::star::uno::Any
& _rSequenceAny
)
174 ::com::sun::star::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 ::com::sun::star::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 ::com::sun::star::uno::Any OSequenceIterator
<TYPE
>::nextElement()
201 return ::com::sun::star::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 ::com::sun::star::uno::Sequence
< DstType
> arrayToSequence( const SrcType
* i_pArray
, sal_Int32 nNum
)
228 ::com::sun::star::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 ::com::sun::star::uno::Sequence
< SrcType
>& i_Sequence
)
259 ::std::copy( i_Sequence
.getConstArray(), i_Sequence
.getConstArray()+i_Sequence
.getLength(), 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 ::com::sun::star::uno::Sequence
< DstType
> containerToSequence( const SrcType
& i_Container
)
289 ::com::sun::star::uno::Sequence
< DstType
> result( i_Container
.size() );
290 ::std::copy( i_Container
.begin(), i_Container
.end(), result
.getArray() );
294 template <typename T
>
295 inline ::com::sun::star::uno::Sequence
<T
> containerToSequence(
296 ::std::vector
<T
> const& v
)
298 return ::com::sun::star::uno::Sequence
<T
>(
299 v
.data(), static_cast<sal_Int32
>(v
.size()) );
303 /** Copy from a Sequence into a container
306 Sequence element type. Must be assignable to SrcType's
310 Container type. This type must fulfill the STL container and
311 sequence concepts, in particular, the begin(), end() and the
312 unary constructor DstType(int) methods must be available and
313 have the usual semantics.
316 Reference to a Sequence of SrcType elements
318 @return the generated container
320 @attention this function always performs a copy. Furthermore,
321 when copying from e.g. a Sequence<double> to a vector<int>, no
322 proper rounding will be performed, but the values will be
323 truncated. There's currently no measure to prevent or detect
324 precision loss, overflow or truncation.
326 template < typename DstType
, typename SrcType
>
327 inline DstType
sequenceToContainer( const ::com::sun::star::uno::Sequence
< SrcType
>& i_Sequence
)
329 DstType
result( i_Sequence
.getLength() );
330 ::std::copy( i_Sequence
.getConstArray(), i_Sequence
.getConstArray()+i_Sequence
.getLength(), result
.begin() );
334 /** Copy from a Sequence into an existing container
336 This potentially saves a needless extra copy operation over
337 the whole container, as it passes the target object by
341 Sequence element type. Must be assignable to SrcType's
345 Container type. This type must fulfill the STL container and
346 sequence concepts, in particular, the begin(), end() and
347 resize(int) methods must be available and have the usual
351 Reference to the target container
354 Reference to a Sequence of SrcType elements
356 @return a non-const reference to the given container
358 @attention this function always performs a copy. Furthermore,
359 when copying from e.g. a Sequence<double> to a vector<int>, no
360 proper rounding will be performed, but the values will be
361 truncated. There's currently no measure to prevent or detect
362 precision loss, overflow or truncation.
364 template < typename DstType
, typename SrcType
>
365 inline DstType
& sequenceToContainer( DstType
& o_Output
, const ::com::sun::star::uno::Sequence
< SrcType
>& i_Sequence
)
367 o_Output
.resize( i_Sequence
.getLength() );
368 ::std::copy( i_Sequence
.getConstArray(), i_Sequence
.getConstArray()+i_Sequence
.getLength(), o_Output
.begin() );
373 } // namespace comphelper
377 #endif // INCLUDED_COMPHELPER_SEQUENCE_HXX
379 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */