fork download
  1. #include <iostream>
  2. #include <functional>
  3.  
  4. template<bool, class Ty1, class Ty2>
  5. struct If
  6. {
  7. typedef Ty2 type;
  8. };
  9.  
  10. template<class Ty1, class Ty2>
  11. struct If<true, Ty1, Ty2>
  12. {
  13. typedef Ty1 type;
  14. };
  15.  
  16. template<class... Types>
  17. struct Arg_types
  18. {
  19. };
  20.  
  21. template<class Ty1>
  22. struct Arg_types<Ty1>
  23. {
  24. typedef Ty1 argument_type;
  25. };
  26.  
  27. template<class Ty1, class Ty2>
  28. struct Arg_types<Ty1, Ty2>
  29. {
  30. typedef Ty1 first_argument_type;
  31. typedef Ty2 second_argument_type;
  32. };
  33.  
  34. template<class Ty>
  35. struct Is_memfunptr
  36. {
  37. typedef std::false_type Bool_type;
  38. };
  39.  
  40. template<class Ret, class Arg0, class... Types>
  41. struct Is_memfunptr<Ret(Arg0::*)(Types...)> : Arg_types<Arg0 *, Types...>
  42. {
  43. typedef std::true_type Bool_type;
  44. typedef Ret result_type;
  45. typedef Arg0 Class_type;
  46. };
  47.  
  48. template<class _Ret, class _Arg0, class... _Types>
  49. struct Is_memfunptr<_Ret(_Arg0::*)(_Types..., ...)>
  50. {
  51. typedef std::true_type Bool_type;
  52. typedef _Ret result_type;
  53. typedef _Arg0 Class_type;
  54. };
  55.  
  56. struct Invoker_pmf_object
  57. {
  58. template<class Decayed, class Ty1, class... Types2>
  59. static auto Call(Decayed Pmf, Ty1&& Arg1, Types2&&... Args2)
  60. -> decltype((std::forward<Ty1>(Arg1).*Pmf)(
  61. std::forward<Types2>(Args2)...))
  62. {
  63. return ((std::forward<Ty1>(Arg1).*Pmf)(
  64. std::forward<Types2>(Args2)...));
  65. }
  66. };
  67.  
  68. struct Invoker_pmf_pointer
  69. {
  70. template<class Decayed, class Ty1, class... Types2>
  71. static auto Call(Decayed Pmf, Ty1&& Arg1, Types2&&... Args2)
  72. -> decltype(((*std::forward<Ty1>(Arg1)).*Pmf)(
  73. std::forward<Types2>(Args2)...))
  74. {
  75. return (((*std::forward<Ty1>(Arg1)).*Pmf)(
  76. std::forward<Types2>(Args2)...));
  77. }
  78. };
  79.  
  80. template<class Callable, class Ty1, class Decayed = typename std::decay<Callable>::type>
  81. struct Invoker1 : If<
  82. std::is_base_of<
  83. typename Is_memfunptr<Decayed>::Class_type,
  84. typename std::decay<Ty1>::type
  85. >::value,
  86. Invoker_pmf_object,
  87. Invoker_pmf_pointer>::type
  88. {
  89. };
  90.  
  91. template<class Callable, class... Types>
  92. struct Invoker;
  93.  
  94. template<class Callable, class Ty1, class... Types2>
  95. struct Invoker<Callable, Ty1, Types2...> : Invoker1<Callable, Ty1>
  96. {
  97. };
  98.  
  99. template<class Callable, class... Types>
  100. inline auto Invoke(Callable&& obj, Types&&... args) -> decltype(
  101. Invoker<Callable, Types...>::Call(std::forward<Callable>(obj), std::forward<Types>(args)...))
  102. {
  103. return (Invoker<Callable, Types...>::Call(
  104. std::forward<Callable>(obj), std::forward<Types>(args)...));
  105. }
  106.  
  107. ///////////////////////////////////////////////////
  108.  
  109. class Test
  110. {
  111. public:
  112. void m1(int x) { std::cout << "m1(" << x << ")\n"; };
  113. };
  114.  
  115. int main()
  116. {
  117. Invoke(&Test::m1, Test(), 20);
  118. }
Success #stdin #stdout 0s 3468KB
stdin
Standard input is empty
stdout
m1(20)