office-gobmx/include/comphelper/sequence.hxx
Mike Kaganski 509b2039f7 Use braces to workaround a strange GCC bug
Using gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04):

    [CXX] ucb/source/ucp/cmis/certvalidation_handler.cxx
    In file included from /home/user/core.git/workdir/UnpackedTarball/boost/boost/lexical_cast/detail/converter_lexical_streams.hpp:62,
                     from /home/user/core.git/workdir/UnpackedTarball/boost/boost/lexical_cast/detail/converter_lexical.hpp:54,
                     from /home/user/core.git/workdir/UnpackedTarball/boost/boost/lexical_cast/try_lexical_convert.hpp:44,
                     from /home/user/core.git/workdir/UnpackedTarball/boost/boost/lexical_cast.hpp:32,
                     from /home/user/core.git/external/boost/include/boost/lexical_cast.hpp:30,
                     from /home/user/core.git/workdir/UnpackedTarball/boost/boost/date_time/format_date_parser.hpp:14,
                     from /home/user/core.git/workdir/UnpackedTarball/boost/boost/date_time/date_generator_parser.hpp:20,
                     from /home/user/core.git/workdir/UnpackedTarball/boost/boost/date_time/date_facet.hpp:25,
                     from /home/user/core.git/workdir/UnpackedTarball/boost/boost/date_time/gregorian/gregorian_io.hpp:16,
                     from /home/user/core.git/workdir/UnpackedTarball/boost/boost/date_time/gregorian/gregorian.hpp:31,
                     from /home/user/core.git/workdir/UnpackedTarball/boost/boost/date_time/posix_time/time_formatters.hpp:12,
                     from /home/user/core.git/workdir/UnpackedTarball/boost/boost/date_time/posix_time/posix_time.hpp:24,
                     from /home/user/core.git/external/boost/include/boost/date_time/posix_time/posix_time.hpp:30,
                     from /home/user/core.git/workdir/UnpackedTarball/boost/boost/date_time/local_time/local_time.hpp:11,
                     from /home/user/core.git/workdir/UnpackedTarball/boost/boost/date_time.hpp:15,
                     from /home/user/core.git/external/boost/include/boost/date_time.hpp:30,
                     from /home/user/core.git/workdir/UnpackedTarball/libcmis/inc/libcmis/object.hxx:40,
                     from /home/user/core.git/workdir/UnpackedTarball/libcmis/inc/libcmis/document.hxx:39,
                     from /home/user/core.git/workdir/UnpackedTarball/libcmis/inc/libcmis/libcmis.hxx:34,
                     from /home/user/core.git/ucb/source/ucp/cmis/certvalidation_handler.hxx:19,
                     from /home/user/core.git/ucb/source/ucp/cmis/certvalidation_handler.cxx:23:
    /home/user/core.git/workdir/UnpackedTarball/boost/boost/lexical_cast/detail/lcast_unsigned_converters.hpp: In member function ‘CharT* boost::detail::lcast_put_unsigned<Traits, T, CharT>::main_convert_loop()’:
    /home/user/core.git/workdir/UnpackedTarball/boost/boost/lexical_cast/detail/lcast_unsigned_converters.hpp:149:17: error: this ‘while’ clause does not guard... [-Werror=misleading-indentation]
      149 |             inline CharT* main_convert_loop() BOOST_NOEXCEPT {
          |                 ^~~~~
    /home/user/core.git/workdir/UnpackedTarball/boost/boost/lexical_cast/detail/lcast_unsigned_converters.hpp:150:17: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘while’
      150 |                 while (main_convert_iteration());
          |                 ^~~~~~

It surfaced after commit 00a76942e4,
apparently showing some version-specific compiler bug.

Change-Id: I92a989726cea5eafd762f724cfc0b3c1f986824c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124474
Reviewed-by: Aron Budea <aron.budea@collabora.com>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Mike Kaganski <mike.kaganski@collabora.com>
2021-11-02 06:49:21 +01:00

322 lines
11 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#ifndef INCLUDED_COMPHELPER_SEQUENCE_HXX
#define INCLUDED_COMPHELPER_SEQUENCE_HXX
#include <com/sun/star/uno/Sequence.hxx>
#include <osl/diagnose.h>
#include <algorithm>
#include <vector>
namespace comphelper
{
/** Search the given value within the given sequence, return the position of the first occurrence.
Returns -1 if nothing found.
*/
template <class T1, class T2>
inline sal_Int32 findValue(const css::uno::Sequence<T1>& _rList, const T2& _rValue)
{
// at which position do I find the value?
for (sal_Int32 i = 0; i < _rList.getLength(); ++i)
{
if (_rList[i] == _rValue)
return i;
}
return -1;
}
/// concat several sequences
template <class T, class... Ss>
inline css::uno::Sequence<T> concatSequences(const css::uno::Sequence<T>& rS1, const Ss&... rSn)
{
// unary fold to disallow empty parameter pack: at least have one sequence in rSn
css::uno::Sequence<T> aReturn(std::size(rS1) + (... + std::size(rSn)));
T* pReturn = std::copy(std::begin(rS1), std::end(rS1), aReturn.getArray());
(..., (pReturn = std::copy(std::begin(rSn), std::end(rSn), pReturn)));
return aReturn;
}
/// concat additional elements from right sequence to left sequence
///
/// be aware that this takes time O(|left| * |right|)
template<typename T> inline css::uno::Sequence<T> combineSequences(
css::uno::Sequence<T> const & left, css::uno::Sequence<T> const & right)
{
sal_Int32 n1 = left.getLength();
css::uno::Sequence<T> ret(n1 + right.getLength());
//TODO: check for overflow
auto pRet = ret.getArray();
std::copy_n(left.getConstArray(), n1, pRet);
sal_Int32 n2 = n1;
for (sal_Int32 i = 0; i != right.getLength(); ++i) {
bool found = false;
for (sal_Int32 j = 0; j != n1; ++j) {
if (right[i] == left[j]) {
found = true;
break;
}
}
if (!found) {
pRet[n2++] = right[i];
}
}
ret.realloc(n2);
return ret;
}
/// remove a specified element from a sequences
template<class T>
inline void removeElementAt(css::uno::Sequence<T>& _rSeq, sal_Int32 _nPos)
{
sal_Int32 nLength = _rSeq.getLength();
OSL_ENSURE(0 <= _nPos && _nPos < nLength, "invalid index");
T* pPos = _rSeq.getArray() + _nPos;
std::move(pPos + 1, pPos + nLength - _nPos, pPos);
_rSeq.realloc(nLength-1);
}
/** Copy from a plain C/C++ array into a Sequence.
@tpl SrcType
Array element type. Must be assignable to DstType
@tpl DstType
Sequence element type. Must be assignable from SrcType
@param i_pArray
Valid pointer to at least num elements of type SrcType
@param nNum
Number of array elements to copy
@return the resulting Sequence
@attention when copying from e.g. a double array to a
Sequence<int>, no proper rounding will be performed, but the
values will be truncated. There's currently no measure to
prevent or detect precision loss, overflow or truncation.
*/
template < typename DstType, typename SrcType >
inline css::uno::Sequence< DstType > arrayToSequence( const SrcType* i_pArray, sal_Int32 nNum )
{
if constexpr (std::is_same_v< DstType, SrcType >)
{
return css::uno::Sequence< DstType >( i_pArray, nNum );
}
else
{
css::uno::Sequence< DstType > result( nNum );
::std::copy( i_pArray, i_pArray+nNum, result.getArray() );
return result;
}
}
/** Copy from a Sequence into a plain C/C++ array
@tpl SrcType
Sequence element type. Must be assignable to DstType
@tpl DstType
Array element type. Must be assignable from SrcType
@param io_pArray
Valid pointer to at least i_Sequence.getLength() elements of
type DstType
@param i_Sequence
Reference to a Sequence of SrcType elements
@return a pointer to the array
@attention when copying from e.g. a Sequence<double> to an int
array, no proper rounding will be performed, but the values
will be truncated. There's currently no measure to prevent or
detect precision loss, overflow or truncation.
*/
template < typename DstType, typename SrcType >
inline DstType* sequenceToArray( DstType* io_pArray, const css::uno::Sequence< SrcType >& i_Sequence )
{
::std::copy( i_Sequence.begin(), i_Sequence.end(), io_pArray );
return io_pArray;
}
/** Copy from a container into a Sequence
@tpl SrcType
Container type. This type must fulfill the STL container
concept, in particular, the size(), begin() and end() methods
must be available and have the usual semantics.
@tpl DstType
Sequence element type. Must be assignable from SrcType's
elements
@param i_Container
Reference to the input contain with elements of type SrcType
@return the generated Sequence
@attention this function always performs a copy. Furthermore,
when copying from e.g. a vector<double> to a Sequence<int>, no
proper rounding will be performed, but the values will be
truncated. There's currently no measure to prevent or detect
precision loss, overflow or truncation.
*/
template < typename DstElementType, typename SrcType >
inline css::uno::Sequence< DstElementType > containerToSequence( const SrcType& i_Container )
{
using ::std::size, ::std::begin, ::std::end;
css::uno::Sequence< DstElementType > result( size(i_Container) );
::std::copy( begin(i_Container), end(i_Container), result.getArray() );
return result;
}
// this one does better type deduction, but does not allow us to copy into a different element type
template < typename SrcType >
inline css::uno::Sequence< typename SrcType::value_type > containerToSequence( const SrcType& i_Container )
{
return containerToSequence<typename SrcType::value_type, SrcType>(i_Container);
}
// handle arrays
template<typename ElementType, std::size_t SrcSize>
inline css::uno::Sequence< ElementType > containerToSequence( ElementType const (&i_Array)[ SrcSize ] )
{
return css::uno::Sequence< ElementType >( i_Array, SrcSize );
}
template <typename T>
inline css::uno::Sequence<T> containerToSequence(
::std::vector<T> const& v )
{
return css::uno::Sequence<T>(
v.data(), static_cast<sal_Int32>(v.size()) );
}
/** Copy from a Sequence into a container
@tpl SrcType
Sequence element type. Must be assignable to SrcType's
elements
@tpl DstType
Container type. This type must have a constructor taking a pair
of iterators defining a range to copy from
@param i_Sequence
Reference to a Sequence of SrcType elements
@return the generated container. C++17 copy elision rules apply
@attention this function always performs a copy. Furthermore,
when copying from e.g. a Sequence<double> to a vector<int>, no
proper rounding will be performed, but the values will be
truncated. There's currently no measure to prevent or detect
precision loss, overflow or truncation.
*/
template < typename DstType, typename SrcType >
inline DstType sequenceToContainer( const css::uno::Sequence< SrcType >& i_Sequence )
{
return DstType(i_Sequence.begin(), i_Sequence.end());
}
// this one does better type deduction, but does not allow us to copy into a different element type
template < typename DstType >
inline DstType sequenceToContainer( const css::uno::Sequence< typename DstType::value_type >& i_Sequence )
{
return DstType(i_Sequence.begin(), i_Sequence.end());
}
/** Copy from a Sequence into an existing container
This potentially saves a needless extra copy operation over
the whole container, as it passes the target object by
reference.
@tpl SrcType
Sequence element type. Must be assignable to SrcType's
elements
@tpl DstType
Container type. This type must fulfill the STL container and
sequence concepts, in particular, the begin(), end() and
resize(int) methods must be available and have the usual
semantics.
@param o_Output
Reference to the target container
@param i_Sequence
Reference to a Sequence of SrcType elements
@return a non-const reference to the given container
@attention this function always performs a copy. Furthermore,
when copying from e.g. a Sequence<double> to a vector<int>, no
proper rounding will be performed, but the values will be
truncated. There's currently no measure to prevent or detect
precision loss, overflow or truncation.
*/
template < typename DstType, typename SrcType >
inline DstType& sequenceToContainer( DstType& o_Output, const css::uno::Sequence< SrcType >& i_Sequence )
{
o_Output.resize( i_Sequence.getLength() );
::std::copy( i_Sequence.begin(), i_Sequence.end(), o_Output.begin() );
return o_Output;
}
/** Copy (keys or values) from an associate container into a Sequence
@tpl M map container type eg. std::map/std::unordered_map
@return the generated Sequence
*/
template < typename M >
inline css::uno::Sequence< typename M::key_type > mapKeysToSequence( M const& map )
{
css::uno::Sequence< typename M::key_type > ret( static_cast<sal_Int32>(map.size()) );
std::transform(map.begin(), map.end(), ret.getArray(),
[](const auto& i) { return i.first; });
return ret;
}
template < typename M >
inline css::uno::Sequence< typename M::mapped_type > mapValuesToSequence( M const& map )
{
css::uno::Sequence< typename M::mapped_type > ret( static_cast<sal_Int32>(map.size()) );
std::transform(map.begin(), map.end(), ret.getArray(),
[](const auto& i) { return i.second; });
return ret;
}
} // namespace comphelper
#endif // INCLUDED_COMPHELPER_SEQUENCE_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */