tags:

views:

79

answers:

1
template<typename Functor, typename Return, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6,
                typename Arg7, typename Arg8, typename Arg9, typename Arg10> class LambdaCall : public Instruction {
                public:
                    LambdaCall(Functor func
                        ,unsigned char constructorarg1
                        ,unsigned char constructorarg2
                        ,unsigned char constructorarg3
                        ,unsigned char constructorarg4
                        ,unsigned char constructorarg5
                        ,unsigned char constructorarg6
                        ,unsigned char constructorarg7
                        ,unsigned char constructorarg8
                        ,unsigned char constructorarg9
                        ,unsigned char constructorarg10)
                        : arg1(constructorarg1)
                        , arg2(constructorarg2)
                        , arg3(constructorarg3)
                        , arg4(constructorarg4)
                        , arg5(constructorarg5)
                        , arg6(constructorarg6)
                        , arg7(constructorarg7)
                        , arg8(constructorarg8)
                        , arg9(constructorarg9)
                        , arg10(constructorarg10)
                        , function(func) {}
                    void Call(State& state) {
                        state.Push<Return>(func(*state.GetRegisterValue<Arg1>(arg1)
                            ,*state.GetRegisterValue<Arg1>(arg1)
                            ,*state.GetRegisterValue<Arg2>(arg2)
                            ,*state.GetRegisterValue<Arg3>(arg3)
                            ,*state.GetRegisterValue<Arg4>(arg4)
                            ,*state.GetRegisterValue<Arg5>(arg5)
                            ,*state.GetRegisterValue<Arg6>(arg6)
                            ,*state.GetRegisterValue<Arg7>(arg7)
                            ,*state.GetRegisterValue<Arg8>(arg8)
                            ,*state.GetRegisterValue<Arg9>(arg9)
                            ,*state.GetRegisterValue<Arg10>(arg10)
                         ));
                    }
                    Functor function;
                    unsigned char arg1;
                    unsigned char arg2;
                    unsigned char arg3;
                    unsigned char arg4;
                    unsigned char arg5;
                    unsigned char arg6;
                    unsigned char arg7;
                    unsigned char arg8;
                    unsigned char arg9;
                    unsigned char arg10;
            };

Then again for every possible number of arguments I want to support, and again for void returns.

Any way to do this faster?

Edit: Apparently there's some (understandable) confusion about the goal of the above function.

I want to create a function that accepts N template arguments, has N unsigned char variables, accepts them in it's constructor and assigns them, calls a specific function with the Nth template and Nth char arguments, and passes the return into a given lamba function, which then passes it's return into the last function, which has a special template argument.
Then I want this to work for any given quantity of arguments or void returns. Preferably without writing an overload for every single argument number and void return possibility, since that would involve 22 specializations.
Edit: Without variadics, not any given quantity, but up to say ten. I checked out the Boost preprocessor library, but it's not working.

A: 

Turns out I just suck at the boost preprocessing library.

#define ternary(z, n, data) data BOOST_PP_COMMA_IF(BOOST_PP_NOT_EQUAL(n, BOOST_PP_SUB(WIDE_RECURSE_UPPER_LIMIT, WIDE_RECURSE)))
#define argternary(z, n, data) data ## n BOOST_PP_COMMA_IF(BOOST_PP_LESS(n, BOOST_PP_SUB(WIDE_RECURSE, 1)))
            template<typename Functor, typename Return, BOOST_PP_REPEAT(WIDE_RECURSE, argternary, typename Arg) >
            class LambdaCall <Functor, Return BOOST_PP_COMMA() BOOST_PP_ENUM_PARAMS(WIDE_RECURSE, Arg) BOOST_PP_COMMA_IF(BOOST_PP_LESS(WIDE_RECURSE, BOOST_PP_SUB(WIDE_RECURSE_UPPER_LIMIT, 1))) BOOST_PP_REPEAT(BOOST_PP_SUB(WIDE_RECURSE_UPPER_LIMIT, WIDE_RECURSE), ternary, void) > : public Instruction {
#undef ternary
#undef argternary
            public:
            LambdaCall(Functor func,
                BOOST_PP_ENUM_PARAMS(WIDE_RECURSE, unsigned char constructorarg)
            )
#define TEMPDECL(n) arg ## n ( constructorarg ## n),
#define DECL(z, n, text) TEMPDECL(n)
            : BOOST_PP_REPEAT(WIDE_RECURSE, DECL, hi)
            function(func) {}
            void Call(State& state) {
                state.Push<Return>(
                    func(
#undef DECL
#define DECL(z, n, text) *state.GetRegisterValue<Arg ## n>(arg ## n) BOOST_PP_COMMA_IF(BOOST_PP_LESS(n, BOOST_PP_SUB(WIDE_RECURSE, 1)))
                        BOOST_PP_REPEAT(WIDE_RECURSE, DECL, hi)
                    ));
                }
                Functor function;
#undef DECL
#define DECL(z, n, text) text ## n;
                BOOST_PP_REPEAT(WIDE_RECURSE, DECL, unsigned char arg)
            };
