diff --git a/include/sol/stack_core.hpp b/include/sol/stack_core.hpp index f4d440910..3b37210e4 100644 --- a/include/sol/stack_core.hpp +++ b/include/sol/stack_core.hpp @@ -530,14 +530,18 @@ namespace sol { } struct properties_enrollment_allowed { + int& times_through; std::bitset<64>& properties; automagic_enrollments& enrollments; - properties_enrollment_allowed(std::bitset<64>& props, automagic_enrollments& enroll) : properties(props), enrollments(enroll) { + properties_enrollment_allowed(int& times, std::bitset<64>& props, automagic_enrollments& enroll) : times_through(times), properties(props), enrollments(enroll) { } bool operator()(meta_function mf) const { bool p = properties[static_cast(mf)]; + if (times_through > 0) { + return p; + } switch (mf) { case meta_function::length: return enrollments.length_operator && !p; diff --git a/include/sol/usertype_storage.hpp b/include/sol/usertype_storage.hpp index 9aa59c10b..b0949060a 100644 --- a/include/sol/usertype_storage.hpp +++ b/include/sol/usertype_storage.hpp @@ -965,7 +965,7 @@ namespace sol { namespace u_detail { // add intrinsics // this one is the actual meta-handling table, // the next one will be the one for - + int for_each_backing_metatable_calls = 0; auto for_each_backing_metatable = [&](lua_State* L, submetatable_type smt, reference& fast_index_table) { // Pointer types, AKA "references" from C++ const char* metakey = nullptr; @@ -1039,8 +1039,8 @@ namespace sol { namespace u_detail { stack::set_field(L, detail::base_class_check_key(), reinterpret_cast(&detail::inheritance::type_check), t.stack_index()); stack::set_field(L, detail::base_class_cast_key(), reinterpret_cast(&detail::inheritance::type_cast), t.stack_index()); - auto prop_fx = detail::properties_enrollment_allowed(storage.properties, enrollments); - auto insert_fx = [&L, &t, &storage](meta_function mf, lua_CFunction reg) { + auto prop_fx = detail::properties_enrollment_allowed(for_each_backing_metatable_calls, storage.properties, enrollments); + auto insert_fx = [&L, &t, &storage, &smt](meta_function mf, lua_CFunction reg) { stack::set_field(L, mf, reg, t.stack_index()); storage.properties[static_cast(mf)] = true; }; @@ -1082,6 +1082,7 @@ namespace sol { namespace u_detail { storage.is_using_new_index = true; } + ++for_each_backing_metatable_calls; fast_index_table = reference(L, t); t.pop(); }; diff --git a/single/include/sol/forward.hpp b/single/include/sol/forward.hpp index ef6ea15d0..a25732fbf 100644 --- a/single/include/sol/forward.hpp +++ b/single/include/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 2019-05-27 05:35:30.258702 UTC -// This header was generated with sol v3.0.2 (revision e814868) +// Generated 2019-05-29 20:53:05.788092 UTC +// This header was generated with sol v3.0.2 (revision 46a2b01) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP diff --git a/single/include/sol/sol.hpp b/single/include/sol/sol.hpp index 8ad0d7103..29aa7d8c3 100644 --- a/single/include/sol/sol.hpp +++ b/single/include/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 2019-05-27 05:35:29.780976 UTC -// This header was generated with sol v3.0.2 (revision e814868) +// Generated 2019-05-29 20:53:04.799735 UTC +// This header was generated with sol v3.0.2 (revision 46a2b01) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -9682,14 +9682,18 @@ namespace sol { } struct properties_enrollment_allowed { + int& times_through; std::bitset<64>& properties; automagic_enrollments& enrollments; - properties_enrollment_allowed(std::bitset<64>& props, automagic_enrollments& enroll) : properties(props), enrollments(enroll) { + properties_enrollment_allowed(int& times, std::bitset<64>& props, automagic_enrollments& enroll) : times_through(times), properties(props), enrollments(enroll) { } bool operator()(meta_function mf) const { bool p = properties[static_cast(mf)]; + if (times_through > 0) { + return p; + } switch (mf) { case meta_function::length: return enrollments.length_operator && !p; @@ -11686,8 +11690,7 @@ namespace sol { namespace stack { static decltype(auto) get(lua_State* L, int index, record& tracking) { using Tu = meta::unqualified_t; static constexpr bool is_userdata_of_some_kind - = !std::is_reference_v< - X> && is_container_v && std::is_default_constructible_v && !is_lua_primitive_v && !is_transparent_argument_v; + = !std::is_reference_v && is_container_v && std::is_default_constructible_v && !is_lua_primitive_v && !is_transparent_argument_v; if constexpr (is_userdata_of_some_kind) { if (type_of(L, index) == type::userdata) { return static_cast(stack_detail::unchecked_unqualified_get(L, index, tracking)); @@ -21676,7 +21679,7 @@ namespace sol { namespace u_detail { // add intrinsics // this one is the actual meta-handling table, // the next one will be the one for - + int for_each_backing_metatable_calls = 0; auto for_each_backing_metatable = [&](lua_State* L, submetatable_type smt, reference& fast_index_table) { // Pointer types, AKA "references" from C++ const char* metakey = nullptr; @@ -21750,8 +21753,8 @@ namespace sol { namespace u_detail { stack::set_field(L, detail::base_class_check_key(), reinterpret_cast(&detail::inheritance::type_check), t.stack_index()); stack::set_field(L, detail::base_class_cast_key(), reinterpret_cast(&detail::inheritance::type_cast), t.stack_index()); - auto prop_fx = detail::properties_enrollment_allowed(storage.properties, enrollments); - auto insert_fx = [&L, &t, &storage](meta_function mf, lua_CFunction reg) { + auto prop_fx = detail::properties_enrollment_allowed(for_each_backing_metatable_calls, storage.properties, enrollments); + auto insert_fx = [&L, &t, &storage, &smt](meta_function mf, lua_CFunction reg) { stack::set_field(L, mf, reg, t.stack_index()); storage.properties[static_cast(mf)] = true; }; @@ -21793,6 +21796,7 @@ namespace sol { namespace u_detail { storage.is_using_new_index = true; } + ++for_each_backing_metatable_calls; fast_index_table = reference(L, t); t.pop(); }; diff --git a/tests/runtime_tests/source/operators.cpp b/tests/runtime_tests/source/operators.cpp index c64483355..f7d0bb387 100644 --- a/tests/runtime_tests/source/operators.cpp +++ b/tests/runtime_tests/source/operators.cpp @@ -29,8 +29,9 @@ #include #include +struct T {}; + TEST_CASE("operators/default", "test that generic equality operators and all sorts of equality tests can be used") { - struct T {}; struct U { int a; U(int x = 20) : a(x) { @@ -186,6 +187,31 @@ TEST_CASE("operators/default", "test that generic equality operators and all sor } } +TEST_CASE("operators/default with pointers", "test that default operations still work when working with reference (pointer) types") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("T"); + + T test; + + lua["t1"] = &test; + lua["t2"] = &test; + lua["t3"] = std::unique_ptr(&test); + lua["t4"] = std::unique_ptr(&test); + + lua.script("ptr_test = t1 == t2"); + lua.script("ptr_unique_test = t1 == t3"); + lua.script("unique_test = t3 == t4"); + + bool ptr_test = lua["ptr_test"]; + bool ptr_unique_test = lua["ptr_unique_test"]; + bool unique_test = lua["unique_test"]; + REQUIRE(ptr_test); + REQUIRE(ptr_unique_test); + REQUIRE(unique_test); +} + TEST_CASE("operators/call", "test call operator generation") { struct callable { int operator()(int a, std::string b) { diff --git a/tests/runtime_tests/source/sol_test.hpp b/tests/runtime_tests/source/sol_test.hpp index d9d07dfd3..ac753eb6e 100644 --- a/tests/runtime_tests/source/sol_test.hpp +++ b/tests/runtime_tests/source/sol_test.hpp @@ -65,4 +65,11 @@ struct test_stack_guard { } }; +struct no_delete { + template + void operator()(P) const noexcept { + + } +}; + #endif // SOL_TESTS_SOL_TEST_HPP