From 4f35e330e8905b1f26d58e88f84cc8c592ff85e3 Mon Sep 17 00:00:00 2001 From: ThePhD Date: Sat, 26 Jan 2019 03:09:37 -0500 Subject: [PATCH] yield fix for sol3 --- include/sol/call.hpp | 14 +++++- include/sol/function_types.hpp | 82 ++++++++++++++++------------------ include/sol/traits.hpp | 39 ++++++---------- 3 files changed, 64 insertions(+), 71 deletions(-) diff --git a/include/sol/call.hpp b/include/sol/call.hpp index 839bacc5..cbd118ce 100644 --- a/include/sol/call.hpp +++ b/include/sol/call.hpp @@ -740,13 +740,23 @@ namespace sol { struct lua_call_wrapper, is_index, is_variable, checked, boost, clean_stack, C> { template static int call(lua_State* L, F&& f) { - return lua_call_wrapper, is_index, is_variable, checked, boost, clean_stack> {}.call(L, std::get<0>(f.arguments)); + return lua_call_wrapper, is_index, is_variable, checked, boost, clean_stack>{}.call(L, std::get<0>(f.arguments)); } }; template inline int call_wrapped(lua_State* L, Fx&& fx, Args&&... args) { - return lua_call_wrapper, is_index, is_variable, checked, boost, clean_stack> {}.call(L, std::forward(fx), std::forward(args)...); + using uFx = meta::unqualified_t; + if constexpr(meta::is_specialization_of_v) { + using real_fx = meta::unqualified_t(fx).func)>; + int nr = lua_call_wrapper{}.call( + L, std::forward(fx).func, std::forward(args)...); + return lua_yield(L, nr); + } + else { + return lua_call_wrapper{}.call( + L, std::forward(fx), std::forward(args)...); + } } template diff --git a/include/sol/function_types.hpp b/include/sol/function_types.hpp index 2b4bd093..affb8558 100644 --- a/include/sol/function_types.hpp +++ b/include/sol/function_types.hpp @@ -43,26 +43,21 @@ namespace sol { namespace stack { template struct unqualified_pusher> { - template - static void select_convertible(std::false_type, types, lua_State* L, Fx&& fx, Args&&... args) { - typedef std::remove_pointer_t> clean_fx; - typedef function_detail::functor_function F; - set_fx(L, std::forward(fx), std::forward(args)...); - } - - template - static void select_convertible(std::true_type, types, lua_State* L, Fx&& fx, Args&&... args) { - using fx_ptr_t = R (*)(A...); - fx_ptr_t fxptr = detail::unwrap(std::forward(fx)); - select_function(std::true_type(), L, fxptr, std::forward(args)...); - } - template static void select_convertible(types t, lua_State* L, Fx&& fx, Args&&... args) { typedef std::decay_t> raw_fx_t; typedef R (*fx_ptr_t)(A...); - typedef std::is_convertible is_convertible; - select_convertible(is_convertible(), t, L, std::forward(fx), std::forward(args)...); + constexpr bool is_convertible = std::is_convertible_v; + if constexpr (is_convertible) { + using fx_ptr_t = R (*)(A...); + fx_ptr_t fxptr = detail::unwrap(std::forward(fx)); + select_function(std::true_type(), L, fxptr, std::forward(args)...); + } + else { + typedef std::remove_pointer_t> clean_fx; + typedef function_detail::functor_function F; + set_fx(L, std::forward(fx), std::forward(args)...); + } } template @@ -71,27 +66,6 @@ namespace sol { select_convertible(types(), L, std::forward(fx), std::forward(args)...); } - template - static void select_reference_member_variable(std::false_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) { - typedef std::remove_pointer_t> clean_fx; - typedef function_detail::member_variable, clean_fx, is_yielding> F; - set_fx(L, std::forward(fx), std::forward(obj), std::forward(args)...); - } - - template - static void select_reference_member_variable(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) { - typedef std::decay_t dFx; - dFx memfxptr(std::forward(fx)); - auto userptr = detail::ptr(std::forward(obj), std::forward(args)...); - lua_CFunction freefunc = &function_detail::upvalue_member_variable, meta::unqualified_t, 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(userptr)); - stack::push(L, c_closure(freefunc, upvalues)); - } - template static void select_member_variable(std::false_type, lua_State* L, Fx&& fx, Args&&... args) { select_convertible(types(), L, std::forward(fx), std::forward(args)...); @@ -99,8 +73,25 @@ namespace sol { template , 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, std::reference_wrapper>::value || std::is_pointer::value> is_reference; - select_reference_member_variable(is_reference(), L, std::forward(fx), std::forward(obj), std::forward(args)...); + constexpr bool is_reference = meta::is_specialization_of_v, std::reference_wrapper> || std::is_pointer_v; + if constexpr(is_reference) { + typedef std::decay_t dFx; + dFx memfxptr(std::forward(fx)); + auto userptr = detail::ptr(std::forward(obj), std::forward(args)...); + lua_CFunction freefunc + = &function_detail::upvalue_member_variable, meta::unqualified_t, 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(userptr)); + stack::push(L, c_closure(freefunc, upvalues)); + } + else { + using clean_fx = std::remove_pointer_t>; + using F = function_detail::member_variable, clean_fx, is_yielding>; + set_fx(L, std::forward(fx), std::forward(obj), std::forward(args)...); + } } template @@ -230,17 +221,20 @@ namespace sol { stack::push(L, c_closure(freefunc, upvalues)); } - template >> = meta::enabler> + template static int push(lua_State* L, Arg0&& arg0, Args&&... args) { - // Set will always place one thing (function) on the stack - select(L, std::forward(arg0), std::forward(args)...); + if constexpr(std::is_same_v, detail::yield_tag_t>) { + select(L, std::forward(args)...); + } + else { + select(L, std::forward(arg0), std::forward(args)...); + } return 1; } template static int push(lua_State* L, detail::yield_tag_t, Args&&... args) { // Set will always place one thing (function) on the stack - select(L, std::forward(args)...); return 1; } }; @@ -258,7 +252,7 @@ namespace sol { static int push(lua_State* L, yielding_t&& f, Args&&... args) { unqualified_pusher> p{}; (void)p; - return p.push(L, detail::yield_tag, f.func, std::forward(args)...); + return p.push(L, detail::yield_tag, std::move(f.func), std::forward(args)...); } }; diff --git a/include/sol/traits.hpp b/include/sol/traits.hpp index b0233350..d97701b2 100644 --- a/include/sol/traits.hpp +++ b/include/sol/traits.hpp @@ -140,11 +140,8 @@ namespace sol { template using boolean = std::integral_constant; - template - using invoke_t = typename T::type; - - template - using invoke_v = boolean; + template + constexpr inline bool boolean_v = boolean::value; template using neg = boolean; @@ -518,29 +515,21 @@ namespace sol { struct is_matched_lookup_impl : std::is_same {}; } // namespace meta_detail -#if defined(_MSC_VER) && _MSC_VER <= 1910 template - using supports_op_less = decltype(meta_detail::supports_op_less_test(std::ref(std::declval()), std::ref(std::declval()))); - template - using supports_op_equal = decltype(meta_detail::supports_op_equal_test(std::ref(std::declval()), std::ref(std::declval()))); - template - using supports_op_less_equal = decltype(meta_detail::supports_op_less_equal_test(std::ref(std::declval()), std::ref(std::declval()))); - template - using supports_ostream_op = decltype(meta_detail::supports_ostream_op(std::ref(std::declval()), std::ref(std::declval()))); + struct supports_op_less : decltype(meta_detail::supports_op_less_test(std::declval(), std::declval())) {}; template - using supports_adl_to_string = decltype(meta_detail::supports_adl_to_string(std::ref(std::declval()))); -#else - template - using supports_op_less = decltype(meta_detail::supports_op_less_test(std::declval(), std::declval())); - template - using supports_op_equal = decltype(meta_detail::supports_op_equal_test(std::declval(), std::declval())); - template - using supports_op_less_equal = decltype(meta_detail::supports_op_less_equal_test(std::declval(), std::declval())); - template - using supports_ostream_op = decltype(meta_detail::supports_ostream_op(std::declval(), std::declval())); + struct supports_op_less : std::false_type {}; template - using supports_adl_to_string = decltype(meta_detail::supports_adl_to_string(std::declval())); -#endif + struct supports_op_less : std::false_type {}; + template + struct supports_op_equal : decltype(meta_detail::supports_op_equal_test(std::declval(), std::declval())) {}; + template + struct supports_op_less_equal : decltype(meta_detail::supports_op_less_equal_test(std::declval(), std::declval())) {}; + template + struct supports_ostream_op : decltype(meta_detail::supports_ostream_op(std::declval(), std::declval())) {}; + template + struct supports_adl_to_string : decltype(meta_detail::supports_adl_to_string(std::declval())) {}; + template using supports_to_string_member = meta::boolean::value>;