fork download
  1. template<unsigned... Is> struct seq{};
  2. template<unsigned N, unsigned... Is>
  3. struct gen_seq : gen_seq<N-1, N-1, Is...>{};
  4. template<unsigned... Is>
  5. struct gen_seq<0, Is...> : seq<Is...>{};
  6.  
  7. template<class T> using Alias = T; // for temporary arrays
  8.  
  9. template<class F, class It, unsigned N, unsigned... Is>
  10. auto invoke_2(F f, It (&&args)[N], seq<Is...>)
  11. -> decltype(f(*args[Is]...))
  12. {
  13. return f(*args[Is]...);
  14. }
  15.  
  16. template<class F, class Args, unsigned... Is>
  17. auto invoke_1(F f, Args& cont, seq<Is...> s)
  18. -> decltype(invoke_2(f, std::declval<decltype(cont.begin())[sizeof...(Is)]>(), s))
  19. {
  20. auto it = cont.begin();
  21. return invoke_2(f, Alias<decltype(it)[]>{(void(Is), ++it)...}, s);
  22. }
  23.  
  24. template<unsigned ArgC, class F, class Args>
  25. auto invoke(F f, Args& cont)
  26. -> decltype(invoke_1(f, cont, gen_seq<ArgC>{}))
  27. {
  28. return invoke_1(f, cont, gen_seq<ArgC>{});
  29. }
  30.  
  31. #include <type_traits>
  32.  
  33. template<unsigned I> using Uint = std::integral_constant<unsigned, I>;
  34.  
  35. struct invoke_test{
  36. template<class F, class T, class... Args, unsigned I>
  37. static auto eval(int, Uint<I> c) -> decltype(void(std::declval<F>()(std::declval<Args>()...)), c);
  38. template<class F, class T, class... Args, unsigned I>
  39. static auto eval(long, Uint<I>) -> decltype(eval<F, T, Args..., T>(0, Uint<I+1>{}));
  40. };
  41.  
  42. template<class F, class T>
  43. struct min_arity : decltype(invoke_test::eval<F, T>(0, Uint<0>{})){};
  44.  
  45. #include <iostream>
  46. #include <vector>
  47.  
  48. void f(int, int, int, int){ std::cout << "f(int,int,int,int) called\n"; }
  49.  
  50. struct X{
  51. void operator()(int, int, int){}
  52. };
  53.  
  54. int main(){
  55. std::vector<int> args{1,2,3,4};
  56. invoke<4>(f, args);
  57. static_assert(min_arity<X, int>::value == 3, "eh");
  58. }
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty