mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Ensure argument transparency.
This commit is contained in:
parent
062d2281d5
commit
96da27d565
|
@ -76,18 +76,18 @@ inline std::pair<T, int> get_as_upvalues(lua_State* L, int index = 1) {
|
||||||
|
|
||||||
template <bool checkargs = default_check_arguments, std::size_t... I, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
|
template <bool checkargs = default_check_arguments, std::size_t... I, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
|
||||||
inline decltype(auto) call(types<R>, types<Args...> ta, std::index_sequence<I...> tai, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
|
inline decltype(auto) call(types<R>, types<Args...> ta, std::index_sequence<I...> tai, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
|
||||||
typedef meta::index_in_pack<this_state, Args...> state_pack_index;
|
typedef meta::index_in_pack<this_state, Args...> state_index;
|
||||||
typedef std::integral_constant<int, state_pack_index::value == -1 ? INT_MAX : static_cast<int>(state_pack_index::value)> state_idx;
|
typedef meta::index_in_pack<variadic_args, Args...> va_pack_index;
|
||||||
check_types<checkargs>{}.check(ta, tai, L, start, type_panic);
|
check_types<checkargs>{}.check(ta, tai, L, start, type_panic);
|
||||||
return fx(std::forward<FxArgs>(args)..., stack_detail::unchecked_get<Args>(L, start + (state_idx::value < I ? I - 1 : I))...);
|
return fx(std::forward<FxArgs>(args)..., stack_detail::unchecked_get<Args>(L, start + I - static_cast<int>(state_index::value < I) - static_cast<int>(va_pack_index::value < I))...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool checkargs = default_check_arguments, std::size_t... I, typename... Args, typename Fx, typename... FxArgs>
|
template <bool checkargs = default_check_arguments, std::size_t... I, typename... Args, typename Fx, typename... FxArgs>
|
||||||
inline void call(types<void>, types<Args...> ta, std::index_sequence<I...> tai, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
|
inline void call(types<void>, types<Args...> ta, std::index_sequence<I...> tai, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
|
||||||
typedef meta::index_in_pack<this_state, Args...> state_pack_index;
|
typedef meta::index_in_pack<this_state, Args...> state_index;
|
||||||
typedef std::integral_constant<int, state_pack_index::value == -1 ? INT_MAX : static_cast<int>(state_pack_index::value)> state_idx;
|
typedef meta::index_in_pack<variadic_args, Args...> va_pack_index;
|
||||||
check_types<checkargs>{}.check(ta, tai, L, start, type_panic);
|
check_types<checkargs>{}.check(ta, tai, L, start, type_panic);
|
||||||
fx(std::forward<FxArgs>(args)..., stack_detail::unchecked_get<Args>(L, start + (state_idx::value < I ? I - 1 : I))...);
|
fx(std::forward<FxArgs>(args)..., stack_detail::unchecked_get<Args>(L, start + I - static_cast<int>(state_index::value < I) - static_cast<int>(va_pack_index::value < I))...);
|
||||||
}
|
}
|
||||||
} // stack_detail
|
} // stack_detail
|
||||||
|
|
||||||
|
|
|
@ -61,11 +61,11 @@ struct basic_check {
|
||||||
|
|
||||||
template <bool b>
|
template <bool b>
|
||||||
struct check_types {
|
struct check_types {
|
||||||
template <std::size_t I0, std::size_t... I, typename Arg0, typename... Args, typename Handler>
|
template <std::size_t I0, std::size_t... I, typename T, typename... Args, typename Handler>
|
||||||
static bool check(types<Arg0, Args...>, std::index_sequence<I0, I...>, lua_State* L, int firstargument, Handler&& handler) {
|
static bool check(types<T, Args...>, std::index_sequence<I0, I...>, lua_State* L, int firstargument, Handler&& handler) {
|
||||||
if (!stack::check<Arg0>(L, firstargument + I0, handler))
|
if (!stack::check<T>(L, firstargument + I0, handler))
|
||||||
return false;
|
return false;
|
||||||
return check(types<Args...>(), std::index_sequence<I...>(), L, firstargument - static_cast<int>(std::is_same<this_state, meta::Unqualified<Arg0>>::value), std::forward<Handler>(handler));
|
return check(types<Args...>(), std::index_sequence<I...>(), L, firstargument - static_cast<int>(is_transparent_argument<meta::Unqualified<T>>::value), std::forward<Handler>(handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Handler>
|
template <typename Handler>
|
||||||
|
|
|
@ -134,7 +134,7 @@ struct find_in_pack_v<V, Vs1, Vs...> : Or<Bool<(V::value == Vs1::value)>, find_i
|
||||||
|
|
||||||
namespace meta_detail {
|
namespace meta_detail {
|
||||||
template<std::size_t I, typename T, typename... Args>
|
template<std::size_t I, typename T, typename... Args>
|
||||||
struct index_in_pack : std::integral_constant<std::ptrdiff_t, -1> { };
|
struct index_in_pack : std::integral_constant<std::size_t, SIZE_MAX> { };
|
||||||
|
|
||||||
template<std::size_t I, typename T, typename T1, typename... Args>
|
template<std::size_t I, typename T, typename T1, typename... Args>
|
||||||
struct index_in_pack<I, T, T1, Args...> : std::conditional_t<std::is_same<T, T1>::value, std::integral_constant<std::ptrdiff_t, I>, index_in_pack<I + 1, T, Args...>> { };
|
struct index_in_pack<I, T, T1, Args...> : std::conditional_t<std::is_same<T, T1>::value, std::integral_constant<std::ptrdiff_t, I>, index_in_pack<I + 1, T, Args...>> { };
|
||||||
|
|
|
@ -315,6 +315,8 @@ using lightuserdata = basic_lightuserdata<reference>;
|
||||||
using stack_lightuserdata = basic_lightuserdata<stack_reference>;
|
using stack_lightuserdata = basic_lightuserdata<stack_reference>;
|
||||||
class coroutine;
|
class coroutine;
|
||||||
class thread;
|
class thread;
|
||||||
|
struct variadic_args;
|
||||||
|
struct this_state;
|
||||||
|
|
||||||
template <typename T, typename = void>
|
template <typename T, typename = void>
|
||||||
struct lua_type_of : std::integral_constant<type, type::userdata> {};
|
struct lua_type_of : std::integral_constant<type, type::userdata> {};
|
||||||
|
@ -434,6 +436,15 @@ struct is_proxy_primitive : is_lua_primitive<T> { };
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_unique_usertype : std::false_type {};
|
struct is_unique_usertype : std::false_type {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_transparent_argument : std::false_type {};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct is_transparent_argument<this_state> : std::true_type {};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct is_transparent_argument<variadic_args> : std::true_type {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline type type_of() {
|
inline type type_of() {
|
||||||
return lua_type_of<meta::Unqualified<T>>::value;
|
return lua_type_of<meta::Unqualified<T>>::value;
|
||||||
|
|
|
@ -781,3 +781,11 @@ TEST_CASE("functions/variadic_args", "Check to see we can receive multiple argum
|
||||||
REQUIRE(lx2.b);
|
REQUIRE(lx2.b);
|
||||||
REQUIRE_FALSE(lx3.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)"));
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user