From 6c6c89132b6b3cff8e53fcbe1ea2442a219e2cd6 Mon Sep 17 00:00:00 2001 From: ThePhD Date: Wed, 21 Feb 2018 02:02:18 -0500 Subject: [PATCH] fix #593 --- single/sol/sol.hpp | 28 +++++++++++++------- single/sol/sol_forward.hpp | 4 +-- sol/container_traits.hpp | 14 +++++----- sol/traits.hpp | 10 ++++++++ tests/test_containers.cpp | 52 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 90 insertions(+), 18 deletions(-) diff --git a/single/sol/sol.hpp b/single/sol/sol.hpp index 91a43ab1..3c5008c5 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-02-20 16:44:34.136549 UTC -// This header was generated with sol v2.19.0 (revision d7425db) +// Generated 2018-02-21 06:23:41.439083 UTC +// This header was generated with sol v2.19.0 (revision a56a890) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -1749,6 +1749,16 @@ namespace sol { return *std::forward(item); } + template >, meta::neg>>> = meta::enabler> + auto deref_non_pointer(T&& item) -> decltype(std::forward(item)) { + return std::forward(item); + } + + template >, meta::neg>>> = meta::enabler> + inline auto deref_non_pointer(T&& item) -> decltype(*std::forward(item)) { + return *std::forward(item); + } + template inline T* ptr(T& val) { return std::addressof(val); @@ -15813,7 +15823,7 @@ namespace sol { typedef std::is_same is_input_iterator; typedef std::conditional_t())) + decltype(detail::deref_non_pointer(std::declval())) > push_type; typedef std::is_copy_assignable is_copyable; typedef meta::neg(L, detail::deref(v.second)); + return stack::stack_detail::push_reference(L, detail::deref_non_pointer(v.second)); } static error_result get_associative(std::false_type, lua_State* L, iterator& it) { - return stack::stack_detail::push_reference(L, detail::deref(*it)); + return stack::stack_detail::push_reference(L, detail::deref_non_pointer(*it)); } static error_result get_category(std::input_iterator_tag, lua_State* L, T& self, K& key) { @@ -16336,7 +16346,7 @@ namespace sol { else { p = stack::push_reference(L, it->first); } - p += stack::stack_detail::push_reference(L, detail::deref(it->second)); + p += stack::stack_detail::push_reference(L, detail::deref_non_pointer(it->second)); std::advance(it, 1); return p; } @@ -16352,7 +16362,7 @@ namespace sol { } int p; p = stack::push_reference(L, k + 1); - p += stack::stack_detail::push_reference(L, detail::deref(*it)); + p += stack::stack_detail::push_reference(L, detail::deref_non_pointer(*it)); std::advance(it, 1); return p; } @@ -16537,7 +16547,7 @@ namespace sol { } int p; p = stack::push_reference(L, k + 1); - p += stack::push_reference(L, detail::deref(*it)); + p += stack::push_reference(L, detail::deref_non_pointer(*it)); std::advance(it, 1); return p; } @@ -16566,7 +16576,7 @@ namespace sol { if (idx >= static_cast(std::extent::value) || idx < 0) { return stack::push(L, lua_nil); } - return stack::push_reference(L, detail::deref(self[idx])); + return stack::push_reference(L, detail::deref_non_pointer(self[idx])); } static int index_get(lua_State* L) { diff --git a/single/sol/sol_forward.hpp b/single/sol/sol_forward.hpp index beaa8337..20016f76 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-02-20 16:44:34.892145 UTC -// This header was generated with sol v2.19.0 (revision d7425db) +// Generated 2018-02-21 06:23:41.719118 UTC +// This header was generated with sol v2.19.0 (revision a56a890) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP diff --git a/sol/container_traits.hpp b/sol/container_traits.hpp index df72c878..70f3fe8a 100644 --- a/sol/container_traits.hpp +++ b/sol/container_traits.hpp @@ -532,7 +532,7 @@ namespace sol { typedef std::is_same is_input_iterator; typedef std::conditional_t())) + decltype(detail::deref_non_pointer(std::declval())) > push_type; typedef std::is_copy_assignable is_copyable; typedef meta::neg(L, detail::deref(v.second)); + return stack::stack_detail::push_reference(L, detail::deref_non_pointer(v.second)); } static error_result get_associative(std::false_type, lua_State* L, iterator& it) { - return stack::stack_detail::push_reference(L, detail::deref(*it)); + return stack::stack_detail::push_reference(L, detail::deref_non_pointer(*it)); } static error_result get_category(std::input_iterator_tag, lua_State* L, T& self, K& key) { @@ -1055,7 +1055,7 @@ namespace sol { else { p = stack::push_reference(L, it->first); } - p += stack::stack_detail::push_reference(L, detail::deref(it->second)); + p += stack::stack_detail::push_reference(L, detail::deref_non_pointer(it->second)); std::advance(it, 1); return p; } @@ -1071,7 +1071,7 @@ namespace sol { } int p; p = stack::push_reference(L, k + 1); - p += stack::stack_detail::push_reference(L, detail::deref(*it)); + p += stack::stack_detail::push_reference(L, detail::deref_non_pointer(*it)); std::advance(it, 1); return p; } @@ -1256,7 +1256,7 @@ namespace sol { } int p; p = stack::push_reference(L, k + 1); - p += stack::push_reference(L, detail::deref(*it)); + p += stack::push_reference(L, detail::deref_non_pointer(*it)); std::advance(it, 1); return p; } @@ -1285,7 +1285,7 @@ namespace sol { if (idx >= static_cast(std::extent::value) || idx < 0) { return stack::push(L, lua_nil); } - return stack::push_reference(L, detail::deref(self[idx])); + return stack::push_reference(L, detail::deref_non_pointer(self[idx])); } static int index_get(lua_State* L) { diff --git a/sol/traits.hpp b/sol/traits.hpp index 78ba92d0..31c64288 100644 --- a/sol/traits.hpp +++ b/sol/traits.hpp @@ -663,6 +663,16 @@ namespace sol { return *std::forward(item); } + template >, meta::neg>>> = meta::enabler> + auto deref_non_pointer(T&& item) -> decltype(std::forward(item)) { + return std::forward(item); + } + + template >, meta::neg>>> = meta::enabler> + inline auto deref_non_pointer(T&& item) -> decltype(*std::forward(item)) { + return *std::forward(item); + } + template inline T* ptr(T& val) { return std::addressof(val); diff --git a/tests/test_containers.cpp b/tests/test_containers.cpp index 2af01c0c..91c299f3 100644 --- a/tests/test_containers.cpp +++ b/tests/test_containers.cpp @@ -1274,3 +1274,55 @@ TEST_CASE("containers/custom indexing", "allow containers to set a custom indexi auto result3 = lua.safe_script("assert(c[-1] == nil)", sol::script_pass_on_error); REQUIRE(result3.valid()); } + +TEST_CASE("containers/containers of pointers", "containers of pointers shouldn't have their value_type's overly stripped") { + sol::state lua; + + class MyContainer { + public: + typedef int** iterator; + typedef int* value_type; + + std::vector m_vec; + + inline iterator begin() { return m_vec.data(); } + inline iterator end() { return m_vec.data() + m_vec.size(); } + inline void push_back(value_type v) { m_vec.push_back(v); } + }; + int a = 500; + int b = 600; + + MyContainer ctr; + ctr.push_back(&a); + ctr.push_back(&b); + lua["c"] = ctr; + { + auto result1 = lua.safe_script("ap = c[1]", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("bp = c[2]", sol::script_pass_on_error); + REQUIRE(result2.valid()); + int* ap = lua["ap"]; + int* bp = lua["bp"]; + REQUIRE(ap == &a); + REQUIRE(bp == &b); + REQUIRE(*ap == 500); + REQUIRE(*bp == 600); + } + + std::unordered_map ptrs; + ptrs[5] = &a; + ptrs[6] = &b; + lua["c2"] = ptrs; + { + auto result1 = lua.safe_script("ap = c2[5]", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("bp = c2[6]", sol::script_pass_on_error); + REQUIRE(result2.valid()); + int* ap = lua["ap"]; + int* bp = lua["bp"]; + REQUIRE(ap == &a); + REQUIRE(bp == &b); + REQUIRE(*ap == 500); + REQUIRE(*bp == 600); + } +}