mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Now protect should work in multiple places, albeit we still need to do some optimizations to kick it in
Address #137 and improve implementation to not have to pop arguments
This commit is contained in:
parent
febfdbadb7
commit
ac5f13ce2f
20
sol/call.hpp
20
sol/call.hpp
|
@ -53,7 +53,7 @@ namespace sol {
|
||||||
static void call(Args...) {}
|
static void call(Args...) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, int additional_pop = 0>
|
template <typename T>
|
||||||
struct constructor_match {
|
struct constructor_match {
|
||||||
T* obj;
|
T* obj;
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ namespace sol {
|
||||||
template <typename Fx, std::size_t I, typename... R, typename... Args>
|
template <typename Fx, std::size_t I, typename... R, typename... Args>
|
||||||
int operator()(types<Fx>, index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) const {
|
int operator()(types<Fx>, index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) const {
|
||||||
detail::default_construct func{};
|
detail::default_construct func{};
|
||||||
return stack::call_into_lua<additional_pop, false>(r, a, L, start, func, obj);
|
return stack::call_into_lua<false>(r, a, L, start, func, obj);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ namespace sol {
|
||||||
typedef typename wrap::returns_list returns_list;
|
typedef typename wrap::returns_list returns_list;
|
||||||
typedef typename wrap::free_args_list args_list;
|
typedef typename wrap::free_args_list args_list;
|
||||||
typedef typename wrap::caller caller;
|
typedef typename wrap::caller caller;
|
||||||
return stack::call_into_lua<is_index ? 1 : 2, checked>(returns_list(), args_list(), L, boost + ( is_index ? 2 : 3 ), caller(), std::forward<Fx>(f));
|
return stack::call_into_lua<checked>(returns_list(), args_list(), L, boost + ( is_index ? 2 : 3 ), caller(), std::forward<Fx>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fx>
|
template <typename Fx>
|
||||||
|
@ -161,7 +161,7 @@ namespace sol {
|
||||||
typedef typename wrap::free_args_list args_list;
|
typedef typename wrap::free_args_list args_list;
|
||||||
typedef typename wrap::returns_list returns_list;
|
typedef typename wrap::returns_list returns_list;
|
||||||
typedef typename wrap::caller caller;
|
typedef typename wrap::caller caller;
|
||||||
return stack::call_into_lua<0, checked>(returns_list(), args_list(), L, boost + 1, caller(), std::forward<Fx>(f));
|
return stack::call_into_lua<checked>(returns_list(), args_list(), L, boost + 1, caller(), std::forward<Fx>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fx>
|
template <typename Fx>
|
||||||
|
@ -219,7 +219,7 @@ namespace sol {
|
||||||
typedef typename wrap::returns_list returns_list;
|
typedef typename wrap::returns_list returns_list;
|
||||||
typedef typename wrap::args_list args_list;
|
typedef typename wrap::args_list args_list;
|
||||||
typedef typename wrap::caller caller;
|
typedef typename wrap::caller caller;
|
||||||
return stack::call_into_lua<is_variable ? 2 : 1, checked>(returns_list(), args_list(), L, boost + ( is_variable ? 3 : 2 ), caller(), std::forward<Fx>(f), o);
|
return stack::call_into_lua<checked>(returns_list(), args_list(), L, boost + ( is_variable ? 3 : 2 ), caller(), std::forward<Fx>(f), o);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fx>
|
template <typename Fx>
|
||||||
|
@ -248,7 +248,7 @@ namespace sol {
|
||||||
static int call_assign(std::true_type, lua_State* L, V&& f, object_type& o) {
|
static int call_assign(std::true_type, lua_State* L, V&& f, object_type& o) {
|
||||||
typedef typename wrap::args_list args_list;
|
typedef typename wrap::args_list args_list;
|
||||||
typedef typename wrap::caller caller;
|
typedef typename wrap::caller caller;
|
||||||
return stack::call_into_lua<is_variable ? 2 : 1>(types<void>(), args_list(), L, boost + ( is_variable ? 3 : 2 ), caller(), f, o);
|
return stack::call_into_lua<checked>(types<void>(), args_list(), L, boost + ( is_variable ? 3 : 2 ), caller(), f, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename V>
|
template <typename V>
|
||||||
|
@ -306,7 +306,7 @@ namespace sol {
|
||||||
static int call(lua_State* L, V&& f, object_type& o) {
|
static int call(lua_State* L, V&& f, object_type& o) {
|
||||||
typedef typename wrap::returns_list returns_list;
|
typedef typename wrap::returns_list returns_list;
|
||||||
typedef typename wrap::caller caller;
|
typedef typename wrap::caller caller;
|
||||||
return stack::call_into_lua<is_variable ? 2 : 1, checked>(returns_list(), types<>(), L, boost + ( is_variable ? 3 : 2 ), caller(), f, o);
|
return stack::call_into_lua<checked>(returns_list(), types<>(), L, boost + ( is_variable ? 3 : 2 ), caller(), f, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename V>
|
template <typename V>
|
||||||
|
@ -344,7 +344,7 @@ namespace sol {
|
||||||
T* obj = reinterpret_cast<T*>(pointerpointer + 1);
|
T* obj = reinterpret_cast<T*>(pointerpointer + 1);
|
||||||
referencepointer = obj;
|
referencepointer = obj;
|
||||||
|
|
||||||
construct_match<T, Args...>(constructor_match<T, 1>(obj), L, argcount, boost + 1 + static_cast<int>(syntax));
|
construct_match<T, Args...>(constructor_match<T>(obj), L, argcount, boost + 1 + static_cast<int>(syntax));
|
||||||
|
|
||||||
userdataref.push();
|
userdataref.push();
|
||||||
luaL_getmetatable(L, &metakey[0]);
|
luaL_getmetatable(L, &metakey[0]);
|
||||||
|
@ -367,13 +367,13 @@ namespace sol {
|
||||||
int operator()(types<Fx>, index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start, F& f) {
|
int operator()(types<Fx>, index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start, F& f) {
|
||||||
const auto& metakey = usertype_traits<T>::metatable;
|
const auto& metakey = usertype_traits<T>::metatable;
|
||||||
T** pointerpointer = reinterpret_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
|
T** pointerpointer = reinterpret_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
|
||||||
reference userdataref(L, -1);
|
stack_reference userdataref(L, -1);
|
||||||
T*& referencepointer = *pointerpointer;
|
T*& referencepointer = *pointerpointer;
|
||||||
T* obj = reinterpret_cast<T*>(pointerpointer + 1);
|
T* obj = reinterpret_cast<T*>(pointerpointer + 1);
|
||||||
referencepointer = obj;
|
referencepointer = obj;
|
||||||
|
|
||||||
auto& func = std::get<I>(f.set);
|
auto& func = std::get<I>(f.set);
|
||||||
stack::call_into_lua<1, checked>(r, a, L, boost + start, func, detail::implicit_wrapper<T>(obj));
|
stack::call_into_lua<checked>(r, a, L, boost + start, func, detail::implicit_wrapper<T>(obj));
|
||||||
|
|
||||||
userdataref.push();
|
userdataref.push();
|
||||||
luaL_getmetatable(L, &metakey[0]);
|
luaL_getmetatable(L, &metakey[0]);
|
||||||
|
|
|
@ -28,11 +28,6 @@
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
namespace function_detail {
|
namespace function_detail {
|
||||||
inline decltype(auto) cleanup_key() {
|
|
||||||
const auto& name = u8"sol.ƒ.♲.🗑.(/¯◡ ‿ ◡)/¯ ~ ┻━┻ (ノ◕ヮ◕)ノ*:・゚✧";
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Fx>
|
template <typename Fx>
|
||||||
inline int call(lua_State* L) {
|
inline int call(lua_State* L) {
|
||||||
Fx& fx = stack::get<user<Fx>>(L, upvalue_index(1));
|
Fx& fx = stack::get<user<Fx>>(L, upvalue_index(1));
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace sol {
|
||||||
functor_function(Function f, Args&&... args) : fx(std::move(f), std::forward<Args>(args)...) {}
|
functor_function(Function f, Args&&... args) : fx(std::move(f), std::forward<Args>(args)...) {}
|
||||||
|
|
||||||
int call(lua_State* L) {
|
int call(lua_State* L) {
|
||||||
return stack::call_into_lua(meta::tuple_types<return_type>(), args_lists(), L, 1, fx);
|
return call_detail::call_wrapped<void, true, false>(L, fx);
|
||||||
}
|
}
|
||||||
|
|
||||||
int operator()(lua_State* L) {
|
int operator()(lua_State* L) {
|
||||||
|
@ -52,35 +52,20 @@ namespace sol {
|
||||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||||
typedef meta::function_return_t<function_type> return_type;
|
typedef meta::function_return_t<function_type> return_type;
|
||||||
typedef meta::function_args_t<function_type> args_lists;
|
typedef meta::function_args_t<function_type> args_lists;
|
||||||
struct functor {
|
|
||||||
function_type invocation;
|
function_type invocation;
|
||||||
T member;
|
T member;
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
functor(function_type f, Args&&... args) : invocation(std::move(f)), member(std::forward<Args>(args)...) {}
|
member_function(function_type f, Args&&... args) : invocation(std::move(f)), member(std::forward<Args>(args)...) {}
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
return_type operator()(Args&&... args) {
|
|
||||||
auto& mem = detail::unwrap(detail::deref(member));
|
|
||||||
return (mem.*invocation)(std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
} fx;
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
member_function(function_type f, Args&&... args) : fx(std::move(f), std::forward<Args>(args)...) {}
|
|
||||||
|
|
||||||
int call(lua_State* L) {
|
int call(lua_State* L) {
|
||||||
return stack::call_into_lua(meta::tuple_types<return_type>(), args_lists(), L, 1, fx);
|
return call_detail::call_wrapped<T, true, false, -1>(L, invocation, detail::unwrap(detail::deref(member)));
|
||||||
}
|
}
|
||||||
|
|
||||||
int operator()(lua_State* L) {
|
int operator()(lua_State* L) {
|
||||||
auto f = [&](lua_State* L) -> int { return this->call(L); };
|
auto f = [&](lua_State* L) -> int { return this->call(L); };
|
||||||
return detail::trampoline(L, f);
|
return detail::trampoline(L, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
~member_function() {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename Function>
|
template<typename T, typename Function>
|
||||||
|
@ -95,34 +80,13 @@ namespace sol {
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
member_variable(function_type v, Args&&... args) : var(std::move(v)), member(std::forward<Args>(args)...) {}
|
member_variable(function_type v, Args&&... args) : var(std::move(v)), member(std::forward<Args>(args)...) {}
|
||||||
|
|
||||||
int set_assignable(std::false_type, lua_State* L, M) {
|
|
||||||
lua_pop(L, 1);
|
|
||||||
return luaL_error(L, "sol: cannot write to this type: copy assignment/constructor not available");
|
|
||||||
}
|
|
||||||
|
|
||||||
int set_assignable(std::true_type, lua_State* L, M mem) {
|
|
||||||
(mem.*var) = stack::get<return_type>(L, 1);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int set_variable(std::true_type, lua_State* L, M mem) {
|
|
||||||
return set_assignable(std::is_assignable<std::add_lvalue_reference_t<return_type>, return_type>(), L, mem);
|
|
||||||
}
|
|
||||||
|
|
||||||
int set_variable(std::false_type, lua_State* L, M) {
|
|
||||||
lua_pop(L, 1);
|
|
||||||
return luaL_error(L, "sol: cannot write to a const variable");
|
|
||||||
}
|
|
||||||
|
|
||||||
int call(lua_State* L) {
|
int call(lua_State* L) {
|
||||||
M mem = detail::unwrap(detail::deref(member));
|
M mem = detail::unwrap(detail::deref(member));
|
||||||
switch (lua_gettop(L)) {
|
switch (lua_gettop(L)) {
|
||||||
case 0:
|
case 0:
|
||||||
stack::push(L, (mem.*var));
|
return call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
|
||||||
return 1;
|
|
||||||
case 1:
|
case 1:
|
||||||
return set_variable(meta::neg<std::is_const<return_type>>(), L, mem);
|
return call_detail::call_wrapped<T, false, false, -1>(L, var, mem);
|
||||||
default:
|
default:
|
||||||
return luaL_error(L, "sol: incorrect number of arguments to member variable function");
|
return luaL_error(L, "sol: incorrect number of arguments to member variable function");
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,7 @@ namespace sol {
|
||||||
static int real_call(lua_State* L) {
|
static int real_call(lua_State* L) {
|
||||||
auto udata = stack::stack_detail::get_as_upvalues<function_type*>(L);
|
auto udata = stack::stack_detail::get_as_upvalues<function_type*>(L);
|
||||||
function_type* fx = udata.first;
|
function_type* fx = udata.first;
|
||||||
int r = stack::call_into_lua(meta::tuple_types<typename traits_type::return_type>(), typename traits_type::args_list(), L, 1, fx);
|
return call_detail::call_wrapped<void, true, false>(L, fx);
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int call(lua_State* L) {
|
static int call(lua_State* L) {
|
||||||
|
@ -62,10 +61,7 @@ namespace sol {
|
||||||
auto objdata = stack::stack_detail::get_as_upvalues<T*>(L, memberdata.second);
|
auto objdata = stack::stack_detail::get_as_upvalues<T*>(L, memberdata.second);
|
||||||
function_type& memfx = memberdata.first;
|
function_type& memfx = memberdata.first;
|
||||||
auto& item = *objdata.first;
|
auto& item = *objdata.first;
|
||||||
auto fx = [&item, &memfx](auto&&... args) -> typename traits_type::return_type {
|
return call_detail::call_wrapped<T, true, false, -1>(L, memfx, item);
|
||||||
return (item.*memfx)(std::forward<decltype(args)>(args)...);
|
|
||||||
};
|
|
||||||
return stack::call_into_lua(meta::tuple_types<typename traits_type::return_type>(), typename traits_type::args_list(), L, 1, fx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int call(lua_State* L) {
|
static int call(lua_State* L) {
|
||||||
|
@ -77,30 +73,6 @@ namespace sol {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <int N, typename R, typename M, typename V>
|
|
||||||
int set_assignable(std::false_type, lua_State* L, M&, V&) {
|
|
||||||
lua_pop(L, N);
|
|
||||||
return luaL_error(L, "sol: cannot write to this type: copy assignment/constructor not available");
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int N, typename R, typename M, typename V>
|
|
||||||
int set_assignable(std::true_type, lua_State* L, M& mem, V& var) {
|
|
||||||
(mem.*var) = stack::get<R>(L, N);
|
|
||||||
lua_pop(L, N);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int N, typename R, typename M, typename V>
|
|
||||||
int set_variable(std::true_type, lua_State* L, M& mem, V& var) {
|
|
||||||
return set_assignable<N, R>(std::is_assignable<std::add_lvalue_reference_t<R>, R>(), L, mem, var);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int N, typename R, typename M, typename V>
|
|
||||||
int set_variable(std::false_type, lua_State* L, M&, V&) {
|
|
||||||
lua_pop(L, N);
|
|
||||||
return luaL_error(L, "sol: cannot write to a const variable");
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename Function>
|
template<typename T, typename Function>
|
||||||
struct upvalue_member_variable {
|
struct upvalue_member_variable {
|
||||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||||
|
@ -118,11 +90,9 @@ namespace sol {
|
||||||
function_type& var = memberdata.first;
|
function_type& var = memberdata.first;
|
||||||
switch (lua_gettop(L)) {
|
switch (lua_gettop(L)) {
|
||||||
case 0:
|
case 0:
|
||||||
stack::push(L, (mem.*var));
|
return call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
|
||||||
return 1;
|
|
||||||
case 1:
|
case 1:
|
||||||
set_variable<1, typename traits_type::return_type>(meta::neg<std::is_const<typename traits_type::return_type>>(), L, mem, var);
|
return call_detail::call_wrapped<T, false, false, -1>(L, var, mem);
|
||||||
return 0;
|
|
||||||
default:
|
default:
|
||||||
return luaL_error(L, "sol: incorrect number of arguments to member variable function");
|
return luaL_error(L, "sol: incorrect number of arguments to member variable function");
|
||||||
}
|
}
|
||||||
|
@ -168,16 +138,12 @@ namespace sol {
|
||||||
// Layout:
|
// Layout:
|
||||||
// idx 1...n: verbatim data of member variable pointer
|
// idx 1...n: verbatim data of member variable pointer
|
||||||
auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L, 1);
|
auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L, 1);
|
||||||
auto& mem = stack::get<T>(L, 1);
|
|
||||||
function_type& var = memberdata.first;
|
function_type& var = memberdata.first;
|
||||||
switch (lua_gettop(L)) {
|
switch (lua_gettop(L)) {
|
||||||
case 1:
|
case 1:
|
||||||
lua_pop(L, 1);
|
return call_detail::call_wrapped<T, true, false>(L, var);
|
||||||
stack::push(L, (mem.*var));
|
|
||||||
return 1;
|
|
||||||
case 2:
|
case 2:
|
||||||
set_variable<2, typename traits_type::return_type>(meta::neg<std::is_const<typename traits_type::return_type>>(), L, mem, var);
|
return call_detail::call_wrapped<T, false, false>(L, var);
|
||||||
return 0;
|
|
||||||
default:
|
default:
|
||||||
return luaL_error(L, "sol: incorrect number of arguments to member variable function");
|
return luaL_error(L, "sol: incorrect number of arguments to member variable function");
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,20 +36,17 @@ namespace sol {
|
||||||
|
|
||||||
template <typename R, typename V, V, typename T>
|
template <typename R, typename V, V, typename T>
|
||||||
inline int call_set_assignable(std::false_type, T&&, lua_State* L) {
|
inline int call_set_assignable(std::false_type, T&&, lua_State* L) {
|
||||||
lua_pop(L, 2);
|
|
||||||
return luaL_error(L, "cannot write to this type: copy assignment/constructor not available");
|
return luaL_error(L, "cannot write to this type: copy assignment/constructor not available");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename R, typename V, V variable, typename T>
|
template <typename R, typename V, V variable, typename T>
|
||||||
inline int call_set_assignable(std::true_type, lua_State* L, T&& mem) {
|
inline int call_set_assignable(std::true_type, lua_State* L, T&& mem) {
|
||||||
(mem.*variable) = stack::get<R>(L, 2);
|
(mem.*variable) = stack::get<R>(L, 2);
|
||||||
lua_pop(L, 2);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename R, typename V, V, typename T>
|
template <typename R, typename V, V, typename T>
|
||||||
inline int call_set_variable(std::false_type, lua_State* L, T&&) {
|
inline int call_set_variable(std::false_type, lua_State* L, T&&) {
|
||||||
lua_pop(L, 2);
|
|
||||||
return luaL_error(L, "cannot write to a const variable");
|
return luaL_error(L, "cannot write to a const variable");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +64,6 @@ namespace sol {
|
||||||
switch (lua_gettop(L)) {
|
switch (lua_gettop(L)) {
|
||||||
case 1: {
|
case 1: {
|
||||||
decltype(auto) r = (mem.*variable);
|
decltype(auto) r = (mem.*variable);
|
||||||
lua_pop(L, 1);
|
|
||||||
stack::push_reference(L, std::forward<decltype(r)>(r));
|
stack::push_reference(L, std::forward<decltype(r)>(r));
|
||||||
return 1; }
|
return 1; }
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -84,17 +80,7 @@ namespace sol {
|
||||||
|
|
||||||
template <typename F, F fx>
|
template <typename F, F fx>
|
||||||
inline int call_wrapper_function(std::true_type, lua_State* L) {
|
inline int call_wrapper_function(std::true_type, lua_State* L) {
|
||||||
typedef meta::bind_traits<meta::unqualified_t<F>> traits_type;
|
return call_detail::call_wrapped<void, false, false>(L, fx);
|
||||||
typedef typename traits_type::object_type T;
|
|
||||||
typedef typename traits_type::args_list args_list;
|
|
||||||
typedef typename traits_type::return_type return_type;
|
|
||||||
typedef meta::tuple_types<return_type> return_type_list;
|
|
||||||
auto mfx = [&](auto&&... args) -> typename traits_type::return_type {
|
|
||||||
auto& member = stack::get<T>(L, 1);
|
|
||||||
return (member.*fx)(std::forward<decltype(args)>(args)...);
|
|
||||||
};
|
|
||||||
int n = stack::call_into_lua<1>(return_type_list(), args_list(), L, 2, mfx);
|
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F, F fx>
|
template <typename F, F fx>
|
||||||
|
|
|
@ -145,23 +145,19 @@ namespace sol {
|
||||||
call<check_args>(tr, ta, L, static_cast<int>(lua_gettop(L) - sizeof...(Args)), std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
|
call<check_args>(tr, ta, L, static_cast<int>(lua_gettop(L) - sizeof...(Args)), std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int additionalpop = 0, bool check_args = stack_detail::default_check_arguments, typename... Args, typename Fx, typename... FxArgs>
|
template<bool check_args = stack_detail::default_check_arguments, typename... Args, typename Fx, typename... FxArgs>
|
||||||
inline int call_into_lua(types<void> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
|
inline int call_into_lua(types<void> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
|
||||||
call<check_args>(tr, ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
|
call<check_args>(tr, ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
|
||||||
int nargs = static_cast<int>(sizeof...(Args)) + additionalpop - meta::count_for_pack<is_transparent_argument, Args...>::value;
|
|
||||||
lua_pop(L, nargs);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int additionalpop = 0, bool check_args = stack_detail::default_check_arguments, typename Ret0, typename... Ret, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<meta::neg<std::is_void<Ret0>>::value>>
|
template<bool check_args = stack_detail::default_check_arguments, typename Ret0, typename... Ret, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<meta::neg<std::is_void<Ret0>>::value>>
|
||||||
inline int call_into_lua(types<Ret0, Ret...>, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
|
inline int call_into_lua(types<Ret0, Ret...>, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
|
||||||
decltype(auto) r = call<check_args>(types<meta::return_type_t<Ret0, Ret...>>(), ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
|
decltype(auto) r = call<check_args>(types<meta::return_type_t<Ret0, Ret...>>(), ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
|
||||||
int nargs = static_cast<int>(sizeof...(Args)) + additionalpop - meta::count_for_pack<is_transparent_argument, Args...>::value;
|
|
||||||
lua_pop(L, nargs);
|
|
||||||
return push_reference(L, std::forward<decltype(r)>(r));
|
return push_reference(L, std::forward<decltype(r)>(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int additionalpop = 0, bool check_args = stack_detail::default_check_arguments, typename Fx, typename... FxArgs>
|
template<bool check_args = stack_detail::default_check_arguments, typename Fx, typename... FxArgs>
|
||||||
inline int call_lua(lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
|
inline int call_lua(lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
|
||||||
typedef lua_bind_traits<meta::unqualified_t<Fx>> traits_type;
|
typedef lua_bind_traits<meta::unqualified_t<Fx>> traits_type;
|
||||||
typedef typename traits_type::args_list args_list;
|
typedef typename traits_type::args_list args_list;
|
||||||
|
|
|
@ -355,7 +355,7 @@ namespace sol {
|
||||||
struct checker<optional<T>, type::poly, C> {
|
struct checker<optional<T>, type::poly, C> {
|
||||||
template <typename Handler>
|
template <typename Handler>
|
||||||
static bool check(lua_State* L, int index, Handler&& handler) {
|
static bool check(lua_State* L, int index, Handler&& handler) {
|
||||||
return stack::check<nil_t>(L, index, no_panic) || stack::check<T>(L, index, std::forward<Handler>(handler));
|
return lua_isnoneornil(L, index) || stack::check<T>(L, index, std::forward<Handler>(handler));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // stack
|
} // stack
|
||||||
|
|
|
@ -95,7 +95,7 @@ namespace sol {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct getter<optional<T>> {
|
struct getter<optional<T>> {
|
||||||
static decltype(auto) get(lua_State* L, int index) {
|
static decltype(auto) get(lua_State* L, int index) {
|
||||||
return check_get<T>(L, index);
|
return check_get<T>(L, index, no_panic);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // stack
|
} // stack
|
||||||
|
|
|
@ -287,12 +287,14 @@ namespace sol {
|
||||||
std::allocator<T> alloc;
|
std::allocator<T> alloc;
|
||||||
alloc.construct(data, std::forward<Args>(args)...);
|
alloc.construct(data, std::forward<Args>(args)...);
|
||||||
if (with_meta) {
|
if (with_meta) {
|
||||||
|
const auto& name = "\x73\x6F\x6C\x2E\xC6\x92\x2E\xE2\x99\xB2\x2E\xF0\x9F\x97\x91\x2E\x28\x2F\xC2\xAF\xE2\x97\xA1\x20\xE2\x80\xBF\x20\xE2\x97\xA1\x29\x2F\xC2\xAF\x20\x7E\x20\xE2\x94\xBB\xE2\x94\x81\xE2\x94\xBB\x20\x28\xEF\xBE\x89\xE2\x97\x95\xE3\x83\xAE\xE2\x97\x95\x29\xEF\xBE\x89\x2A\x3A\xEF\xBD\xA5\xEF\xBE\x9F\xE2\x9C\xA7";
|
||||||
lua_CFunction cdel = stack_detail::alloc_destroy<T>;
|
lua_CFunction cdel = stack_detail::alloc_destroy<T>;
|
||||||
// Make sure we have a plain GC set for this data
|
// Make sure we have a plain GC set for this data
|
||||||
lua_createtable(L, 0, 1);
|
if (luaL_newmetatable(L, name) != 0) {
|
||||||
lua_pushlightuserdata(L, rawdata);
|
lua_pushlightuserdata(L, rawdata);
|
||||||
lua_pushcclosure(L, cdel, 1);
|
lua_pushcclosure(L, cdel, 1);
|
||||||
lua_setfield(L, -2, "__gc");
|
lua_setfield(L, -2, "__gc");
|
||||||
|
}
|
||||||
lua_setmetatable(L, -2);
|
lua_setmetatable(L, -2);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -93,19 +93,20 @@ namespace sol {
|
||||||
return (mem.*fx)(std::forward<Args>(args)...);
|
return (mem.*fx)(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
static decltype(auto) call(F& fx, object_type& mem) {
|
template <typename Fx>
|
||||||
|
static decltype(auto) call(Fx&& fx, object_type& mem) {
|
||||||
return (mem.*fx);
|
return (mem.*fx);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Arg, typename... Args>
|
template <typename Fx, typename Arg, typename... Args>
|
||||||
static void call(F& fx, object_type& mem, Arg&& arg, Args&&...) {
|
static void call(Fx&& fx, object_type& mem, Arg&& arg, Args&&...) {
|
||||||
(mem.*fx) = std::forward<Arg>(arg);
|
(mem.*fx) = std::forward<Arg>(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct caller {
|
struct caller {
|
||||||
template <typename... Args>
|
template <typename Fx, typename... Args>
|
||||||
decltype(auto) operator()(F& fx, object_type& mem, Args&&... args) const {
|
decltype(auto) operator()(Fx&& fx, object_type& mem, Args&&... args) const {
|
||||||
return call(fx, mem, std::forward<Args>(args)...);
|
return call(std::forward<Fx>(fx), mem, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -131,15 +132,15 @@ namespace sol {
|
||||||
return (mem.*fx)(std::forward<Args>(args)...);
|
return (mem.*fx)(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename Fx, typename... Args>
|
||||||
static R call(F& fx, O& mem, Args&&... args) {
|
static R call(Fx&& fx, O& mem, Args&&... args) {
|
||||||
return (mem.*fx)(std::forward<Args>(args)...);
|
return (mem.*fx)(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct caller {
|
struct caller {
|
||||||
template <typename... Args>
|
template <typename Fx, typename... Args>
|
||||||
decltype(auto) operator()(F& fx, O& mem, Args&&... args) const {
|
decltype(auto) operator()(Fx&& fx, O& mem, Args&&... args) const {
|
||||||
return call(fx, mem, std::forward<Args>(args)...);
|
return call(std::forward<Fx>(fx), mem, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
24
tests.cpp
24
tests.cpp
|
@ -9,6 +9,14 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "test_stack_guard.hpp"
|
#include "test_stack_guard.hpp"
|
||||||
|
|
||||||
|
bool func_opt_ret_bool(sol::optional<int> i) {
|
||||||
|
if (i)
|
||||||
|
std::cout << i.value() << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << "optional isn't set" << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("table/traversal", "ensure that we can chain requests and tunnel down into a value if we desire") {
|
TEST_CASE("table/traversal", "ensure that we can chain requests and tunnel down into a value if we desire") {
|
||||||
|
|
||||||
sol::state lua;
|
sol::state lua;
|
||||||
|
@ -536,3 +544,19 @@ TEST_CASE("regressions/std::ref", "Ensure that std::reference_wrapper<> isn't co
|
||||||
REQUIRE(vp->a1 == 568);
|
REQUIRE(vp->a1 == 568);
|
||||||
REQUIRE(vr.a1 == 568);
|
REQUIRE(vr.a1 == 568);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("optional/left-out-args", "Make sure arguments can be left out of optional without tanking miserably") {
|
||||||
|
|
||||||
|
sol::state lua;
|
||||||
|
lua.open_libraries(sol::lib::base);
|
||||||
|
|
||||||
|
// sol::optional needs an argument no matter what
|
||||||
|
lua.set_function("func_opt_ret_bool", func_opt_ret_bool);
|
||||||
|
REQUIRE_NOTHROW(
|
||||||
|
lua.script(R"(
|
||||||
|
func_opt_ret_bool(42)
|
||||||
|
func_opt_ret_bool()
|
||||||
|
print('ok')
|
||||||
|
)");
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user