Home > Enterprise >  Copying elements of multiple source tuples to the destination tuple
Copying elements of multiple source tuples to the destination tuple

Time:11-05

I'm trying to assign values of all elements from multiple source tuples to elements of one destination tuple as follows:

#include <tuple>

template<std::size_t from_element, typename dstT, typename srcTs, std::size_t... Is>
void assign_elms(dstT& dst, const srcTs& src, std::index_sequence<Is...>) {
    ((std::get<from_element   Is>(dst) = std::get<Is>(src)), ...);
}

template<std::size_t from_element, typename dstT, typename srcT>
void assign_impl(dstT& dst, const srcT& src) {
    assign_elms<from_element>(dst, src, std::make_index_sequence<std::tuple_size_v<srcT>>());
}

template<typename dstT, typename... srsTs>
void assign(dstT& dst, const srsTs&... srcs) {
    (assign_impl<???>(dst, srcs), ...); // ???
}

template<typename... Ts>
using tuple_concat_t = decltype(std::tuple_cat(std::declval<Ts>()...));

int main() {

    std::tuple t1{ 1, 2.2f, 3.33 };
    std::tuple t2{ 4, 5.5f };
    std::tuple t3{ 6 };

    tuple_concat_t<decltype(t1), decltype(t2), decltype(t3)> tr;
    assign(tr, t1, t2, t3); // required (1, 2.2f, 3.33, 4, 5.5f, 6)
}

I want to create a destination tuple in advance and then assign elements many times. But I don't know what to substitute instead of '???'. Please help me.

I solved this problem using recursion, but I want to do it without recursion.

Creating a new tuple doesn't suit me:

template <typename... Ts>
auto tuple_concat(const Ts&... srcs) { return std::tuple_cat(srcs...); }

CodePudding user response:

You might create an array of offsets and iterate over it:

template<typename dstT, typename... srsTs>
void assign(dstT& dst, const srsTs&... srcs) {
    constexpr std::array offsets = [](){
        std::array<std::size_t, 1   sizeof...(srcs)> res{{0, std::tuple_size_v<srsTs>...}};
        std::partial_sum(res.begin(), res.end(), res.begin());

        return res;
    }();
    [&]<std::size_t...Is>(std::index_sequence<Is...>){
        (assign_impl<offsets[Is]>(dst, srcs), ...);
    }(std::make_index_sequence<sizeof...(srsTs)>());
}

Demo.

  • Related