From 29f171e124ed8bc70f97256fb7df04c000736431 Mon Sep 17 00:00:00 2001 From: ThePhD Date: Mon, 2 Dec 2013 18:11:25 -0500 Subject: [PATCH] Style fixes and fixes for templates not usually used by MSVC (broken two-phase lookup killing me here. :c) Member functions now work as well for set_function. If performance of `new`ing a type ever becomes too large, we can create a custom allocator for the std::shared_ptr's of the types. We can also up-front allocate for the unordered_map as well. --- sol/functional.hpp | 78 ++++++++++++++++++++-------------------- sol/lua_function.hpp | 65 +++++++++++++++++++++------------- sol/stack.hpp | 4 +-- sol/state.hpp | 10 ++++-- sol/table.hpp | 84 ++++++++++++++++++++++++-------------------- 5 files changed, 135 insertions(+), 106 deletions(-) diff --git a/sol/functional.hpp b/sol/functional.hpp index 7c0e8e34..f16fc528 100644 --- a/sol/functional.hpp +++ b/sol/functional.hpp @@ -30,70 +30,70 @@ namespace detail { template struct function_traits; -template -struct function_traits { - static const std::size_t arity = sizeof...(Tn); +template +struct function_traits { + static const std::size_t arity = sizeof...(Args); static const bool is_member_function = true; - typedef std::tuple arg_tuple_t; - typedef types args_t; - typedef R(T::* func_t)(Tn...); - typedef R(T::* func_pointer_t)(Tn...); - typedef R return_t; + typedef std::tuple arg_tuple_type; + typedef types args_type; + typedef R(T::* func_pointer_type)(Args...); + typedef typename std::remove_pointer::type func_type; + typedef R return_type; template - using arg_n = std::tuple_element; + using arg_n = std::tuple_element; }; -template -struct function_traits { - static const std::size_t arity = sizeof...(Tn); +template +struct function_traits { + static const std::size_t arity = sizeof...(Args); static const bool is_member_function = true; - typedef std::tuple arg_tuple_t; - typedef types args_t; - typedef R(T::* func_t)(Tn...); - typedef R(T::* func_pointer_t)(Tn...); - typedef R return_t; + typedef std::tuple arg_tuple_type; + typedef types args_type; + typedef R(T::* func_type)(Args...); + typedef R(T::* func_pointer_type)(Args...); + typedef R return_type; template - using arg_n = std::tuple_element; + using arg_n = std::tuple_element; }; -template -struct function_traits { - static const std::size_t arity = sizeof...(Tn); +template +struct function_traits { + static const std::size_t arity = sizeof...(Args); static const bool is_member_function = false; - typedef std::tuple arg_tuple_t; - typedef types args_t; - typedef R(func_t)(Tn...); - typedef R(*func_pointer_t)(Tn...); - typedef R return_t; + typedef std::tuple arg_tuple_type; + typedef types args_type; + typedef R(func_type)(Args...); + typedef R(*func_pointer_type)(Args...); + typedef R return_type; template - using arg_n = std::tuple_element; + using arg_n = std::tuple_element; }; -template -struct function_traits { - static const std::size_t arity = sizeof...(Tn); +template +struct function_traits { + static const std::size_t arity = sizeof...(Args); static const bool is_member_function = false; - typedef std::tuple arg_tuple_t; - typedef types args_t; - typedef R(func_t)(Tn...); - typedef R(*func_pointer_t)(Tn...); - typedef R return_t; + typedef std::tuple arg_tuple_type; + typedef types args_type; + typedef R(func_type)(Args...); + typedef R(*func_pointer_type)(Args...); + typedef R return_type; template - using arg_n = std::tuple_element; + using arg_n = std::tuple_element; }; using std::get; template -inline auto call(Function f, const Tuple& t, indices) -> decltype(f(get(t)...)) { +inline auto call(Function&& f, const Tuple& t, indices) -> decltype(f(get(t)...)) { return f(get(t)...); } } // detail template -inline auto call(Function f, const std::tuple& t) -> decltype(detail::call(f, t, detail::build_indices{})) { - return call(f, t, detail::build_indices{}); +inline auto call(Function&& f, const std::tuple& t) -> decltype(detail::call(std::forward(f), t, build_indices{})) { + return call(std::forward(f), t, build_indices{}); } } // sol diff --git a/sol/lua_function.hpp b/sol/lua_function.hpp index 6889cd31..af9a2cab 100644 --- a/sol/lua_function.hpp +++ b/sol/lua_function.hpp @@ -42,23 +42,23 @@ struct lambda_lua_func : public lua_func { typedef function_traits fx_traits; TFx fx; - template - lambda_lua_func(TFxn&&... fxn) : fx(std::forward(fxn)...) { + template + lambda_lua_func(FxArgs&&... fxargs) : fx(std::forward(fxargs)...) { } virtual int operator () (lua_State* L) override { - return (*this)(tuple_types(), fx_traits::args_t(), L); + return (*this)(tuple_types(), fx_traits::args_type(), L); } - template - int operator()(types, types t, lua_State* L) { + template + int operator()(types, types t, lua_State* L) { stack::pop_call(L, fx, t); return 0; } - template - int operator()(types, types t, lua_State* L) { + template + int operator()(types, types t, lua_State* L) { auto r = stack::pop_call(L, fx, t); stack::push(L, r); return sizeof...(TRn); @@ -71,23 +71,23 @@ struct explicit_lua_func : public lua_func { typedef function_traits fx_traits; TFx fx; - template - explicit_lua_func(TFxn&&... fxn) : fx(std::forward(fxn)...) { + template + explicit_lua_func(FxArgs&&... fxargs) : fx(std::forward(fxargs)...) { } virtual int operator () (lua_State* L) override { - return (*this)(tuple_types(), fx_traits::args_t(), L); + return (*this)(tuple_types(), fx_traits::args_type(), L); } - template - int operator () (types, types t, lua_State* L) { + template + int operator () (types, types t, lua_State* L) { stack::pop_call(L, fx, t); return 0; } - template - int operator () (types, types t, lua_State* L) { + template + int operator () (types, types t, lua_State* L) { auto r = stack::pop_call(L, fx, t); stack::push(L, r); return sizeof...(TRn); @@ -98,26 +98,43 @@ template struct explicit_lua_func : public lua_func { typedef typename std::remove_pointer::type>::type fx_t; typedef function_traits fx_traits; - T* member; - TFx fx; - - template - explicit_lua_func(T* m, TFxn&&... fxn) : member(m), fx(std::forward(fxn)...) { + struct lambda { + T* member; + TFx invocation; + + template + lambda(T* m, FxArgs&&... fxargs) : member(m), invocation(std::forward(fxargs)...) { + + } + + template + typename fx_traits::return_type operator () (Args&&... args) { + return ((*member).*invocation)(std::forward(args)...); + } + } fx; + + template + explicit_lua_func(T* m, FxArgs&&... fxargs) : fx(m, std::forward(fxargs)...) { + + } + + template + explicit_lua_func(T& m, FxArgs&&... fxargs) : fx(std::addressof(m), std::forward(fxargs)...) { } virtual int operator () (lua_State* L) override { - return (*this)(tuple_types(), fx_traits::args_t(), L); + return (*this)(tuple_types(), fx_traits::args_type(), L); } - template - int operator () (types, types, lua_State* L) { + template + int operator () (types, types, lua_State* L) { stack::pop_call(L, fx, t); return 0; } - template - int operator () (types, types t, lua_State* L) { + template + int operator () (types, types t, lua_State* L) { auto r = stack::pop_call(L, fx, t); stack::push(L, r); return sizeof...(TRn); diff --git a/sol/stack.hpp b/sol/stack.hpp index b34ba40f..02c302bd 100644 --- a/sol/stack.hpp +++ b/sol/stack.hpp @@ -45,8 +45,8 @@ auto ltr_pop(T&& extra, F f, types<>, Vs&&... vs) // take head, produce value from it, pass after other values template auto ltr_pop(lua_State* L, F f, types, Vs&&... vs) --> decltype(ltr_pop(L, f, types{}, std::forward(vs)..., stack::pop(L))) { - return ltr_pop(L, f, types{}, std::forward(vs)..., stack::pop(L)); +-> decltype(ltr_pop(L, f, types{}, std::forward(vs)..., pop(L))) { + return ltr_pop(L, f, types{}, std::forward(vs)..., pop(L)); } template diff --git a/sol/state.hpp b/sol/state.hpp index 0347685d..fc56f4c4 100644 --- a/sol/state.hpp +++ b/sol/state.hpp @@ -149,8 +149,14 @@ public: template state& set_function(T&& key, TFx&& fx) { - global.set_function(std::forward(key), std::forward(fx)); - return *this; + global.set_function(std::forward(key), std::forward(fx)); + return *this; + } + + template + state& set_function(T&& key, TFx&& fx, TM& mem) { + global.set_function(std::forward(key), std::forward(fx), mem); + return *this; } template diff --git a/sol/table.hpp b/sol/table.hpp index a2090c4f..81525579 100644 --- a/sol/table.hpp +++ b/sol/table.hpp @@ -60,53 +60,59 @@ public: template table& set_function(T&& key, TFx&& fx) { - typedef typename std::remove_pointer::type>::type clean_fx; - const static bool isfunction = std::is_function::value; - return set_function(std::integral_constant(), - std::forward(key), std::forward(fx)); + typedef typename std::remove_pointer::type>::type clean_fx; + const static bool isfunction = std::is_function::value; + return set_fx(std::integral_constant(), + std::forward(key), std::forward(fx)); } - template - table& set_function(std::true_type, T&& key, TFx&& fx) { - typedef typename std::decay::type clean_fx; - std::string fkey(key); - lua_CFunction freefunc = &detail::lua_cfun; - auto hint = funcs.find(fkey); - detail::lua_func* target = nullptr; - if (hint == funcs.end()) { - std::shared_ptr sptr(new detail::lambda_lua_func(std::forward(fx))); - hint = funcs.emplace_hint(hint, fkey, std::move(sptr)); - } - target = hint->second.get(); - lua_pushlightuserdata(state(), static_cast(target)); - lua_pushcclosure(state(), freefunc, 1); - lua_setglobal(state(), fkey.c_str()); - return *this; - } - - template - table& set_function(std::false_type, T&& key, TFx&& fx) { - typedef typename std::decay::type clean_fx; - std::string fkey(key); - lua_CFunction freefunc = &detail::lua_cfun; - auto hint = funcs.find(fkey); - detail::lua_func* target = nullptr; - if (hint == funcs.end()) { - std::shared_ptr sptr(new detail::explicit_lua_func(std::forward(fx))); - hint = funcs.emplace_hint(hint, fkey, std::move(sptr)); - } - target = hint->second.get(); - lua_pushlightuserdata(state(), static_cast(target)); - lua_pushcclosure(state(), freefunc, 1); - lua_setglobal(state(), fkey.c_str()); - return *this; + template + table& set_function(T&& key, TFx&& fx, TM& mem) { + typedef typename std::remove_pointer::type>::type clean_fx; + std::unique_ptr sptr(new detail::explicit_lua_func(mem, std::forward(fx))); + return set_fx(std::forward(key), std::move(sptr)); } size_t size() const { push(); return lua_rawlen(state(), -1); } - + +private: + + template + table& set_fx(std::true_type, T&& key, TFx&& fx) { + typedef typename std::remove_pointer::type>::type clean_fx; + std::unique_ptr sptr(new detail::lambda_lua_func(std::forward(fx))); + return set_fx(std::forward(key), std::move(sptr)); + } + + template + table& set_fx(std::false_type, T&& key, TFx&& fx) { + typedef typename std::remove_pointer::type>::type clean_fx; + typedef typename std::decay::type ptr_fx; + std::unique_ptr sptr(new detail::explicit_lua_func(std::forward(fx))); + return set_fx(std::forward(key), std::move(sptr)); + } + + template + table& set_fx(T&& key, std::unique_ptr funcptr) { + std::string fkey(key); + auto hint = funcs.find(fkey); + if (hint == funcs.end()) { + std::shared_ptr sptr(funcptr.release()); + hint = funcs.emplace_hint(hint, fkey, std::move(sptr)); + } + else { + hint->second.reset(funcptr.release()); + } + detail::lua_func* target = target = hint->second.get(); + lua_CFunction freefunc = &detail::lua_cfun; + lua_pushlightuserdata(state(), static_cast(target)); + lua_pushcclosure(state(), freefunc, 1); + lua_setglobal(state(), fkey.c_str()); + return *this; + } }; } // sol