Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering a tuple with an integer_sequence

Tags:

c++

c++11

c++14

#include <tuple>
#include <utility>
using namespace std;

template <size_t... Indices, class F, class T>
auto map_filter_tuple(F f, T &t) {
    return make_tuple(f(std::get<Indices>(t))...);
}

int main()
{
    auto times2 = [](auto i) { return i * 2; };
    auto t = make_tuple(1, 2, 3, 4);
    auto t2 = map_filter_tuple<0, 1, 2>(times2, t);
}

This works but I am wondering how I could pass an integer_sequence to map_filter_tuple

auto t3 = map_filter_tuple<std::integer_sequence<size_t,0,1,2>>(times2,t);

I have looked at the source for integer_sequenceand it doesn't expose the variadic template.

I guess I would have to use specialization? I am just not sure how I would approach it.

like image 329
Maik Klein Avatar asked Nov 21 '15 15:11

Maik Klein


2 Answers

template <std::size_t... Is, typename F, typename T>
auto map_filter_tuple(F f, T& t)
{
    return std::make_tuple(f(std::get<Is>(t))...);
}

template <std::size_t... Is, typename F, typename T>
auto map_filter_tuple(std::index_sequence<Is...>, F f, T& t)
{
    return std::make_tuple(f(std::get<Is>(t))...);
}

template <typename S, typename F, typename T>
auto map_filter_tuple(F&& f, T& t)
{
    return map_filter_tuple(S{}, std::forward<F>(f), t);
}

DEMO

like image 141
Piotr Skotnicki Avatar answered Sep 24 '22 00:09

Piotr Skotnicki


The solution is already there. You can pass in an index sequence to infer the indices :

template <size_t ...Indices, class F, class T>
auto map_filter_tuple(F f,T &t, std::index_sequence<Indices...>)
{//                               ^^^^^^^^^^^^^^^^^^^^
    return make_tuple(f(std::get<Indices>(t))...);
}

The code is showcased in this Demo where we only use a portion of the initial tuple. furthermore the std::index_sequence<> parameter is not named so it will be optmized away and only its type will be used.

like image 31
Lorah Attkins Avatar answered Sep 25 '22 00:09

Lorah Attkins