diff --git a/single/sol/sol.hpp b/single/sol/sol.hpp index 6b3452cf..2854b7f7 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 2018-06-16 11:58:58.595822 UTC -// This header was generated with sol v2.20.3 (revision 968989b) +// Generated 2018-06-27 11:13:10.992580 UTC +// This header was generated with sol v2.20.3 (revision 301547f) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -5760,7 +5760,7 @@ namespace sol { struct is_environment : std::integral_constant::value || is_table::value> {}; template - struct is_automagical : std::true_type {}; + struct is_automagical : meta::neg>> {}; template inline type type_of() { @@ -7854,7 +7854,8 @@ namespace sol { template inline decltype(auto) unqualified_check_get(lua_State* L, int index, Handler&& handler, record& tracking) { - check_getter cg{}; + typedef meta::unqualified_t Tu; + check_getter cg{}; (void)cg; return cg.get(L, index, std::forward(handler), tracking); } @@ -7895,6 +7896,9 @@ namespace sol { #if defined(SOL_SAFE_GETTER) && SOL_SAFE_GETTER template inline auto tagged_unqualified_get(types, lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_unqualified_get(L, index, tracking)) { + if (is_lua_reference::value) { + return stack_detail::unchecked_unqualified_get(L, index, tracking); + } auto op = unqualified_check_get(L, index, type_panic_c_str, tracking); return *std::move(op); } @@ -7906,6 +7910,9 @@ namespace sol { template inline auto tagged_get(types, lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_get(L, index, tracking)) { + if (is_lua_reference::value) { + return stack_detail::unchecked_get(L, index, tracking); + } auto op = check_get(L, index, type_panic_c_str, tracking); return *std::move(op); } @@ -10087,7 +10094,7 @@ namespace stack { static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { // actually check if it's none here, otherwise // we'll have a none object inside an optional! - bool success = stack::check(L, index, no_panic); + bool success = lua_isnoneornil(L, index) == 0 && stack::check(L, index, no_panic); if (!success) { // expected type, actual type tracking.use(static_cast(success)); @@ -10098,14 +10105,6 @@ namespace stack { } }; - template - struct check_getter> { - template - static decltype(auto) get(lua_State* L, int index, Handler&&, record& tracking) { - return check_get(L, index, no_panic, tracking); - } - }; - template struct check_getter::value && lua_type_of::value == type::number>> { template @@ -10231,18 +10230,7 @@ namespace stack { namespace sol { namespace stack { template - struct qualified_check_getter { - typedef decltype(stack_detail::unchecked_get(nullptr, 0, std::declval())) R; - - template - static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { - if (!check(L, index, std::forward(handler))) { - tracking.use(static_cast(!lua_isnone(L, index))); - return nullopt; - } - return stack_detail::unchecked_get(L, index, tracking); - } - }; + struct qualified_check_getter : check_getter, C> {}; } } // namespace sol::stack @@ -18038,7 +18026,7 @@ namespace sol { template int comparsion_operator_wrap(lua_State* L) { - auto maybel = stack::unqualified_check_get(L, 1); + auto maybel = stack::unqualified_check_get(L, 1); if (maybel) { auto mayber = stack::unqualified_check_get(L, 2); if (mayber) { @@ -18434,7 +18422,7 @@ namespace sol { int runtime_new_index(lua_State* L, void*, int runtimetarget); template - inline int metatable_newindex(lua_State* L) { + inline int metatable_new_index(lua_State* L) { if (is_toplevel(L)) { auto non_indexable = [&L]() { if (is_simple) { @@ -18718,7 +18706,7 @@ namespace sol { template > usertype_metatable(Args&&... args) - : usertype_metatable_core(&usertype_detail::indexing_fail, &usertype_detail::metatable_newindex), usertype_detail::registrar(), functions(std::forward(args)...), destructfunc(nullptr), callconstructfunc(nullptr), indexbase(&core_indexing_call), newindexbase(&core_indexing_call), indexbaseclasspropogation(usertype_detail::walk_all_bases), newindexbaseclasspropogation(usertype_detail::walk_all_bases), baseclasscheck(nullptr), baseclasscast(nullptr), secondarymeta(contains_variable()), properties() { + : usertype_metatable_core(&usertype_detail::indexing_fail, &usertype_detail::metatable_new_index), usertype_detail::registrar(), functions(std::forward(args)...), destructfunc(nullptr), callconstructfunc(nullptr), indexbase(&core_indexing_call), newindexbase(&core_indexing_call), indexbaseclasspropogation(usertype_detail::walk_all_bases), newindexbaseclasspropogation(usertype_detail::walk_all_bases), baseclasscheck(nullptr), baseclasscast(nullptr), secondarymeta(contains_variable()), properties() { properties.reset(); std::initializer_list ilist{{std::pair(usertype_detail::make_string(std::get(functions)), usertype_detail::call_information(&usertype_metatable::real_find_call, @@ -18756,7 +18744,7 @@ namespace sol { return is_index ? f.indexfunc(L) : f.newindexfunc(L); } - template + template static int core_indexing_call(lua_State* L) { usertype_metatable& f = toplevel ? static_cast(stack::get>(L, upvalue_index(usertype_detail::metatable_index))) @@ -18795,6 +18783,9 @@ namespace sol { if (found) { return ret; } + if (is_meta_bound) { + return is_index ? usertype_detail::indexing_fail(L) : usertype_detail::metatable_new_index(L); + } return toplevel ? (is_index ? f.indexfunc(L) : f.newindexfunc(L)) : -1; } @@ -18806,6 +18797,14 @@ namespace sol { return core_indexing_call(L); } + static int real_meta_index_call(lua_State* L) { + return core_indexing_call(L); + } + + static int real_meta_new_index_call(lua_State* L) { + return core_indexing_call(L); + } + template static int real_call(lua_State* L) { usertype_metatable& f = stack::get>(L, upvalue_index(usertype_detail::metatable_index)); @@ -18842,6 +18841,14 @@ namespace sol { return detail::typed_static_trampoline(L); } + static int meta_index_call(lua_State* L) { + return detail::typed_static_trampoline(L); + } + + static int meta_new_index_call(lua_State* L) { + return detail::typed_static_trampoline(L); + } + virtual int push_um(lua_State* L) override { return stack::push(L, std::move(*this)); } @@ -18995,8 +19002,8 @@ namespace sol { stack::set_field(L, meta_function::call_function, make_closure(um.callconstructfunc, nullptr, make_light(um), make_light(umc)), metabehind.stack_index()); } - stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, nullptr, make_light(um), make_light(umc), nullptr, usertype_detail::toplevel_magic), metabehind.stack_index()); - stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, nullptr, make_light(um), make_light(umc), nullptr, usertype_detail::toplevel_magic), metabehind.stack_index()); + stack::set_field(L, meta_function::index, make_closure(umt_t::meta_index_call, nullptr, make_light(um), make_light(umc), nullptr, usertype_detail::toplevel_magic), metabehind.stack_index()); + stack::set_field(L, meta_function::new_index, make_closure(umt_t::meta_new_index_call, nullptr, make_light(um), make_light(umc), nullptr, usertype_detail::toplevel_magic), metabehind.stack_index()); stack::set_field(L, metatable_key, metabehind, t.stack_index()); metabehind.pop(); } @@ -19048,7 +19055,7 @@ namespace sol { else { return is_index ? indexing_fail(L) - : metatable_newindex(L); + : metatable_new_index(L); } } } @@ -19098,7 +19105,7 @@ namespace sol { else { return is_index ? indexing_fail(L) - : metatable_newindex(L); + : metatable_new_index(L); } } /* Check table storage first for a method that works @@ -19137,7 +19144,7 @@ namespace sol { else { return is_index ? indexing_fail(L) - : metatable_newindex(L); + : metatable_new_index(L); } } return -1; diff --git a/single/sol/sol_forward.hpp b/single/sol/sol_forward.hpp index f2674fc7..b35bb9fc 100644 --- a/single/sol/sol_forward.hpp +++ b/single/sol/sol_forward.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 2018-06-16 11:58:58.882218 UTC -// This header was generated with sol v2.20.3 (revision 968989b) +// Generated 2018-06-27 11:13:11.257646 UTC +// This header was generated with sol v2.20.3 (revision 301547f) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP diff --git a/sol/simple_usertype_metatable.hpp b/sol/simple_usertype_metatable.hpp index 377068ec..b720bd82 100644 --- a/sol/simple_usertype_metatable.hpp +++ b/sol/simple_usertype_metatable.hpp @@ -63,7 +63,7 @@ namespace sol { else { return is_index ? indexing_fail(L) - : metatable_newindex(L); + : metatable_new_index(L); } } } @@ -113,7 +113,7 @@ namespace sol { else { return is_index ? indexing_fail(L) - : metatable_newindex(L); + : metatable_new_index(L); } } /* Check table storage first for a method that works @@ -152,7 +152,7 @@ namespace sol { else { return is_index ? indexing_fail(L) - : metatable_newindex(L); + : metatable_new_index(L); } } return -1; diff --git a/sol/stack_core.hpp b/sol/stack_core.hpp index ea36cd38..92d34146 100644 --- a/sol/stack_core.hpp +++ b/sol/stack_core.hpp @@ -809,6 +809,9 @@ namespace sol { #if defined(SOL_SAFE_GETTER) && SOL_SAFE_GETTER template inline auto tagged_unqualified_get(types, lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_unqualified_get(L, index, tracking)) { + if (is_lua_reference::value) { + return stack_detail::unchecked_unqualified_get(L, index, tracking); + } auto op = unqualified_check_get(L, index, type_panic_c_str, tracking); return *std::move(op); } @@ -820,6 +823,9 @@ namespace sol { template inline auto tagged_get(types, lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_get(L, index, tracking)) { + if (is_lua_reference::value) { + return stack_detail::unchecked_get(L, index, tracking); + } auto op = check_get(L, index, type_panic_c_str, tracking); return *std::move(op); } diff --git a/sol/usertype_metatable.hpp b/sol/usertype_metatable.hpp index a5ee4e0a..a091f4f3 100644 --- a/sol/usertype_metatable.hpp +++ b/sol/usertype_metatable.hpp @@ -242,7 +242,7 @@ namespace sol { int runtime_new_index(lua_State* L, void*, int runtimetarget); template - inline int metatable_newindex(lua_State* L) { + inline int metatable_new_index(lua_State* L) { if (is_toplevel(L)) { auto non_indexable = [&L]() { if (is_simple) { @@ -526,7 +526,7 @@ namespace sol { template > usertype_metatable(Args&&... args) - : usertype_metatable_core(&usertype_detail::indexing_fail, &usertype_detail::metatable_newindex), usertype_detail::registrar(), functions(std::forward(args)...), destructfunc(nullptr), callconstructfunc(nullptr), indexbase(&core_indexing_call), newindexbase(&core_indexing_call), indexbaseclasspropogation(usertype_detail::walk_all_bases), newindexbaseclasspropogation(usertype_detail::walk_all_bases), baseclasscheck(nullptr), baseclasscast(nullptr), secondarymeta(contains_variable()), properties() { + : usertype_metatable_core(&usertype_detail::indexing_fail, &usertype_detail::metatable_new_index), usertype_detail::registrar(), functions(std::forward(args)...), destructfunc(nullptr), callconstructfunc(nullptr), indexbase(&core_indexing_call), newindexbase(&core_indexing_call), indexbaseclasspropogation(usertype_detail::walk_all_bases), newindexbaseclasspropogation(usertype_detail::walk_all_bases), baseclasscheck(nullptr), baseclasscast(nullptr), secondarymeta(contains_variable()), properties() { properties.reset(); std::initializer_list ilist{{std::pair(usertype_detail::make_string(std::get(functions)), usertype_detail::call_information(&usertype_metatable::real_find_call, @@ -564,7 +564,7 @@ namespace sol { return is_index ? f.indexfunc(L) : f.newindexfunc(L); } - template + template static int core_indexing_call(lua_State* L) { usertype_metatable& f = toplevel ? static_cast(stack::get>(L, upvalue_index(usertype_detail::metatable_index))) @@ -603,6 +603,9 @@ namespace sol { if (found) { return ret; } + if (is_meta_bound) { + return is_index ? usertype_detail::indexing_fail(L) : usertype_detail::metatable_new_index(L); + } return toplevel ? (is_index ? f.indexfunc(L) : f.newindexfunc(L)) : -1; } @@ -614,6 +617,14 @@ namespace sol { return core_indexing_call(L); } + static int real_meta_index_call(lua_State* L) { + return core_indexing_call(L); + } + + static int real_meta_new_index_call(lua_State* L) { + return core_indexing_call(L); + } + template static int real_call(lua_State* L) { usertype_metatable& f = stack::get>(L, upvalue_index(usertype_detail::metatable_index)); @@ -650,6 +661,14 @@ namespace sol { return detail::typed_static_trampoline(L); } + static int meta_index_call(lua_State* L) { + return detail::typed_static_trampoline(L); + } + + static int meta_new_index_call(lua_State* L) { + return detail::typed_static_trampoline(L); + } + virtual int push_um(lua_State* L) override { return stack::push(L, std::move(*this)); } @@ -803,8 +822,8 @@ namespace sol { stack::set_field(L, meta_function::call_function, make_closure(um.callconstructfunc, nullptr, make_light(um), make_light(umc)), metabehind.stack_index()); } - stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, nullptr, make_light(um), make_light(umc), nullptr, usertype_detail::toplevel_magic), metabehind.stack_index()); - stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, nullptr, make_light(um), make_light(umc), nullptr, usertype_detail::toplevel_magic), metabehind.stack_index()); + stack::set_field(L, meta_function::index, make_closure(umt_t::meta_index_call, nullptr, make_light(um), make_light(umc), nullptr, usertype_detail::toplevel_magic), metabehind.stack_index()); + stack::set_field(L, meta_function::new_index, make_closure(umt_t::meta_new_index_call, nullptr, make_light(um), make_light(umc), nullptr, usertype_detail::toplevel_magic), metabehind.stack_index()); stack::set_field(L, metatable_key, metabehind, t.stack_index()); metabehind.pop(); } diff --git a/tests/test_simple_usertypes.cpp b/tests/test_simple_usertypes.cpp index 6f8d6180..6a2f6634 100644 --- a/tests/test_simple_usertypes.cpp +++ b/tests/test_simple_usertypes.cpp @@ -759,6 +759,26 @@ TEST_CASE("simple_usertype/runtime replacement", "ensure that functions can be p } } +TEST_CASE("simple_usertype/runtime additions with newindex", "ensure that additions when new_index is overriden don't hit the specified new_index function") { + class newindex_object {}; + sol::state lua; + lua.open_libraries(sol::lib::base); + lua.new_simple_usertype("object", + sol::meta_function::new_index, [](newindex_object& o, sol::object key, sol::object value) { + return; + }); + + lua["object"]["test"] = [](newindex_object& o) { + std::cout << "test" << std::endl; + return 446; + }; + + auto result1 = lua.safe_script("o = object.new()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("assert(o:test() == 446)", sol::script_pass_on_error); + REQUIRE(result2.valid()); +} + TEST_CASE("simple_usertype/meta key retrievals", "allow for special meta keys (__index, __newindex) to trigger methods even if overwritten directly") { SECTION("dynamically") { static int writes = 0; diff --git a/tests/test_usertypes.cpp b/tests/test_usertypes.cpp index 4135235d..a39387e9 100644 --- a/tests/test_usertypes.cpp +++ b/tests/test_usertypes.cpp @@ -1801,6 +1801,26 @@ TEST_CASE("usertype/runtime-replacement", "ensure that functions can be properly } } +TEST_CASE("usertype/runtime additions with newindex", "ensure that additions when new_index is overriden don't hit the specified new_index function") { + class newindex_object {}; + sol::state lua; + lua.open_libraries(sol::lib::base); + lua.new_usertype("object", + sol::meta_function::new_index, [](newindex_object& o, sol::object key, sol::object value) { + return; + }); + + lua["object"]["test"] = [](newindex_object& o) { + std::cout << "test" << std::endl; + return 446; + }; + + auto result1 = lua.safe_script("o = object.new()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("assert(o:test() == 446)", sol::script_pass_on_error); + REQUIRE(result2.valid()); +} + TEST_CASE("usertype/alignment", "ensure that alignment does not trigger weird aliasing issues") { struct aligned_base {}; struct aligned_derived : aligned_base {};