Given a list of size_t values as a variadic template parameter pack, how does one make a tuple of derived types (e.g. Matrix) depending on the parameter pack in such a way, that n-th element of variadic generates Matrix<n, n+1>
. For example:
make_matrix_tuple<2,3,4,5>() == make_tuple( Matrix<2,3>, Matrix<3,4>, Matrix<4,5> );
By a type derived I do not mean inheritance but dependence (?). I'm not sure what the proper term is.
Unpacking parameter pack is simple enough
template <typename ElementType, size_t... Sizes>
void make_tuple_of_vectors() { std::tuple < std::array<ElementType, Sizes> ... > tuple; }
However I believe I am a bit over my head where it comes to the next part. I was trying recursively unpack a pair of arguments from parameter pack like so:
template <typename Type, size_t size1, size_t size2>
struct dummy_matrix
{
size_t SIZE1 = size1;
size_t SIZE2 = size2;
using type = Type;
};
template <size_t Iterator, typename ElementType, size_t T, size_t... Sizes>
struct unpack_two
{
using type = typename unpack_two<Iterator - 1, ElementType, Sizes...>::type;
};
template<typename ElementType, size_t T, size_t T2, size_t... Sizes>
struct unpack_two<0, ElementType, T, T2, Sizes...>
{
using type = dummy_matrix<ElementType, T, T2>;
};
So that unpack_two<N, Type, Sizes...>::type
gives N-th and (N+1)-nth Matrix type.
With that, I'm stuck with something that appears sensible to me, yet the compiler disagrees harshly.
template <size_t... Sizes, size_t... Is>
auto
foo_impl(std::index_sequence<Is...>) {
std::tuple < unpack_two<Is, float, Sizes ... >::type ... > tuple;
return tuple;
}
template <size_t... Args>
void foo()
{
auto vs = foo_impl<Args...>(std::make_index_sequence<sizeof...(Args)-1>{});
}
int main() { foo<6,9,12>(); }
I'm trying to unpack list of std::size_t
Sizes for the unpack_two template, and then unpack std::index_sequence
for the std::make_tuple()
.
I would appreciate explanations as to why my tries are failing, or even is the std::index_sequence
right tool here. But I'm mostly interested in any solution to the posed problem.
how does one make a tuple of derived types (e.g. Matrix) depending on the parameter pack in such a way, that n-th element of variadic generates
Matrix<n, n+1>
[?]
Maybe using a constexpr
std::array
in an helper function?
An example
#include <array>
#include <tuple>
#include <utility>
template <std::size_t, std::size_t>
struct Matrix
{ };
template <std::size_t ... Ds, std::size_t ... Is>
auto mmt_helper (std::index_sequence<Is...>)
{
constexpr std::array ca { Ds... };
return std::make_tuple(Matrix<ca[Is], ca[Is+1u]>{}...);
}
template <std::size_t ... Ds>
auto make_matrix_tuple ()
{ return mmt_helper<Ds...>(std::make_index_sequence<sizeof...(Ds)-1>{}); }
int main ()
{
auto mt = make_matrix_tuple<2,3,4,5>();
using T1 = decltype(mt);
using T2 = std::tuple<Matrix<2u, 3u>, Matrix<3u, 4u>, Matrix<4u, 5u>>;
static_assert( std::is_same_v<T1, T2> );
}