Variadic Templates: Iterating over a Type / Template Argument

I have been working with libffi recently , and since it uses the C API, any abstraction is done using void (good ol 'C) pointers. I am creating a class (with variable templates) that uses this API. The class declaration is as follows: (where Ret = return value and Args = function arguments)

 template <typename Ret, typename... Args> class Function 

In this class, I have two different functions declared (simplified):

 Ret Call(Args... args); // Calls the wrapped function void CallbackBind(Ret * ret, void * args[]); // The libffi callback function (it actually static...) 

I want to use Call from CallbackBind ; and this is my problem. I do not know how I should convert the void* array to a list of template arguments. This is what I want more or less:

 CallbackBind(Ret * ret, void * args[]) { // I want to somehow expand the array of void pointers and convert each // one of them to the corresponding template type/argument. The length // of the 'void*' vector equals sizeof...(Args) (variadic template argument count) // Cast each of one of the pointers to their original type *ret = Call(*((typeof(Args[0])*) args[0]), *((typeof(Args[1])*) args[1]), ... /* and so on */); } 

If this is not possible, are there any workarounds or different solutions?

+6
source share
1 answer

You do not want to iterate over types, you want to create a package of parameters and deploy it in a variation template. You have an array, so the package you want is a package of integers 0,1,2 ... for serving indexes of arrays.

 #include <redi/index_tuple.h> template<typename Ret, typename... Args> struct Function { Ret (*wrapped_function)(Args...); template<unsigned... I> Ret dispatch(void* args[], redi::index_tuple<I...>) { return wrapped_function(*static_cast<Args*>(args[I])...); } void CallbackBind(Ret * ret, void * args[]) { *ret = dispatch(args, to_index_tuple<Args...>()); } }; 

Something like this using index_tuple.h

The trick is that CallbackBind creates an index_tuple integers representing arg positions and sends it to another function that outputs integers and extends the package to the list of expressions to use as arguments for the wrapped function.

+5
source

Source: https://habr.com/ru/post/918974/


All Articles