From 3342e65b385aac57caca3b8284713682c9ea1211 Mon Sep 17 00:00:00 2001 From: ThePhD Date: Thu, 23 Mar 2017 21:13:46 -0400 Subject: [PATCH] fixes to a lot of tests and proper subclassing for internal metatable data and work done to all of the usertypes to make them behave as expected --- single/sol/sol.hpp | 138 +++++++++++++++++++++---------------- sol/usertype_metatable.hpp | 134 +++++++++++++++++++---------------- test_simple_usertypes.cpp | 47 ++++++++----- test_usertypes.cpp | 47 ++++++++----- 4 files changed, 214 insertions(+), 152 deletions(-) diff --git a/single/sol/sol.hpp b/single/sol/sol.hpp index 0f2712d9..d30d9697 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 2017-03-23 14:12:13.335349 UTC -// This header was generated with sol v2.16.0 (revision 6ceb715) +// Generated 2017-03-24 01:12:07.656967 UTC +// This header was generated with sol v2.16.0 (revision 7c29964) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -10125,6 +10125,43 @@ namespace sol { #include namespace sol { + namespace usertype_detail { + typedef void(*base_walk)(lua_State*, bool&, int&, string_detail::string_shim&); + typedef int(*member_search)(lua_State*, void*, int); + + struct call_information { + member_search first; + member_search second; + int runtime_target; + + call_information(member_search first, member_search second) : call_information(first, second, -1) {} + call_information(member_search first, member_search second, int runtimetarget) : first(first), second(second), runtime_target(runtimetarget) {} + }; + + typedef std::unordered_map mapping_t; + } + + struct usertype_metatable_core { + usertype_detail::mapping_t mapping; + lua_CFunction indexfunc; + lua_CFunction newindexfunc; + std::vector runtime; + bool mustindex; + + usertype_metatable_core(lua_CFunction ifx, lua_CFunction nifx) : + mapping(), indexfunc(ifx), + newindexfunc(nifx), runtime(), mustindex(false) + { + + } + + usertype_metatable_core(const usertype_metatable_core&) = default; + usertype_metatable_core(usertype_metatable_core&&) = default; + usertype_metatable_core& operator=(const usertype_metatable_core&) = default; + usertype_metatable_core& operator=(usertype_metatable_core&&) = default; + + }; + namespace usertype_detail { const lua_Integer toplevel_magic = static_cast(0x00020001); @@ -10169,20 +10206,6 @@ namespace sol { } }; - typedef void(*base_walk)(lua_State*, bool&, int&, string_detail::string_shim&); - typedef int(*member_search)(lua_State*, void*, int); - - struct call_information { - member_search first; - member_search second; - int runtime_target; - - call_information(member_search first, member_search second) : call_information(first, second, -1) {} - call_information(member_search first, member_search second, int runtimetarget) : first(first), second(second), runtime_target(runtimetarget) {} - }; - - typedef std::unordered_map mapping_t; - inline bool is_indexer(string_detail::string_shim s) { return s == name_of(meta_function::index) || s == name_of(meta_function::new_index); } @@ -10238,7 +10261,8 @@ namespace sol { }; inline int runtime_object_call(lua_State* L, void*, int runtimetarget) { - std::vector& runtime = stack::get>>(L, lua_upvalueindex(2)); + usertype_metatable_core& umc = stack::get>(L, upvalue_index(2)); + std::vector& runtime = umc.runtime; return stack::push(L, runtime[runtimetarget]); } @@ -10266,12 +10290,17 @@ namespace sol { int isnum = 0; lua_Integer magic = lua_tointegerx(L, upvalue_index(4), &isnum); if (isnum != 0 && magic == toplevel_magic) { - 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, upvalue_index(3)); - std::vector& runtime = stack::get>>(L, upvalue_index(2)); - int target = static_cast(runtime.size()); + auto non_simple = [&L]() { + if (is_simple) + return; + usertype_metatable_core& umc = stack::get>(L, upvalue_index(2)); + bool mustindex = umc.mustindex; + if (!mustindex) + return; std::string accessor = stack::get(L, 2); + mapping_t& mapping = umc.mapping; + std::vector& runtime = umc.runtime; + int target = static_cast(runtime.size()); auto preexistingit = mapping.find(accessor); if (preexistingit == mapping.cend()) { runtime.emplace_back(L, 3); @@ -10282,7 +10311,8 @@ namespace sol { runtime[target] = sol::object(L, 3); preexistingit->second = call_information(&runtime_object_call, &runtime_object_call, target); } - } + }; + non_simple(); for (std::size_t i = 0; i < 4; lua_pop(L, 1), ++i) { const char* metakey = nullptr; switch (i) { @@ -10396,7 +10426,7 @@ namespace sol { struct usertype_metatable : usertype_detail::registrar {}; template - struct usertype_metatable, Tn...> : usertype_detail::registrar { + struct usertype_metatable, Tn...> : usertype_metatable_core, usertype_detail::registrar { typedef std::make_index_sequence indices; typedef std::index_sequence half_indices; typedef std::array regs_t; @@ -10404,11 +10434,7 @@ namespace sol { typedef std::tuple ...> Tuple; template struct check_binding : is_variable_binding> {}; - usertype_detail::mapping_t mapping; - std::vector runtime; Tuple functions; - lua_CFunction indexfunc; - lua_CFunction newindexfunc; lua_CFunction destructfunc; lua_CFunction callconstructfunc; lua_CFunction indexbase; @@ -10417,7 +10443,6 @@ namespace sol { usertype_detail::base_walk newindexbaseclasspropogation; void* baseclasscheck; void* baseclasscast; - bool mustindex; bool secondarymeta; bool hasequals; bool hasless; @@ -10523,34 +10548,26 @@ namespace sol { ++index; } - template - static std::pair make_call_info(std::string n) { - return{ n, (n == "__newindex" || n == "__index") ? - usertype_detail::call_information(&usertype_metatable::real_meta_call, - &usertype_metatable::real_meta_call) - : - usertype_detail::call_information(&usertype_metatable::real_find_call, - &usertype_metatable::real_find_call) - }; - } - template > - usertype_metatable(Args&&... args) : - mapping(), + usertype_metatable(Args&&... args) : usertype_metatable_core(&usertype_detail::indexing_fail, &usertype_detail::metatable_newindex), usertype_detail::registrar(), functions(std::forward(args)...), - indexfunc(&usertype_detail::indexing_fail), newindexfunc(&usertype_detail::metatable_newindex), 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), - mustindex(contains_variable() || contains_index()), secondarymeta(contains_variable()), + secondarymeta(contains_variable()), hasequals(false), hasless(false), haslessequals(false) { std::initializer_list ilist{ { - std::pair( - make_call_info(usertype_detail::make_string(std::get(functions))) + std::pair( usertype_detail::make_string(std::get(functions)), + usertype_detail::call_information(&usertype_metatable::real_find_call, + &usertype_metatable::real_find_call) ) }... }; - mapping.insert(ilist); + this->mapping.insert(ilist); + for (const auto& n : meta_function_names) { + this->mapping.erase(n); + } + this->mustindex = contains_variable() || contains_index(); } usertype_metatable(const usertype_metatable&) = default; @@ -10569,10 +10586,10 @@ namespace sol { return stack::push(L, c_closure(cfunc, upvalues)); } - template + template static int real_meta_call(lua_State* L, void* um, int) { auto& f = *static_cast(um); - return real_call_with(L, f); + return is_index ? f.indexfunc(L) : f.newindexfunc(L); } template @@ -10693,6 +10710,7 @@ namespace sol { static int push(lua_State* L, umt_t&& umx) { umt_t& um = make_cleanup(L, std::move(umx)); + usertype_metatable_core& umc = um; regs_t value_table{ {} }; int lastreg = 0; (void)detail::swallow{ 0, (um.template make_regs<(I * 2)>(value_table, lastreg, std::get<(I * 2)>(um.functions), std::get<(I * 2 + 1)>(um.functions)), 0)... }; @@ -10707,7 +10725,7 @@ namespace sol { } // Now use um - const bool& mustindex = um.mustindex; + const bool& mustindex = umc.mustindex; for (std::size_t i = 0; i < 3; ++i) { // Pointer types, AKA "references" from C++ const char* metakey = nullptr; @@ -10739,14 +10757,14 @@ namespace sol { stack::set_field(L, detail::base_class_cast_key(), um.baseclasscast, t.stack_index()); } - stack::set_field(L, detail::base_class_index_propogation_key(), make_closure(um.indexbase, make_light(um), make_light(um.runtime)), t.stack_index()); - stack::set_field(L, detail::base_class_new_index_propogation_key(), make_closure(um.newindexbase, make_light(um), make_light(um.runtime)), t.stack_index()); + stack::set_field(L, detail::base_class_index_propogation_key(), make_closure(um.indexbase, make_light(um), make_light(umc)), t.stack_index()); + stack::set_field(L, detail::base_class_new_index_propogation_key(), make_closure(um.newindexbase, make_light(um), make_light(umc)), t.stack_index()); if (mustindex) { // Basic index pushing: specialize // index and newindex to give variables and stuff - stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, make_light(um), make_light(um.runtime)), t.stack_index()); - stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, make_light(um), make_light(um.runtime)), t.stack_index()); + stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, make_light(um), make_light(umc)), t.stack_index()); + stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, make_light(um), make_light(umc)), t.stack_index()); } else { // If there's only functions, we can use the fast index version @@ -10757,11 +10775,11 @@ namespace sol { lua_createtable(L, 0, 3); stack_reference metabehind(L, -1); if (um.callconstructfunc != nullptr) { - stack::set_field(L, meta_function::call_function, make_closure(um.callconstructfunc, make_light(um), make_light(um.runtime)), metabehind.stack_index()); + stack::set_field(L, meta_function::call_function, make_closure(um.callconstructfunc, make_light(um), make_light(umc)), metabehind.stack_index()); } if (um.secondarymeta) { - stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, make_light(um), make_light(um.runtime)), metabehind.stack_index()); - stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, make_light(um), make_light(um.runtime)), metabehind.stack_index()); + stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, make_light(um), make_light(umc)), metabehind.stack_index()); + stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, make_light(um), make_light(umc)), metabehind.stack_index()); } stack::set_field(L, metatable_key, metabehind, t.stack_index()); metabehind.pop(); @@ -10779,11 +10797,11 @@ namespace sol { lua_createtable(L, 0, 3); stack_reference metabehind(L, -1); if (um.callconstructfunc != nullptr) { - stack::set_field(L, meta_function::call_function, make_closure(um.callconstructfunc, make_light(um), static_cast(&um.runtime)), metabehind.stack_index()); + stack::set_field(L, meta_function::call_function, make_closure(um.callconstructfunc, make_light(um), make_light(umc)), metabehind.stack_index()); } - stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, make_light(um), static_cast(&um.runtime), static_cast(&um.mapping), usertype_detail::toplevel_magic, um.mustindex), metabehind.stack_index()); - stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, make_light(um), static_cast(&um.runtime), static_cast(&um.mapping), usertype_detail::toplevel_magic, um.mustindex), metabehind.stack_index()); + stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, make_light(um), make_light(umc), 0, usertype_detail::toplevel_magic), metabehind.stack_index()); + stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, make_light(um), make_light(umc), 0, usertype_detail::toplevel_magic), metabehind.stack_index()); stack::set_field(L, metatable_key, metabehind, t.stack_index()); metabehind.pop(); diff --git a/sol/usertype_metatable.hpp b/sol/usertype_metatable.hpp index 81df4e1e..1d4c29d2 100644 --- a/sol/usertype_metatable.hpp +++ b/sol/usertype_metatable.hpp @@ -35,6 +35,43 @@ #include namespace sol { + namespace usertype_detail { + typedef void(*base_walk)(lua_State*, bool&, int&, string_detail::string_shim&); + typedef int(*member_search)(lua_State*, void*, int); + + struct call_information { + member_search first; + member_search second; + int runtime_target; + + call_information(member_search first, member_search second) : call_information(first, second, -1) {} + call_information(member_search first, member_search second, int runtimetarget) : first(first), second(second), runtime_target(runtimetarget) {} + }; + + typedef std::unordered_map mapping_t; + } + + struct usertype_metatable_core { + usertype_detail::mapping_t mapping; + lua_CFunction indexfunc; + lua_CFunction newindexfunc; + std::vector runtime; + bool mustindex; + + usertype_metatable_core(lua_CFunction ifx, lua_CFunction nifx) : + mapping(), indexfunc(ifx), + newindexfunc(nifx), runtime(), mustindex(false) + { + + } + + usertype_metatable_core(const usertype_metatable_core&) = default; + usertype_metatable_core(usertype_metatable_core&&) = default; + usertype_metatable_core& operator=(const usertype_metatable_core&) = default; + usertype_metatable_core& operator=(usertype_metatable_core&&) = default; + + }; + namespace usertype_detail { const lua_Integer toplevel_magic = static_cast(0x00020001); @@ -79,20 +116,6 @@ namespace sol { } }; - typedef void(*base_walk)(lua_State*, bool&, int&, string_detail::string_shim&); - typedef int(*member_search)(lua_State*, void*, int); - - struct call_information { - member_search first; - member_search second; - int runtime_target; - - call_information(member_search first, member_search second) : call_information(first, second, -1) {} - call_information(member_search first, member_search second, int runtimetarget) : first(first), second(second), runtime_target(runtimetarget) {} - }; - - typedef std::unordered_map mapping_t; - inline bool is_indexer(string_detail::string_shim s) { return s == name_of(meta_function::index) || s == name_of(meta_function::new_index); } @@ -148,7 +171,8 @@ namespace sol { }; inline int runtime_object_call(lua_State* L, void*, int runtimetarget) { - std::vector& runtime = stack::get>>(L, lua_upvalueindex(2)); + usertype_metatable_core& umc = stack::get>(L, upvalue_index(2)); + std::vector& runtime = umc.runtime; return stack::push(L, runtime[runtimetarget]); } @@ -176,12 +200,17 @@ namespace sol { int isnum = 0; lua_Integer magic = lua_tointegerx(L, upvalue_index(4), &isnum); if (isnum != 0 && magic == toplevel_magic) { - 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, upvalue_index(3)); - std::vector& runtime = stack::get>>(L, upvalue_index(2)); - int target = static_cast(runtime.size()); + auto non_simple = [&L]() { + if (is_simple) + return; + usertype_metatable_core& umc = stack::get>(L, upvalue_index(2)); + bool mustindex = umc.mustindex; + if (!mustindex) + return; std::string accessor = stack::get(L, 2); + mapping_t& mapping = umc.mapping; + std::vector& runtime = umc.runtime; + int target = static_cast(runtime.size()); auto preexistingit = mapping.find(accessor); if (preexistingit == mapping.cend()) { runtime.emplace_back(L, 3); @@ -192,7 +221,8 @@ namespace sol { runtime[target] = sol::object(L, 3); preexistingit->second = call_information(&runtime_object_call, &runtime_object_call, target); } - } + }; + non_simple(); for (std::size_t i = 0; i < 4; lua_pop(L, 1), ++i) { const char* metakey = nullptr; switch (i) { @@ -306,7 +336,7 @@ namespace sol { struct usertype_metatable : usertype_detail::registrar {}; template - struct usertype_metatable, Tn...> : usertype_detail::registrar { + struct usertype_metatable, Tn...> : usertype_metatable_core, usertype_detail::registrar { typedef std::make_index_sequence indices; typedef std::index_sequence half_indices; typedef std::array regs_t; @@ -314,11 +344,7 @@ namespace sol { typedef std::tuple ...> Tuple; template struct check_binding : is_variable_binding> {}; - usertype_detail::mapping_t mapping; - std::vector runtime; Tuple functions; - lua_CFunction indexfunc; - lua_CFunction newindexfunc; lua_CFunction destructfunc; lua_CFunction callconstructfunc; lua_CFunction indexbase; @@ -327,7 +353,6 @@ namespace sol { usertype_detail::base_walk newindexbaseclasspropogation; void* baseclasscheck; void* baseclasscast; - bool mustindex; bool secondarymeta; bool hasequals; bool hasless; @@ -433,34 +458,26 @@ namespace sol { ++index; } - template - static std::pair make_call_info(std::string n) { - return{ n, (n == "__newindex" || n == "__index") ? - usertype_detail::call_information(&usertype_metatable::real_meta_call, - &usertype_metatable::real_meta_call) - : - usertype_detail::call_information(&usertype_metatable::real_find_call, - &usertype_metatable::real_find_call) - }; - } - template > - usertype_metatable(Args&&... args) : - mapping(), + usertype_metatable(Args&&... args) : usertype_metatable_core(&usertype_detail::indexing_fail, &usertype_detail::metatable_newindex), usertype_detail::registrar(), functions(std::forward(args)...), - indexfunc(&usertype_detail::indexing_fail), newindexfunc(&usertype_detail::metatable_newindex), 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), - mustindex(contains_variable() || contains_index()), secondarymeta(contains_variable()), + secondarymeta(contains_variable()), hasequals(false), hasless(false), haslessequals(false) { std::initializer_list ilist{ { - std::pair( - make_call_info(usertype_detail::make_string(std::get(functions))) + std::pair( usertype_detail::make_string(std::get(functions)), + usertype_detail::call_information(&usertype_metatable::real_find_call, + &usertype_metatable::real_find_call) ) }... }; - mapping.insert(ilist); + this->mapping.insert(ilist); + for (const auto& n : meta_function_names) { + this->mapping.erase(n); + } + this->mustindex = contains_variable() || contains_index(); } usertype_metatable(const usertype_metatable&) = default; @@ -479,10 +496,10 @@ namespace sol { return stack::push(L, c_closure(cfunc, upvalues)); } - template + template static int real_meta_call(lua_State* L, void* um, int) { auto& f = *static_cast(um); - return real_call_with(L, f); + return is_index ? f.indexfunc(L) : f.newindexfunc(L); } template @@ -603,6 +620,7 @@ namespace sol { static int push(lua_State* L, umt_t&& umx) { umt_t& um = make_cleanup(L, std::move(umx)); + usertype_metatable_core& umc = um; regs_t value_table{ {} }; int lastreg = 0; (void)detail::swallow{ 0, (um.template make_regs<(I * 2)>(value_table, lastreg, std::get<(I * 2)>(um.functions), std::get<(I * 2 + 1)>(um.functions)), 0)... }; @@ -617,7 +635,7 @@ namespace sol { } // Now use um - const bool& mustindex = um.mustindex; + const bool& mustindex = umc.mustindex; for (std::size_t i = 0; i < 3; ++i) { // Pointer types, AKA "references" from C++ const char* metakey = nullptr; @@ -649,14 +667,14 @@ namespace sol { stack::set_field(L, detail::base_class_cast_key(), um.baseclasscast, t.stack_index()); } - stack::set_field(L, detail::base_class_index_propogation_key(), make_closure(um.indexbase, make_light(um), make_light(um.runtime)), t.stack_index()); - stack::set_field(L, detail::base_class_new_index_propogation_key(), make_closure(um.newindexbase, make_light(um), make_light(um.runtime)), t.stack_index()); + stack::set_field(L, detail::base_class_index_propogation_key(), make_closure(um.indexbase, make_light(um), make_light(umc)), t.stack_index()); + stack::set_field(L, detail::base_class_new_index_propogation_key(), make_closure(um.newindexbase, make_light(um), make_light(umc)), t.stack_index()); if (mustindex) { // Basic index pushing: specialize // index and newindex to give variables and stuff - stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, make_light(um), make_light(um.runtime)), t.stack_index()); - stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, make_light(um), make_light(um.runtime)), t.stack_index()); + stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, make_light(um), make_light(umc)), t.stack_index()); + stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, make_light(um), make_light(umc)), t.stack_index()); } else { // If there's only functions, we can use the fast index version @@ -667,11 +685,11 @@ namespace sol { lua_createtable(L, 0, 3); stack_reference metabehind(L, -1); if (um.callconstructfunc != nullptr) { - stack::set_field(L, meta_function::call_function, make_closure(um.callconstructfunc, make_light(um), make_light(um.runtime)), metabehind.stack_index()); + stack::set_field(L, meta_function::call_function, make_closure(um.callconstructfunc, make_light(um), make_light(umc)), metabehind.stack_index()); } if (um.secondarymeta) { - stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, make_light(um), make_light(um.runtime)), metabehind.stack_index()); - stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, make_light(um), make_light(um.runtime)), metabehind.stack_index()); + stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, make_light(um), make_light(umc)), metabehind.stack_index()); + stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, make_light(um), make_light(umc)), metabehind.stack_index()); } stack::set_field(L, metatable_key, metabehind, t.stack_index()); metabehind.pop(); @@ -689,11 +707,11 @@ namespace sol { lua_createtable(L, 0, 3); stack_reference metabehind(L, -1); if (um.callconstructfunc != nullptr) { - stack::set_field(L, meta_function::call_function, make_closure(um.callconstructfunc, make_light(um), static_cast(&um.runtime)), metabehind.stack_index()); + stack::set_field(L, meta_function::call_function, make_closure(um.callconstructfunc, make_light(um), make_light(umc)), metabehind.stack_index()); } - stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, make_light(um), static_cast(&um.runtime), static_cast(&um.mapping), usertype_detail::toplevel_magic, um.mustindex), metabehind.stack_index()); - stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, make_light(um), static_cast(&um.runtime), static_cast(&um.mapping), usertype_detail::toplevel_magic, um.mustindex), metabehind.stack_index()); + stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, make_light(um), make_light(umc), 0, usertype_detail::toplevel_magic), metabehind.stack_index()); + stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, make_light(um), make_light(umc), 0, usertype_detail::toplevel_magic), metabehind.stack_index()); stack::set_field(L, metatable_key, metabehind, t.stack_index()); metabehind.pop(); diff --git a/test_simple_usertypes.cpp b/test_simple_usertypes.cpp index aa8a47ab..cf8e3e5b 100644 --- a/test_simple_usertypes.cpp +++ b/test_simple_usertypes.cpp @@ -700,8 +700,8 @@ end 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; - static std::string keys[2] = {}; - static int values[2] = {}; + static std::string keys[4] = {}; + static int values[4] = {}; struct d_sample { void foo(std::string k, int v) { keys[writes] = k; @@ -710,25 +710,32 @@ TEST_CASE("simple_usertype/meta-key-retrievals", "allow for special meta keys (_ } }; - sol::state state; - state.new_simple_usertype("sample"); - sol::table s = state["sample"]["new"](); + sol::state lua; + lua.new_simple_usertype("sample"); + sol::table s = lua["sample"]["new"](); s[sol::metatable_key][sol::meta_function::new_index] = &d_sample::foo; - state["var"] = s; + lua["var"] = s; - state.script("var.key = 2"); - state.script("var.__newindex = 4"); + lua.script("var = sample.new()"); + lua.script("var.key = 2"); + lua.script("var.__newindex = 4"); + lua.script("var.__index = 3"); + lua.script("var.__call = 1"); REQUIRE(values[0] == 2); - REQUIRE(keys[0] == "key"); REQUIRE(values[1] == 4); + REQUIRE(values[2] == 3); + REQUIRE(values[3] == 1); + REQUIRE(keys[0] == "key"); REQUIRE(keys[1] == "__newindex"); + REQUIRE(keys[2] == "__index"); + REQUIRE(keys[3] == "__call"); } SECTION("statically") { static int writes = 0; - static std::string keys[2] = {}; - static int values[2] = {}; + static std::string keys[4] = {}; + static int values[4] = {}; struct sample { void foo(std::string k, int v) { keys[writes] = k; @@ -737,15 +744,21 @@ TEST_CASE("simple_usertype/meta-key-retrievals", "allow for special meta keys (_ } }; - sol::state state; - state.new_simple_usertype("sample", sol::meta_function::new_index, &sample::foo); + sol::state lua; + lua.new_simple_usertype("sample", sol::meta_function::new_index, &sample::foo); - state.script("var = sample.new()"); - state.script("var.key = 2"); - state.script("var.__newindex = 4"); + lua.script("var = sample.new()"); + lua.script("var.key = 2"); + lua.script("var.__newindex = 4"); + lua.script("var.__index = 3"); + lua.script("var.__call = 1"); REQUIRE(values[0] == 2); - REQUIRE(keys[0] == "key"); REQUIRE(values[1] == 4); + REQUIRE(values[2] == 3); + REQUIRE(values[3] == 1); + REQUIRE(keys[0] == "key"); REQUIRE(keys[1] == "__newindex"); + REQUIRE(keys[2] == "__index"); + REQUIRE(keys[3] == "__call"); } } diff --git a/test_usertypes.cpp b/test_usertypes.cpp index 20a4d35a..75b843b9 100644 --- a/test_usertypes.cpp +++ b/test_usertypes.cpp @@ -1626,8 +1626,8 @@ end TEST_CASE("usertype/meta-key-retrievals", "allow for special meta keys (__index, __newindex) to trigger methods even if overwritten directly") { SECTION("dynamically") { static int writes = 0; - static std::string keys[2] = {}; - static int values[2] = {}; + static std::string keys[4] = {}; + static int values[4] = {}; struct d_sample { void foo(std::string k, int v) { keys[writes] = k; @@ -1636,25 +1636,32 @@ TEST_CASE("usertype/meta-key-retrievals", "allow for special meta keys (__index, } }; - sol::state state; - state.new_usertype("sample"); - sol::table s = state["sample"]["new"](); + sol::state lua; + lua.new_usertype("sample"); + sol::table s = lua["sample"]["new"](); s[sol::metatable_key][sol::meta_function::new_index] = &d_sample::foo; - state["var"] = s; + lua["var"] = s; - state.script("var.key = 2"); - state.script("var.__newindex = 4"); + lua.script("var = sample.new()"); + lua.script("var.key = 2"); + lua.script("var.__newindex = 4"); + lua.script("var.__index = 3"); + lua.script("var.__call = 1"); REQUIRE(values[0] == 2); - REQUIRE(keys[0] == "key"); REQUIRE(values[1] == 4); + REQUIRE(values[2] == 3); + REQUIRE(values[3] == 1); + REQUIRE(keys[0] == "key"); REQUIRE(keys[1] == "__newindex"); + REQUIRE(keys[2] == "__index"); + REQUIRE(keys[3] == "__call"); } SECTION("statically") { static int writes = 0; - static std::string keys[2] = {}; - static int values[2] = {}; + static std::string keys[4] = {}; + static int values[4] = {}; struct sample { void foo(std::string k, int v) { keys[writes] = k; @@ -1663,15 +1670,21 @@ TEST_CASE("usertype/meta-key-retrievals", "allow for special meta keys (__index, } }; - sol::state state; - state.new_usertype("sample", sol::meta_function::new_index, &sample::foo); + sol::state lua; + lua.new_usertype("sample", sol::meta_function::new_index, &sample::foo); - state.script("var = sample.new()"); - state.script("var.key = 2"); - state.script("var.__newindex = 4"); + lua.script("var = sample.new()"); + lua.script("var.key = 2"); + lua.script("var.__newindex = 4"); + lua.script("var.__index = 3"); + lua.script("var.__call = 1"); REQUIRE(values[0] == 2); - REQUIRE(keys[0] == "key"); REQUIRE(values[1] == 4); + REQUIRE(values[2] == 3); + REQUIRE(values[3] == 1); + REQUIRE(keys[0] == "key"); REQUIRE(keys[1] == "__newindex"); + REQUIRE(keys[2] == "__index"); + REQUIRE(keys[3] == "__call"); } }