[Fusion] Building parameter list for fusion::invoke

I am building a library in which users pass in function pointers of any type. I would like the library to determine the function's signature (using function_types), build a fusion vector for the function's arguments, populate the vector with data from a particular source, and then invoke the function using fusion::invoke. The kicker is that the argument types may not be default constructible. Therefore I need a way of initializing a fusion vector from a source as it is being created. For example, the following won't work namespace ft = ::boost::function_types; namespace bf = ::boost::fusion; struct non_def_type { private: non_def_type(); }; void my_func(non_def_type); template <typename FPTR> void my_invoker(FPTR f) { typedef typename ft::parameter_types<FPTR>::type parameter_types; typedef typename bf::result_of::as_vector<parameter_types>::type parameter_vector; parameter_vector params; // error if FPTR contains a parameter_type that is not default-constructible // // ... do something to populate params from data source // bf::invoke(f, params); } int main() { my_invoker(my_func); } Any idea how I might initialize the fusion vector as it is being created? I feel like there might be a way to transform parameter_types into a version in which each type is wrapped in a default-constructible wrapper, then transform that list into the final boost fusion list while at the same time populating it with data, but I can't seem to get the functors to work. E.g.: template <typename T> struct type_wrapper { type_wrapper() {} }; template <typename T> struct wrap { typedef type_wrapper<T> type; }; // Metafunction to unwrap types, and function to populate data // (data should never need to be default-constructible) struct fill { template <typename SIG> struct result; template <typename T> struct result<fill(const type_wrapper<T>&)> { typedef T type; }; // Reference type needed for bf::transform_view template <typename T> struct result<fill(type_wrapper<T>&)> { typedef T type; }; // Non-reference type needed for bf::vector template <typename T> struct result<fill(type_wrapper<T>)> { typedef T type; }; template <typename T> T operator()(const type_wrapper<T>&) const {return data_source<T>().pop();} }; template <typename FPTR> void my_invoker(FPTR f) { typedef typename ft::parameter_types<FPTR>::type parameter_types; // Conversion 1: create a fusion vector with types wrapped in a // default-constructible wrapper typedef mpl::transform<parameter_types, wrap<mpl::_1>, mpl::back_inserter<mpl::vector<> > >::type wrapped_parameter_types; typedef typename bf::result_of::as_vector<wrapped_parameter_types>::type wrapped_parameter_vector; // Conversion 2: create a fusion vector with the unwrapped types // that is also populated with the data from the data_source // (without having to ever default_construct any of the parameter_types) typedef typename bf::result_of::transform<const wrapped_params, fill>::type params_view; typedef typename bf::result_of::as_vector<const params_view>::type params_t; // Finally: invoke the function with arguments bf::invoke(f, bf::as_vector(bf::transform(params_view(), fill()))); } I can't seem to get the meta-function calls or the 'fill' metafunction itself quite right, instead getting vast reams of compiler complaints. Am I missing something? Or alternatively, is there a direct way to initialize a fusion vector? Many thanks, Vivek

On Jan 21, 2011, at 4:52 PM, Vivek <vivek@xmain.com> wrote:
I am building a library in which users pass in function pointers of any type. I would like the library to determine the function's signature (using function_types), build a fusion vector for the function's arguments, populate the vector with data from a particular source, and then invoke the function using fusion::invoke.
I recommend you study and adapt http://www.boost.org/doc/libs/1_45_0/libs/function_types/example/interpreter... .
participants (3)
-
Nat Goodspeed
-
TONGARI
-
Vivek