From 09ee4db1edd49e8829a7b16d0aef915350c684b7 Mon Sep 17 00:00:00 2001 From: ThePhD Date: Wed, 29 Jun 2016 14:08:26 -0400 Subject: [PATCH] More templated fixes. Closes #131 Closes #126, for the time being -- we can't make it go any faster without fundamentally breaking the system, and I can't do that to users rn --- single/sol/sol.hpp | 58 +++++++++++++++++++++++++++----------- sol/call.hpp | 12 ++++---- sol/proxy.hpp | 4 +-- sol/raii.hpp | 12 ++++++++ sol/traits.hpp | 6 ++++ sol/usertype.hpp | 4 +-- sol/usertype_metatable.hpp | 16 ++++++++--- test_usertypes.cpp | 2 +- tests.cpp | 25 ++++++++++++++++ 9 files changed, 108 insertions(+), 31 deletions(-) diff --git a/single/sol/sol.hpp b/single/sol/sol.hpp index 1f4d56c9..481fc8ba 100644 --- a/single/sol/sol.hpp +++ b/single/sol/sol.hpp @@ -20,8 +20,8 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // This file was generated with a script. -// Generated 2016-06-27 16:44:52.053533 UTC -// This header was generated with sol v2.8.9 (revision 4a0bfe1) +// Generated 2016-06-29 18:04:02.541304 UTC +// This header was generated with sol v2.8.9 (revision 833be87) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -385,6 +385,12 @@ namespace sol { template using unwrapped_t = typename unwrapped::type; + template + struct unwrap_unqualified : unwrapped> {}; + + template + using unwrap_unqualified_t = typename unwrap_unqualified::type; + template struct remove_member_pointer; @@ -5142,6 +5148,18 @@ namespace sol { destroy(std::forward(obj)); } }; + + struct deleter { + template + void operator()(T* p) const { + delete p; + } + }; + + template + inline std::unique_ptr make_unique_deleter(Args&&... args) { + return std::unique_ptr(new T(std::forward(args)...)); + } } // detail template @@ -6811,21 +6829,21 @@ namespace sol { template struct agnostic_lua_call_wrapper { - static int call(lua_State* L, no_prop&) { + static int call(lua_State* L, const no_prop&) { return luaL_error(L, is_index ? "sol: cannot read from a writeonly property" : "sol: cannot write to a readonly property"); } }; template struct agnostic_lua_call_wrapper { - static int call(lua_State* L, no_construction&) { + static int call(lua_State* L, const no_construction&) { return luaL_error(L, "sol: cannot call this constructor (tagged as non-constructible)"); } }; template struct agnostic_lua_call_wrapper, is_index, is_variable, C> { - static int call(lua_State*, bases&) { + static int call(lua_State*, const bases&) { // Uh. How did you even call this, lul return 0; } @@ -6997,7 +7015,7 @@ namespace sol { struct lua_call_wrapper, is_index, is_variable, std::enable_if_t::value>> { typedef sol::destructor_wrapper F; - static int call(lua_State* L, F&) { + static int call(lua_State* L, const F&) { return destruct(L); } }; @@ -7006,8 +7024,8 @@ namespace sol { struct lua_call_wrapper, is_index, is_variable, std::enable_if_t::value>> { typedef sol::destructor_wrapper F; - static int call(lua_State* L, F& f) { - T* obj = stack::get>(L); + static int call(lua_State* L, const F& f) { + T& obj = stack::get(L); f.fx(detail::implicit_wrapper(obj)); return 0; } @@ -8583,12 +8601,12 @@ namespace sol { return *this; } - template>> = meta::enabler> + template>> = meta::enabler> proxy& operator=(U&& other) { return set_function(std::forward(other)); } - template>> = meta::enabler> + template>> = meta::enabler> proxy& operator=(U&& other) { return set(std::forward(other)); } @@ -8775,9 +8793,16 @@ namespace sol { else return luaL_error(L, "sol: attempt to index (set) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.data()); } - } // usertype_detail + template + struct clean_type { + typedef std::conditional_t>::value, T&, std::decay_t> type; + }; + + template + using clean_type_t = typename clean_type::type; + template struct usertype_metatable : usertype_detail::registrar {}; @@ -8786,7 +8811,8 @@ namespace sol { typedef std::make_index_sequence indices; typedef std::index_sequence half_indices; typedef std::array regs_t; - typedef std::tuple Tuple; + typedef std::tuple RawTuple; + typedef std::tuple ...> Tuple; template struct check_binding : is_variable_binding> {}; Tuple functions; @@ -8799,12 +8825,12 @@ namespace sol { bool mustindex; bool secondarymeta; - template >> = meta::enabler> + template >> = meta::enabler> inline lua_CFunction make_func() { return std::get(functions); } - template >> = meta::enabler> + template >> = meta::enabler> inline lua_CFunction make_func() { return call; } @@ -9111,10 +9137,10 @@ using has_destructor = meta::any>...>; template class usertype { private: - std::unique_ptr metatableregister; + std::unique_ptr metatableregister; template - usertype(usertype_detail::verified_tag, Args&&... args) : metatableregister( std::make_unique, std::decay_t...>>(std::forward(args)...) ) {} + usertype(usertype_detail::verified_tag, Args&&... args) : metatableregister( detail::make_unique_deleter, Args...>, detail::deleter>(std::forward(args)...) ) {} template usertype(usertype_detail::add_destructor_tag, Args&&... args) : usertype(usertype_detail::verified, std::forward(args)..., "__gc", default_destructor) {} diff --git a/sol/call.hpp b/sol/call.hpp index 071e104f..9583ce9d 100644 --- a/sol/call.hpp +++ b/sol/call.hpp @@ -182,21 +182,21 @@ namespace sol { template struct agnostic_lua_call_wrapper { - static int call(lua_State* L, no_prop&) { + static int call(lua_State* L, const no_prop&) { return luaL_error(L, is_index ? "sol: cannot read from a writeonly property" : "sol: cannot write to a readonly property"); } }; template struct agnostic_lua_call_wrapper { - static int call(lua_State* L, no_construction&) { + static int call(lua_State* L, const no_construction&) { return luaL_error(L, "sol: cannot call this constructor (tagged as non-constructible)"); } }; template struct agnostic_lua_call_wrapper, is_index, is_variable, C> { - static int call(lua_State*, bases&) { + static int call(lua_State*, const bases&) { // Uh. How did you even call this, lul return 0; } @@ -368,7 +368,7 @@ namespace sol { struct lua_call_wrapper, is_index, is_variable, std::enable_if_t::value>> { typedef sol::destructor_wrapper F; - static int call(lua_State* L, F&) { + static int call(lua_State* L, const F&) { return destruct(L); } }; @@ -377,8 +377,8 @@ namespace sol { struct lua_call_wrapper, is_index, is_variable, std::enable_if_t::value>> { typedef sol::destructor_wrapper F; - static int call(lua_State* L, F& f) { - T* obj = stack::get>(L); + static int call(lua_State* L, const F& f) { + T& obj = stack::get(L); f.fx(detail::implicit_wrapper(obj)); return 0; } diff --git a/sol/proxy.hpp b/sol/proxy.hpp index f829b4dc..796bf6cf 100644 --- a/sol/proxy.hpp +++ b/sol/proxy.hpp @@ -63,12 +63,12 @@ namespace sol { return *this; } - template>> = meta::enabler> + template>> = meta::enabler> proxy& operator=(U&& other) { return set_function(std::forward(other)); } - template>> = meta::enabler> + template>> = meta::enabler> proxy& operator=(U&& other) { return set(std::forward(other)); } diff --git a/sol/raii.hpp b/sol/raii.hpp index d15fe3cd..610591f3 100644 --- a/sol/raii.hpp +++ b/sol/raii.hpp @@ -52,6 +52,18 @@ namespace sol { destroy(std::forward(obj)); } }; + + struct deleter { + template + void operator()(T* p) const { + delete p; + } + }; + + template + inline std::unique_ptr make_unique_deleter(Args&&... args) { + return std::unique_ptr(new T(std::forward(args)...)); + } } // detail template diff --git a/sol/traits.hpp b/sol/traits.hpp index 31f55775..b7789d68 100644 --- a/sol/traits.hpp +++ b/sol/traits.hpp @@ -58,6 +58,12 @@ namespace sol { template using unwrapped_t = typename unwrapped::type; + template + struct unwrap_unqualified : unwrapped> {}; + + template + using unwrap_unqualified_t = typename unwrap_unqualified::type; + template struct remove_member_pointer; diff --git a/sol/usertype.hpp b/sol/usertype.hpp index 3e67415a..f052c577 100644 --- a/sol/usertype.hpp +++ b/sol/usertype.hpp @@ -60,10 +60,10 @@ using has_destructor = meta::any>...>; template class usertype { private: - std::unique_ptr metatableregister; + std::unique_ptr metatableregister; template - usertype(usertype_detail::verified_tag, Args&&... args) : metatableregister( std::make_unique, std::decay_t...>>(std::forward(args)...) ) {} + usertype(usertype_detail::verified_tag, Args&&... args) : metatableregister( detail::make_unique_deleter, Args...>, detail::deleter>(std::forward(args)...) ) {} template usertype(usertype_detail::add_destructor_tag, Args&&... args) : usertype(usertype_detail::verified, std::forward(args)..., "__gc", default_destructor) {} diff --git a/sol/usertype_metatable.hpp b/sol/usertype_metatable.hpp index bb7343a1..23bea2dc 100644 --- a/sol/usertype_metatable.hpp +++ b/sol/usertype_metatable.hpp @@ -86,9 +86,16 @@ namespace sol { else return luaL_error(L, "sol: attempt to index (set) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.data()); } - } // usertype_detail + template + struct clean_type { + typedef std::conditional_t>::value, T&, std::decay_t> type; + }; + + template + using clean_type_t = typename clean_type::type; + template struct usertype_metatable : usertype_detail::registrar {}; @@ -97,7 +104,8 @@ namespace sol { typedef std::make_index_sequence indices; typedef std::index_sequence half_indices; typedef std::array regs_t; - typedef std::tuple Tuple; + typedef std::tuple RawTuple; + typedef std::tuple ...> Tuple; template struct check_binding : is_variable_binding> {}; Tuple functions; @@ -110,12 +118,12 @@ namespace sol { bool mustindex; bool secondarymeta; - template >> = meta::enabler> + template >> = meta::enabler> inline lua_CFunction make_func() { return std::get(functions); } - template >> = meta::enabler> + template >> = meta::enabler> inline lua_CFunction make_func() { return call; } diff --git a/test_usertypes.cpp b/test_usertypes.cpp index 82538109..18e18526 100644 --- a/test_usertypes.cpp +++ b/test_usertypes.cpp @@ -1033,4 +1033,4 @@ nocopy = NoCopy.new() nocopy.val = 5 )__") ); -} \ No newline at end of file +} diff --git a/tests.cpp b/tests.cpp index 694437e7..cc440242 100644 --- a/tests.cpp +++ b/tests.cpp @@ -511,3 +511,28 @@ TEST_CASE("features/multiple-inheritance", "Ensure that multiple inheritance wor REQUIRE(cb1->a1 == 250); REQUIRE(cb2->a2 == 500); } + + +TEST_CASE("regressions/std::ref", "Ensure that std::reference_wrapper<> isn't considered as a function by using unwrap_unqualified_t trait") { + struct base1 { + int a1 = 250; + }; + + sol::state lua; + base1 v; + lua["vp"] = &v; + lua["vr"] = std::ref(v); + + base1* vp = lua["vp"]; + base1& vr = lua["vr"]; + REQUIRE(vp != nullptr); + REQUIRE(vp == &v); + + REQUIRE(vp->a1 == 250); + REQUIRE(vr.a1 == 250); + + v.a1 = 568; + + REQUIRE(vp->a1 == 568); + REQUIRE(vr.a1 == 568); +}