diff --git a/sol/function.hpp b/sol/function.hpp index 9da99ede..65ed135f 100644 --- a/sol/function.hpp +++ b/sol/function.hpp @@ -31,27 +31,27 @@ namespace sol { class function : public reference { private: - void luacall (std::size_t argcount, std::size_t resultcount) { + void luacall (std::size_t argcount, std::size_t resultcount) const { lua_call(state(), static_cast(argcount), static_cast(resultcount)); } template - std::tuple invoke(types, std::size_t n) { + std::tuple invoke(types, std::size_t n) const { luacall(n, sizeof...(Ret)); return stack::pop_reverse_call(state(), std::make_tuple, types()); } template - Ret invoke(types, std::size_t n) { + Ret invoke(types, std::size_t n) const { luacall(n, 1); return stack::pop(state()); } - void invoke(types, std::size_t n) { + void invoke(types, std::size_t n) const { luacall(n, 0); } - void invoke(types<>, std::size_t n) { + void invoke(types<>, std::size_t n) const { luacall(n, 0); } @@ -64,17 +64,17 @@ public: function& operator=(const function&) = default; template - void operator()(Args&&... args) { + void operator()(Args&&... args) const { call<>(std::forward(args)...); } template - typename return_type::type operator()(types, Args&&... args) { + typename return_type::type operator()(types, Args&&... args) const { return call(std::forward(args)...); } template - typename return_type::type call(Args&&... args) { + typename return_type::type call(Args&&... args) const { push(); stack::push_args(state(), std::forward(args)...); return invoke(types(), sizeof...(Args)); @@ -83,10 +83,37 @@ public: namespace stack { namespace detail { - template - inline std::function get(types>, lua_State* L, int index = -1) { - return std::function(sol::function(L, index)); - } +template +inline std::function get_std_func(types, types, lua_State* L, int index = -1) { + typedef typename function_traits::return_type return_t; + sol::function f(L, index); + auto fx = [ f, L, index ] (FxArgs&&... args) -> return_t { + return f(types(), std::forward(args)...); + }; + return std::move(fx); +} + +template +inline std::function get_std_func(types, types, lua_State* L, int index = -1) { + sol::function f(L, index); + auto fx = [ f, L, index ] (FxArgs&&... args) -> void { + f(std::forward(args)...); + }; + return std::move(fx); +} + +template +inline std::function get_std_func(types t, types<>, lua_State* L, int index = -1) { + return get_std_func(std::move(t), types(), L, index); +} + +template +inline std::function get(types>, lua_State* L, int index = -1) { + typedef typename function_traits fx_t; + typedef typename fx_t::args_type args_t; + typedef typename tuple_types::types_type ret_t; + return get_std_func(args_t(), ret_t(), L, index); +} } // detail } // stack } // sol