Автоматическая сортировка параметров и результатов обратного вызова скрипта - PullRequest
2 голосов
/ 20 декабря 2011

Я пытаюсь автоматизировать создание функций для выполнения параметризации и распределения результатов в / из функций обратного вызова на основе вариантов.Конечная цель - облегчить интеграцию обратных вызовов к одному или нескольким языкам сценариев (возможно, JavaScript и / или Lua).

Я новичок в метапрограммировании шаблонов C ++ (и SO), поэтому я уверен, чтоЯ сделал кучу ошибок новичка в моем подходе.Вот что у меня есть ...

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 представляет функцию, которая в конечном итоге вызовет функцию языка сценариев.OnSomeEvent - это пример того места, где я хочу вызвать функцию обратного вызова скрипта.Идея состоит в том, что методы callback_binder::apply повторяют типы параметров OnSomeEvent и создают функтор, который заполняет VariantList, вызывает InvokeCallback и возвращает результат.

Кажется, что все работает доЯ ввел параметр шаблона < int n > в методы apply, чтобы я мог выполнить итерацию boost::args.К сожалению, попытка скомпилировать приведенный выше код приводит к сбою MS VC ++ 2010 RTM, поэтому я застрял в том, что делать дальше.

РЕДАКТИРОВАТЬ: возможно, конкретный вопрос, который я задаю, - «как мне получить доступ к boost::bindзаполнители в 'metaloop', который я использую выше? "

Спасибо
Simon

1 Ответ

0 голосов
/ 25 февраля 2012

Я думаю, что я очень похож на вас: я всегда хочу автоматизировать такого рода задачи.

Вы можете запустить эту автоматическую сортировку самостоятельно, используя шаблоны.

Но я предпочитаю использовать что-то вроде SWIG, Упрощенного Обертки и Генератора Интерфейса. http://www.swig.org/

К сожалению, в прошлый раз, когда я использовал SWIG, он не поддерживал все стандартные функции языка C ++, которые я использовал. Но это часто достаточно хорошо.

Я также использовал OpenC ++.

Я также использовал gccxml, http://www.gccxml.org,, хотя он устарел.

См. Библиотеки атрибутов и отражений для C ++?

Я не использовал XRTTI.


Наконец, я иногда заставляю себя использовать макроязык, который я могу легко предварительно обработать, чтобы сгенерировать необходимый код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...