I am trying to write some code that wraps C++ functions into something that Lua can use. One of the main problems I'm trying to solve is passing values popped from the Lua stack into parameters for the C++ functions. The naive approach that has worked for me has been:
template<typename Ret, typename... Args>
int luaDRCall(lua_State* s) {
typedef RDelegate<Ret, Args...>* FunctionPtr;
FunctionPtr f = (FunctionPtr)popUpvalueObject(s);
Ret retValue = f->invoke(popValue<Args>(h)...);
return ScriptValueSender<Ret>::push(h, retValue);
}
However, this has caused me problems because "popValue(h)..." is not guaranteed to execute from right to left. Under a "Debug" build from MSVC, it works fine.... but the "Release" version calls the functions in reverse order. Therefore, I have written some code that is guaranteed to pop the values in correct order:
template<typename Ret, typename... Args>
int luaDRCall(lua_State* s) {
void* del = popUpvalueObject(s);
return fRCall<Ret, Args...>(s, del);
}
template<typename Ret, typename Arg, typename... Args>
int fRCall(EnvironmentHandle h, void* del) {
Arg v = popValue<Arg>(h);
return fRCall<Ret, Args..., Arg>(h, del, v);
}
template<typename Ret, typename Arg, typename... Args, typename... Popped>
int fRCall(EnvironmentHandle h, void* del, Popped... vPopped) {
Arg v = popValue<Arg>(h);
return fRCall<Ret, Args..., Popped..., Arg>(h, del, vPopped..., v);
}
template<typename Ret, typename... Args>
int fRCall(EnvironmentHandle h, void* del, Args... vPopped) {
typedef RDelegate<Ret, Args...>* FunctionPtr;
FunctionPtr f = (FunctionPtr)del;
Ret retValue = f->invoke(vPopped...);
return ScriptValueSender<Ret>::push(h, retValue);
}
Now, attempting to compile this code results in:
2>c:\induztry\git\vorb\include\script\Script.h(66): fatal error C1060: compiler is out of heap space
2>c1xx : fatal error C1063: INTERNAL COMPILER ERROR
2> Please choose the Technical Support command on the Visual C++
2> Help menu, or open the Technical Support help file for more information
Anybody have any ideas what is wrong and how I can fix it? Any other solutions to this problem would also be appreciated. Thank you.
EDIT 1: I have changed my code to the following with the help of one of the answers below, and it works now correctly as long as the function has at least one argument. If no arguments are present, I have compiler errors:
template<size_t... Is>
struct index_sequence {};
template<size_t N, size_t... Is>
struct make_index_sequence : make_index_sequence<N - 1, N - 1, Is...> {};
template<size_t... Is>
struct make_index_sequence<0, Is...> : index_sequence<Is...> {};
template<typename... T>
struct index_sequence_for : make_index_sequence<sizeof...(T)> {};
template <typename Ret, typename F, typename Tuple, size_t... Is>
Ret invoke(F f, Tuple& t, index_sequence<Is...>) {
return f->invoke(std::get<Is>(t)...);
}
template<typename Ret, typename... Args>
int luaDRCall(EnvironmentHandle h) {
typedef RDelegate<Ret, Args...>* FunctionPtr;
FunctionPtr f = (FunctionPtr)popUpvalueObject(h);
std::tuple<Args...> tValue { popValue<Args>(h)... };
Ret retValue = invoke<Ret>(f, tValue, index_sequence_for<Args...>());
return ScriptValueSender<Ret>::push(h, retValue);
}
It is necessary for me to put this all into one function for use, and attempting to do template specializations for no arguments results in compiler errors.
1>c:\induztry\git\vorb\include\script\Script.h(68): error C2143: syntax error : missing '}' before '<fake-type>'
1> c:\induztry\git\vorb\include\script\Script.h(105) : see reference to function template instantiation 'i32 vorb::script::impl::fRCall<Ret,>(vorb::script::EnvironmentHandle,void *)' being compiled
1> with
1> [
1> Ret=int
1> ]
1> c:\induztry\git\vorb\include\script\Script.h(122) : see reference to function template instantiation 'int vorb::script::impl::luaDRCall<Ret,>(lua_State *)' being compiled
1> with
1> [
1> Ret=int
1> ]
1> C:\InduZtry\Git\Vorb\include/script/Environment.h(76) : see reference to function template instantiation 'vorb::script::ScriptFunc vorb::script::fromRDelegate<Ret,>(void)' being compiled
1> with
1> [
1> Ret=int
1> ]
1> VorbScript.cpp(101) : see reference to function template instantiation 'void vorb::script::Environment::addCRDelegate<int,>(const std::string &,RDelegate<int,> &)' being compiled
1>c:\induztry\git\vorb\include\script\Script.h(68): error C2143: syntax error : missing ';' before '<fake-type>'
1>c:\induztry\git\vorb\include\script\Script.h(69): error C2146: syntax error : missing ';' before identifier 'retValue'
1>c:\induztry\git\vorb\include\script\Script.h(69): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\induztry\git\vorb\include\script\Script.h(69): error C2065: 'f' : undeclared identifier
1>c:\induztry\git\vorb\include\script\Script.h(69): error C2065: 'tValue' : undeclared identifier
1>c:\induztry\git\vorb\include\script\Script.h(69): error C3546: '...' : there are no parameter packs available to expand
1>c:\induztry\git\vorb\include\script\Script.h(69): error C2065: 'Args' : undeclared identifier
1>c:\induztry\git\vorb\include\script\Script.h(69): error C3544: 'T': parameter pack expects a type template argument
1>c:\induztry\git\vorb\include\script\Script.h(69): error C2955: 'vorb::script::impl::index_sequence_for' : use of class template requires template argument list
1> c:\induztry\git\vorb\include\script\Script.h(58) : see declaration of 'vorb::script::impl::index_sequence_for'
1>c:\induztry\git\vorb\include\script\Script.h(70): error C2059: syntax error : 'return'
1>c:\induztry\git\vorb\include\script\Script.h(70): error C2923: 'vorb::script::ScriptValueSender' : 'vorb::script::impl::Ret' is not a valid template type argument for parameter 'T'
1> c:\induztry\git\vorb\include\script\Script.h(69) : see declaration of 'vorb::script::impl::Ret'
1>c:\induztry\git\vorb\include\script\Script.h(70): error C2955: 'vorb::script::ScriptValueSender' : use of class template requires template argument list
1> c:\induztry\git\vorb\include\script\ScriptValueSenders.h(36) : see declaration of 'vorb::script::ScriptValueSender'
1>c:\induztry\git\vorb\include\script\Script.h(70): error C2027: use of undefined type 'vorb::script::ScriptValueSender'
1> c:\induztry\git\vorb\include\script\ScriptValueSenders.h(36) : see declaration of 'vorb::script::ScriptValueSender'
1>c:\induztry\git\vorb\include\script\Script.h(71): error C2059: syntax error : '}'
1>c:\induztry\git\vorb\include\script\Script.h(71): error C2143: syntax error : missing ';' before '}'
1>c:\induztry\git\vorb\include\script\ScriptImpl.h(82): error C2143: syntax error : missing ';' before '{'
1>c:\induztry\git\vorb\include\script\ScriptImpl.h(82): error C2447: '{' : missing function header (old-style formal list?)