Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Append to std::array

Tags:

c++

arrays

c++11

Since I was not able to find such a function (incorrectly?), I'm trying to make a compile-time function (constexpr) function which takes a std::array<T,n> arr and a T t and returns a new std::array<T,n+1> with t added to the end of arr. I've started with something like this:

template <typename T, int n>
constexpr std::array<T,n+1> append(std::array<T,n> a, T t);

template <typename T>
constexpr std::array<T,1> append(std::array<T,0> a, T t)
{
  return std::array<T,1>{t};
}

template <typename T>
constexpr std::array<T,2> append(std::array<T,1> a, T t)
{
  return std::array<T,2>{a[0], t};
}

Here I get stuck. What I need is a way to expand a in the first n places of the initializer list, and then add t add the end. Is that possible? Or is there another way of doing this?

like image 528
kalj Avatar asked Dec 30 '16 15:12

kalj


2 Answers

It was easy to extend Dietmar's answer to a util that lets you constexpr- catenate two arrays:

// constexpr util to catenate two array's.
//
// Usage:
//
// constexpr std::array<int, 2> a1 = { 1, 2 };
// constexpr std::array<int, 2> a2 = { 3, 4 };
//
// constexpr auto a3 = catenate_array(a1, a2);

template <typename T, std::size_t N, std::size_t M, std::size_t... I, std::size_t... J>
constexpr std::array<T, N + M>
catenate_array_aux(std::array<T, N> a1, std::array<T, M> a2, std::index_sequence<I...>, std::index_sequence<J...>) {
    return std::array<T, N + M>{ a1[I]..., a2[J]... };
}

template <typename T, std::size_t N, std::size_t M>
constexpr std::array<T, N + M> catenate_array(std::array<T, N> a1, std::array<T, M> a2) {
    return catenate_array_aux(a1, a2, std::make_index_sequence<N>(), std::make_index_sequence<M>());
}
like image 177
Carlo Wood Avatar answered Oct 22 '22 18:10

Carlo Wood


Of course, it is possible: std::index_sequence<I...> is your friend! You'd simply dispatch to a function which takes a suitable std::index_sequence<I...> as argument and expands the pack with all the values. For example:

template <typename T, std::size_t N, std::size_t... I>
constexpr std::array<T, N + 1>
append_aux(std::array<T, N> a, T t, std::index_sequence<I...>) {
    return std::array<T, N + 1>{ a[I]..., t };
}
template <typename T, std::size_t N>
constexpr std::array<T, N + 1> append(std::array<T, N> a, T t) {
    return append_aux(a, t, std::make_index_sequence<N>());
}
like image 21
Dietmar Kühl Avatar answered Oct 22 '22 18:10

Dietmar Kühl