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