Reputation:
I need a function fulfilling the following functionality:
template<typename T, std::size_t SIZE_L, std::size_t ...SIZE_R>
std::array<T, SIZE_L> concat(const std::array<T, SIZE_R...>&);
This is supposed to concatenate all passed arrays on the RHS into a single array. The sum of SIZE_R should be identical to SIZE_L -- and if possible one should not need to specify SIZE_L by hand.
The element type of this array will be always double.
Upvotes: 0
Views: 387
Reputation: 72346
If needed, here's a version that can deal with a type which can't be default-constructed (try it online):
#include <array>
#include <type_traits>
#include <utility>
#include <tuple>
namespace array_concat_helper {
template <std::size_t Idx, typename SizeSeq, typename Enable=void>
struct indices
{
static constexpr std::size_t tuple_index = 0;
static constexpr std::size_t elem_index = Idx;
};
template <std::size_t Idx, std::size_t FirstN, std::size_t ...Ns>
struct indices<Idx, std::index_sequence<FirstN, Ns...>,
std::enable_if_t<(Idx >= FirstN)>>
{
static constexpr std::size_t tuple_index =
1 + indices<Idx-FirstN, std::index_sequence<Ns...>>::tuple_index;
static constexpr std::size_t elem_index =
indices<Idx-FirstN, std::index_sequence<Ns...>>::elem_index;
};
template <typename T, std::size_t ...Ns, std::size_t ...Is>
std::array<T, (... + Ns)> concat(
std::index_sequence<Is...>,
const std::array<T, Ns>&... arrs)
{
auto arr_tuple = std::tie(arrs...);
return {{
std::get<indices<Is, std::index_sequence<Ns...>>::tuple_index>
(arr_tuple)
[indices<Is, std::index_sequence<Ns...>>::elem_index]...
}};
}
} // end namespace array_concat_helper
template<typename T, std::size_t ...Ns>
std::array<T, (... + Ns)> concat(const std::array<T, Ns>&... arrs)
{
return array_concat_helper::concat(
std::make_index_sequence<(... + Ns)>{}, arrs...);
}
Upvotes: 3
Reputation: 217283
With default constructible T
, you might do (C++17):
template<typename T, std::size_t ...Ns>
std::array<T, (... + Ns)> concat(const std::array<T, Ns>&... arrs)
{
std::array<T, (... + Ns)> res;
std::size_t offset = 0;
((std::copy(arrs.begin(), arrs.end(), res.begin() + offset),
offset += arrs.size()),
...);
return res;
}
Upvotes: 4