From 21f59a997a7f071685abd44ea29f39d39cebb27a Mon Sep 17 00:00:00 2001 From: ThePhD Date: Thu, 16 Mar 2017 03:07:20 -0400 Subject: [PATCH] The new constructor syntax was very easy to implement... --- sol/call.hpp | 8 ++++---- sol/usertype_metatable.hpp | 21 +++++++++++++++------ test_usertypes.cpp | 1 - 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/sol/call.hpp b/sol/call.hpp index cbe4e2cf..db27c1d4 100644 --- a/sol/call.hpp +++ b/sol/call.hpp @@ -47,7 +47,7 @@ namespace sol { } template - struct void_call; + struct void_call : void_call> {}; template struct void_call> { @@ -345,12 +345,12 @@ namespace sol { template static int call(lua_State* L, V&& f) { - return call_const(std::is_const(), L, f); + return call_const(std::is_const(), L, std::forward(f)); } template static int call(lua_State* L, V&& f, object_type& o) { - return call_const(std::is_const(), L, f, o); + return call_const(std::is_const(), L, std::forward(f), o); } }; @@ -364,7 +364,7 @@ namespace sol { static int call(lua_State* L, V&& f, object_type& o) { typedef typename wrap::returns_list returns_list; typedef typename wrap::caller caller; - return stack::call_into_lua(returns_list(), types<>(), L, boost + ( is_variable ? 3 : 2 ), caller(), f, o); + return stack::call_into_lua(returns_list(), types<>(), L, boost + ( is_variable ? 3 : 2 ), caller(), std::forward(f), o); } template diff --git a/sol/usertype_metatable.hpp b/sol/usertype_metatable.hpp index 423869df..02cd8586 100644 --- a/sol/usertype_metatable.hpp +++ b/sol/usertype_metatable.hpp @@ -174,15 +174,24 @@ namespace sol { template inline int metatable_newindex(lua_State* L) { int isnum = 0; - lua_Integer magic = lua_tointegerx(L, lua_upvalueindex(4), &isnum); + lua_Integer magic = lua_tointegerx(L, upvalue_index(4), &isnum); if (isnum != 0 && magic == toplevel_magic) { - bool mustindex = lua_isboolean(L, lua_upvalueindex(5)) != 0 && (lua_toboolean(L, lua_upvalueindex(5)) != 0); + bool mustindex = lua_isboolean(L, upvalue_index(5)) != 0 && (lua_toboolean(L, upvalue_index(5)) != 0); if (!is_simple && mustindex) { - mapping_t& mapping = stack::get>(L, lua_upvalueindex(3)); - std::vector& runtime = stack::get>>(L, lua_upvalueindex(2)); + mapping_t& mapping = stack::get>(L, upvalue_index(3)); + std::vector& runtime = stack::get>>(L, upvalue_index(2)); int target = static_cast(runtime.size()); - runtime.emplace_back(L, 3); - mapping.emplace_hint(mapping.cend(), stack::get(L, 2), call_information(&runtime_object_call, &runtime_object_call, target)); + std::string accessor = stack::get(L, 2); + auto preexistingit = mapping.find(accessor); + if (preexistingit == mapping.cend()) { + target = preexistingit->second.runtime_target; + runtime[target] = sol::object(L, 3); + preexistingit->second = call_information(&runtime_object_call, &runtime_object_call, target); + } + else { + runtime.emplace_back(L, 3); + mapping.emplace_hint(mapping.cend(), accessor, call_information(&runtime_object_call, &runtime_object_call, target)); + } } for (std::size_t i = 0; i < 4; lua_pop(L, 1), ++i) { const char* metakey = nullptr; diff --git a/test_usertypes.cpp b/test_usertypes.cpp index d2c12d4e..22689110 100644 --- a/test_usertypes.cpp +++ b/test_usertypes.cpp @@ -715,7 +715,6 @@ TEST_CASE("usertype/overloading", "Check if overloading works properly for usert REQUIRE((lua["a"] == 1)); REQUIRE((lua["b"] == 3.5)); REQUIRE((lua["c"] == bark_58)); - REQUIRE_THROWS(lua.script("r:func(1,2,'meow')")); }