#include template struct Pack { }; template struct Interleave { }; template struct Append { }; template struct Append, Pack> { using type = Pack; }; template struct Interleave, Pack> { using type = typename Append, typename Interleave, Pack>::type >::type; }; template struct Interleave, Pack<>> { using type = Pack; }; template struct Interleave, Pack> { using type = Pack; }; template <> struct Interleave, Pack<>> { using type = Pack<>; }; int main() { // two equally sized packs { using Left = Pack; using Right = Pack; using Interleaving = typename Interleave::type; using Answer = Pack; static_assert( std::is_same_v ); } // Left is larger than Right { using Left = Pack; using Right = Pack; using Interleaving = typename Interleave::type; using Answer = Pack; static_assert( std::is_same_v ); } // Right is larger than Left { using Left = Pack; using Right = Pack; using Interleaving = typename Interleave::type; using Answer = Pack; static_assert( std::is_same_v ); } // Right is empty { using Left = Pack; using Right = Pack<>; using Interleaving = typename Interleave::type; static_assert( std::is_same_v ); } // Left is empty { using Left = Pack<>; using Right = Pack; using Interleaving = typename Interleave::type; static_assert( std::is_same_v ); } // Both are empty { using Left = Pack<>; using Interleaving = typename Interleave::type; static_assert( std::is_same_v ); } }