mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Add more tests and fix smaller errors with overloading and such.
This commit is contained in:
parent
115dfe39eb
commit
14ced4af69
|
@ -20,8 +20,8 @@
|
|||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// This file was generated with a script.
|
||||
// Generated 2016-07-08 00:10:28.267637 UTC
|
||||
// This header was generated with sol v2.9.0 (revision f7108d5)
|
||||
// Generated 2016-07-09 04:51:51.604138 UTC
|
||||
// This header was generated with sol v2.9.0 (revision 115dfe3)
|
||||
// https://github.com/ThePhD/sol2
|
||||
|
||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||
|
@ -325,6 +325,7 @@ namespace sol {
|
|||
typedef std::tuple<Arg> args_tuple;
|
||||
typedef R return_type;
|
||||
typedef types<Arg> args_list;
|
||||
typedef types<T, Arg> free_args_list;
|
||||
typedef meta::tuple_types<R> returns_list;
|
||||
typedef R(function_type)(T&, R);
|
||||
typedef R(*function_pointer_type)(T&, R);
|
||||
|
@ -6563,11 +6564,20 @@ namespace sol {
|
|||
template <typename T>
|
||||
struct protect_t {
|
||||
T value;
|
||||
|
||||
template <typename Arg, typename... Args, meta::disable<std::is_same<protect_t, meta::unqualified_t<Arg>>> = meta::enabler>
|
||||
protect_t(Arg&& arg, Args&&... args) : value(std::forward<Arg>(arg), std::forward<Args>(args)...) {}
|
||||
|
||||
protect_t(const protect_t&) = default;
|
||||
protect_t(protect_t&&) = default;
|
||||
protect_t& operator=(const protect_t&) = default;
|
||||
protect_t& operator=(protect_t&&) = default;
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
auto protect(T&& value) {
|
||||
return protect_t<std::decay_t<T>>{ std::forward<T>(value) };
|
||||
return protect_t<std::decay_t<T>>(std::forward<T>(value));
|
||||
}
|
||||
|
||||
} // sol
|
||||
|
@ -6755,101 +6765,116 @@ namespace sol {
|
|||
return 1;
|
||||
}
|
||||
|
||||
template <typename F, bool is_index, bool is_variable, bool checked, typename = void>
|
||||
template <typename F, bool is_index, bool is_variable, bool checked, int boost, typename = void>
|
||||
struct agnostic_lua_call_wrapper {
|
||||
static int var_call(std::true_type, lua_State* L, F& f) {
|
||||
template <typename Fx>
|
||||
static int var_call(std::true_type, lua_State* L, Fx&& f) {
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
typedef typename wrap::returns_list returns_list;
|
||||
typedef typename wrap::free_args_list args_list;
|
||||
typedef typename wrap::caller caller;
|
||||
return stack::call_into_lua<is_index ? 1 : 2, checked>(returns_list(), args_list(), L, is_index ? 2 : 3, caller(), f);
|
||||
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));
|
||||
}
|
||||
|
||||
static int var_call(std::false_type, lua_State* L, F& f) {
|
||||
template <typename Fx>
|
||||
static int var_call(std::false_type, lua_State* L, Fx&& f) {
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
typedef typename wrap::free_args_list args_list;
|
||||
typedef typename wrap::returns_list returns_list;
|
||||
typedef typename wrap::caller caller;
|
||||
return stack::call_into_lua<0, checked>(returns_list(), args_list(), L, 1, caller(), f);
|
||||
return stack::call_into_lua<0, checked>(returns_list(), args_list(), L, boost + 1, caller(), std::forward<Fx>(f));
|
||||
}
|
||||
|
||||
static int call(lua_State* L, F& f) {
|
||||
return var_call(std::integral_constant<bool, is_variable>(), L, f);
|
||||
template <typename Fx>
|
||||
static int call(lua_State* L, Fx&& f) {
|
||||
return var_call(std::integral_constant<bool, is_variable>(), L, std::forward<Fx>(f));
|
||||
}
|
||||
};
|
||||
|
||||
template <bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct agnostic_lua_call_wrapper<lua_r_CFunction, is_index, is_variable, checked, C> {
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<lua_r_CFunction, is_index, is_variable, checked, boost, C> {
|
||||
static int call(lua_State* L, lua_r_CFunction f) {
|
||||
return f(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct agnostic_lua_call_wrapper<lua_CFunction, is_index, is_variable, checked, C> {
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<lua_CFunction, is_index, is_variable, checked, boost, C> {
|
||||
static int call(lua_State* L, lua_CFunction f) {
|
||||
return f(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct agnostic_lua_call_wrapper<no_prop, is_index, is_variable, checked, C> {
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<no_prop, is_index, is_variable, checked, boost, C> {
|
||||
static int call(lua_State* L, const no_prop&) {
|
||||
return luaL_error(L, is_index ? "sol: cannot read from a writeonly property" : "sol: cannot write to a readonly property");
|
||||
}
|
||||
};
|
||||
|
||||
template <bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct agnostic_lua_call_wrapper<no_construction, is_index, is_variable, checked, C> {
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<no_construction, is_index, is_variable, checked, boost, C> {
|
||||
static int call(lua_State* L, const no_construction&) {
|
||||
return luaL_error(L, "sol: cannot call this constructor (tagged as non-constructible)");
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Args, bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct agnostic_lua_call_wrapper<bases<Args...>, is_index, is_variable, checked, C> {
|
||||
template <typename... Args, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<bases<Args...>, is_index, is_variable, checked, boost, C> {
|
||||
static int call(lua_State*, const bases<Args...>&) {
|
||||
// Uh. How did you even call this, lul
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename F, bool is_index, bool is_variable, bool checked = stack::stack_detail::default_check_arguments, typename = void>
|
||||
struct lua_call_wrapper : agnostic_lua_call_wrapper<F, is_index, is_variable, checked> {};
|
||||
template <typename T, typename F, bool is_index, bool is_variable, bool checked = stack::stack_detail::default_check_arguments, int boost = 0, typename = void>
|
||||
struct lua_call_wrapper : agnostic_lua_call_wrapper<F, is_index, is_variable, checked, boost> {};
|
||||
|
||||
template <typename T, typename F, bool is_index, bool is_variable, bool checked>
|
||||
struct lua_call_wrapper<T, F, is_index, is_variable, checked, std::enable_if_t<std::is_member_function_pointer<F>::value>> {
|
||||
static int call(lua_State* L, F& f) {
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
template <typename T, typename F, bool is_index, bool is_variable, bool checked, int boost>
|
||||
struct lua_call_wrapper<T, F, is_index, is_variable, checked, boost, std::enable_if_t<std::is_member_function_pointer<F>::value>> {
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
typedef typename wrap::object_type object_type;
|
||||
|
||||
template <typename Fx>
|
||||
static int call(lua_State* L, Fx&& f, object_type& o) {
|
||||
typedef typename wrap::returns_list returns_list;
|
||||
typedef typename wrap::args_list args_list;
|
||||
typedef typename wrap::caller caller;
|
||||
typedef typename wrap::object_type object_type;
|
||||
typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
|
||||
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);
|
||||
}
|
||||
|
||||
template <typename Fx>
|
||||
static int call(lua_State* L, Fx&& f) {
|
||||
typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
|
||||
#ifdef SOL_SAFE_USERTYPE
|
||||
object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
|
||||
if (o == nullptr) {
|
||||
return luaL_error(L, "sol: received null for 'self' argument (use ':' for accessing member functions, make sure member variables are preceeded by the actual object with '.' syntax)");
|
||||
}
|
||||
return stack::call_into_lua<is_variable ? 2 : 1, checked>(returns_list(), args_list(), L, is_variable ? 3 : 2, caller(), f, *o);
|
||||
return call(L, std::forward<Fx>(f), *o);
|
||||
#else
|
||||
object_type& o = static_cast<object_type&>(stack::get<Ta&>(L, 1));
|
||||
return stack::call_into_lua<is_variable ? 2 : 1, checked>(returns_list(), args_list(), L, is_variable ? 3 : 2, caller(), f, o);
|
||||
return call(L, std::forward<Fx>(f), o);
|
||||
#endif // Safety
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename F, bool is_variable, bool checked>
|
||||
struct lua_call_wrapper<T, F, false, is_variable, checked, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
|
||||
template <typename T, typename F, bool is_variable, bool checked, int boost>
|
||||
struct lua_call_wrapper<T, F, false, is_variable, checked, boost, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
|
||||
typedef sol::lua_bind_traits<F> traits_type;
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
typedef typename wrap::object_type object_type;
|
||||
|
||||
static int call_assign(std::true_type, lua_State* L, F& f) {
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
template <typename V>
|
||||
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::object_type object_type;
|
||||
typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
|
||||
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);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
static int call_assign(std::true_type, lua_State* L, V&& f) {
|
||||
typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
|
||||
#ifdef SOL_SAFE_USERTYPE
|
||||
object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
|
||||
if (o == nullptr) {
|
||||
|
@ -6858,58 +6883,74 @@ namespace sol {
|
|||
}
|
||||
return luaL_error(L, "sol: received nil for 'self' argument (pass 'self' as first argument)");
|
||||
}
|
||||
return stack::call_into_lua<is_variable ? 2 : 1>(types<void>(), args_list(), L, is_variable ? 3 : 2, caller(), f, *o);
|
||||
return call_assign(std::true_type(), L, f, *o);
|
||||
#else
|
||||
object_type& o = static_cast<object_type&>(stack::get<Ta&>(L, 1));
|
||||
return stack::call_into_lua<is_variable ? 2 : 1>(types<void>(), args_list(), L, is_variable ? 3 : 2, caller(), f, o);
|
||||
return call_assign(std::true_type(), L, f, o);
|
||||
#endif // Safety
|
||||
}
|
||||
|
||||
static int call_assign(std::false_type, lua_State* L, F&) {
|
||||
template <typename... Args>
|
||||
static int call_assign(std::false_type, lua_State* L, Args&&...) {
|
||||
return luaL_error(L, "sol: cannot write to this variable: copy assignment/constructor not available");
|
||||
}
|
||||
|
||||
static int call_const(std::false_type, lua_State* L, F& f) {
|
||||
template <typename... Args>
|
||||
static int call_const(std::false_type, lua_State* L, Args&&... args) {
|
||||
typedef typename traits_type::return_type R;
|
||||
return call_assign(std::is_assignable<std::add_lvalue_reference_t<meta::unqualified_t<R>>, R>(), L, f);
|
||||
return call_assign(std::is_assignable<std::add_lvalue_reference_t<meta::unqualified_t<R>>, R>(), L, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
static int call_const(std::true_type, lua_State* L, F&) {
|
||||
template <typename... Args>
|
||||
static int call_const(std::true_type, lua_State* L, Args&&...) {
|
||||
return luaL_error(L, "sol: cannot write to a readonly (const) variable");
|
||||
}
|
||||
|
||||
static int call(lua_State* L, F& f) {
|
||||
template <typename V>
|
||||
static int call(lua_State* L, V&& f) {
|
||||
return call_const(std::is_const<typename traits_type::return_type>(), L, f);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
static int call(lua_State* L, V&& f, object_type& o) {
|
||||
return call_const(std::is_const<typename traits_type::return_type>(), L, f, o);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename F, bool is_variable, bool checked>
|
||||
struct lua_call_wrapper<T, F, true, is_variable, checked, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
|
||||
template <typename T, typename F, bool is_variable, bool checked, int boost>
|
||||
struct lua_call_wrapper<T, F, true, is_variable, checked, boost, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
|
||||
typedef sol::lua_bind_traits<F> traits_type;
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
typedef typename wrap::object_type object_type;
|
||||
|
||||
static int call(lua_State* L, F& f) {
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
typedef typename wrap::object_type object_type;
|
||||
template <typename V>
|
||||
static int call(lua_State* L, V&& f, object_type& o) {
|
||||
typedef typename wrap::returns_list returns_list;
|
||||
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);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
static int call(lua_State* L, V&& f) {
|
||||
typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
|
||||
#ifdef SOL_SAFE_USERTYPE
|
||||
object_type* o = static_cast<object_type*>(stack::get<T*>(L, 1));
|
||||
object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
|
||||
if (o == nullptr) {
|
||||
if (is_variable) {
|
||||
return luaL_error(L, "sol: 'self' argument is nil (bad '.' access?)");
|
||||
}
|
||||
return luaL_error(L, "sol: 'self' argument is nil (pass 'self' as first argument)");
|
||||
}
|
||||
return stack::call_into_lua<is_variable ? 2 : 1, checked>(returns_list(), types<>(), L, is_variable ? 3 : 2, caller(), f, *o);
|
||||
return call(L, f, *o);
|
||||
#else
|
||||
object_type& o = static_cast<object_type&>(stack::get<T&>(L, 1));
|
||||
return stack::call_into_lua<is_variable ? 2 : 1, checked>(returns_list(), types<>(), L, is_variable ? 3 : 2, caller(), f, o);
|
||||
object_type& o = static_cast<object_type&>(stack::get<Ta&>(L, 1));
|
||||
return call(L, f, o);
|
||||
#endif // Safety
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Args, bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct lua_call_wrapper<T, sol::constructor_list<Args...>, is_index, is_variable, checked, C> {
|
||||
template <typename T, typename... Args, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct lua_call_wrapper<T, sol::constructor_list<Args...>, is_index, is_variable, checked, boost, C> {
|
||||
typedef sol::constructor_list<Args...> F;
|
||||
|
||||
static int call(lua_State* L, F&) {
|
||||
|
@ -6924,7 +6965,7 @@ namespace sol {
|
|||
T* obj = reinterpret_cast<T*>(pointerpointer + 1);
|
||||
referencepointer = obj;
|
||||
|
||||
construct_match<T, Args...>(constructor_match<T, 1>(obj), L, argcount, 1 + static_cast<int>(syntax));
|
||||
construct_match<T, Args...>(constructor_match<T, 1>(obj), L, argcount, boost + 1 + static_cast<int>(syntax));
|
||||
|
||||
userdataref.push();
|
||||
luaL_getmetatable(L, &metakey[0]);
|
||||
|
@ -6938,8 +6979,8 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Cxs, bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct lua_call_wrapper<T, sol::constructor_wrapper<Cxs...>, is_index, is_variable, checked, C> {
|
||||
template <typename T, typename... Cxs, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct lua_call_wrapper<T, sol::constructor_wrapper<Cxs...>, is_index, is_variable, checked, boost, C> {
|
||||
typedef sol::constructor_wrapper<Cxs...> F;
|
||||
|
||||
struct onmatch {
|
||||
|
@ -6953,7 +6994,7 @@ namespace sol {
|
|||
referencepointer = obj;
|
||||
|
||||
auto& func = std::get<I>(f.set);
|
||||
stack::call_into_lua<1, checked>(r, a, L, start, func, detail::implicit_wrapper<T>(obj));
|
||||
stack::call_into_lua<1, checked>(r, a, L, boost + start, func, detail::implicit_wrapper<T>(obj));
|
||||
|
||||
userdataref.push();
|
||||
luaL_getmetatable(L, &metakey[0]);
|
||||
|
@ -6978,8 +7019,8 @@ namespace sol {
|
|||
|
||||
};
|
||||
|
||||
template <typename T, typename Fx, bool is_index, bool is_variable, bool checked>
|
||||
struct lua_call_wrapper<T, sol::destructor_wrapper<Fx>, is_index, is_variable, checked, std::enable_if_t<std::is_void<Fx>::value>> {
|
||||
template <typename T, typename Fx, bool is_index, bool is_variable, bool checked, int boost>
|
||||
struct lua_call_wrapper<T, sol::destructor_wrapper<Fx>, is_index, is_variable, checked, boost, std::enable_if_t<std::is_void<Fx>::value>> {
|
||||
typedef sol::destructor_wrapper<Fx> F;
|
||||
|
||||
static int call(lua_State* L, const F&) {
|
||||
|
@ -6987,8 +7028,8 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Fx, bool is_index, bool is_variable, bool checked>
|
||||
struct lua_call_wrapper<T, sol::destructor_wrapper<Fx>, is_index, is_variable, checked, std::enable_if_t<!std::is_void<Fx>::value>> {
|
||||
template <typename T, typename Fx, bool is_index, bool is_variable, bool checked, int boost>
|
||||
struct lua_call_wrapper<T, sol::destructor_wrapper<Fx>, is_index, is_variable, checked, boost, std::enable_if_t<!std::is_void<Fx>::value>> {
|
||||
typedef sol::destructor_wrapper<Fx> F;
|
||||
|
||||
static int call(lua_State* L, const F& f) {
|
||||
|
@ -6998,8 +7039,8 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct lua_call_wrapper<T, overload_set<Fs...>, is_index, is_variable, checked, C> {
|
||||
template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct lua_call_wrapper<T, overload_set<Fs...>, is_index, is_variable, checked, boost, C> {
|
||||
typedef overload_set<Fs...> F;
|
||||
|
||||
struct on_match {
|
||||
|
@ -7015,18 +7056,19 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename V, bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct lua_call_wrapper<T, protect_t<V>, is_index, is_variable, checked, C> {
|
||||
template <typename T, typename V, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct lua_call_wrapper<T, protect_t<V>, is_index, is_variable, checked, boost, C> {
|
||||
typedef protect_t<V> F;
|
||||
|
||||
static int call(lua_State* L, F& fx) {
|
||||
return lua_call_wrapper<T, V, is_index, is_variable, true>{}.call(L, fx.value);
|
||||
template <typename... Args>
|
||||
static int call(lua_State* L, F& fx, Args&&... args) {
|
||||
return lua_call_wrapper<T, V, is_index, is_variable, true, boost>{}.call(L, fx.value, std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, bool is_index, bool is_variable, typename Fx>
|
||||
inline int call_wrapped(lua_State* L, Fx&& fx) {
|
||||
return lua_call_wrapper<T, meta::unqualified_t<Fx>, is_index, is_variable>{}.call(L, std::forward<Fx>(fx));
|
||||
template <typename T, bool is_index, bool is_variable, int boost = 0, typename Fx, typename... Args>
|
||||
inline int call_wrapped(lua_State* L, Fx&& fx, Args&&... args) {
|
||||
return lua_call_wrapper<T, meta::unqualified_t<Fx>, is_index, is_variable, stack::stack_detail::default_check_arguments, boost>{}.call(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T, bool is_index, bool is_variable, typename F>
|
||||
|
@ -7191,16 +7233,15 @@ namespace sol {
|
|||
|
||||
static int real_call(lua_State* L) {
|
||||
auto udata = stack::stack_detail::get_as_upvalues<function_type*>(L);
|
||||
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 r;
|
||||
function_type* f = udata.first;
|
||||
return call_detail::call_wrapped<void, false, false>(L, f);
|
||||
}
|
||||
|
||||
static int call(lua_State* L) {
|
||||
return detail::static_trampoline<(&real_call)>(L);
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
int operator()(lua_State* L) const {
|
||||
return call(L);
|
||||
}
|
||||
};
|
||||
|
@ -7220,10 +7261,7 @@ namespace sol {
|
|||
auto objdata = stack::stack_detail::get_as_upvalues<T*>(L, memberdata.second);
|
||||
function_type& memfx = memberdata.first;
|
||||
auto& item = *objdata.first;
|
||||
auto fx = [&item, &memfx](auto&&... args) -> typename traits_type::return_type {
|
||||
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);
|
||||
return call_detail::call_wrapped<T, false, false, -1>(L, memfx, item);
|
||||
}
|
||||
|
||||
static int call(lua_State* L) {
|
||||
|
@ -7235,30 +7273,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>
|
||||
struct upvalue_member_variable {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
|
@ -7276,11 +7290,9 @@ namespace sol {
|
|||
function_type& var = memberdata.first;
|
||||
switch (lua_gettop(L)) {
|
||||
case 0:
|
||||
stack::push(L, (mem.*var));
|
||||
return 1;
|
||||
return call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
|
||||
case 1:
|
||||
set_variable<1, typename traits_type::return_type>(meta::neg<std::is_const<typename traits_type::return_type>>(), L, mem, var);
|
||||
return 0;
|
||||
return call_detail::call_wrapped<T, false, false, -1>(L, var, mem);
|
||||
default:
|
||||
return luaL_error(L, "sol: incorrect number of arguments to member variable function");
|
||||
}
|
||||
|
@ -7326,16 +7338,12 @@ namespace sol {
|
|||
// Layout:
|
||||
// idx 1...n: verbatim data of member variable pointer
|
||||
auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L, 1);
|
||||
auto& mem = stack::get<T>(L, 1);
|
||||
function_type& var = memberdata.first;
|
||||
switch (lua_gettop(L)) {
|
||||
case 1:
|
||||
lua_pop(L, 1);
|
||||
stack::push(L, (mem.*var));
|
||||
return 1;
|
||||
return call_detail::call_wrapped<T, true, false>(L, var);
|
||||
case 2:
|
||||
set_variable<2, typename traits_type::return_type>(meta::neg<std::is_const<typename traits_type::return_type>>(), L, mem, var);
|
||||
return 0;
|
||||
return call_detail::call_wrapped<T, false, false>(L, var);
|
||||
default:
|
||||
return luaL_error(L, "sol: incorrect number of arguments to member variable function");
|
||||
}
|
||||
|
@ -7590,44 +7598,6 @@ namespace sol {
|
|||
}
|
||||
|
||||
namespace stack {
|
||||
template <typename F, typename G>
|
||||
struct pusher<property_wrapper<F, G>, std::enable_if_t<!std::is_void<F>::value && !std::is_void<G>::value>> {
|
||||
static int push(lua_State* L, property_wrapper<F, G> pw) {
|
||||
return stack::push(L, sol::overload(std::move(pw.read), std::move(pw.write)));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct pusher<property_wrapper<F, void>> {
|
||||
static int push(lua_State* L, property_wrapper<F, void> pw) {
|
||||
return stack::push(L, std::move(pw.read));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct pusher<property_wrapper<void, F>> {
|
||||
static int push(lua_State* L, property_wrapper<void, F> pw) {
|
||||
return stack::push(L, std::move(pw.write));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Lists>
|
||||
struct pusher<detail::constructors_for<T, constructor_list<Lists...>>> {
|
||||
static int push(lua_State* L, detail::constructors_for<T, constructor_list<Lists...>>) {
|
||||
lua_CFunction cf = call_detail::construct<T, Lists...>;
|
||||
return stack::push(L, cf);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Fxs>
|
||||
struct pusher<detail::constructors_for<T, constructor_wrapper<Fxs...>>> {
|
||||
static int push(lua_State* L, constructor_wrapper<Fxs...> c) {
|
||||
lua_CFunction cf = call_detail::call_user<T, false, false>;
|
||||
int closures = stack::push(L, make_user(std::move(c)));
|
||||
return stack::push(L, c_closure(cf, closures));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... Sigs>
|
||||
struct pusher<function_sig<Sigs...>> {
|
||||
template <typename... Sig, typename Fx, typename... Args>
|
||||
|
@ -7824,6 +7794,68 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct pusher<protect_t<T>> {
|
||||
static int push(lua_State* L, protect_t<T>&& pw) {
|
||||
lua_CFunction cf = call_detail::call_user<void, false, false, protect_t<T>>;
|
||||
int closures = stack::push<user<protect_t<T>>>(L, std::move(pw.value));
|
||||
return stack::push(L, c_closure(cf, closures));
|
||||
}
|
||||
|
||||
static int push(lua_State* L, const protect_t<T>& pw) {
|
||||
lua_CFunction cf = call_detail::call_user<void, false, false, protect_t<T>>;
|
||||
int closures = stack::push<user<protect_t<T>>>(L, pw.value);
|
||||
return stack::push(L, c_closure(cf, closures));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F, typename G>
|
||||
struct pusher<property_wrapper<F, G>, std::enable_if_t<!std::is_void<F>::value && !std::is_void<G>::value>> {
|
||||
static int push(lua_State* L, property_wrapper<F, G>&& pw) {
|
||||
return stack::push(L, sol::overload(std::move(pw.read), std::move(pw.write)));
|
||||
}
|
||||
static int push(lua_State* L, const property_wrapper<F, G>& pw) {
|
||||
return stack::push(L, sol::overload(pw.read, pw.write));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct pusher<property_wrapper<F, void>> {
|
||||
static int push(lua_State* L, property_wrapper<F, void>&& pw) {
|
||||
return stack::push(L, std::move(pw.read));
|
||||
}
|
||||
static int push(lua_State* L, const property_wrapper<F, void>& pw) {
|
||||
return stack::push(L, pw.read);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct pusher<property_wrapper<void, F>> {
|
||||
static int push(lua_State* L, property_wrapper<void, F>&& pw) {
|
||||
return stack::push(L, std::move(pw.write));
|
||||
}
|
||||
static int push(lua_State* L, const property_wrapper<void, F>& pw) {
|
||||
return stack::push(L, pw.write);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Lists>
|
||||
struct pusher<detail::constructors_for<T, constructor_list<Lists...>>> {
|
||||
static int push(lua_State* L, detail::constructors_for<T, constructor_list<Lists...>>) {
|
||||
lua_CFunction cf = call_detail::construct<T, Lists...>;
|
||||
return stack::push(L, cf);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Fxs>
|
||||
struct pusher<detail::constructors_for<T, constructor_wrapper<Fxs...>>> {
|
||||
static int push(lua_State* L, constructor_wrapper<Fxs...> c) {
|
||||
lua_CFunction cf = call_detail::call_user<T, false, false, constructor_wrapper<Fxs...>>;
|
||||
int closures = stack::push<user<T>>(L, std::move(c));
|
||||
return stack::push(L, c_closure(cf, closures));
|
||||
}
|
||||
};
|
||||
|
||||
} // stack
|
||||
} // sol
|
||||
|
||||
|
@ -9173,24 +9205,25 @@ namespace sol {
|
|||
}
|
||||
|
||||
template<typename... Args>
|
||||
simple_usertype_metatable(usertype_detail::verified_tag v, lua_State* L, Args&&... args) : simple_usertype_metatable(v, std::make_index_sequence<sizeof...(Args) / 2>(), L, std::forward_as_tuple(std::forward<Args>(args)...)) {}
|
||||
simple_usertype_metatable(lua_State* L, usertype_detail::verified_tag v, Args&&... args) : simple_usertype_metatable(v, std::make_index_sequence<sizeof...(Args) / 2>(), L, std::forward_as_tuple(std::forward<Args>(args)...)) {}
|
||||
|
||||
template<typename... Args>
|
||||
simple_usertype_metatable(usertype_detail::add_destructor_tag, lua_State* L, Args&&... args) : simple_usertype_metatable(usertype_detail::verified, L, std::forward<Args>(args)..., "__gc", default_destructor) {}
|
||||
simple_usertype_metatable(lua_State* L, usertype_detail::add_destructor_tag, Args&&... args) : simple_usertype_metatable(L, usertype_detail::verified, std::forward<Args>(args)..., "__gc", default_destructor) {}
|
||||
|
||||
template<typename... Args>
|
||||
simple_usertype_metatable(usertype_detail::check_destructor_tag, lua_State* L, Args&&... args) : simple_usertype_metatable(meta::condition<meta::all<std::is_destructible<T>, meta::neg<usertype_detail::has_destructor<Args...>>>, usertype_detail::add_destructor_tag, usertype_detail::verified_tag>(), L, std::forward<Args>(args)...) {}
|
||||
simple_usertype_metatable(lua_State* L, usertype_detail::check_destructor_tag, Args&&... args) : simple_usertype_metatable(L, meta::condition<meta::all<std::is_destructible<T>, meta::neg<usertype_detail::has_destructor<Args...>>>, usertype_detail::add_destructor_tag, usertype_detail::verified_tag>(), std::forward<Args>(args)...) {}
|
||||
|
||||
public:
|
||||
simple_usertype_metatable(lua_State* L) : simple_usertype_metatable(meta::condition<meta::all<std::is_default_constructible<T>>, decltype(default_constructor), usertype_detail::check_destructor_tag>(), L) {}
|
||||
|
||||
template<typename... Args>
|
||||
simple_usertype_metatable(lua_State* L, Args&&... args) : simple_usertype_metatable(meta::condition<meta::all<std::is_default_constructible<T>, meta::neg<usertype_detail::has_constructor<Args...>>>, decltype(default_constructor), usertype_detail::check_destructor_tag>(), L, std::forward<Args>(args)...) {}
|
||||
template<typename Arg, typename... Args, meta::disable<meta::is_specialization_of<constructors, meta::unqualified_t<Arg>>, meta::is_specialization_of<constructor_wrapper, meta::unqualified_t<Arg>>> = meta::enabler>
|
||||
simple_usertype_metatable(lua_State* L, Arg&& arg, Args&&... args) : simple_usertype_metatable(L, meta::condition<meta::all<std::is_default_constructible<T>, meta::neg<usertype_detail::has_constructor<Args...>>>, decltype(default_constructor), usertype_detail::check_destructor_tag>(), std::forward<Arg>(arg), std::forward<Args>(args)...) {}
|
||||
|
||||
template<typename... Args, typename... CArgs>
|
||||
simple_usertype_metatable(constructors<CArgs...> constructorlist, lua_State* L, Args&&... args) : simple_usertype_metatable(usertype_detail::check_destructor_tag(), L, std::forward<Args>(args)..., "new", constructorlist) {}
|
||||
simple_usertype_metatable(lua_State* L, constructors<CArgs...> constructorlist, Args&&... args) : simple_usertype_metatable(L, usertype_detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
|
||||
|
||||
template<typename... Args, typename... Fxs>
|
||||
simple_usertype_metatable(constructor_wrapper<Fxs...> constructorlist, lua_State* L, Args&&... args) : simple_usertype_metatable(usertype_detail::check_destructor_tag(), L, std::forward<Args>(args)..., "new", constructorlist) {}
|
||||
simple_usertype_metatable(lua_State* L, constructor_wrapper<Fxs...> constructorlist, Args&&... args) : simple_usertype_metatable(L, usertype_detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
|
||||
|
||||
virtual int push_um(lua_State* L) override {
|
||||
return stack::push(L, std::move(*this));
|
||||
|
|
|
@ -215,6 +215,7 @@ namespace sol {
|
|||
typedef std::tuple<Arg> args_tuple;
|
||||
typedef R return_type;
|
||||
typedef types<Arg> args_list;
|
||||
typedef types<T, Arg> free_args_list;
|
||||
typedef meta::tuple_types<R> returns_list;
|
||||
typedef R(function_type)(T&, R);
|
||||
typedef R(*function_pointer_type)(T&, R);
|
||||
|
|
168
sol/call.hpp
168
sol/call.hpp
|
@ -144,101 +144,116 @@ namespace sol {
|
|||
return 1;
|
||||
}
|
||||
|
||||
template <typename F, bool is_index, bool is_variable, bool checked, typename = void>
|
||||
template <typename F, bool is_index, bool is_variable, bool checked, int boost, typename = void>
|
||||
struct agnostic_lua_call_wrapper {
|
||||
static int var_call(std::true_type, lua_State* L, F& f) {
|
||||
template <typename Fx>
|
||||
static int var_call(std::true_type, lua_State* L, Fx&& f) {
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
typedef typename wrap::returns_list returns_list;
|
||||
typedef typename wrap::free_args_list args_list;
|
||||
typedef typename wrap::caller caller;
|
||||
return stack::call_into_lua<is_index ? 1 : 2, checked>(returns_list(), args_list(), L, is_index ? 2 : 3, caller(), f);
|
||||
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));
|
||||
}
|
||||
|
||||
static int var_call(std::false_type, lua_State* L, F& f) {
|
||||
template <typename Fx>
|
||||
static int var_call(std::false_type, lua_State* L, Fx&& f) {
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
typedef typename wrap::free_args_list args_list;
|
||||
typedef typename wrap::returns_list returns_list;
|
||||
typedef typename wrap::caller caller;
|
||||
return stack::call_into_lua<0, checked>(returns_list(), args_list(), L, 1, caller(), f);
|
||||
return stack::call_into_lua<0, checked>(returns_list(), args_list(), L, boost + 1, caller(), std::forward<Fx>(f));
|
||||
}
|
||||
|
||||
static int call(lua_State* L, F& f) {
|
||||
return var_call(std::integral_constant<bool, is_variable>(), L, f);
|
||||
template <typename Fx>
|
||||
static int call(lua_State* L, Fx&& f) {
|
||||
return var_call(std::integral_constant<bool, is_variable>(), L, std::forward<Fx>(f));
|
||||
}
|
||||
};
|
||||
|
||||
template <bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct agnostic_lua_call_wrapper<lua_r_CFunction, is_index, is_variable, checked, C> {
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<lua_r_CFunction, is_index, is_variable, checked, boost, C> {
|
||||
static int call(lua_State* L, lua_r_CFunction f) {
|
||||
return f(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct agnostic_lua_call_wrapper<lua_CFunction, is_index, is_variable, checked, C> {
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<lua_CFunction, is_index, is_variable, checked, boost, C> {
|
||||
static int call(lua_State* L, lua_CFunction f) {
|
||||
return f(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct agnostic_lua_call_wrapper<no_prop, is_index, is_variable, checked, C> {
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<no_prop, is_index, is_variable, checked, boost, C> {
|
||||
static int call(lua_State* L, const no_prop&) {
|
||||
return luaL_error(L, is_index ? "sol: cannot read from a writeonly property" : "sol: cannot write to a readonly property");
|
||||
}
|
||||
};
|
||||
|
||||
template <bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct agnostic_lua_call_wrapper<no_construction, is_index, is_variable, checked, C> {
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<no_construction, is_index, is_variable, checked, boost, C> {
|
||||
static int call(lua_State* L, const no_construction&) {
|
||||
return luaL_error(L, "sol: cannot call this constructor (tagged as non-constructible)");
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Args, bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct agnostic_lua_call_wrapper<bases<Args...>, is_index, is_variable, checked, C> {
|
||||
template <typename... Args, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<bases<Args...>, is_index, is_variable, checked, boost, C> {
|
||||
static int call(lua_State*, const bases<Args...>&) {
|
||||
// Uh. How did you even call this, lul
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename F, bool is_index, bool is_variable, bool checked = stack::stack_detail::default_check_arguments, typename = void>
|
||||
struct lua_call_wrapper : agnostic_lua_call_wrapper<F, is_index, is_variable, checked> {};
|
||||
template <typename T, typename F, bool is_index, bool is_variable, bool checked = stack::stack_detail::default_check_arguments, int boost = 0, typename = void>
|
||||
struct lua_call_wrapper : agnostic_lua_call_wrapper<F, is_index, is_variable, checked, boost> {};
|
||||
|
||||
template <typename T, typename F, bool is_index, bool is_variable, bool checked>
|
||||
struct lua_call_wrapper<T, F, is_index, is_variable, checked, std::enable_if_t<std::is_member_function_pointer<F>::value>> {
|
||||
static int call(lua_State* L, F& f) {
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
template <typename T, typename F, bool is_index, bool is_variable, bool checked, int boost>
|
||||
struct lua_call_wrapper<T, F, is_index, is_variable, checked, boost, std::enable_if_t<std::is_member_function_pointer<F>::value>> {
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
typedef typename wrap::object_type object_type;
|
||||
|
||||
template <typename Fx>
|
||||
static int call(lua_State* L, Fx&& f, object_type& o) {
|
||||
typedef typename wrap::returns_list returns_list;
|
||||
typedef typename wrap::args_list args_list;
|
||||
typedef typename wrap::caller caller;
|
||||
typedef typename wrap::object_type object_type;
|
||||
typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
|
||||
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);
|
||||
}
|
||||
|
||||
template <typename Fx>
|
||||
static int call(lua_State* L, Fx&& f) {
|
||||
typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
|
||||
#ifdef SOL_SAFE_USERTYPE
|
||||
object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
|
||||
if (o == nullptr) {
|
||||
return luaL_error(L, "sol: received null for 'self' argument (use ':' for accessing member functions, make sure member variables are preceeded by the actual object with '.' syntax)");
|
||||
}
|
||||
return stack::call_into_lua<is_variable ? 2 : 1, checked>(returns_list(), args_list(), L, is_variable ? 3 : 2, caller(), f, *o);
|
||||
return call(L, std::forward<Fx>(f), *o);
|
||||
#else
|
||||
object_type& o = static_cast<object_type&>(stack::get<Ta&>(L, 1));
|
||||
return stack::call_into_lua<is_variable ? 2 : 1, checked>(returns_list(), args_list(), L, is_variable ? 3 : 2, caller(), f, o);
|
||||
return call(L, std::forward<Fx>(f), o);
|
||||
#endif // Safety
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename F, bool is_variable, bool checked>
|
||||
struct lua_call_wrapper<T, F, false, is_variable, checked, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
|
||||
template <typename T, typename F, bool is_variable, bool checked, int boost>
|
||||
struct lua_call_wrapper<T, F, false, is_variable, checked, boost, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
|
||||
typedef sol::lua_bind_traits<F> traits_type;
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
typedef typename wrap::object_type object_type;
|
||||
|
||||
static int call_assign(std::true_type, lua_State* L, F& f) {
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
template <typename V>
|
||||
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::object_type object_type;
|
||||
typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
|
||||
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);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
static int call_assign(std::true_type, lua_State* L, V&& f) {
|
||||
typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
|
||||
#ifdef SOL_SAFE_USERTYPE
|
||||
object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
|
||||
if (o == nullptr) {
|
||||
|
@ -247,58 +262,74 @@ namespace sol {
|
|||
}
|
||||
return luaL_error(L, "sol: received nil for 'self' argument (pass 'self' as first argument)");
|
||||
}
|
||||
return stack::call_into_lua<is_variable ? 2 : 1>(types<void>(), args_list(), L, is_variable ? 3 : 2, caller(), f, *o);
|
||||
return call_assign(std::true_type(), L, f, *o);
|
||||
#else
|
||||
object_type& o = static_cast<object_type&>(stack::get<Ta&>(L, 1));
|
||||
return stack::call_into_lua<is_variable ? 2 : 1>(types<void>(), args_list(), L, is_variable ? 3 : 2, caller(), f, o);
|
||||
return call_assign(std::true_type(), L, f, o);
|
||||
#endif // Safety
|
||||
}
|
||||
|
||||
static int call_assign(std::false_type, lua_State* L, F&) {
|
||||
template <typename... Args>
|
||||
static int call_assign(std::false_type, lua_State* L, Args&&...) {
|
||||
return luaL_error(L, "sol: cannot write to this variable: copy assignment/constructor not available");
|
||||
}
|
||||
|
||||
static int call_const(std::false_type, lua_State* L, F& f) {
|
||||
template <typename... Args>
|
||||
static int call_const(std::false_type, lua_State* L, Args&&... args) {
|
||||
typedef typename traits_type::return_type R;
|
||||
return call_assign(std::is_assignable<std::add_lvalue_reference_t<meta::unqualified_t<R>>, R>(), L, f);
|
||||
return call_assign(std::is_assignable<std::add_lvalue_reference_t<meta::unqualified_t<R>>, R>(), L, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
static int call_const(std::true_type, lua_State* L, F&) {
|
||||
template <typename... Args>
|
||||
static int call_const(std::true_type, lua_State* L, Args&&...) {
|
||||
return luaL_error(L, "sol: cannot write to a readonly (const) variable");
|
||||
}
|
||||
|
||||
static int call(lua_State* L, F& f) {
|
||||
template <typename V>
|
||||
static int call(lua_State* L, V&& f) {
|
||||
return call_const(std::is_const<typename traits_type::return_type>(), L, f);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
static int call(lua_State* L, V&& f, object_type& o) {
|
||||
return call_const(std::is_const<typename traits_type::return_type>(), L, f, o);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename F, bool is_variable, bool checked>
|
||||
struct lua_call_wrapper<T, F, true, is_variable, checked, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
|
||||
template <typename T, typename F, bool is_variable, bool checked, int boost>
|
||||
struct lua_call_wrapper<T, F, true, is_variable, checked, boost, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
|
||||
typedef sol::lua_bind_traits<F> traits_type;
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
typedef typename wrap::object_type object_type;
|
||||
|
||||
static int call(lua_State* L, F& f) {
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
typedef typename wrap::object_type object_type;
|
||||
template <typename V>
|
||||
static int call(lua_State* L, V&& f, object_type& o) {
|
||||
typedef typename wrap::returns_list returns_list;
|
||||
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);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
static int call(lua_State* L, V&& f) {
|
||||
typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
|
||||
#ifdef SOL_SAFE_USERTYPE
|
||||
object_type* o = static_cast<object_type*>(stack::get<T*>(L, 1));
|
||||
object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
|
||||
if (o == nullptr) {
|
||||
if (is_variable) {
|
||||
return luaL_error(L, "sol: 'self' argument is nil (bad '.' access?)");
|
||||
}
|
||||
return luaL_error(L, "sol: 'self' argument is nil (pass 'self' as first argument)");
|
||||
}
|
||||
return stack::call_into_lua<is_variable ? 2 : 1, checked>(returns_list(), types<>(), L, is_variable ? 3 : 2, caller(), f, *o);
|
||||
return call(L, f, *o);
|
||||
#else
|
||||
object_type& o = static_cast<object_type&>(stack::get<T&>(L, 1));
|
||||
return stack::call_into_lua<is_variable ? 2 : 1, checked>(returns_list(), types<>(), L, is_variable ? 3 : 2, caller(), f, o);
|
||||
object_type& o = static_cast<object_type&>(stack::get<Ta&>(L, 1));
|
||||
return call(L, f, o);
|
||||
#endif // Safety
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Args, bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct lua_call_wrapper<T, sol::constructor_list<Args...>, is_index, is_variable, checked, C> {
|
||||
template <typename T, typename... Args, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct lua_call_wrapper<T, sol::constructor_list<Args...>, is_index, is_variable, checked, boost, C> {
|
||||
typedef sol::constructor_list<Args...> F;
|
||||
|
||||
static int call(lua_State* L, F&) {
|
||||
|
@ -313,7 +344,7 @@ namespace sol {
|
|||
T* obj = reinterpret_cast<T*>(pointerpointer + 1);
|
||||
referencepointer = obj;
|
||||
|
||||
construct_match<T, Args...>(constructor_match<T, 1>(obj), L, argcount, 1 + static_cast<int>(syntax));
|
||||
construct_match<T, Args...>(constructor_match<T, 1>(obj), L, argcount, boost + 1 + static_cast<int>(syntax));
|
||||
|
||||
userdataref.push();
|
||||
luaL_getmetatable(L, &metakey[0]);
|
||||
|
@ -327,8 +358,8 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Cxs, bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct lua_call_wrapper<T, sol::constructor_wrapper<Cxs...>, is_index, is_variable, checked, C> {
|
||||
template <typename T, typename... Cxs, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct lua_call_wrapper<T, sol::constructor_wrapper<Cxs...>, is_index, is_variable, checked, boost, C> {
|
||||
typedef sol::constructor_wrapper<Cxs...> F;
|
||||
|
||||
struct onmatch {
|
||||
|
@ -342,7 +373,7 @@ namespace sol {
|
|||
referencepointer = obj;
|
||||
|
||||
auto& func = std::get<I>(f.set);
|
||||
stack::call_into_lua<1, checked>(r, a, L, start, func, detail::implicit_wrapper<T>(obj));
|
||||
stack::call_into_lua<1, checked>(r, a, L, boost + start, func, detail::implicit_wrapper<T>(obj));
|
||||
|
||||
userdataref.push();
|
||||
luaL_getmetatable(L, &metakey[0]);
|
||||
|
@ -367,8 +398,8 @@ namespace sol {
|
|||
|
||||
};
|
||||
|
||||
template <typename T, typename Fx, bool is_index, bool is_variable, bool checked>
|
||||
struct lua_call_wrapper<T, sol::destructor_wrapper<Fx>, is_index, is_variable, checked, std::enable_if_t<std::is_void<Fx>::value>> {
|
||||
template <typename T, typename Fx, bool is_index, bool is_variable, bool checked, int boost>
|
||||
struct lua_call_wrapper<T, sol::destructor_wrapper<Fx>, is_index, is_variable, checked, boost, std::enable_if_t<std::is_void<Fx>::value>> {
|
||||
typedef sol::destructor_wrapper<Fx> F;
|
||||
|
||||
static int call(lua_State* L, const F&) {
|
||||
|
@ -376,8 +407,8 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Fx, bool is_index, bool is_variable, bool checked>
|
||||
struct lua_call_wrapper<T, sol::destructor_wrapper<Fx>, is_index, is_variable, checked, std::enable_if_t<!std::is_void<Fx>::value>> {
|
||||
template <typename T, typename Fx, bool is_index, bool is_variable, bool checked, int boost>
|
||||
struct lua_call_wrapper<T, sol::destructor_wrapper<Fx>, is_index, is_variable, checked, boost, std::enable_if_t<!std::is_void<Fx>::value>> {
|
||||
typedef sol::destructor_wrapper<Fx> F;
|
||||
|
||||
static int call(lua_State* L, const F& f) {
|
||||
|
@ -387,8 +418,8 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct lua_call_wrapper<T, overload_set<Fs...>, is_index, is_variable, checked, C> {
|
||||
template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct lua_call_wrapper<T, overload_set<Fs...>, is_index, is_variable, checked, boost, C> {
|
||||
typedef overload_set<Fs...> F;
|
||||
|
||||
struct on_match {
|
||||
|
@ -404,18 +435,19 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename V, bool is_index, bool is_variable, bool checked, typename C>
|
||||
struct lua_call_wrapper<T, protect_t<V>, is_index, is_variable, checked, C> {
|
||||
template <typename T, typename V, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct lua_call_wrapper<T, protect_t<V>, is_index, is_variable, checked, boost, C> {
|
||||
typedef protect_t<V> F;
|
||||
|
||||
static int call(lua_State* L, F& fx) {
|
||||
return lua_call_wrapper<T, V, is_index, is_variable, true>{}.call(L, fx.value);
|
||||
template <typename... Args>
|
||||
static int call(lua_State* L, F& fx, Args&&... args) {
|
||||
return lua_call_wrapper<T, V, is_index, is_variable, true, boost>{}.call(L, fx.value, std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, bool is_index, bool is_variable, typename Fx>
|
||||
inline int call_wrapped(lua_State* L, Fx&& fx) {
|
||||
return lua_call_wrapper<T, meta::unqualified_t<Fx>, is_index, is_variable>{}.call(L, std::forward<Fx>(fx));
|
||||
template <typename T, bool is_index, bool is_variable, int boost = 0, typename Fx, typename... Args>
|
||||
inline int call_wrapped(lua_State* L, Fx&& fx, Args&&... args) {
|
||||
return lua_call_wrapper<T, meta::unqualified_t<Fx>, is_index, is_variable, stack::stack_detail::default_check_arguments, boost>{}.call(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T, bool is_index, bool is_variable, typename F>
|
||||
|
|
|
@ -44,44 +44,6 @@ namespace sol {
|
|||
}
|
||||
|
||||
namespace stack {
|
||||
template <typename F, typename G>
|
||||
struct pusher<property_wrapper<F, G>, std::enable_if_t<!std::is_void<F>::value && !std::is_void<G>::value>> {
|
||||
static int push(lua_State* L, property_wrapper<F, G> pw) {
|
||||
return stack::push(L, sol::overload(std::move(pw.read), std::move(pw.write)));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct pusher<property_wrapper<F, void>> {
|
||||
static int push(lua_State* L, property_wrapper<F, void> pw) {
|
||||
return stack::push(L, std::move(pw.read));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct pusher<property_wrapper<void, F>> {
|
||||
static int push(lua_State* L, property_wrapper<void, F> pw) {
|
||||
return stack::push(L, std::move(pw.write));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Lists>
|
||||
struct pusher<detail::constructors_for<T, constructor_list<Lists...>>> {
|
||||
static int push(lua_State* L, detail::constructors_for<T, constructor_list<Lists...>>) {
|
||||
lua_CFunction cf = call_detail::construct<T, Lists...>;
|
||||
return stack::push(L, cf);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Fxs>
|
||||
struct pusher<detail::constructors_for<T, constructor_wrapper<Fxs...>>> {
|
||||
static int push(lua_State* L, constructor_wrapper<Fxs...> c) {
|
||||
lua_CFunction cf = call_detail::call_user<T, false, false>;
|
||||
int closures = stack::push(L, make_user(std::move(c)));
|
||||
return stack::push(L, c_closure(cf, closures));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... Sigs>
|
||||
struct pusher<function_sig<Sigs...>> {
|
||||
template <typename... Sig, typename Fx, typename... Args>
|
||||
|
@ -278,6 +240,68 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct pusher<protect_t<T>> {
|
||||
static int push(lua_State* L, protect_t<T>&& pw) {
|
||||
lua_CFunction cf = call_detail::call_user<void, false, false, protect_t<T>>;
|
||||
int closures = stack::push<user<protect_t<T>>>(L, std::move(pw.value));
|
||||
return stack::push(L, c_closure(cf, closures));
|
||||
}
|
||||
|
||||
static int push(lua_State* L, const protect_t<T>& pw) {
|
||||
lua_CFunction cf = call_detail::call_user<void, false, false, protect_t<T>>;
|
||||
int closures = stack::push<user<protect_t<T>>>(L, pw.value);
|
||||
return stack::push(L, c_closure(cf, closures));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F, typename G>
|
||||
struct pusher<property_wrapper<F, G>, std::enable_if_t<!std::is_void<F>::value && !std::is_void<G>::value>> {
|
||||
static int push(lua_State* L, property_wrapper<F, G>&& pw) {
|
||||
return stack::push(L, sol::overload(std::move(pw.read), std::move(pw.write)));
|
||||
}
|
||||
static int push(lua_State* L, const property_wrapper<F, G>& pw) {
|
||||
return stack::push(L, sol::overload(pw.read, pw.write));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct pusher<property_wrapper<F, void>> {
|
||||
static int push(lua_State* L, property_wrapper<F, void>&& pw) {
|
||||
return stack::push(L, std::move(pw.read));
|
||||
}
|
||||
static int push(lua_State* L, const property_wrapper<F, void>& pw) {
|
||||
return stack::push(L, pw.read);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct pusher<property_wrapper<void, F>> {
|
||||
static int push(lua_State* L, property_wrapper<void, F>&& pw) {
|
||||
return stack::push(L, std::move(pw.write));
|
||||
}
|
||||
static int push(lua_State* L, const property_wrapper<void, F>& pw) {
|
||||
return stack::push(L, pw.write);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Lists>
|
||||
struct pusher<detail::constructors_for<T, constructor_list<Lists...>>> {
|
||||
static int push(lua_State* L, detail::constructors_for<T, constructor_list<Lists...>>) {
|
||||
lua_CFunction cf = call_detail::construct<T, Lists...>;
|
||||
return stack::push(L, cf);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Fxs>
|
||||
struct pusher<detail::constructors_for<T, constructor_wrapper<Fxs...>>> {
|
||||
static int push(lua_State* L, constructor_wrapper<Fxs...> c) {
|
||||
lua_CFunction cf = call_detail::call_user<T, false, false, constructor_wrapper<Fxs...>>;
|
||||
int closures = stack::push<user<T>>(L, std::move(c));
|
||||
return stack::push(L, c_closure(cf, closures));
|
||||
}
|
||||
};
|
||||
|
||||
} // stack
|
||||
} // sol
|
||||
|
||||
|
|
|
@ -33,16 +33,15 @@ namespace sol {
|
|||
|
||||
static int real_call(lua_State* L) {
|
||||
auto udata = stack::stack_detail::get_as_upvalues<function_type*>(L);
|
||||
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 r;
|
||||
function_type* f = udata.first;
|
||||
return call_detail::call_wrapped<void, false, false>(L, f);
|
||||
}
|
||||
|
||||
static int call(lua_State* L) {
|
||||
return detail::static_trampoline<(&real_call)>(L);
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
int operator()(lua_State* L) const {
|
||||
return call(L);
|
||||
}
|
||||
};
|
||||
|
@ -62,10 +61,7 @@ namespace sol {
|
|||
auto objdata = stack::stack_detail::get_as_upvalues<T*>(L, memberdata.second);
|
||||
function_type& memfx = memberdata.first;
|
||||
auto& item = *objdata.first;
|
||||
auto fx = [&item, &memfx](auto&&... args) -> typename traits_type::return_type {
|
||||
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);
|
||||
return call_detail::call_wrapped<T, false, false, -1>(L, memfx, item);
|
||||
}
|
||||
|
||||
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>
|
||||
struct upvalue_member_variable {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
|
@ -118,11 +90,9 @@ namespace sol {
|
|||
function_type& var = memberdata.first;
|
||||
switch (lua_gettop(L)) {
|
||||
case 0:
|
||||
stack::push(L, (mem.*var));
|
||||
return 1;
|
||||
return call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
|
||||
case 1:
|
||||
set_variable<1, typename traits_type::return_type>(meta::neg<std::is_const<typename traits_type::return_type>>(), L, mem, var);
|
||||
return 0;
|
||||
return call_detail::call_wrapped<T, false, false, -1>(L, var, mem);
|
||||
default:
|
||||
return luaL_error(L, "sol: incorrect number of arguments to member variable function");
|
||||
}
|
||||
|
@ -168,16 +138,12 @@ namespace sol {
|
|||
// Layout:
|
||||
// idx 1...n: verbatim data of member variable pointer
|
||||
auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L, 1);
|
||||
auto& mem = stack::get<T>(L, 1);
|
||||
function_type& var = memberdata.first;
|
||||
switch (lua_gettop(L)) {
|
||||
case 1:
|
||||
lua_pop(L, 1);
|
||||
stack::push(L, (mem.*var));
|
||||
return 1;
|
||||
return call_detail::call_wrapped<T, true, false>(L, var);
|
||||
case 2:
|
||||
set_variable<2, typename traits_type::return_type>(meta::neg<std::is_const<typename traits_type::return_type>>(), L, mem, var);
|
||||
return 0;
|
||||
return call_detail::call_wrapped<T, false, false>(L, var);
|
||||
default:
|
||||
return luaL_error(L, "sol: incorrect number of arguments to member variable function");
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#ifndef SOL_PROTECT_HPP
|
||||
#define SOL_PROTECT_HPP
|
||||
|
||||
#include "traits.hpp"
|
||||
#include <utility>
|
||||
|
||||
namespace sol {
|
||||
|
@ -29,11 +30,20 @@ namespace sol {
|
|||
template <typename T>
|
||||
struct protect_t {
|
||||
T value;
|
||||
|
||||
template <typename Arg, typename... Args, meta::disable<std::is_same<protect_t, meta::unqualified_t<Arg>>> = meta::enabler>
|
||||
protect_t(Arg&& arg, Args&&... args) : value(std::forward<Arg>(arg), std::forward<Args>(args)...) {}
|
||||
|
||||
protect_t(const protect_t&) = default;
|
||||
protect_t(protect_t&&) = default;
|
||||
protect_t& operator=(const protect_t&) = default;
|
||||
protect_t& operator=(protect_t&&) = default;
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
auto protect(T&& value) {
|
||||
return protect_t<std::decay_t<T>>{ std::forward<T>(value) };
|
||||
return protect_t<std::decay_t<T>>(std::forward<T>(value));
|
||||
}
|
||||
|
||||
} // sol
|
||||
|
|
|
@ -66,24 +66,33 @@ namespace sol {
|
|||
}
|
||||
|
||||
template<typename... Args>
|
||||
simple_usertype_metatable(usertype_detail::verified_tag v, lua_State* L, Args&&... args) : simple_usertype_metatable(v, std::make_index_sequence<sizeof...(Args) / 2>(), L, std::forward_as_tuple(std::forward<Args>(args)...)) {}
|
||||
simple_usertype_metatable(lua_State* L, usertype_detail::verified_tag v, Args&&... args) : simple_usertype_metatable(v, std::make_index_sequence<sizeof...(Args) / 2>(), L, std::forward_as_tuple(std::forward<Args>(args)...)) {}
|
||||
|
||||
template<typename... Args>
|
||||
simple_usertype_metatable(usertype_detail::add_destructor_tag, lua_State* L, Args&&... args) : simple_usertype_metatable(usertype_detail::verified, L, std::forward<Args>(args)..., "__gc", default_destructor) {}
|
||||
simple_usertype_metatable(lua_State* L, usertype_detail::add_destructor_tag, Args&&... args) : simple_usertype_metatable(L, usertype_detail::verified, std::forward<Args>(args)..., "__gc", default_destructor) {}
|
||||
|
||||
template<typename... Args>
|
||||
simple_usertype_metatable(usertype_detail::check_destructor_tag, lua_State* L, Args&&... args) : simple_usertype_metatable(meta::condition<meta::all<std::is_destructible<T>, meta::neg<usertype_detail::has_destructor<Args...>>>, usertype_detail::add_destructor_tag, usertype_detail::verified_tag>(), L, std::forward<Args>(args)...) {}
|
||||
simple_usertype_metatable(lua_State* L, usertype_detail::check_destructor_tag, Args&&... args) : simple_usertype_metatable(L, meta::condition<meta::all<std::is_destructible<T>, meta::neg<usertype_detail::has_destructor<Args...>>>, usertype_detail::add_destructor_tag, usertype_detail::verified_tag>(), std::forward<Args>(args)...) {}
|
||||
|
||||
public:
|
||||
simple_usertype_metatable(lua_State* L) : simple_usertype_metatable(meta::condition<meta::all<std::is_default_constructible<T>>, decltype(default_constructor), usertype_detail::check_destructor_tag>(), L) {}
|
||||
|
||||
template<typename... Args>
|
||||
simple_usertype_metatable(lua_State* L, Args&&... args) : simple_usertype_metatable(meta::condition<meta::all<std::is_default_constructible<T>, meta::neg<usertype_detail::has_constructor<Args...>>>, decltype(default_constructor), usertype_detail::check_destructor_tag>(), L, std::forward<Args>(args)...) {}
|
||||
template<typename Arg, typename... Args, meta::disable_any<
|
||||
meta::any_same<meta::unqualified_t<Arg>,
|
||||
usertype_detail::verified_tag,
|
||||
usertype_detail::add_destructor_tag,
|
||||
usertype_detail::check_destructor_tag
|
||||
>,
|
||||
meta::is_specialization_of<constructors, meta::unqualified_t<Arg>>,
|
||||
meta::is_specialization_of<constructor_wrapper, meta::unqualified_t<Arg>>
|
||||
> = meta::enabler>
|
||||
simple_usertype_metatable(lua_State* L, Arg&& arg, Args&&... args) : simple_usertype_metatable(L, meta::condition<meta::all<std::is_default_constructible<T>, meta::neg<usertype_detail::has_constructor<Args...>>>, decltype(default_constructor), usertype_detail::check_destructor_tag>(), std::forward<Arg>(arg), std::forward<Args>(args)...) {}
|
||||
|
||||
template<typename... Args, typename... CArgs>
|
||||
simple_usertype_metatable(constructors<CArgs...> constructorlist, lua_State* L, Args&&... args) : simple_usertype_metatable(usertype_detail::check_destructor_tag(), L, std::forward<Args>(args)..., "new", constructorlist) {}
|
||||
simple_usertype_metatable(lua_State* L, constructors<CArgs...> constructorlist, Args&&... args) : simple_usertype_metatable(L, usertype_detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
|
||||
|
||||
template<typename... Args, typename... Fxs>
|
||||
simple_usertype_metatable(constructor_wrapper<Fxs...> constructorlist, lua_State* L, Args&&... args) : simple_usertype_metatable(usertype_detail::check_destructor_tag(), L, std::forward<Args>(args)..., "new", constructorlist) {}
|
||||
simple_usertype_metatable(lua_State* L, constructor_wrapper<Fxs...> constructorlist, Args&&... args) : simple_usertype_metatable(L, usertype_detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
|
||||
|
||||
virtual int push_um(lua_State* L) override {
|
||||
return stack::push(L, std::move(*this));
|
||||
|
|
|
@ -133,6 +133,9 @@ namespace sol {
|
|||
template<typename... Args>
|
||||
using disable = std::enable_if_t<neg<all<Args...>>::value, enable_t>;
|
||||
|
||||
template<typename... Args>
|
||||
using disable_any = std::enable_if_t<neg<any<Args...>>::value, enable_t>;
|
||||
|
||||
template<typename V, typename... Vs>
|
||||
struct find_in_pack_v : boolean<false> { };
|
||||
|
||||
|
|
|
@ -816,7 +816,10 @@ TEST_CASE("functions/variadic_args", "Check to see we can receive multiple argum
|
|||
|
||||
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) {});
|
||||
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)"));
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
#define SOL_CHECK_ARGUMENTS
|
||||
|
||||
#include <sol.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
|
||||
TEST_CASE("usertypes/simple_usertypes", "Ensure that simple usertypes properly work here") {
|
||||
struct marker {
|
||||
bool value = false;
|
||||
};
|
||||
struct bark {
|
||||
int var = 50;
|
||||
marker mark;
|
||||
|
||||
void fun() {
|
||||
var = 51;
|
||||
}
|
||||
|
||||
int get() const {
|
||||
return var;
|
||||
}
|
||||
|
||||
int set(int x) {
|
||||
var = x;
|
||||
return var;
|
||||
}
|
||||
|
||||
std::string special() const {
|
||||
return mark.value ? "woof" : "pantpant";
|
||||
}
|
||||
|
||||
const marker& the_marker() const {
|
||||
return mark;
|
||||
}
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua.new_simple_usertype<bark>("bark",
|
||||
"fun", &bark::fun,
|
||||
"get", &bark::get,
|
||||
"var", &bark::var,
|
||||
"the_marker", &bark::the_marker,
|
||||
"x", sol::property(&bark::get),
|
||||
"y", sol::property(&bark::set),
|
||||
"z", sol::property(&bark::get, &bark::set)
|
||||
);
|
||||
|
||||
lua.script("b = bark.new()");
|
||||
bark& b = lua["b"];
|
||||
|
||||
lua.script("b:fun()");
|
||||
int var = b.var;
|
||||
REQUIRE(var == 51);
|
||||
|
||||
lua.script("b:var(20)");
|
||||
lua.script("v = b:var()");
|
||||
int v = lua["v"];
|
||||
REQUIRE(v == 20);
|
||||
|
||||
lua.script("m = b:the_marker()");
|
||||
marker& m = lua["m"];
|
||||
REQUIRE_FALSE(b.mark.value);
|
||||
REQUIRE_FALSE(m.value);
|
||||
m.value = true;
|
||||
REQUIRE(&b.mark == &m);
|
||||
REQUIRE(b.mark.value);
|
||||
|
||||
sol::table barktable = lua["bark"];
|
||||
barktable["special"] = &bark::special;
|
||||
|
||||
lua.script("s = b:special()");
|
||||
std::string s = lua["s"];
|
||||
REQUIRE(s == "woof");
|
||||
|
||||
lua.script("b:y(24)");
|
||||
lua.script("x = b:x()");
|
||||
int x = lua["x"];
|
||||
REQUIRE(x == 24);
|
||||
|
||||
lua.script("z = b:z(b:z() + 5)");
|
||||
int z = lua["z"];
|
||||
REQUIRE(z == 29);
|
||||
}
|
172
test_simple_usertypes.cpp
Normal file
172
test_simple_usertypes.cpp
Normal file
|
@ -0,0 +1,172 @@
|
|||
#define SOL_CHECK_ARGUMENTS
|
||||
|
||||
#include <sol.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
|
||||
TEST_CASE("usertypes/simple_usertypes", "Ensure that simple usertypes properly work here") {
|
||||
struct marker {
|
||||
bool value = false;
|
||||
};
|
||||
struct bark {
|
||||
int var = 50;
|
||||
marker mark;
|
||||
|
||||
void fun() {
|
||||
var = 51;
|
||||
}
|
||||
|
||||
int get() const {
|
||||
return var;
|
||||
}
|
||||
|
||||
int set(int x) {
|
||||
var = x;
|
||||
return var;
|
||||
}
|
||||
|
||||
std::string special() const {
|
||||
return mark.value ? "woof" : "pantpant";
|
||||
}
|
||||
|
||||
const marker& the_marker() const {
|
||||
return mark;
|
||||
}
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua.new_simple_usertype<bark>("bark",
|
||||
"fun", &bark::fun,
|
||||
"get", &bark::get,
|
||||
"var", &bark::var,
|
||||
"the_marker", &bark::the_marker,
|
||||
"x", sol::property(&bark::get),
|
||||
"y", sol::property(&bark::set),
|
||||
"z", sol::property(&bark::get, &bark::set)
|
||||
);
|
||||
|
||||
lua.script("b = bark.new()");
|
||||
bark& b = lua["b"];
|
||||
|
||||
lua.script("b:fun()");
|
||||
int var = b.var;
|
||||
REQUIRE(var == 51);
|
||||
|
||||
lua.script("b:var(20)");
|
||||
lua.script("v = b:var()");
|
||||
int v = lua["v"];
|
||||
REQUIRE(v == 20);
|
||||
|
||||
lua.script("m = b:the_marker()");
|
||||
marker& m = lua["m"];
|
||||
REQUIRE_FALSE(b.mark.value);
|
||||
REQUIRE_FALSE(m.value);
|
||||
m.value = true;
|
||||
REQUIRE(&b.mark == &m);
|
||||
REQUIRE(b.mark.value);
|
||||
|
||||
sol::table barktable = lua["bark"];
|
||||
barktable["special"] = &bark::special;
|
||||
|
||||
lua.script("s = b:special()");
|
||||
std::string s = lua["s"];
|
||||
REQUIRE(s == "woof");
|
||||
|
||||
lua.script("b:y(24)");
|
||||
lua.script("x = b:x()");
|
||||
int x = lua["x"];
|
||||
REQUIRE(x == 24);
|
||||
|
||||
lua.script("z = b:z(b:z() + 5)");
|
||||
int z = lua["z"];
|
||||
REQUIRE(z == 29);
|
||||
}
|
||||
|
||||
TEST_CASE("usertypes/simple-usertypes-constructors", "Ensure that calls with specific arguments work") {
|
||||
struct marker {
|
||||
bool value = false;
|
||||
};
|
||||
struct bark {
|
||||
int var = 50;
|
||||
marker mark;
|
||||
|
||||
bark() {}
|
||||
bark(int v) : var(v) {}
|
||||
|
||||
void fun() {
|
||||
var = 51;
|
||||
}
|
||||
|
||||
int get() const {
|
||||
return var;
|
||||
}
|
||||
|
||||
int set(int x) {
|
||||
var = x;
|
||||
return var;
|
||||
}
|
||||
|
||||
std::string special() const {
|
||||
return mark.value ? "woof" : "pantpant";
|
||||
}
|
||||
|
||||
const marker& the_marker() const {
|
||||
return mark;
|
||||
}
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua.new_simple_usertype<bark>("bark",
|
||||
sol::constructors<sol::types<>, sol::types<int>>(),
|
||||
"fun", sol::protect( &bark::fun ),
|
||||
"get", &bark::get,
|
||||
"var", &bark::var,
|
||||
"the_marker", &bark::the_marker,
|
||||
"x", sol::property(&bark::get),
|
||||
"y", sol::property(&bark::set),
|
||||
"z", sol::property(&bark::get, &bark::set)
|
||||
);
|
||||
|
||||
lua.script("bx = bark.new(760)");
|
||||
bark& bx = lua["bx"];
|
||||
REQUIRE(bx.var == 760);
|
||||
|
||||
lua.script("b = bark.new()");
|
||||
bark& b = lua["b"];
|
||||
|
||||
lua.script("b:fun()");
|
||||
int var = b.var;
|
||||
REQUIRE(var == 51);
|
||||
|
||||
lua.script("b:var(20)");
|
||||
lua.script("v = b:var()");
|
||||
int v = lua["v"];
|
||||
REQUIRE(v == 20);
|
||||
|
||||
lua.script("m = b:the_marker()");
|
||||
marker& m = lua["m"];
|
||||
REQUIRE_FALSE(b.mark.value);
|
||||
REQUIRE_FALSE(m.value);
|
||||
m.value = true;
|
||||
REQUIRE(&b.mark == &m);
|
||||
REQUIRE(b.mark.value);
|
||||
|
||||
sol::table barktable = lua["bark"];
|
||||
barktable["special"] = &bark::special;
|
||||
|
||||
lua.script("s = b:special()");
|
||||
std::string s = lua["s"];
|
||||
REQUIRE(s == "woof");
|
||||
|
||||
lua.script("b:y(24)");
|
||||
lua.script("x = b:x()");
|
||||
int x = lua["x"];
|
||||
REQUIRE(x == 24);
|
||||
|
||||
lua.script("z = b:z(b:z() + 5)");
|
||||
int z = lua["z"];
|
||||
REQUIRE(z == 29);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user