vendredi 22 septembre 2017

Expand two parameter packs

Consider following piece of code:

static constexpr size_t Num {2};
struct S {
    std::array<size_t, Num> get () { return {1, 2}; }
};

struct S1 : S {};
struct S2 : S {};

struct M {
    template <typename T>
    typename std::enable_if<std::is_same<T, S1>::value, S1>::type get () const { 
        return S1 {}; 
    }

    template <typename T>
    typename std::enable_if<std::is_same<T, S2>::value, S2>::type get () const { 
        return S2 {}; 
    }
};

I want to have a function which merges two or more std::arrays making one std::array.

So far I ended with something like this:

template <typename Mode, typename... Rs, size_t... Ns>
std::array<size_t, sizeof... (Rs)*Num> get_array (const Mode& mode, Sequence::Sequence<Ns...>) {
    return {std::get<Ns> (mode.template get<Rs...> ().get ())...};
}

I want to have that the following code

M m;
auto x = get_array<M, S1, S2> (m, Sequence::Make<2> {});

produces std::array<size_t, 4> filled with {1, 2, 1, 2}.

Where Sequence::Sequence and Sequence::Make are described here.

I know that placing ... of Rs is incorrect in this context (If sizeof... (Rs) is 1 then it is fine, std::array<size_t, 2> with {1, 2} is returned) but I have no idea where to put it to make expansion which looks like this:

std::get<0> (mode.template get<Rs[0]> ().get ()), 
std::get<1> (mode.template get<Rs[0]> ().get ()),
std::get<0> (mode.template get<Rs[1]> ().get ()), 
std::get<1> (mode.template get<Rs[1]> ().get ());

Of course Rs[0] I mean first type from parameter pack.

Is it even possible?

Aucun commentaire:

Enregistrer un commentaire