| 16271 | struct agnostic_lua_call_wrapper { |
| 16272 | template <typename Fx, typename... Args> |
| 16273 | static int call(lua_State* L, Fx&& f, Args&&... args) { |
| 16274 | using uFx = meta::unqualified_t<Fx>; |
| 16275 | static constexpr bool is_ref = is_lua_reference_v<uFx>; |
| 16276 | if constexpr (is_ref) { |
| 16277 | if constexpr (is_index) { |
| 16278 | return stack::push(L, std::forward<Fx>(f), std::forward<Args>(args)...); |
| 16279 | } |
| 16280 | else { |
| 16281 | std::forward<Fx>(f) = stack::unqualified_get<F>(L, boost + (is_variable ? 3 : 1)); |
| 16282 | return 0; |
| 16283 | } |
| 16284 | } |
| 16285 | else { |
| 16286 | using wrap = wrapper<uFx>; |
| 16287 | using traits_type = typename wrap::traits_type; |
| 16288 | using fp_t = typename traits_type::function_pointer_type; |
| 16289 | constexpr bool is_function_pointer_convertible |
| 16290 | = std::is_class_v<uFx> && std::is_convertible_v<std::decay_t<Fx>, fp_t>; |
| 16291 | if constexpr (is_function_pointer_convertible) { |
| 16292 | fp_t fx = f; |
| 16293 | return agnostic_lua_call_wrapper<fp_t, is_index, is_variable, checked, boost, clean_stack>{}.call( |
| 16294 | L, fx, std::forward<Args>(args)...); |
| 16295 | } |
| 16296 | else { |
| 16297 | using returns_list = typename wrap::returns_list; |
| 16298 | using args_list = typename wrap::free_args_list; |
| 16299 | using caller = typename wrap::caller; |
| 16300 | return stack::call_into_lua<checked, clean_stack>( |
| 16301 | returns_list(), args_list(), L, boost + 1, caller(), std::forward<Fx>(f), std::forward<Args>(args)...); |
| 16302 | } |
| 16303 | } |
| 16304 | } |
| 16305 | }; |
| 16306 | |
| 16307 | template <typename T, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C> |