mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
yield fix for sol3
This commit is contained in:
parent
56fd896bed
commit
4f35e330e8
|
@ -740,13 +740,23 @@ namespace sol {
|
|||
struct lua_call_wrapper<T, function_arguments<Sig, P>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
template <typename F>
|
||||
static int call(lua_State* L, F&& f) {
|
||||
return lua_call_wrapper<T, meta::unqualified_t<P>, is_index, is_variable, checked, boost, clean_stack> {}.call(L, std::get<0>(f.arguments));
|
||||
return lua_call_wrapper<T, meta::unqualified_t<P>, is_index, is_variable, checked, boost, clean_stack>{}.call(L, std::get<0>(f.arguments));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, bool is_index, bool is_variable, int boost = 0, bool checked = detail::default_safe_function_calls, bool clean_stack = true, 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, checked, boost, clean_stack> {}.call(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
using uFx = meta::unqualified_t<Fx>;
|
||||
if constexpr(meta::is_specialization_of_v<uFx, yielding_t>) {
|
||||
using real_fx = meta::unqualified_t<decltype(std::forward<Fx>(fx).func)>;
|
||||
int nr = lua_call_wrapper<T, real_fx, is_index, is_variable, checked, boost, clean_stack>{}.call(
|
||||
L, std::forward<Fx>(fx).func, std::forward<Args>(args)...);
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return lua_call_wrapper<T, uFx, is_index, is_variable, checked, boost, clean_stack>{}.call(
|
||||
L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, bool is_index, bool is_variable, typename F, int start = 1, bool checked = detail::default_safe_function_calls, bool clean_stack = true>
|
||||
|
|
|
@ -43,26 +43,21 @@ namespace sol {
|
|||
namespace stack {
|
||||
template <typename... Sigs>
|
||||
struct unqualified_pusher<function_sig<Sigs...>> {
|
||||
template <bool is_yielding, typename... Sig, typename Fx, typename... Args>
|
||||
static void select_convertible(std::false_type, types<Sig...>, lua_State* L, Fx&& fx, Args&&... args) {
|
||||
typedef std::remove_pointer_t<std::decay_t<Fx>> clean_fx;
|
||||
typedef function_detail::functor_function<clean_fx, is_yielding, true> F;
|
||||
set_fx<false, F>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <bool is_yielding, typename R, typename... A, typename Fx, typename... Args>
|
||||
static void select_convertible(std::true_type, types<R(A...)>, lua_State* L, Fx&& fx, Args&&... args) {
|
||||
using fx_ptr_t = R (*)(A...);
|
||||
fx_ptr_t fxptr = detail::unwrap(std::forward<Fx>(fx));
|
||||
select_function<is_yielding>(std::true_type(), L, fxptr, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <bool is_yielding, typename R, typename... A, typename Fx, typename... Args>
|
||||
static void select_convertible(types<R(A...)> t, lua_State* L, Fx&& fx, Args&&... args) {
|
||||
typedef std::decay_t<meta::unwrap_unqualified_t<Fx>> raw_fx_t;
|
||||
typedef R (*fx_ptr_t)(A...);
|
||||
typedef std::is_convertible<raw_fx_t, fx_ptr_t> is_convertible;
|
||||
select_convertible<is_yielding>(is_convertible(), t, L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
constexpr bool is_convertible = std::is_convertible_v<raw_fx_t, fx_ptr_t>;
|
||||
if constexpr (is_convertible) {
|
||||
using fx_ptr_t = R (*)(A...);
|
||||
fx_ptr_t fxptr = detail::unwrap(std::forward<Fx>(fx));
|
||||
select_function<is_yielding>(std::true_type(), L, fxptr, std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
typedef std::remove_pointer_t<std::decay_t<Fx>> clean_fx;
|
||||
typedef function_detail::functor_function<clean_fx, is_yielding, true> F;
|
||||
set_fx<false, F>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <bool is_yielding, typename Fx, typename... Args>
|
||||
|
@ -71,27 +66,6 @@ namespace sol {
|
|||
select_convertible<is_yielding>(types<Sig>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <bool is_yielding, typename Fx, typename T, typename... Args>
|
||||
static void select_reference_member_variable(std::false_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
|
||||
typedef std::remove_pointer_t<std::decay_t<Fx>> clean_fx;
|
||||
typedef function_detail::member_variable<meta::unwrap_unqualified_t<T>, clean_fx, is_yielding> F;
|
||||
set_fx<false, F>(L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <bool is_yielding, typename Fx, typename T, typename... Args>
|
||||
static void select_reference_member_variable(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
|
||||
typedef std::decay_t<Fx> dFx;
|
||||
dFx memfxptr(std::forward<Fx>(fx));
|
||||
auto userptr = detail::ptr(std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
lua_CFunction freefunc = &function_detail::upvalue_member_variable<std::decay_t<decltype(*userptr)>, meta::unqualified_t<Fx>, is_yielding>::call;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::stack_detail::push_as_upvalues(L, memfxptr);
|
||||
upvalues += stack::push(L, static_cast<void const*>(userptr));
|
||||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
|
||||
template <bool is_yielding, typename Fx, typename... Args>
|
||||
static void select_member_variable(std::false_type, lua_State* L, Fx&& fx, Args&&... args) {
|
||||
select_convertible<is_yielding>(types<Sigs...>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
|
@ -99,8 +73,25 @@ namespace sol {
|
|||
|
||||
template <bool is_yielding, typename Fx, typename T, typename... Args, meta::disable<meta::is_specialization_of<meta::unqualified_t<T>, function_detail::class_indicator>> = meta::enabler>
|
||||
static void select_member_variable(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
|
||||
typedef meta::boolean<meta::is_specialization_of<meta::unqualified_t<T>, std::reference_wrapper>::value || std::is_pointer<T>::value> is_reference;
|
||||
select_reference_member_variable<is_yielding>(is_reference(), L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
constexpr bool is_reference = meta::is_specialization_of_v<meta::unqualified_t<T>, std::reference_wrapper> || std::is_pointer_v<T>;
|
||||
if constexpr(is_reference) {
|
||||
typedef std::decay_t<Fx> dFx;
|
||||
dFx memfxptr(std::forward<Fx>(fx));
|
||||
auto userptr = detail::ptr(std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
lua_CFunction freefunc
|
||||
= &function_detail::upvalue_member_variable<std::decay_t<decltype(*userptr)>, meta::unqualified_t<Fx>, is_yielding>::call;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::stack_detail::push_as_upvalues(L, memfxptr);
|
||||
upvalues += stack::push(L, static_cast<void const*>(userptr));
|
||||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
else {
|
||||
using clean_fx = std::remove_pointer_t<std::decay_t<Fx>>;
|
||||
using F = function_detail::member_variable<meta::unwrap_unqualified_t<T>, clean_fx, is_yielding>;
|
||||
set_fx<false, F>(L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <bool is_yielding, typename Fx, typename C>
|
||||
|
@ -230,17 +221,20 @@ namespace sol {
|
|||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
|
||||
template <typename Arg0, typename... Args, meta::disable<std::is_same<detail::yield_tag_t, meta::unqualified_t<Arg0>>> = meta::enabler>
|
||||
template <typename Arg0, typename... Args>
|
||||
static int push(lua_State* L, Arg0&& arg0, Args&&... args) {
|
||||
// Set will always place one thing (function) on the stack
|
||||
select<false>(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
|
||||
if constexpr(std::is_same_v<meta::unqualified_t<Arg0>, detail::yield_tag_t>) {
|
||||
select<true>(L, std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
select<false>(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static int push(lua_State* L, detail::yield_tag_t, Args&&... args) {
|
||||
// Set will always place one thing (function) on the stack
|
||||
select<true>(L, std::forward<Args>(args)...);
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
@ -258,7 +252,7 @@ namespace sol {
|
|||
static int push(lua_State* L, yielding_t<T>&& f, Args&&... args) {
|
||||
unqualified_pusher<function_sig<>> p{};
|
||||
(void)p;
|
||||
return p.push(L, detail::yield_tag, f.func, std::forward<Args>(args)...);
|
||||
return p.push(L, detail::yield_tag, std::move(f.func), std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -140,11 +140,8 @@ namespace sol {
|
|||
template <bool B>
|
||||
using boolean = std::integral_constant<bool, B>;
|
||||
|
||||
template <typename T>
|
||||
using invoke_t = typename T::type;
|
||||
|
||||
template <typename T>
|
||||
using invoke_v = boolean<T::value>;
|
||||
template <bool B>
|
||||
constexpr inline bool boolean_v = boolean<B>::value;
|
||||
|
||||
template <typename T>
|
||||
using neg = boolean<!T::value>;
|
||||
|
@ -518,29 +515,21 @@ namespace sol {
|
|||
struct is_matched_lookup_impl<T, true> : std::is_same<typename T::key_type, typename T::value_type> {};
|
||||
} // namespace meta_detail
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1910
|
||||
template <typename T, typename U = T>
|
||||
using supports_op_less = decltype(meta_detail::supports_op_less_test(std::ref(std::declval<T&>()), std::ref(std::declval<U&>())));
|
||||
template <typename T, typename U = T>
|
||||
using supports_op_equal = decltype(meta_detail::supports_op_equal_test(std::ref(std::declval<T&>()), std::ref(std::declval<U&>())));
|
||||
template <typename T, typename U = T>
|
||||
using supports_op_less_equal = decltype(meta_detail::supports_op_less_equal_test(std::ref(std::declval<T&>()), std::ref(std::declval<U&>())));
|
||||
template <typename T, typename U = std::ostream>
|
||||
using supports_ostream_op = decltype(meta_detail::supports_ostream_op(std::ref(std::declval<T&>()), std::ref(std::declval<U&>())));
|
||||
struct supports_op_less : decltype(meta_detail::supports_op_less_test(std::declval<T&>(), std::declval<U&>())) {};
|
||||
template <typename T>
|
||||
using supports_adl_to_string = decltype(meta_detail::supports_adl_to_string(std::ref(std::declval<T&>())));
|
||||
#else
|
||||
template <typename T, typename U = T>
|
||||
using supports_op_less = decltype(meta_detail::supports_op_less_test(std::declval<T&>(), std::declval<U&>()));
|
||||
template <typename T, typename U = T>
|
||||
using supports_op_equal = decltype(meta_detail::supports_op_equal_test(std::declval<T&>(), std::declval<U&>()));
|
||||
template <typename T, typename U = T>
|
||||
using supports_op_less_equal = decltype(meta_detail::supports_op_less_equal_test(std::declval<T&>(), std::declval<U&>()));
|
||||
template <typename T, typename U = std::ostream>
|
||||
using supports_ostream_op = decltype(meta_detail::supports_ostream_op(std::declval<T&>(), std::declval<U&>()));
|
||||
struct supports_op_less<void, T> : std::false_type {};
|
||||
template <typename T>
|
||||
using supports_adl_to_string = decltype(meta_detail::supports_adl_to_string(std::declval<T&>()));
|
||||
#endif
|
||||
struct supports_op_less<T, void> : std::false_type {};
|
||||
template <typename T, typename U = T>
|
||||
struct supports_op_equal : decltype(meta_detail::supports_op_equal_test(std::declval<T&>(), std::declval<U&>())) {};
|
||||
template <typename T, typename U = T>
|
||||
struct supports_op_less_equal : decltype(meta_detail::supports_op_less_equal_test(std::declval<T&>(), std::declval<U&>())) {};
|
||||
template <typename T, typename U = std::ostream>
|
||||
struct supports_ostream_op : decltype(meta_detail::supports_ostream_op(std::declval<T&>(), std::declval<U&>())) {};
|
||||
template <typename T>
|
||||
struct supports_adl_to_string : decltype(meta_detail::supports_adl_to_string(std::declval<T&>())) {};
|
||||
|
||||
template <typename T>
|
||||
using supports_to_string_member = meta::boolean<meta_detail::has_to_string_test<T>::value>;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user