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.
|
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
// This file was generated with a script.
|
// This file was generated with a script.
|
||||||
// Generated 2016-07-08 00:10:28.267637 UTC
|
// Generated 2016-07-09 04:51:51.604138 UTC
|
||||||
// This header was generated with sol v2.9.0 (revision f7108d5)
|
// This header was generated with sol v2.9.0 (revision 115dfe3)
|
||||||
// https://github.com/ThePhD/sol2
|
// https://github.com/ThePhD/sol2
|
||||||
|
|
||||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||||
@ -325,6 +325,7 @@ namespace sol {
|
|||||||
typedef std::tuple<Arg> args_tuple;
|
typedef std::tuple<Arg> args_tuple;
|
||||||
typedef R return_type;
|
typedef R return_type;
|
||||||
typedef types<Arg> args_list;
|
typedef types<Arg> args_list;
|
||||||
|
typedef types<T, Arg> free_args_list;
|
||||||
typedef meta::tuple_types<R> returns_list;
|
typedef meta::tuple_types<R> returns_list;
|
||||||
typedef R(function_type)(T&, R);
|
typedef R(function_type)(T&, R);
|
||||||
typedef R(*function_pointer_type)(T&, R);
|
typedef R(*function_pointer_type)(T&, R);
|
||||||
@ -6563,11 +6564,20 @@ namespace sol {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct protect_t {
|
struct protect_t {
|
||||||
T value;
|
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>
|
template <typename T>
|
||||||
auto protect(T&& value) {
|
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
|
} // sol
|
||||||
@ -6755,101 +6765,116 @@ namespace sol {
|
|||||||
return 1;
|
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 {
|
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 wrapper<meta::unqualified_t<F>> wrap;
|
||||||
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, 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 wrapper<meta::unqualified_t<F>> wrap;
|
||||||
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, 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) {
|
template <typename Fx>
|
||||||
return var_call(std::integral_constant<bool, is_variable>(), L, f);
|
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>
|
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, 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) {
|
static int call(lua_State* L, lua_r_CFunction f) {
|
||||||
return f(L);
|
return f(L);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <bool is_index, bool is_variable, bool checked, typename 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, C> {
|
struct agnostic_lua_call_wrapper<lua_CFunction, is_index, is_variable, checked, boost, C> {
|
||||||
static int call(lua_State* L, lua_CFunction f) {
|
static int call(lua_State* L, lua_CFunction f) {
|
||||||
return f(L);
|
return f(L);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <bool is_index, bool is_variable, bool checked, typename 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, C> {
|
struct agnostic_lua_call_wrapper<no_prop, is_index, is_variable, checked, boost, C> {
|
||||||
static int call(lua_State* L, const no_prop&) {
|
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");
|
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>
|
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, C> {
|
struct agnostic_lua_call_wrapper<no_construction, is_index, is_variable, checked, boost, C> {
|
||||||
static int call(lua_State* L, const no_construction&) {
|
static int call(lua_State* L, const no_construction&) {
|
||||||
return luaL_error(L, "sol: cannot call this constructor (tagged as non-constructible)");
|
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>
|
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, C> {
|
struct agnostic_lua_call_wrapper<bases<Args...>, is_index, is_variable, checked, boost, C> {
|
||||||
static int call(lua_State*, const bases<Args...>&) {
|
static int call(lua_State*, const bases<Args...>&) {
|
||||||
// Uh. How did you even call this, lul
|
// Uh. How did you even call this, lul
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename F, bool is_index, bool is_variable, bool checked = stack::stack_detail::default_check_arguments, typename = void>
|
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> {};
|
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>
|
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, std::enable_if_t<std::is_member_function_pointer<F>::value>> {
|
struct lua_call_wrapper<T, F, is_index, is_variable, checked, boost, 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;
|
||||||
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::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;
|
||||||
typedef typename wrap::object_type object_type;
|
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);
|
||||||
typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
|
}
|
||||||
|
|
||||||
|
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
|
#ifdef SOL_SAFE_USERTYPE
|
||||||
object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
|
object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
|
||||||
if (o == nullptr) {
|
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 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
|
#else
|
||||||
object_type& o = static_cast<object_type&>(stack::get<Ta&>(L, 1));
|
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
|
#endif // Safety
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename F, bool is_variable, bool checked>
|
template <typename T, typename F, bool is_variable, bool checked, int boost>
|
||||||
struct lua_call_wrapper<T, F, false, is_variable, checked, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
|
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 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) {
|
template <typename V>
|
||||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
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::object_type object_type;
|
|
||||||
typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
|
|
||||||
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
#ifdef SOL_SAFE_USERTYPE
|
||||||
object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
|
object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
|
||||||
if (o == nullptr) {
|
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 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
|
#else
|
||||||
object_type& o = static_cast<object_type&>(stack::get<Ta&>(L, 1));
|
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
|
#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");
|
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;
|
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");
|
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);
|
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>
|
template <typename T, typename F, bool is_variable, bool checked, int boost>
|
||||||
struct lua_call_wrapper<T, F, true, is_variable, checked, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
|
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 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) {
|
template <typename V>
|
||||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
static int call(lua_State* L, V&& f, object_type& o) {
|
||||||
typedef typename wrap::object_type object_type;
|
|
||||||
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
#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 (o == nullptr) {
|
||||||
if (is_variable) {
|
if (is_variable) {
|
||||||
return luaL_error(L, "sol: 'self' argument is nil (bad '.' access?)");
|
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 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
|
#else
|
||||||
object_type& o = static_cast<object_type&>(stack::get<T&>(L, 1));
|
object_type& o = static_cast<object_type&>(stack::get<Ta&>(L, 1));
|
||||||
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);
|
||||||
#endif // Safety
|
#endif // Safety
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename... Args, bool is_index, bool is_variable, bool checked, typename 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, C> {
|
struct lua_call_wrapper<T, sol::constructor_list<Args...>, is_index, is_variable, checked, boost, C> {
|
||||||
typedef sol::constructor_list<Args...> F;
|
typedef sol::constructor_list<Args...> F;
|
||||||
|
|
||||||
static int call(lua_State* L, F&) {
|
static int call(lua_State* L, F&) {
|
||||||
@ -6924,7 +6965,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, 1 + static_cast<int>(syntax));
|
construct_match<T, Args...>(constructor_match<T, 1>(obj), L, argcount, boost + 1 + static_cast<int>(syntax));
|
||||||
|
|
||||||
userdataref.push();
|
userdataref.push();
|
||||||
luaL_getmetatable(L, &metakey[0]);
|
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>
|
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, C> {
|
struct lua_call_wrapper<T, sol::constructor_wrapper<Cxs...>, is_index, is_variable, checked, boost, C> {
|
||||||
typedef sol::constructor_wrapper<Cxs...> F;
|
typedef sol::constructor_wrapper<Cxs...> F;
|
||||||
|
|
||||||
struct onmatch {
|
struct onmatch {
|
||||||
@ -6953,7 +6994,7 @@ namespace sol {
|
|||||||
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, 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();
|
userdataref.push();
|
||||||
luaL_getmetatable(L, &metakey[0]);
|
luaL_getmetatable(L, &metakey[0]);
|
||||||
@ -6978,8 +7019,8 @@ namespace sol {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename Fx, bool is_index, bool is_variable, bool checked>
|
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, std::enable_if_t<std::is_void<Fx>::value>> {
|
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;
|
typedef sol::destructor_wrapper<Fx> F;
|
||||||
|
|
||||||
static int call(lua_State* L, const 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>
|
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, std::enable_if_t<!std::is_void<Fx>::value>> {
|
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;
|
typedef sol::destructor_wrapper<Fx> F;
|
||||||
|
|
||||||
static int call(lua_State* L, const F& 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>
|
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, C> {
|
struct lua_call_wrapper<T, overload_set<Fs...>, is_index, is_variable, checked, boost, C> {
|
||||||
typedef overload_set<Fs...> F;
|
typedef overload_set<Fs...> F;
|
||||||
|
|
||||||
struct on_match {
|
struct on_match {
|
||||||
@ -7015,18 +7056,19 @@ namespace sol {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename V, bool is_index, bool is_variable, bool checked, typename 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, C> {
|
struct lua_call_wrapper<T, protect_t<V>, is_index, is_variable, checked, boost, C> {
|
||||||
typedef protect_t<V> F;
|
typedef protect_t<V> F;
|
||||||
|
|
||||||
static int call(lua_State* L, F& fx) {
|
template <typename... Args>
|
||||||
return lua_call_wrapper<T, V, is_index, is_variable, true>{}.call(L, fx.value);
|
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>
|
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) {
|
inline int call_wrapped(lua_State* L, Fx&& fx, Args&&... args) {
|
||||||
return lua_call_wrapper<T, meta::unqualified_t<Fx>, is_index, is_variable>{}.call(L, std::forward<Fx>(fx));
|
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>
|
template <typename T, bool is_index, bool is_variable, typename F>
|
||||||
@ -7191,16 +7233,15 @@ 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* f = 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, false, false>(L, f);
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int call(lua_State* L) {
|
static int call(lua_State* L) {
|
||||||
return detail::static_trampoline<(&real_call)>(L);
|
return detail::static_trampoline<(&real_call)>(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
int operator()(lua_State* L) {
|
int operator()(lua_State* L) const {
|
||||||
return call(L);
|
return call(L);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -7220,10 +7261,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, false, 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) {
|
||||||
@ -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>
|
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;
|
||||||
@ -7276,11 +7290,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");
|
||||||
}
|
}
|
||||||
@ -7326,16 +7338,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");
|
||||||
}
|
}
|
||||||
@ -7590,44 +7598,6 @@ namespace sol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace stack {
|
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>
|
template<typename... Sigs>
|
||||||
struct pusher<function_sig<Sigs...>> {
|
struct pusher<function_sig<Sigs...>> {
|
||||||
template <typename... Sig, typename Fx, typename... Args>
|
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
|
} // stack
|
||||||
} // sol
|
} // sol
|
||||||
|
|
||||||
@ -9173,24 +9205,25 @@ namespace sol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
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>
|
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>
|
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:
|
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>
|
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, 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)...) {}
|
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>
|
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>
|
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 {
|
virtual int push_um(lua_State* L) override {
|
||||||
return stack::push(L, std::move(*this));
|
return stack::push(L, std::move(*this));
|
||||||
|
@ -215,6 +215,7 @@ namespace sol {
|
|||||||
typedef std::tuple<Arg> args_tuple;
|
typedef std::tuple<Arg> args_tuple;
|
||||||
typedef R return_type;
|
typedef R return_type;
|
||||||
typedef types<Arg> args_list;
|
typedef types<Arg> args_list;
|
||||||
|
typedef types<T, Arg> free_args_list;
|
||||||
typedef meta::tuple_types<R> returns_list;
|
typedef meta::tuple_types<R> returns_list;
|
||||||
typedef R(function_type)(T&, R);
|
typedef R(function_type)(T&, R);
|
||||||
typedef R(*function_pointer_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;
|
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 {
|
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 wrapper<meta::unqualified_t<F>> wrap;
|
||||||
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, 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 wrapper<meta::unqualified_t<F>> wrap;
|
||||||
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, 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) {
|
template <typename Fx>
|
||||||
return var_call(std::integral_constant<bool, is_variable>(), L, f);
|
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>
|
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, 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) {
|
static int call(lua_State* L, lua_r_CFunction f) {
|
||||||
return f(L);
|
return f(L);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <bool is_index, bool is_variable, bool checked, typename 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, C> {
|
struct agnostic_lua_call_wrapper<lua_CFunction, is_index, is_variable, checked, boost, C> {
|
||||||
static int call(lua_State* L, lua_CFunction f) {
|
static int call(lua_State* L, lua_CFunction f) {
|
||||||
return f(L);
|
return f(L);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <bool is_index, bool is_variable, bool checked, typename 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, C> {
|
struct agnostic_lua_call_wrapper<no_prop, is_index, is_variable, checked, boost, C> {
|
||||||
static int call(lua_State* L, const no_prop&) {
|
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");
|
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>
|
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, C> {
|
struct agnostic_lua_call_wrapper<no_construction, is_index, is_variable, checked, boost, C> {
|
||||||
static int call(lua_State* L, const no_construction&) {
|
static int call(lua_State* L, const no_construction&) {
|
||||||
return luaL_error(L, "sol: cannot call this constructor (tagged as non-constructible)");
|
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>
|
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, C> {
|
struct agnostic_lua_call_wrapper<bases<Args...>, is_index, is_variable, checked, boost, C> {
|
||||||
static int call(lua_State*, const bases<Args...>&) {
|
static int call(lua_State*, const bases<Args...>&) {
|
||||||
// Uh. How did you even call this, lul
|
// Uh. How did you even call this, lul
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename F, bool is_index, bool is_variable, bool checked = stack::stack_detail::default_check_arguments, typename = void>
|
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> {};
|
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>
|
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, std::enable_if_t<std::is_member_function_pointer<F>::value>> {
|
struct lua_call_wrapper<T, F, is_index, is_variable, checked, boost, 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;
|
||||||
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::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;
|
||||||
typedef typename wrap::object_type object_type;
|
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);
|
||||||
typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
|
}
|
||||||
|
|
||||||
|
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
|
#ifdef SOL_SAFE_USERTYPE
|
||||||
object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
|
object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
|
||||||
if (o == nullptr) {
|
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 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
|
#else
|
||||||
object_type& o = static_cast<object_type&>(stack::get<Ta&>(L, 1));
|
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
|
#endif // Safety
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename F, bool is_variable, bool checked>
|
template <typename T, typename F, bool is_variable, bool checked, int boost>
|
||||||
struct lua_call_wrapper<T, F, false, is_variable, checked, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
|
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 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) {
|
template <typename V>
|
||||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
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::object_type object_type;
|
|
||||||
typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
|
|
||||||
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
#ifdef SOL_SAFE_USERTYPE
|
||||||
object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
|
object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
|
||||||
if (o == nullptr) {
|
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 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
|
#else
|
||||||
object_type& o = static_cast<object_type&>(stack::get<Ta&>(L, 1));
|
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
|
#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");
|
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;
|
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");
|
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);
|
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>
|
template <typename T, typename F, bool is_variable, bool checked, int boost>
|
||||||
struct lua_call_wrapper<T, F, true, is_variable, checked, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
|
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 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) {
|
template <typename V>
|
||||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
static int call(lua_State* L, V&& f, object_type& o) {
|
||||||
typedef typename wrap::object_type object_type;
|
|
||||||
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
#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 (o == nullptr) {
|
||||||
if (is_variable) {
|
if (is_variable) {
|
||||||
return luaL_error(L, "sol: 'self' argument is nil (bad '.' access?)");
|
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 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
|
#else
|
||||||
object_type& o = static_cast<object_type&>(stack::get<T&>(L, 1));
|
object_type& o = static_cast<object_type&>(stack::get<Ta&>(L, 1));
|
||||||
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);
|
||||||
#endif // Safety
|
#endif // Safety
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename... Args, bool is_index, bool is_variable, bool checked, typename 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, C> {
|
struct lua_call_wrapper<T, sol::constructor_list<Args...>, is_index, is_variable, checked, boost, C> {
|
||||||
typedef sol::constructor_list<Args...> F;
|
typedef sol::constructor_list<Args...> F;
|
||||||
|
|
||||||
static int call(lua_State* L, F&) {
|
static int call(lua_State* L, F&) {
|
||||||
@ -313,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, 1 + static_cast<int>(syntax));
|
construct_match<T, Args...>(constructor_match<T, 1>(obj), L, argcount, boost + 1 + static_cast<int>(syntax));
|
||||||
|
|
||||||
userdataref.push();
|
userdataref.push();
|
||||||
luaL_getmetatable(L, &metakey[0]);
|
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>
|
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, C> {
|
struct lua_call_wrapper<T, sol::constructor_wrapper<Cxs...>, is_index, is_variable, checked, boost, C> {
|
||||||
typedef sol::constructor_wrapper<Cxs...> F;
|
typedef sol::constructor_wrapper<Cxs...> F;
|
||||||
|
|
||||||
struct onmatch {
|
struct onmatch {
|
||||||
@ -342,7 +373,7 @@ namespace sol {
|
|||||||
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, 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();
|
userdataref.push();
|
||||||
luaL_getmetatable(L, &metakey[0]);
|
luaL_getmetatable(L, &metakey[0]);
|
||||||
@ -367,8 +398,8 @@ namespace sol {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename Fx, bool is_index, bool is_variable, bool checked>
|
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, std::enable_if_t<std::is_void<Fx>::value>> {
|
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;
|
typedef sol::destructor_wrapper<Fx> F;
|
||||||
|
|
||||||
static int call(lua_State* L, const 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>
|
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, std::enable_if_t<!std::is_void<Fx>::value>> {
|
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;
|
typedef sol::destructor_wrapper<Fx> F;
|
||||||
|
|
||||||
static int call(lua_State* L, const F& 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>
|
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, C> {
|
struct lua_call_wrapper<T, overload_set<Fs...>, is_index, is_variable, checked, boost, C> {
|
||||||
typedef overload_set<Fs...> F;
|
typedef overload_set<Fs...> F;
|
||||||
|
|
||||||
struct on_match {
|
struct on_match {
|
||||||
@ -404,18 +435,19 @@ namespace sol {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename V, bool is_index, bool is_variable, bool checked, typename 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, C> {
|
struct lua_call_wrapper<T, protect_t<V>, is_index, is_variable, checked, boost, C> {
|
||||||
typedef protect_t<V> F;
|
typedef protect_t<V> F;
|
||||||
|
|
||||||
static int call(lua_State* L, F& fx) {
|
template <typename... Args>
|
||||||
return lua_call_wrapper<T, V, is_index, is_variable, true>{}.call(L, fx.value);
|
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>
|
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) {
|
inline int call_wrapped(lua_State* L, Fx&& fx, Args&&... args) {
|
||||||
return lua_call_wrapper<T, meta::unqualified_t<Fx>, is_index, is_variable>{}.call(L, std::forward<Fx>(fx));
|
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>
|
template <typename T, bool is_index, bool is_variable, typename F>
|
||||||
|
@ -44,44 +44,6 @@ namespace sol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace stack {
|
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>
|
template<typename... Sigs>
|
||||||
struct pusher<function_sig<Sigs...>> {
|
struct pusher<function_sig<Sigs...>> {
|
||||||
template <typename... Sig, typename Fx, typename... Args>
|
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
|
} // stack
|
||||||
} // sol
|
} // sol
|
||||||
|
|
||||||
|
@ -33,16 +33,15 @@ 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* f = 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, false, false>(L, f);
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int call(lua_State* L) {
|
static int call(lua_State* L) {
|
||||||
return detail::static_trampoline<(&real_call)>(L);
|
return detail::static_trampoline<(&real_call)>(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
int operator()(lua_State* L) {
|
int operator()(lua_State* L) const {
|
||||||
return call(L);
|
return call(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, false, 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");
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#ifndef SOL_PROTECT_HPP
|
#ifndef SOL_PROTECT_HPP
|
||||||
#define SOL_PROTECT_HPP
|
#define SOL_PROTECT_HPP
|
||||||
|
|
||||||
|
#include "traits.hpp"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
@ -29,11 +30,20 @@ namespace sol {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct protect_t {
|
struct protect_t {
|
||||||
T value;
|
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>
|
template <typename T>
|
||||||
auto protect(T&& value) {
|
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
|
} // sol
|
||||||
|
@ -66,24 +66,33 @@ namespace sol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
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>
|
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>
|
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:
|
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>
|
template<typename Arg, typename... Args, meta::disable_any<
|
||||||
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)...) {}
|
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>
|
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>
|
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 {
|
virtual int push_um(lua_State* L) override {
|
||||||
return stack::push(L, std::move(*this));
|
return stack::push(L, std::move(*this));
|
||||||
|
@ -133,6 +133,9 @@ namespace sol {
|
|||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
using disable = std::enable_if_t<neg<all<Args...>>::value, enable_t>;
|
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>
|
template<typename V, typename... Vs>
|
||||||
struct find_in_pack_v : boolean<false> { };
|
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") {
|
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;
|
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, 30)"));
|
||||||
REQUIRE_NOTHROW(lua.script("v(20, 25)"));
|
REQUIRE_NOTHROW(lua.script("v(20, 25)"));
|
||||||
REQUIRE_THROWS(lua.script("v(20)"));
|
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…
x
Reference in New Issue
Block a user