tags:

views:

313

answers:

1

I'm trying to initialise a list of args to use with fusion::invoke. The args are all of the form:

template <typename Type>
struct ArgWrapper
{
    inline ArgWrapper(){}
    inline void Setup(lua_State*L,int idx)
    {
        //setup this value from the lua state...
        //in reality this class is specialised for different lua types
    }
    operator Type{return value;}
    Type value;
};

So I can do, for example

int add(int a,int b){return a+b;}
fusion::vector<ArgsWrapper<int>,ArgsWrapper<int> > v;
fusion::at_c<0>.value=1;
fusion::at_c<1>.value=2;
std::cout<<fusion::invoke(add,v)//prints 3

But if I have a fusion sequence of type FusionListType, where I know each type in the sequence is an ArgWrapper of some type, how can I iterate through that list and call the Setup function on each element (I have just one lua_State pointer and want to use it as the first argument for Setup, and I want to use the position in the sequence as the second argument).

So for a vector of size 3 I want the resultant logic to be:

lua_State*L;
fusion::at_c<0>.Setup(L,1);
fusion::at_c<1>.Setup(L,2);
fusion::at_c<2>.Setup(L,3);

I have tried:

template<typename ArgWrapperType,int N>
void FillArgWrapper(ArgWrapperType arg,lua_State*L)
{
    fusion::at_c<N>(arg).Setup(L,N+1);
}
template<typename ArgWrapperType>
void FillArgWrapper<ArgWrapperType,0>(ArgWrapperType arg,lua_State*L)
{
    fusion::at_c<0>(arg).Setup(L,1);
}

But this fails to compile, saying function template partial specialisation ‘FillArgWrapper<ArgWrapperType, 0>’ is not allowed.

Thanks in advance.

+4  A: 

Ok, I figured it out. I need to be using a struct:

template <typename ArgWrapperList,u32 N=mpl::size<ArgWrapperList>::value-1>
struct ArgWrapperListFiller
{
    static inline void Setup(ArgWrapperList &args,lua_State*L)
    {
     fusion::at_c<N>(args).Setup(L,N+1);
     ArgWrapperListFiller<ArgWrapperList,N-1>::Setup(args,L);
    }
};
template <typename ArgWrapperList> //base case, do not recurse
struct ArgWrapperListFiller<ArgWrapperList,0>
{
    static inline void Fill(ArgWrapperList &args,lua_State*L)
    {
     fusion::at_c<0>(args).Setup(L,1);
    };
};
DaedalusFall