#undef DECL
#undef TEMPDECL

#define ternary(z, n, data) data BOOST_PP_COMMA_IF(BOOST_PP_NOT_EQUAL(n, BOOST_PP_SUB(WIDE_RECURSE_UPPER_LIMIT, WIDE_RECURSE)))
#define argternary(z, n, data) data ## n BOOST_PP_COMMA_IF(BOOST_PP_NOT_EQUAL(n, BOOST_PP_SUB(WIDE_RECURSE, 1)))
            template<typename Functor, BOOST_PP_REPEAT(WIDE_RECURSE, argternary, typename Arg) >
            class LambdaCall <Functor, void, BOOST_PP_ENUM_PARAMS(WIDE_RECURSE, Arg) BOOST_PP_COMMA_IF(BOOST_PP_LESS(WIDE_RECURSE, BOOST_PP_SUB(WIDE_RECURSE_UPPER_LIMIT, 1))) BOOST_PP_REPEAT(BOOST_PP_SUB(WIDE_RECURSE_UPPER_LIMIT, WIDE_RECURSE), ternary, void) > : public Instruction {
#undef ternary
#undef argternary
            public:
            LambdaCall(Functor func,
                BOOST_PP_ENUM_PARAMS(WIDE_RECURSE, unsigned char constructorarg)
                )
#define TEMPDECL(n) arg ## n ( constructorarg ## n),
#define DECL(z, n, text) TEMPDECL(n)
                : BOOST_PP_REPEAT(WIDE_RECURSE, DECL, hi)
                function(func) {}
                void Call(State& state) {
                    func(
#undef DECL
#define DECL(z, n, text) *state.GetRegisterValue<Arg ## n>(arg ## n) BOOST_PP_COMMA_IF(BOOST_PP_LESS(n, BOOST_PP_SUB(WIDE_RECURSE, 1)))
                         BOOST_PP_REPEAT(WIDE_RECURSE, DECL, hi)
                    );
                }
                Functor function;
#undef DECL
#define DECL(z, n, text) text ## n;
                BOOST_PP_REPEAT(WIDE_RECURSE, DECL, unsigned char arg)
            };
#undef DECL
#undef TEMPDECL

#undef WIDE_RECURSE

Using:

#define WIDE_RECURSE_UPPER_LIMIT 10
#define WIDE_RECURSE 10
#include "functors.h"
#define WIDE_RECURSE 9
#include "functors.h"
#define WIDE_RECURSE 8
#include "functors.h"
#define WIDE_RECURSE 7
#include "functors.h"
#define WIDE_RECURSE 6
#include "functors.h"
#define WIDE_RECURSE 5
#include "functors.h"
#define WIDE_RECURSE 4
#include "functors.h"
#define WIDE_RECURSE 3
#include "functors.h"
#define WIDE_RECURSE 2
#include "functors.h"
#define WIDE_RECURSE 1
#include "functors.h"

Pretty much generated what I was looking for.

DeadMG
Oh dear, this looks like a bad idea. I hope your future self will slap you for this. May the force be with you.
the_drow
It is and I will, but not until it becomes a bad idea. :P
DeadMG