- 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=