Sunday, December 13, 2015

Varaidic templated template parameters for a loop unroller/code repeater

This basically a demonstration how to use variadic templated template parameter in combination with a variadic template outer handler that locks the typing of the inner part into place with automatic type resolution. This application is basically demonstrating how to create a static loop unroller or code repeater...

// compile: g++ -std=c++11 metafunctor.cpp

#include <iostream>
#include <map>

// **************************************************************
// **********************TEMPLATE FOR****************************
// **************************************************************

template <template<int> class Func, int... IDs> class ForFunctor;

template <template<int> class Func, int ID, int... IDs>
class ForFunctor<Func,ID,IDs...>
{
public:
    template <typename... Params>
    static void with(Params& ...params)
    {
        Func<ID>::op(params...);
        ForFunctor<Func,IDs...>::with(params...);
    }
};

template <template<int> class Func>
class ForFunctor<Func>
{
public:
    template <typename... Params>
    static void with(Params& ...params) {}
};

// **************************************************************
// **********************SOME FUNCTORS****************************
// **************************************************************

template <int ID>
class Init
{
public:
    template <typename OUT>
    static void op(OUT& out)
    {
        out[ID] = ID;
    }
};

template <int ID>
class CopyID
{
public:
    template <typename OUT, typename IN>
    static void op(OUT& out,IN& in)
    {
        out[ID] = in[ID];
    }
};

// **************************************************************
// ***************************MAIN*******************************
// **************************************************************

int main()
{
    typedef std::map<int,int>    A;

    A a;
    A b;

    ForFunctor<Init,1,2,6,3,10>::with(a);
    ForFunctor<CopyID,1,2,6>::with(b,a);

    std::cout << "a: ";
    for (auto value: a) std::cout << value.second << " ";
    std::cout << "\nb: ";
    for (auto value: b) std::cout << value.second << " ";
    std::cout << "\n";
}