From 4cde2b6a3b9506195a42c927a463dc21a808bd53 Mon Sep 17 00:00:00 2001 From: ThePhD Date: Thu, 11 Aug 2016 07:25:57 -0400 Subject: [PATCH] making questionable decisions since 1892 --- single/sol/sol.hpp | 133 +++++++++++++++++++++++++++++++++++---------- sol/stack_core.hpp | 2 +- sol/stack_push.hpp | 14 +++-- 3 files changed, 116 insertions(+), 33 deletions(-) diff --git a/single/sol/sol.hpp b/single/sol/sol.hpp index 5bd7ca41..a0a8f433 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 2016-08-08 00:57:18.871859 UTC -// This header was generated with sol v2.10.5 (revision 49cc3bd) +// Generated 2016-08-11 11:25:37.090286 UTC +// This header was generated with sol v2.10.5 (revision b88a49a) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -3919,7 +3919,7 @@ namespace sol { typedef meta::all< std::is_lvalue_reference, meta::neg>, - meta::neg> + meta::neg>> > use_reference_tag; return pusher>>{}.push(L, std::forward(t), std::forward(args)...); } @@ -4367,6 +4367,16 @@ namespace sol { return key; } + inline decltype(auto) base_class_index_propogation_key() { + static const auto& key = u8"\xF0\x9F\x8C\xB2.index"; + return key; + } + + inline decltype(auto) base_class_new_index_propogation_key() { + static const auto& key = u8"\xF0\x9F\x8C\xB2.new_index"; + return key; + } + template struct inheritance { static bool type_check_bases(types<>, std::size_t) { @@ -5611,10 +5621,18 @@ namespace sol { template<> struct pusher { - static int push(lua_State* L, const char* str) { - lua_pushlstring(L, str, std::char_traits::length(str)); + static int push_sized(lua_State* L, const char* str, std::size_t len) { + lua_pushlstring(L, str, len); return 1; } + + static int push(lua_State* L, const char* str) { + return push_sized(L, str, std::char_traits::length(str)); + } + + static int push(lua_State* L, const char* str, std::size_t len) { + return push_sized(L, str, len); + } }; template @@ -9063,11 +9081,16 @@ namespace sol { typedef std::tuple ...> Tuple; template struct check_binding : is_variable_binding> {}; + typedef void (*base_walk)(lua_State*, bool&, int&, string_detail::string_shim&); Tuple functions; lua_CFunction indexfunc; lua_CFunction newindexfunc; lua_CFunction destructfunc; lua_CFunction callconstructfunc; + lua_CFunction indexbase; + lua_CFunction newindexbase; + base_walk indexbaseclasspropogation; + base_walk newindexbaseclasspropogation; void* baseclasscheck; void* baseclasscast; bool mustindex; @@ -9113,12 +9136,15 @@ namespace sol { if (sizeof...(Bases) < 1) { return; } + mustindex = true; (void)detail::swallow{ 0, ((detail::has_derived::value = true), 0)... }; static_assert(sizeof(void*) <= sizeof(detail::inheritance_check_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report."); static_assert(sizeof(void*) <= sizeof(detail::inheritance_cast_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report."); baseclasscheck = (void*)&detail::inheritance::type_check; baseclasscast = (void*)&detail::inheritance::type_cast; + indexbaseclasspropogation = walk_all_bases; + newindexbaseclasspropogation = walk_all_bases; } template , base_classes_tag, call_construction>::value>> @@ -9151,7 +9177,10 @@ namespace sol { template > usertype_metatable(Args&&... args) : functions(std::forward(args)...), indexfunc(usertype_detail::indexing_fail), newindexfunc(usertype_detail::indexing_fail), - destructfunc(nullptr), callconstructfunc(nullptr), baseclasscheck(nullptr), baseclasscast(nullptr), + destructfunc(nullptr), callconstructfunc(nullptr), + indexbase(&core_indexing_call), newindexbase(&core_indexing_call), + indexbaseclasspropogation(walk_all_bases), newindexbaseclasspropogation(walk_all_bases), + baseclasscheck(nullptr), baseclasscast(nullptr), mustindex(contains_variable() || contains_index()), secondarymeta(contains_variable()) { } @@ -9176,32 +9205,77 @@ namespace sol { ret = real_find_call(idx, L); } - static int real_index_call(lua_State* L) { - usertype_metatable& f = stack::get>(L, upvalue_index(1)); - if (stack::get(L, -1) == type::string) { - string_detail::string_shim accessor = stack::get(L, -1); - bool found = false; - int ret = 0; - (void)detail::swallow{ 0, (f.find_call(std::true_type(), L, found, ret, accessor), 0)... }; - if (found) { - return ret; - } + template + void propogating_call(lua_State* L, bool& found, int& ret, string_detail::string_shim& accessor) { + (void)detail::swallow{ 0, (find_call(std::integral_constant(), L, found, ret, accessor), 0)... }; + } + + template + static void walk_single_base(lua_State* L, bool& found, int& ret, string_detail::string_shim&) { + if (found) + return; + const char* metakey = &usertype_traits::metatable[0]; + const char* gcmetakey = &usertype_traits::gc_table[0]; + const char* basewalkkey = b ? detail::base_class_index_propogation_key() : detail::base_class_new_index_propogation_key(); + + luaL_getmetatable(L, metakey); + if (type_of(L, -1) == type::nil) { + lua_pop(L, 1); + return; } - return f.indexfunc(L); + stack::get_field(L, basewalkkey); + if (type_of(L, -1) == type::nil) { + lua_pop(L, 2); + return; + } + lua_CFunction basewalkfunc = stack::pop(L); + lua_pop(L, 1); + + stack::get_field(L, gcmetakey); + int value = basewalkfunc(L); + if (value > -1) { + found = true; + ret = value; + } + } + + template + static void walk_all_bases(lua_State* L, bool& found, int& ret, string_detail::string_shim& accessor) { + (void)L; + (void)found; + (void)ret; + (void)accessor; + (void)detail::swallow{ 0, (walk_single_base(L, found, ret, accessor), 0)... }; + } + + template + static int core_indexing_call(lua_State* L) { + usertype_metatable& f = toplevel ? stack::get>(L, upvalue_index(1)) : stack::pop>(L); + static const int keyidx = -2 + static_cast(b); + if (toplevel && stack::get(L, keyidx) != type::string) { + return b ? f.indexfunc(L) : f.newindexfunc(L); + } + string_detail::string_shim accessor = stack::get(L, keyidx); + int ret = 0; + bool found = false; + f.propogating_call(L, found, ret, accessor); + if (found) { + return ret; + } + // Otherwise, we need to do propagating calls through the bases + f.indexbaseclasspropogation(L, found, ret, accessor); + if (found) { + return ret; + } + return toplevel ? (b ? f.indexfunc(L) : f.newindexfunc(L)) : -1; + } + + static int real_index_call(lua_State* L) { + return core_indexing_call(L); } static int real_new_index_call(lua_State* L) { - usertype_metatable& f = stack::get>(L, upvalue_index(1)); - if (stack::get(L, -2) == type::string) { - string_detail::string_shim accessor = stack::get(L, -2); - bool found = false; - int ret = 0; - (void)detail::swallow{ 0, (f.find_call(std::false_type(), L, found, ret, accessor), 0)... }; - if (found) { - return ret; - } - } - return f.newindexfunc(L); + return core_indexing_call(L); } template @@ -9319,6 +9393,9 @@ namespace sol { else { stack::set_field(L, detail::base_class_cast_key(), nil, t.stack_index()); } + + stack::set_field(L, detail::base_class_index_propogation_key(), make_closure(um.indexbase, make_light(um)), t.stack_index()); + stack::set_field(L, detail::base_class_new_index_propogation_key(), make_closure(um.newindexbase, make_light(um)), t.stack_index()); if (mustindex) { // Basic index pushing: specialize diff --git a/sol/stack_core.hpp b/sol/stack_core.hpp index dfc9e43d..b980a197 100644 --- a/sol/stack_core.hpp +++ b/sol/stack_core.hpp @@ -145,7 +145,7 @@ namespace sol { typedef meta::all< std::is_lvalue_reference, meta::neg>, - meta::neg> + meta::neg>> > use_reference_tag; return pusher>>{}.push(L, std::forward(t), std::forward(args)...); } diff --git a/sol/stack_push.hpp b/sol/stack_push.hpp index 98a8bda5..7d5753c3 100644 --- a/sol/stack_push.hpp +++ b/sol/stack_push.hpp @@ -338,10 +338,18 @@ namespace sol { template<> struct pusher { - static int push(lua_State* L, const char* str) { - lua_pushlstring(L, str, std::char_traits::length(str)); + static int push_sized(lua_State* L, const char* str, std::size_t len) { + lua_pushlstring(L, str, len); return 1; } + + static int push(lua_State* L, const char* str) { + return push_sized(L, str, std::char_traits::length(str)); + } + + static int push(lua_State* L, const char* str, std::size_t len) { + return push_sized(L, str, len); + } }; template @@ -377,8 +385,6 @@ namespace sol { } }; - - #if 0 template<>