fork download
  1. // Some metaprogramming boilerplate:
  2.  
  3. #include <tuple>
  4.  
  5. template<int...> struct seq {};
  6. template<int Min, int Max, int... s> struct make_seq:make_seq<Min, Max-1, Max-1, s...> {};
  7. template<int Min, int... s> struct make_seq<Min, Min, s...> {
  8. typedef seq<s...> type;
  9. };
  10. template<int Max, int Min=0>
  11. using MakeSeq = typename make_seq<Min, Max>::type;
  12.  
  13. // helper to unpack a tuple:
  14. template<typename Func, Func f, typename Tuple, int... s>
  15. void do_call( seq<s...>, Tuple&& tup ) {
  16. f( std::get<s>(tup)... );
  17. }
  18.  
  19. // Type of the resulting function pointer:
  20. typedef void(*pvoidary)(void*);
  21.  
  22. template<typename FuncType, FuncType Func, typename... Args>
  23. std::tuple<pvoidary, std::tuple<Args...>*> make_task( Args&&... args ) {
  24. typedef std::tuple<Args...> pack;
  25. pack* pvoid = new pack( std::forward<Args>(args)... );
  26. return std::make_tuple(
  27. [](void* pdata)->void {
  28. pack* ppack = reinterpret_cast<pack*>(pdata);
  29. do_call<FuncType, Func>( MakeSeq<sizeof...(Args)>(), *ppack );
  30. },
  31. pvoid
  32. );
  33. }
  34. #define MAKE_TASK( FUNC ) make_task< typename std::decay<decltype(FUNC)>::type, FUNC >
  35.  
  36. #include <iostream>
  37.  
  38.  
  39. void test( int x ) {
  40. std::cout << "X:" << x << "\n";
  41. }
  42. void test2( std::string s ) {
  43. std::cout << "S:" << s.c_str() << "\n";
  44. }
  45. int main() {
  46. auto task = MAKE_TASK(test)( 7 );
  47. pvoidary pFunc;
  48. void* pVoid;
  49. std::tie(pFunc, pVoid) = task;
  50. pFunc(pVoid);
  51. delete std::get<1>(task); // cleanup of the "void*"
  52. auto task2 = MAKE_TASK(test2)("hello");
  53. std::tie(pFunc, pVoid) = task2;
  54. pFunc(pVoid);
  55. delete std::get<1>(task2); // cleanup of the "void*"
  56. }
  57.  
Success #stdin #stdout 0s 2984KB
stdin
Standard input is empty
stdout
X:7
S:hello