I have a macro:
#define WRAP_FUNCTION(wrapper_name, function, ret_type, arg1_type, arg2_type, ...)
And I would like it to define a function like this:
ret_type wrapper_name(arg1_type arg1, arg2_type arg2, ...) {
return function(arg1, arg2, ...)
}
Except where the ellipses (along with arg1 and arg2) are a dynamically sized list. I could create the function prototype using __VA_ARGS__, but that doesn't give me names for the arguments to pass to the wrapped function.
I assume the usual approach would be std::apply (or to copy-paste the implementation of std::apply, since it's not available in C++11). Unfortunately the argument function may be overloaded or a compiler built-in so it cannot reliably be passed as a function type.
What I have right now is the generation of a variadic template function:
template<class... Args>
ret_type wrapper_name(Args... args) {
return function(std::forward<Args>(args)...);
}
But this causes a world of problems with conversions because there's a lot that cannot be done with implicit conversions in this form when the wrapped function is overloaded. It also can't wrap function-like macros, but I think addressing that problem may be impossible anyway.
Update: With a bit of fiddling I can make the wrapper function enforce its argument types this way:
#define WRAPPER(name, ret_type, function, ...) \
template<class... Args> struct name##_impl { static inline \
ret_type func(Args... args) { return function(std::forward<Args>(args)...); } }; \
template<class... Args> ret_type name(Args... args) \
{ return name##_impl<__VA_ARGS__>::func(std::forward<Args>(args)...); }
Unfortunately, this leaves me with the problem that I cannot overload the identifier name with different argument lists. My attempts at making the name template a specialisation have resulted in a lot of complaints either about partial specialisation of a function or about not forwarding any template arguments to the generic template.
Using a variadic macro to generate a non-template wrapper, you can use some macro tricks, specifically this trick, to generate your argument list with names so you can call your target function, eg:
And then you can use
WRAP_FUNCTIONlike you want:Online Demo
With some tweaking, I'm sure you can also generate a template wrapper, too.