2

I'm attempting to automate the production of functions to perform parameter and result marshalling to/from variant-based callback functions. The ultimate aim is to ease the integration of callbacks to one or more scripting languages (probably JavaScript and/or Lua).

I'm new to C++ template metaprogramming (and SO) so I'm sure I've made a bunch of newbie mistakes in my approach. Here's what I have so far...

namespace mpl = boost::mpl;
namespace ft = boost::function_types;
namespace fusion = boost::fusion;

typedef boost::variant<boost::none_t, bool, int, double, std::wstring> Variant;
typedef std::vector<Variant> VariantList;

template < typename T >
VariantList AppendVariantToList(VariantList list, const T &t)
{
   list.push_back(t);
   return list;
}

template < typename T >
T get(Variant &v)
{
   return boost::get<T>(v);
}

typedef Variant callback_type(const VariantList &);

Variant InvokeCallback(const VariantList &args)
{
   // This method will eventually invoke the actual script callback.
   return true;
}

template < typename Function
   , class From = typename mpl::begin<ft::parameter_types<Function>>::type
   , class To   = typename mpl::end<ft::parameter_types<Function>>::type
   >
struct callback_binder
{
   typedef typename mpl::deref<From>::type arg_type;
   typedef typename mpl::next<From>::type next_iter_type;

   template < int n >
   static auto apply() -> decltype(boost::bind(AppendVariantToList<arg_type>, callback_binder<Function, next_iter_type, To>::apply<n + 1>(), boost::arg<n>()))
   {
      return boost::bind(AppendVariantToList<arg_type>, callback_binder<Function, next_iter_type, To>::apply<n + 1>(), boost::arg<n>());
   }

   static boost::function<Function> apply_1st(callback_type callback)
   {
      return boost::bind(get<bool>, boost::bind(callback, callback_binder<Function, From, To>::apply<1>()));
   }
};

template < typename Function, class To >
struct callback_binder < Function, To, To >
{
   template < int n >
   static auto apply() -> decltype(boost::bind(boost::value_factory<VariantList>()))
   {
      return boost::bind(boost::value_factory<VariantList>());
   }
};

template < typename Function >
boost::function<Function> make_callback(callback_type callback)
{
   return callback_binder<Function>::apply_1st(callback);
}

bool OnSomeEvent(int a, int b)
{
   const static auto callback(make_callback<BOOST_TYPEOF(OnSomeEvent)>(InvokeCallback));
   return callback(a, b);
}

InvokeCallback represents the function that will ultimately invoke the scripting language's function. OnSomeEvent is an example of the sort of place I'll want to invoke a script's callback function. The idea is that the callback_binder::apply methods iterate OnSomeEvent's parameter types and create a functor that populates a VariantList, calls InvokeCallback and returns the result.

Things seemed to be working up to the point I introduced the < int n > template parameter to the apply methods to enable me to iterate boost::args. Unfortunately, attempting to compile the code above crashes MS VC++ 2010 RTM so I'm stuck as to how to proceed.

EDIT: perhaps the specific question I'm asking is, "how do I access boost::bind's placeholders in the 'metaloop' I'm using above?"

Thanks
Simon

sdc395
  • 255
  • 1
  • 3
  • 12

1 Answers1

0

I tghink that I am a lot like you: I always want to automate this sort of task.

You can roll this automatic marshalling yourself using templates.

But I much prefer using something like SWIG, the Simplified Wrapper and Interface Generator. http://www.swig.org/

Unfortunately, last time I used SWIG it did not support all the srtandard language features of C++ that I was using. But it is often good enough.

I have also used OpenC++.

I have also used gccxml, http://www.gccxml.org, although it is quite out of date.

See Attribute & Reflection libraries for C++?

I have not used XRTTI.


Finally, I sometimes force myself to use a macro language that I can easily preprocess myself, to gehnerate the necessary code.

Community
  • 1
  • 1
Krazy Glew
  • 7,210
  • 2
  • 49
  • 62