#include <iostream>
#include <string>
using namespace std;
#define _ARG_PARAMS3(type1, type2, type3) type1 arg1, type2 arg2, type3 arg3
#define _ARG_NAMES3(type1, type2, type3) arg1, arg2, arg3
#define _ARG_PARAMS2(type1, type2) type1 arg1, type2 arg2
#define _ARG_NAMES2(type1, type2) arg1, arg2
#define _ARG_PARAMS1(type1) type1 arg1
#define _ARG_NAMES1(type1) arg1
#define _ARG_PARAMS0()
#define _ARG_NAMES0()
#define _GET_OVERRIDE(_1, _2, _3, _4, NAME, ...) NAME
#define ARG_PARAMS(...) _GET_OVERRIDE("ignored", __VA_ARGS__ __VA_OPT__(,) \
_ARG_PARAMS3, _ARG_PARAMS2, _ARG_PARAMS1, _ARG_PARAMS0)(__VA_ARGS__)
#define ARG_NAMES(...) _GET_OVERRIDE("ignored", __VA_ARGS__ __VA_OPT__(,) \
_ARG_NAMES3, _ARG_NAMES2, _ARG_NAMES1, _ARG_NAMES0)(__VA_ARGS__)
#define WRAP_FUNCTION(wrapper_name, function, ret_type, ...) \
ret_type wrapper_name(ARG_PARAMS(__VA_ARGS__)) { \
return function(ARG_NAMES(__VA_ARGS__)); \
}
int realFunc1(int arg1, int arg2, int arg3)
{
return arg1 + arg2 + arg3;
}
string realFunc2()
{
return "nada!";
}
WRAP_FUNCTION(doIt1, realFunc1, int, int, int, int)
WRAP_FUNCTION(doIt2, realFunc2, string)
int main()
{
cout << doIt1(1, 2, 3) << endl;
cout << doIt2();
return 0;
}