fork download
  1. #include <iostream>
  2. struct lua_State {};
  3. template<typename T>
  4. T CheckLuaValue( int n, lua_State* l)
  5. {
  6. std::cout << "arg[" << n << "] gotten\n";
  7. return T(n);
  8. }
  9.  
  10. template<int ...>
  11. struct seq { };
  12.  
  13. template<int First, int Last>
  14. struct gen_seq
  15. {
  16. template<int N, int... S>
  17. struct helper : helper<N-1, N-1, S...> {};
  18. template<int... S>
  19. struct helper<First, S...> {
  20. typedef seq<S...> type;
  21. };
  22. typedef typename helper<Last>::type type;
  23. };
  24.  
  25. template< typename X >
  26. struct MemberFunctionWrapper;
  27.  
  28. template< typename F >
  29. struct MemberFunctionHelper
  30. {
  31. typedef F MethodPtr;
  32. };
  33. template<class InstanceType, typename ReturnType, typename... Params>
  34. struct MemberFunctionWrapper< ReturnType(InstanceType::*)(Params...) >
  35. {
  36. typedef MemberFunctionHelper<ReturnType(InstanceType::*)(Params...)> Helper;
  37. typedef typename Helper::MethodPtr MethodPtr;
  38. static MethodPtr& GetFunctionPointer() {static MethodPtr pFunc; return pFunc;}
  39. static InstanceType*& GetMemberPointer() {static InstanceType* pThis;return pThis;}
  40. template<int n, typename Param>
  41. static auto GetLuaValue( lua_State* luaState )->decltype(CheckLuaValue<Param>(n,luaState))
  42. {
  43. return CheckLuaValue<Param>(n,luaState);
  44. }
  45.  
  46. template< typename sequence >
  47. struct call;
  48.  
  49. template< int... I >
  50. struct call<seq<I...>>
  51. {
  52. ReturnType operator()( lua_State* luaState, InstanceType* instance, MethodPtr method ) const
  53. {
  54. return (instance->*method)( GetLuaValue<I,Params>( luaState )... );
  55. }
  56. };
  57. static int CFunctionWrapper( lua_State* luaState)
  58. {
  59. MethodPtr func = GetFunctionPointer();
  60. InstanceType* instance = GetMemberPointer();
  61. ReturnType retval = call< typename gen_seq< 1, sizeof...(Params)+1 >::type >()( luaState, instance, func );
  62. return 0;
  63. }
  64. };
  65.  
  66. struct test{ int foo(int x, double d){std::cout << "x:" << x << " d:" << d << "\n";}};
  67. int main(){
  68. typedef MemberFunctionWrapper< int(test::*)(int, double) > wrapper;
  69. test bar;
  70. wrapper::GetFunctionPointer() = &test::foo;
  71. wrapper::GetMemberPointer() = &bar;
  72. wrapper::CFunctionWrapper(0);
  73. }
Success #stdin #stdout 0s 2884KB
stdin
Standard input is empty
stdout
arg[2] gotten
arg[1] gotten
x:1 d:2