diff --git a/library/include/DataFuncs.h b/library/include/DataFuncs.h index 5f5a4bd72e..e8bfc7e284 100644 --- a/library/include/DataFuncs.h +++ b/library/include/DataFuncs.h @@ -48,9 +48,28 @@ namespace df { template concept isPrimitive = identity_traits::is_primitive || std::is_enum_v || std::is_void_v; - template - T get_from_lua_state(lua_State* L, int idx) { - T val; + // handle call-by-reference function arguments by converting pointers to a reference + // will throw if lua code tries to pass a null pointer + template requires std::is_reference_v + T get_from_lua_state(lua_State* L, int idx) + { + using DFHack::LuaWrapper::field_error; + using Ptr = std::add_pointer_t>; + Ptr ptr{}; + df::identity_traits::get()->lua_write(L, UPVAL_METHOD_NAME, &ptr, idx); + if (ptr == nullptr) + { + field_error(L, UPVAL_METHOD_NAME, "cannot convert null pointer to reference", "call"); + } + return *ptr; + } + + // handle call-by-value function arguments. only semi-regular types are allowed + // (semi-regular covers copyable and default-constructible) + template + T get_from_lua_state(lua_State* L, int idx) + { + T val{}; df::identity_traits::get()->lua_write(L, UPVAL_METHOD_NAME, &val, idx); return val; }