#include <iostream>
template <typename...> struct InterlacePacksHelper;
template <template <typename...> class PRes, typename... Ts,
template <typename...> class P, typename U, typename... Us,
typename... Packs>
struct InterlacePacksHelper<PRes<Ts...>, P<U, Us...>, Packs...>
{
using type = typename InterlacePacksHelper<PRes<Ts..., U>, Packs..., P<Us...>>::type;
};
template <template <typename...> class PRes, typename... Ts>
struct InterlacePacksHelper<PRes<Ts...>>
{
using type = PRes<Ts...>;
};
template <template <typename...> class PRes, typename... Ts,
template <typename...> class P,
typename... Packs>
struct InterlacePacksHelper<PRes<Ts...>, P<>, Packs...>
{
using type = typename InterlacePacksHelper<PRes<Ts...>, Packs...>::type;
};
// Finally, InterlacePacks itself.
template <typename...> struct InterlacePacks;
template <template <typename...> class P, typename... Ts, typename... Packs>
struct InterlacePacks<P<Ts...>, Packs...> : InterlacePacksHelper<P<>, P<Ts...>, Packs...>::type
{
using type = typename InterlacePacksHelper<P<>, P<Ts...>, Packs...>::type;
};
// test ----------------------------------------------------------------
template <typename...> struct Pack {};
template <typename...> struct Group {};
template <typename...> struct Wrap {};
struct Object {}; struct Blob {};
int main() {
using TestPack1 = Pack<int, double, Object>; // 3 types
using TestPack2 = Group<double, std::string, int, short, long>; // 5 types
using TestPack3 = Wrap<char, short, Blob, std::string>; // 4 types
InterlacePacks<TestPack1, TestPack2, TestPack3>::type interlacedPack;
std::cout << std::boolalpha << std::is_same< decltype(interlacedPack),
Pack<int, double, char, double, std::string, short, Object, int, Blob, short, std::string, long> >::value << std::endl; // true
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGUgPHR5cGVuYW1lLi4uPiBzdHJ1Y3QgSW50ZXJsYWNlUGFja3NIZWxwZXI7Cgp0ZW1wbGF0ZSA8dGVtcGxhdGUgPHR5cGVuYW1lLi4uPiBjbGFzcyBQUmVzLCB0eXBlbmFtZS4uLiBUcywKICAgICAgICAgIHRlbXBsYXRlIDx0eXBlbmFtZS4uLj4gY2xhc3MgUCwgdHlwZW5hbWUgVSwgdHlwZW5hbWUuLi4gVXMsCiAgICAgICAgICB0eXBlbmFtZS4uLiBQYWNrcz4Kc3RydWN0IEludGVybGFjZVBhY2tzSGVscGVyPFBSZXM8VHMuLi4+LCBQPFUsIFVzLi4uPiwgUGFja3MuLi4+CnsKICAgIHVzaW5nIHR5cGUgPSB0eXBlbmFtZSBJbnRlcmxhY2VQYWNrc0hlbHBlcjxQUmVzPFRzLi4uLCBVPiwgUGFja3MuLi4sIFA8VXMuLi4+Pjo6dHlwZTsKfTsKCnRlbXBsYXRlIDx0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4+IGNsYXNzIFBSZXMsIHR5cGVuYW1lLi4uIFRzPgpzdHJ1Y3QgSW50ZXJsYWNlUGFja3NIZWxwZXI8UFJlczxUcy4uLj4+CnsKICAgIHVzaW5nIHR5cGUgPSBQUmVzPFRzLi4uPjsKfTsKCnRlbXBsYXRlIDx0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4+IGNsYXNzIFBSZXMsIHR5cGVuYW1lLi4uIFRzLAogICAgICAgICAgdGVtcGxhdGUgPHR5cGVuYW1lLi4uPiBjbGFzcyBQLAogICAgICAgICAgdHlwZW5hbWUuLi4gUGFja3M+CnN0cnVjdCBJbnRlcmxhY2VQYWNrc0hlbHBlcjxQUmVzPFRzLi4uPiwgUDw+LCBQYWNrcy4uLj4KewogICAgdXNpbmcgdHlwZSA9IHR5cGVuYW1lIEludGVybGFjZVBhY2tzSGVscGVyPFBSZXM8VHMuLi4+LCBQYWNrcy4uLj46OnR5cGU7Cn07CgoKLy8gRmluYWxseSwgSW50ZXJsYWNlUGFja3MgaXRzZWxmLgp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4+IHN0cnVjdCBJbnRlcmxhY2VQYWNrczsKCnRlbXBsYXRlIDx0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4+IGNsYXNzIFAsIHR5cGVuYW1lLi4uIFRzLCB0eXBlbmFtZS4uLiBQYWNrcz4Kc3RydWN0IEludGVybGFjZVBhY2tzPFA8VHMuLi4+LCBQYWNrcy4uLj4gOiBJbnRlcmxhY2VQYWNrc0hlbHBlcjxQPD4sIFA8VHMuLi4+LCBQYWNrcy4uLj46OnR5cGUKewogICAgdXNpbmcgdHlwZSA9IHR5cGVuYW1lIEludGVybGFjZVBhY2tzSGVscGVyPFA8PiwgUDxUcy4uLj4sIFBhY2tzLi4uPjo6dHlwZTsKfTsKCi8vIHRlc3QgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4+IHN0cnVjdCBQYWNrIHt9Owp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4+IHN0cnVjdCBHcm91cCB7fTsKdGVtcGxhdGUgPHR5cGVuYW1lLi4uPiBzdHJ1Y3QgV3JhcCB7fTsKc3RydWN0IE9iamVjdCB7fTsgIHN0cnVjdCBCbG9iIHt9OwoKaW50IG1haW4oKSB7CiAgICB1c2luZyBUZXN0UGFjazEgPSBQYWNrPGludCwgZG91YmxlLCBPYmplY3Q+OyAgLy8gMyB0eXBlcwogICAgdXNpbmcgVGVzdFBhY2syID0gR3JvdXA8ZG91YmxlLCBzdGQ6OnN0cmluZywgaW50LCBzaG9ydCwgbG9uZz47ICAvLyA1IHR5cGVzCiAgICB1c2luZyBUZXN0UGFjazMgPSBXcmFwPGNoYXIsIHNob3J0LCBCbG9iLCBzdGQ6OnN0cmluZz47ICAvLyA0IHR5cGVzCiAgICBJbnRlcmxhY2VQYWNrczxUZXN0UGFjazEsIFRlc3RQYWNrMiwgVGVzdFBhY2szPjo6dHlwZSBpbnRlcmxhY2VkUGFjazsKICAgIHN0ZDo6Y291dCA8PCBzdGQ6OmJvb2xhbHBoYSA8PCBzdGQ6OmlzX3NhbWU8IGRlY2x0eXBlKGludGVybGFjZWRQYWNrKSwKICAgICAgICBQYWNrPGludCwgZG91YmxlLCBjaGFyLCBkb3VibGUsIHN0ZDo6c3RyaW5nLCBzaG9ydCwgT2JqZWN0LCBpbnQsIEJsb2IsIHNob3J0LCBzdGQ6OnN0cmluZywgbG9uZz4gPjo6dmFsdWUgPDwgc3RkOjplbmRsOyAgLy8gdHJ1ZQp9Cg==