Home > Net >  How to zip vectors using template metaprogramming
How to zip vectors using template metaprogramming

Time:07-21

I am practicing on template meta-programming and wanted to implement a simple trivial meta-function. I wonder how one can implement zip functionality on custom vectors. What I have in my mind is as follows:

Here is how the zip operation for this custom vector look like:

Inputs:

Vector<1, 2, 3>
Vector<2, 3, 4>
Vector<3, 4, 5>

Output:

Vector<6, 24, 60>

I believe my Vector class should be declared like:

template<int... vals>
struct Vector;

zip meta-function should have the signature:

template<typename... Vectors>
struct zip
{
    ///
}

I cannot figure out how to multiply values in the input vectors that happen to be in the same index via template meta-programming?

CodePudding user response:

You can partially specialise zip in order to expose the template parameters of the Vectors you pass.

template<typename...>
struct zip;

template<int... Us, int... Vs, typename... Tail>
struct zip<Vector<Us...>, Vector<Vs...>, Tail...> {
    using type = zip<Vector<(Us * Vs)...>, Tail...>::type;
};

template<typename T>
struct zip<T> {
    using type = T;
};

static_assert(std::is_same<zip<Vector<2, 4, 6>, 
                               Vector<1, 2, 3>, 
                               Vector<3, 6, 9>>::type, 
                               /* == */ Vector<6, 48, 162>>::value);

CodePudding user response:

template<int... vals>
struct Vector;

template<typename...Ts>
struct zip;

template<int...vals>
struct zip<Vector<vals...>>
{
    using type = Vector<vals...>;
};

template<int...Avals, int...Bvals, typename...Ts>
struct zip<Vector<Avals...>, Vector<Bvals...>, Ts...>
{
    using type = typename zip<Vector<(Avals*Bvals)...>, Ts...>::type;
};

template<typename...Ts>
using zip_t = typename zip<Ts...>::type;

https://godbolt.org/z/8KjMj69Y6

CodePudding user response:

By taking the heads off and zipping those:-

template <typename...Ts>
struct Vector
    {
    using type = Vector <Ts...>;
    };

// concatenate adds an item to a list
template <class ...>
struct con;
template <class T, class...Ts>
struct con <T, Vector<Ts...>>:
    Vector <T, Ts...>
    {};

template <class...>
struct zip;
template <class L1> 
struct zip <L1, Vector <>>:
    Vector <>
    {};
template <class L2> 
struct zip <Vector <>, L2>:
    Vector <>
    {};
template <class H1, class...T1s, class H2, class...T2s> 
struct zip <Vector <H1, T1s...>, Vector <H2, T2s...>>:
    con
        <
        Vector <H1, H2>, 
        typename zip <Vector <T1s...>, Vector <T2s...>>::type
        >
    {};
  • Related