template<unsigned... Is> struct seq{};
template<unsigned N, unsigned... Is>
struct gen_seq : gen_seq<N-1, N-1, Is...>{};
template<unsigned... Is>
struct gen_seq<0, Is...> : seq<Is...>{};
template<class T> using Alias = T; // for temporary arrays
template<class F, class It, unsigned N, unsigned... Is>
auto invoke_2(F f, It (&&args)[N], seq<Is...>)
-> decltype(f(*args[Is]...))
{
return f(*args[Is]...);
}
template<class F, class Args, unsigned... Is>
auto invoke_1(F f, Args& cont, seq<Is...> s)
-> decltype(invoke_2(f, std::declval<decltype(cont.begin())[sizeof...(Is)]>(), s))
{
auto it = cont.begin();
return invoke_2(f, Alias<decltype(it)[]>{(void(Is), ++it)...}, s);
}
template<unsigned ArgC, class F, class Args>
auto invoke(F f, Args& cont)
-> decltype(invoke_1(f, cont, gen_seq<ArgC>{}))
{
return invoke_1(f, cont, gen_seq<ArgC>{});
}
#include <type_traits>
template<unsigned I> using Uint = std::integral_constant<unsigned, I>;
struct invoke_test{
template<class F, class T, class... Args, unsigned I>
static auto eval(int, Uint<I> c) -> decltype(void(std::declval<F>()(std::declval<Args>()...)), c);
template<class F, class T, class... Args, unsigned I>
static auto eval(long, Uint<I>) -> decltype(eval<F, T, Args..., T>(0, Uint<I+1>{}));
};
template<class F, class T>
struct min_arity : decltype(invoke_test::eval<F, T>(0, Uint<0>{})){};
#include <iostream>
#include <vector>
void f(int, int, int, int){ std::cout << "f(int,int,int,int) called\n"; }
struct X{
void operator()(int, int, int){}
};
int main(){
std::vector<int> args{1,2,3,4};
invoke<4>(f, args);
static_assert(min_arity<X, int>::value == 3, "eh");
}
dGVtcGxhdGU8dW5zaWduZWQuLi4gSXM+IHN0cnVjdCBzZXF7fTsKdGVtcGxhdGU8dW5zaWduZWQgTiwgdW5zaWduZWQuLi4gSXM+CnN0cnVjdCBnZW5fc2VxIDogZ2VuX3NlcTxOLTEsIE4tMSwgSXMuLi4+e307CnRlbXBsYXRlPHVuc2lnbmVkLi4uIElzPgpzdHJ1Y3QgZ2VuX3NlcTwwLCBJcy4uLj4gOiBzZXE8SXMuLi4+e307Cgp0ZW1wbGF0ZTxjbGFzcyBUPiB1c2luZyBBbGlhcyA9IFQ7IC8vIGZvciB0ZW1wb3JhcnkgYXJyYXlzCgp0ZW1wbGF0ZTxjbGFzcyBGLCBjbGFzcyBJdCwgdW5zaWduZWQgTiwgdW5zaWduZWQuLi4gSXM+CmF1dG8gaW52b2tlXzIoRiBmLCBJdCAoJiZhcmdzKVtOXSwgc2VxPElzLi4uPikKICAtPiBkZWNsdHlwZShmKCphcmdzW0lzXS4uLikpCnsKICByZXR1cm4gZigqYXJnc1tJc10uLi4pOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBGLCBjbGFzcyBBcmdzLCB1bnNpZ25lZC4uLiBJcz4KYXV0byBpbnZva2VfMShGIGYsIEFyZ3MmIGNvbnQsIHNlcTxJcy4uLj4gcykKICAtPiBkZWNsdHlwZShpbnZva2VfMihmLCBzdGQ6OmRlY2x2YWw8ZGVjbHR5cGUoY29udC5iZWdpbigpKVtzaXplb2YuLi4oSXMpXT4oKSwgcykpCnsKICBhdXRvIGl0ID0gY29udC5iZWdpbigpOwogIHJldHVybiBpbnZva2VfMihmLCBBbGlhczxkZWNsdHlwZShpdClbXT57KHZvaWQoSXMpLCArK2l0KS4uLn0sIHMpOwp9Cgp0ZW1wbGF0ZTx1bnNpZ25lZCBBcmdDLCBjbGFzcyBGLCBjbGFzcyBBcmdzPgphdXRvIGludm9rZShGIGYsIEFyZ3MmIGNvbnQpCiAgLT4gZGVjbHR5cGUoaW52b2tlXzEoZiwgY29udCwgZ2VuX3NlcTxBcmdDPnt9KSkKewogIHJldHVybiBpbnZva2VfMShmLCBjb250LCBnZW5fc2VxPEFyZ0M+e30pOwp9CgojaW5jbHVkZSA8dHlwZV90cmFpdHM+Cgp0ZW1wbGF0ZTx1bnNpZ25lZCBJPiB1c2luZyBVaW50ID0gc3RkOjppbnRlZ3JhbF9jb25zdGFudDx1bnNpZ25lZCwgST47CgpzdHJ1Y3QgaW52b2tlX3Rlc3R7CiAgdGVtcGxhdGU8Y2xhc3MgRiwgY2xhc3MgVCwgY2xhc3MuLi4gQXJncywgdW5zaWduZWQgST4KICBzdGF0aWMgYXV0byBldmFsKGludCwgVWludDxJPiBjKSAtPiBkZWNsdHlwZSh2b2lkKHN0ZDo6ZGVjbHZhbDxGPigpKHN0ZDo6ZGVjbHZhbDxBcmdzPigpLi4uKSksIGMpOwogIHRlbXBsYXRlPGNsYXNzIEYsIGNsYXNzIFQsIGNsYXNzLi4uIEFyZ3MsIHVuc2lnbmVkIEk+CiAgc3RhdGljIGF1dG8gZXZhbChsb25nLCBVaW50PEk+KSAtPiBkZWNsdHlwZShldmFsPEYsIFQsIEFyZ3MuLi4sIFQ+KDAsIFVpbnQ8SSsxPnt9KSk7Cn07Cgp0ZW1wbGF0ZTxjbGFzcyBGLCBjbGFzcyBUPgpzdHJ1Y3QgbWluX2FyaXR5IDogZGVjbHR5cGUoaW52b2tlX3Rlc3Q6OmV2YWw8RiwgVD4oMCwgVWludDwwPnt9KSl7fTsKCiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHZlY3Rvcj4KCnZvaWQgZihpbnQsIGludCwgaW50LCBpbnQpeyBzdGQ6OmNvdXQgPDwgImYoaW50LGludCxpbnQsaW50KSBjYWxsZWRcbiI7IH0KCnN0cnVjdCBYewogIHZvaWQgb3BlcmF0b3IoKShpbnQsIGludCwgaW50KXt9Cn07CgppbnQgbWFpbigpewogICAgc3RkOjp2ZWN0b3I8aW50PiBhcmdzezEsMiwzLDR9OwogICAgaW52b2tlPDQ+KGYsIGFyZ3MpOwogICAgc3RhdGljX2Fzc2VydChtaW5fYXJpdHk8WCwgaW50Pjo6dmFsdWUgPT0gMywgImVoIik7Cn0=