diff --git a/sol/stack.hpp b/sol/stack.hpp index 43adfc70..c2c11683 100644 --- a/sol/stack.hpp +++ b/sol/stack.hpp @@ -76,18 +76,18 @@ inline std::pair get_as_upvalues(lua_State* L, int index = 1) { template ::value>> inline decltype(auto) call(types, types ta, std::index_sequence tai, lua_State* L, int start, Fx&& fx, FxArgs&&... args) { - typedef meta::index_in_pack state_pack_index; - typedef std::integral_constant(state_pack_index::value)> state_idx; + typedef meta::index_in_pack state_index; + typedef meta::index_in_pack va_pack_index; check_types{}.check(ta, tai, L, start, type_panic); - return fx(std::forward(args)..., stack_detail::unchecked_get(L, start + (state_idx::value < I ? I - 1 : I))...); + return fx(std::forward(args)..., stack_detail::unchecked_get(L, start + I - static_cast(state_index::value < I) - static_cast(va_pack_index::value < I))...); } template inline void call(types, types ta, std::index_sequence tai, lua_State* L, int start, Fx&& fx, FxArgs&&... args) { - typedef meta::index_in_pack state_pack_index; - typedef std::integral_constant(state_pack_index::value)> state_idx; + typedef meta::index_in_pack state_index; + typedef meta::index_in_pack va_pack_index; check_types{}.check(ta, tai, L, start, type_panic); - fx(std::forward(args)..., stack_detail::unchecked_get(L, start + (state_idx::value < I ? I - 1 : I))...); + fx(std::forward(args)..., stack_detail::unchecked_get(L, start + I - static_cast(state_index::value < I) - static_cast(va_pack_index::value < I))...); } } // stack_detail diff --git a/sol/stack_check.hpp b/sol/stack_check.hpp index 30559331..d23643e2 100644 --- a/sol/stack_check.hpp +++ b/sol/stack_check.hpp @@ -61,11 +61,11 @@ struct basic_check { template struct check_types { - template - static bool check(types, std::index_sequence, lua_State* L, int firstargument, Handler&& handler) { - if (!stack::check(L, firstargument + I0, handler)) + template + static bool check(types, std::index_sequence, lua_State* L, int firstargument, Handler&& handler) { + if (!stack::check(L, firstargument + I0, handler)) return false; - return check(types(), std::index_sequence(), L, firstargument - static_cast(std::is_same>::value), std::forward(handler)); + return check(types(), std::index_sequence(), L, firstargument - static_cast(is_transparent_argument>::value), std::forward(handler)); } template diff --git a/sol/traits.hpp b/sol/traits.hpp index fe5464d5..e1eed967 100644 --- a/sol/traits.hpp +++ b/sol/traits.hpp @@ -134,7 +134,7 @@ struct find_in_pack_v : Or, find_i namespace meta_detail { template - struct index_in_pack : std::integral_constant { }; + struct index_in_pack : std::integral_constant { }; template struct index_in_pack : std::conditional_t::value, std::integral_constant, index_in_pack> { }; diff --git a/sol/types.hpp b/sol/types.hpp index 3a47b289..93f67160 100644 --- a/sol/types.hpp +++ b/sol/types.hpp @@ -315,6 +315,8 @@ using lightuserdata = basic_lightuserdata; using stack_lightuserdata = basic_lightuserdata; class coroutine; class thread; +struct variadic_args; +struct this_state; template struct lua_type_of : std::integral_constant {}; @@ -434,6 +436,15 @@ struct is_proxy_primitive : is_lua_primitive { }; template struct is_unique_usertype : std::false_type {}; +template +struct is_transparent_argument : std::false_type {}; + +template <> +struct is_transparent_argument : std::true_type {}; + +template <> +struct is_transparent_argument : std::true_type {}; + template inline type type_of() { return lua_type_of>::value; diff --git a/test_functions.cpp b/test_functions.cpp index 68cd0c18..312816e9 100644 --- a/test_functions.cpp +++ b/test_functions.cpp @@ -781,3 +781,11 @@ TEST_CASE("functions/variadic_args", "Check to see we can receive multiple argum REQUIRE(lx2.b); REQUIRE_FALSE(lx3.b); } + +TEST_CASE("functions/required_and_variadic_args", "Check if a certain number of arguments can still be required even when using variadic_args") { + sol::state lua; + lua.set_function("v", [](sol::this_state, sol::variadic_args, int, int) {}); + REQUIRE_NOTHROW(lua.script("v(20, 25, 30)")); + REQUIRE_NOTHROW(lua.script("v(20, 25)")); + REQUIRE_THROWS(lua.script("v(20)")); +}