Tim Quelch
Tim Quelch

Reputation: 13

How to append the corresponding value from a tuple of values to a tuple of vectors of the same types?

I have a structure of arrays class

template <typename... Ts>
class soa {
    std::tuple<std::vector<Ts>...> vectors;
    void push_back(std::tuple<Ts...> values);
}

I want push_back to push the tuple of values onto each of the corresponding vectors of each type. I was thinking of doing something with index_sequences but I'm not too sure how to properly do the pack expansion.

This is kind of what I was thinking, but the expansion doesn't work. How should I correctly do the expansion?

template <typename... Ts>
class soa {
    std::tuple<std::vector<Ts>...> vectors;

    template <std::size_t... Is>
    void push_back_impl(std::tuple<Ts...> values, std::index_sequence<Is...>) {
        // Some kind of pack expansion here
        // This doesn't work, but is kinda what I want
        //std::get<Is>(vectors).push_back(std::get<Is>(values))...;
    }

    void push_back(std::tuple<Ts...> values) {
        push_back_impl(values, std::index_sequence_for<Ts...>{});
    }
};

Please also correct me if I'm using index_sequence incorrectly. The meta programming is messing with my head a bit.

Upvotes: 1

Views: 59

Answers (1)

llllllllll
llllllllll

Reputation: 16404

Pre-C++17, you can use an eater:

template<class... Ts> void eater(Ts... ts) {}

Then the function can be:

template <std::size_t... Is>
void push_back_impl(std::tuple<Ts...> values, std::index_sequence<Is...>) {
    eater((std::get<Is>(vectors).push_back(std::get<Is>(values)), 0)...);
}

In C++17, just use comma operator:

template <std::size_t... Is>
void push_back_impl(std::tuple<Ts...> values, std::index_sequence<Is...>) {
    (std::get<Is>(vectors).push_back(std::get<Is>(values)),...);
}

Upvotes: 2

Related Questions