From 2192e98eecd0ea4956a56a2045451184c86debf0 Mon Sep 17 00:00:00 2001 From: ThePhD Date: Fri, 13 Dec 2013 14:16:59 -0500 Subject: [PATCH 1/3] MSVC needs explicit overloads and explicit =default operators on `sol::function`. It's quite whacky, really. Anyway, it compiles, so let's just make sure this works for GCC too. --- sol/function.hpp | 2 ++ sol/table.hpp | 56 +++++++++++++++++++++++++++--------------------- sol/traits.hpp | 4 ++-- tests.cpp | 4 ++-- 4 files changed, 38 insertions(+), 28 deletions(-) diff --git a/sol/function.hpp b/sol/function.hpp index 49319308..264fc0e9 100644 --- a/sol/function.hpp +++ b/sol/function.hpp @@ -58,6 +58,8 @@ public: function(lua_State* L, int index = -1): reference(L, index) { type_assert(L, index, type::function); } + function(const function&) = default; + function& operator=(const function&) = default; template auto call(Args&&... args) -> decltype(invoke(types(), sizeof...(Args))) { diff --git a/sol/table.hpp b/sol/table.hpp index 3ea92e20..5f15f869 100644 --- a/sol/table.hpp +++ b/sol/table.hpp @@ -24,6 +24,7 @@ #include "stack.hpp" #include "lua_function.hpp" +#include "function.hpp" #include #include @@ -90,6 +91,37 @@ public: push(); return lua_rawlen(state(), -1); } + + template + struct proxy { + private: + table& t; + T& key; + public: + proxy(table& t, T& key) : t(t), key(key) {} + + template + void operator=(U&& other) { + typedef Function> isfunction; + assign(std::forward(other), isfunction()); + } + + template + operator U() const { + return t.get(key); + } + + private: + template + void assign(U&& other, std::true_type) { + t.set_function(key, std::forward(other)); + } + + template + void assign(U&& other, std::false_type) { + t.set(key, std::forward(other)); + } + }; private: template table& set_isfunction_fx(std::true_type, T&& key, TFx&& fx) { @@ -207,30 +239,6 @@ private: lua_pop(state(), 1); return *this; } - - template - struct proxy { - private: - table& t; - T& key; - public: - proxy(table& t, T& key): t(t), key(key) {} - - template - DisableIf>> operator=(U&& other) { - t.set(key, std::forward(other)); - } - - template - EnableIf>> operator=(U&& other) { - t.set_function(key, std::forward(other)); - } - - template - operator U() const { - return t.get(key); - } - }; }; } // sol diff --git a/sol/traits.hpp b/sol/traits.hpp index 63f5b9be..5bcd35d3 100644 --- a/sol/traits.hpp +++ b/sol/traits.hpp @@ -40,11 +40,11 @@ using Decay = typename std::decay::type; namespace detail { // code borrowed from Gears // https://github.com/Rapptz/Gears/ -template +template>::value> struct is_function_impl : std::is_function::type> {}; template -struct is_function_impl>>> { +struct is_function_impl { using yes = char; using no = struct { char s[2]; }; diff --git a/tests.cpp b/tests.cpp index 0ed2659a..10a57b80 100644 --- a/tests.cpp +++ b/tests.cpp @@ -165,7 +165,7 @@ TEST_CASE("tables/functions_variables", "Check if tables and function calls work std::cout << "stateless lambda()" << std::endl; return "test"; } - ); + ); REQUIRE_NOTHROW(run_script(lua)); lua.get("os").set_function("fun", &free_function); @@ -183,7 +183,7 @@ TEST_CASE("tables/functions_variables", "Check if tables and function calls work std::cout << "stateless lambda()" << std::endl; return "test"; } - ); + ); REQUIRE_NOTHROW(run_script(lua)); // r-value, cannot optomize From dc6935553b5d4ad4ab8eb15cc6d64844289be038 Mon Sep 17 00:00:00 2001 From: ThePhD Date: Fri, 13 Dec 2013 14:19:04 -0500 Subject: [PATCH 2/3] Forgot a private on table. --- sol/table.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sol/table.hpp b/sol/table.hpp index 5f15f869..5f8aff8e 100644 --- a/sol/table.hpp +++ b/sol/table.hpp @@ -91,7 +91,7 @@ public: push(); return lua_rawlen(state(), -1); } - +private: template struct proxy { private: From 856d28ab706060cf9095681ab30a3df55c2ee566 Mon Sep 17 00:00:00 2001 From: ThePhD Date: Fri, 13 Dec 2013 14:59:46 -0500 Subject: [PATCH 3/3] EnableIf and DisableIf back in place, type trait fixed for MSVC. Bleh, this is a lot of work. Removed `functional` header, because nobody's using it. --- sol/functional.hpp | 125 ------------------------------------------- sol/lua_function.hpp | 11 ++-- sol/table.hpp | 46 +++++++--------- sol/traits.hpp | 59 ++++++++++++++++++++ 4 files changed, 83 insertions(+), 158 deletions(-) delete mode 100644 sol/functional.hpp diff --git a/sol/functional.hpp b/sol/functional.hpp deleted file mode 100644 index 0ede1e5a..00000000 --- a/sol/functional.hpp +++ /dev/null @@ -1,125 +0,0 @@ -// The MIT License (MIT) - -// Copyright (c) 2013 Danny Y., Rapptz - -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -#ifndef SOL_FUNCTIONAL_HPP -#define SOL_FUNCTIONAL_HPP - -#include "tuple.hpp" - -namespace sol { -namespace detail { - -template -struct function_traits; - -template -struct function_traits { - static const std::size_t arity = sizeof...(Args); - static const bool is_member_function = true; - typedef std::tuple arg_tuple_type; - typedef types args_type; - typedef R(T::* function_pointer_type)(Args...); - typedef typename std::remove_pointer::type function_type; - typedef R(* free_function_pointer_type)(Args...); - typedef R return_type; - template - using arg = typename std::tuple_element::type; -}; - -template -struct function_traits { - static const std::size_t arity = sizeof...(Args); - static const bool is_member_function = true; - typedef std::tuple arg_tuple_type; - typedef types args_type; - typedef R(T::* function_pointer_type)(Args...); - typedef typename std::remove_pointer::type function_type; - typedef R(* free_function_pointer_type)(Args...); - typedef R return_type; - template - using arg = typename std::tuple_element::type; -}; - -template -struct function_traits { - static const std::size_t arity = sizeof...(Args); - static const bool is_member_function = false; - typedef std::tuple arg_tuple_type; - typedef types args_type; - typedef R(function_type)(Args...); - typedef R(*function_pointer_type)(Args...); - typedef R(* free_function_pointer_type)(Args...); - typedef R return_type; - template - using arg = typename std::tuple_element::type; -}; - -template -struct function_traits { - static const std::size_t arity = sizeof...(Args); - static const bool is_member_function = false; - typedef std::tuple arg_tuple_type; - typedef types args_type; - typedef R(function_type)(Args...); - typedef R(*function_pointer_type)(Args...); - typedef R(* free_function_pointer_type)(Args...); - typedef R return_type; - template - using arg = typename std::tuple_element::type; -}; - -using std::get; - -template -inline auto call(Function&& f, const Tuple& t, indices) -> decltype(f(get(t)...)) { - return f(get(t)...); -} -} // detail - -template -struct lua_return_type { - typedef std::tuple type; -}; - -template -struct lua_return_type { - typedef Ret type; -}; - -template<> -struct lua_return_type<> { - typedef void type; -}; - -template<> -struct lua_return_type { - typedef void type; -}; - -template -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 - - -#endif // SOL_FUNCTIONAL_HPP \ No newline at end of file diff --git a/sol/lua_function.hpp b/sol/lua_function.hpp index 5fc65538..89c56614 100644 --- a/sol/lua_function.hpp +++ b/sol/lua_function.hpp @@ -22,7 +22,6 @@ #ifndef SOL_LUA_FUNC_HPP #define SOL_LUA_FUNC_HPP -#include "functional.hpp" #include "stack.hpp" #include @@ -62,7 +61,7 @@ void get_upvalue(lua_State* L, T& data, int& upvalue) { template struct static_lua_func { typedef typename std::remove_pointer::type>::type fx_t; - typedef detail::function_traits fx_traits; + typedef function_traits fx_traits; template static int typed_call(types, types t, fx_t* fx, lua_State* L) { @@ -93,7 +92,7 @@ struct static_lua_func { template struct static_object_lua_func { typedef typename std::decay::type fx_t; - typedef detail::function_traits fx_traits; + typedef function_traits fx_traits; template static int typed_call(types, types, T& item, fx_t& ifx, lua_State* L) { @@ -173,7 +172,7 @@ struct lua_func { template struct lambda_lua_func : public lua_func { typedef decltype(&TFx::operator()) fx_t; - typedef detail::function_traits fx_traits; + typedef function_traits fx_traits; TFx fx; template @@ -200,7 +199,7 @@ struct lambda_lua_func : public lua_func { template::value> struct explicit_lua_func : public lua_func { typedef typename std::remove_pointer::type>::type fx_t; - typedef detail::function_traits fx_traits; + typedef function_traits fx_traits; TFx fx; template @@ -227,7 +226,7 @@ struct explicit_lua_func : public lua_func { template struct explicit_lua_func : public lua_func { typedef typename std::remove_pointer::type>::type fx_t; - typedef detail::function_traits fx_traits; + typedef function_traits fx_traits; struct lambda { T member; TFx invocation; diff --git a/sol/table.hpp b/sol/table.hpp index 5f8aff8e..462bb34e 100644 --- a/sol/table.hpp +++ b/sol/table.hpp @@ -24,7 +24,6 @@ #include "stack.hpp" #include "lua_function.hpp" -#include "function.hpp" #include #include @@ -95,34 +94,27 @@ private: template struct proxy { private: - table& t; - T& key; + table& t; + T& key; public: - proxy(table& t, T& key) : t(t), key(key) {} + proxy(table& t, T& key) : t(t), key(key) {} - template - void operator=(U&& other) { - typedef Function> isfunction; - assign(std::forward(other), isfunction()); - } + template + EnableIf>> operator=(U&& other) { + t.set_function(key, std::forward(other)); + } + + template + DisableIf>> operator=(U&& other) { + t.set(key, std::forward(other)); + } - template - operator U() const { - return t.get(key); - } - - private: - template - void assign(U&& other, std::true_type) { - t.set_function(key, std::forward(other)); - } - - template - void assign(U&& other, std::false_type) { - t.set(key, std::forward(other)); - } + template + operator U() const { + return t.get(key); + } }; -private: + template table& set_isfunction_fx(std::true_type, T&& key, TFx&& fx) { return set_fx(std::false_type(), std::forward(key), std::forward(fx)); @@ -131,7 +123,7 @@ private: template table& set_isfunction_fx(std::false_type, T&& key, TFx&& fx) { typedef Decay clean_lambda; - typedef typename detail::function_traits::free_function_pointer_type raw_func_t; + typedef typename function_traits::free_function_pointer_type raw_func_t; typedef std::is_convertible isconvertible; return set_isconvertible_fx(isconvertible(), std::forward(key), std::forward(fx)); } @@ -139,7 +131,7 @@ private: template table& set_isconvertible_fx(std::true_type, T&& key, TFx&& fx) { typedef Decay clean_lambda; - typedef typename detail::function_traits::free_function_pointer_type raw_func_t; + typedef typename function_traits::free_function_pointer_type raw_func_t; return set_isfunction_fx(std::true_type(), std::forward(key), raw_func_t(std::forward(fx))); } diff --git a/sol/traits.hpp b/sol/traits.hpp index 5bcd35d3..9b998305 100644 --- a/sol/traits.hpp +++ b/sol/traits.hpp @@ -67,6 +67,65 @@ using Bool = std::integral_constant; template struct Function : Bool::value> {}; + +template +struct function_traits; + +template +struct function_traits { + static const std::size_t arity = sizeof...( Args ); + static const bool is_member_function = true; + typedef std::tuple arg_tuple_type; + typedef types args_type; + typedef R( T::* function_pointer_type )( Args... ); + typedef typename std::remove_pointer::type function_type; + typedef R( *free_function_pointer_type )( Args... ); + typedef R return_type; + template + using arg = typename std::tuple_element::type; +}; + +template +struct function_traits { + static const std::size_t arity = sizeof...( Args ); + static const bool is_member_function = true; + typedef std::tuple arg_tuple_type; + typedef types args_type; + typedef R( T::* function_pointer_type )( Args... ); + typedef typename std::remove_pointer::type function_type; + typedef R( *free_function_pointer_type )( Args... ); + typedef R return_type; + template + using arg = typename std::tuple_element::type; +}; + +template +struct function_traits { + static const std::size_t arity = sizeof...( Args ); + static const bool is_member_function = false; + typedef std::tuple arg_tuple_type; + typedef types args_type; + typedef R( function_type )( Args... ); + typedef R( *function_pointer_type )( Args... ); + typedef R( *free_function_pointer_type )( Args... ); + typedef R return_type; + template + using arg = typename std::tuple_element::type; +}; + +template +struct function_traits { + static const std::size_t arity = sizeof...( Args ); + static const bool is_member_function = false; + typedef std::tuple arg_tuple_type; + typedef types args_type; + typedef R( function_type )( Args... ); + typedef R( *function_pointer_type )( Args... ); + typedef R( *free_function_pointer_type )( Args... ); + typedef R return_type; + template + using arg = typename std::tuple_element::type; +}; } // sol #endif // SOL_TRAITS_HPP \ No newline at end of file