#include <iostream>
template<typename T> struct Type {};
typedef double lua_Number;
struct lua_State {};
int luaL_checkint( lua_State*, int index) {
return 7+index;
}
lua_Number luaL_checknumber( lua_State*, int index) {
return 3.14+index;
}
bool lua_toboolean( lua_State*, int index ) {
return index%2 == 0;
}
namespace lua_to_cpp {
inline int get(Type<int>, lua_State *l, const int index) {
return luaL_checkint(l, index);
};
inline lua_Number get(Type<lua_Number>, lua_State *l, const int index) {
return luaL_checknumber(l, index);
}
inline bool get(Type<bool>, lua_State *l, const int index) {
return lua_toboolean(l, index) != 0;
}
}
template<unsigned...>struct indexes{typedef indexes type;};
template<unsigned Max, unsigned...Is>struct make_indexes:make_indexes<Max-1, Max-1, Is...>{};
template<unsigned... Is>struct make_indexes<0, Is...>:indexes<Is...>{};
template<unsigned Max>using make_indexes_t=typename make_indexes<Max>::type;
template<typename... Args, unsigned... Is>
void invoke( void(*func)(Args...), lua_State* state, indexes<Is...>) {
return func( lua_to_cpp::get( Type<Args>{}, state, Is+2 )... );
}
template<typename... Args>
void invoke( void(*func)(Args...), lua_State* state ) {
invoke( func, state, make_indexes_t<sizeof...(Args)>{} );
}
void foo( int, lua_Number ) {
std::cout << "called!\n";
}
void call_foo( lua_State* state ) {
invoke(foo, state);
}
int main() {
call_foo(nullptr);
// your code goes here
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IFR5cGUge307CnR5cGVkZWYgZG91YmxlIGx1YV9OdW1iZXI7CnN0cnVjdCBsdWFfU3RhdGUge307CmludCBsdWFMX2NoZWNraW50KCBsdWFfU3RhdGUqLCBpbnQgaW5kZXgpIHsKCXJldHVybiA3K2luZGV4Owp9Cmx1YV9OdW1iZXIgbHVhTF9jaGVja251bWJlciggbHVhX1N0YXRlKiwgaW50IGluZGV4KSB7CglyZXR1cm4gMy4xNCtpbmRleDsKfQpib29sIGx1YV90b2Jvb2xlYW4oIGx1YV9TdGF0ZSosIGludCBpbmRleCApIHsKCXJldHVybiBpbmRleCUyID09IDA7Cn0KbmFtZXNwYWNlIGx1YV90b19jcHAgewoJaW5saW5lIGludCBnZXQoVHlwZTxpbnQ+LCBsdWFfU3RhdGUgKmwsIGNvbnN0IGludCBpbmRleCkgewoJCXJldHVybiBsdWFMX2NoZWNraW50KGwsIGluZGV4KTsKCX07CiAKCWlubGluZSBsdWFfTnVtYmVyIGdldChUeXBlPGx1YV9OdW1iZXI+LCBsdWFfU3RhdGUgKmwsIGNvbnN0IGludCBpbmRleCkgewoJCXJldHVybiBsdWFMX2NoZWNrbnVtYmVyKGwsIGluZGV4KTsKCX0KIAoJaW5saW5lIGJvb2wgZ2V0KFR5cGU8Ym9vbD4sIGx1YV9TdGF0ZSAqbCwgY29uc3QgaW50IGluZGV4KSB7CgkJcmV0dXJuIGx1YV90b2Jvb2xlYW4obCwgaW5kZXgpICE9IDA7Cgl9Cn0KdGVtcGxhdGU8dW5zaWduZWQuLi4+c3RydWN0IGluZGV4ZXN7dHlwZWRlZiBpbmRleGVzIHR5cGU7fTsKdGVtcGxhdGU8dW5zaWduZWQgTWF4LCB1bnNpZ25lZC4uLklzPnN0cnVjdCBtYWtlX2luZGV4ZXM6bWFrZV9pbmRleGVzPE1heC0xLCBNYXgtMSwgSXMuLi4+e307CnRlbXBsYXRlPHVuc2lnbmVkLi4uIElzPnN0cnVjdCBtYWtlX2luZGV4ZXM8MCwgSXMuLi4+OmluZGV4ZXM8SXMuLi4+e307CnRlbXBsYXRlPHVuc2lnbmVkIE1heD51c2luZyBtYWtlX2luZGV4ZXNfdD10eXBlbmFtZSBtYWtlX2luZGV4ZXM8TWF4Pjo6dHlwZTsKCnRlbXBsYXRlPHR5cGVuYW1lLi4uIEFyZ3MsIHVuc2lnbmVkLi4uIElzPgp2b2lkIGludm9rZSggdm9pZCgqZnVuYykoQXJncy4uLiksIGx1YV9TdGF0ZSogc3RhdGUsIGluZGV4ZXM8SXMuLi4+KSB7CglyZXR1cm4gZnVuYyggbHVhX3RvX2NwcDo6Z2V0KCBUeXBlPEFyZ3M+e30sIHN0YXRlLCBJcysyICkuLi4gKTsKfQp0ZW1wbGF0ZTx0eXBlbmFtZS4uLiBBcmdzPgp2b2lkIGludm9rZSggdm9pZCgqZnVuYykoQXJncy4uLiksIGx1YV9TdGF0ZSogc3RhdGUgKSB7CglpbnZva2UoIGZ1bmMsIHN0YXRlLCBtYWtlX2luZGV4ZXNfdDxzaXplb2YuLi4oQXJncyk+e30gKTsKfQoKdm9pZCBmb28oIGludCwgbHVhX051bWJlciApIHsKCXN0ZDo6Y291dCA8PCAiY2FsbGVkIVxuIjsKfQoKdm9pZCBjYWxsX2ZvbyggbHVhX1N0YXRlKiBzdGF0ZSApIHsKCWludm9rZShmb28sIHN0YXRlKTsKfQoKCmludCBtYWluKCkgewoJY2FsbF9mb28obnVsbHB0cik7CgkvLyB5b3VyIGNvZGUgZ29lcyBoZXJlCglyZXR1cm4gMDsKfQ==