From 30c7e40f081d5f61c97b0477c20f8320cb915912 Mon Sep 17 00:00:00 2001 From: ThePhD Date: Wed, 6 Sep 2017 16:50:27 -0400 Subject: [PATCH] ipairs for array types too --- single/sol/sol.hpp | 250 +++++++++++++++++++++++++++++---------- sol/container_traits.hpp | 4 + 2 files changed, 193 insertions(+), 61 deletions(-) diff --git a/single/sol/sol.hpp b/single/sol/sol.hpp index ea40c3f5..e36e286c 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-09-06 03:05:33.019474 UTC -// This header was generated with sol v2.18.2 (revision fc91147) +// Generated 2017-09-06 20:49:28.612590 UTC +// This header was generated with sol v2.18.2 (revision fbdc5d9) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -4527,6 +4527,7 @@ namespace sol { bitwise_or, bitwise_xor, pairs, + ipairs, next, type, type_info, @@ -4534,8 +4535,8 @@ namespace sol { typedef meta_function meta_method; - inline const std::array& meta_function_names() { - static const std::array names = { { + inline const std::array& meta_function_names() { + static const std::array names = { { "new", "__index", "__newindex", @@ -4566,6 +4567,7 @@ namespace sol { "__bxor", "__pairs", + "__ipairs", "__next", "__type", "__typeinfo" @@ -8910,6 +8912,8 @@ namespace sol { namespace sol { namespace detail { + using typical_chunk_name_t = char[32]; + inline const std::string& default_chunk_name() { static const std::string name = ""; return name; @@ -9085,7 +9089,7 @@ namespace sol { } inline void script(lua_State* L, const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) { - char basechunkname[17] = {}; + detail::typical_chunk_name_t basechunkname = {}; const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname); if (luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) { lua_error(L); @@ -13042,6 +13046,19 @@ namespace sol { static const bool value = sizeof(test(0)) == sizeof(char); }; + template + struct has_traits_ipairs_test { + private: + typedef std::array one; + typedef std::array two; + + template static one test(decltype(&C::ipairs)); + template static two test(...); + + public: + static const bool value = sizeof(test(0)) == sizeof(char); + }; + template struct has_traits_add_test { private: @@ -13085,6 +13102,9 @@ namespace sol { template using has_traits_pairs = meta::boolean::value>; + template + using has_traits_ipairs = meta::boolean::value>; + template using has_traits_add = meta::boolean::value>; @@ -13201,6 +13221,10 @@ namespace sol { return luaL_error(L, "sol: cannot call '__pairs' on type '%s': it is not recognized as a container", detail::demangle().c_str()); } + static int ipairs(lua_State* L) { + return luaL_error(L, "sol: cannot call '__ipairs' on type '%s': it is not recognized as a container", detail::demangle().c_str()); + } + static iterator begin(lua_State* L, T&) { luaL_error(L, "sol: cannot call 'being' on type '%s': it is not recognized as a container", detail::demangle().c_str()); return lua_nil; @@ -13253,8 +13277,9 @@ namespace sol { struct iter { T& source; iterator it; + std::size_t i; - iter(T& source, iterator it) : source(source), it(std::move(it)) {} + iter(T& source, iterator it) : source(source), it(std::move(it)), i(0) {} }; static auto& get_src(lua_State* L) { @@ -13735,6 +13760,7 @@ namespace sol { erase_has(has_erase(), L, self, key); } + template static int next_associative(std::true_type, lua_State* L) { iter& i = stack::get>(L, 1); auto& source = i.source; @@ -13743,20 +13769,28 @@ namespace sol { return 0; } int p; - p = stack::push_reference(L, it->first); + if (ip) { + p = stack::push_reference(L, it->first); + } + else { + ++i.i; + p = stack::push_reference(L, i.i); + } p += stack::stack_detail::push_reference(L, detail::deref(it->second)); std::advance(it, 1); return p; } + template static int pairs_associative(std::true_type, lua_State* L) { auto& src = get_src(L); - stack::push(L, next); + stack::push(L, next); stack::push>(L, src, deferred_traits::begin(L, src)); stack::push(L, sol::lua_nil); return 3; } + template static int next_associative(std::false_type, lua_State* L) { iter& i = stack::get>(L, 1); auto& source = i.source; @@ -13772,16 +13806,18 @@ namespace sol { return p; } + template static int pairs_associative(std::false_type, lua_State* L) { auto& src = get_src(L); - stack::push(L, next); + stack::push(L, next); stack::push>(L, src, deferred_traits::begin(L, src)); stack::push(L, 0); return 3; } + template static int next(lua_State* L) { - return next_associative(is_associative(), L); + return next_associative(is_associative(), L); } public: @@ -13861,7 +13897,11 @@ namespace sol { } static int pairs(lua_State* L) { - return pairs_associative(is_associative(), L); + return pairs_associative(is_associative(), L); + } + + static int ipairs(lua_State* L) { + return pairs_associative(is_associative(), L); } }; @@ -13993,6 +14033,10 @@ namespace sol { return 3; } + static int ipairs(lua_State* L) { + return pairs(L); + } + static iterator begin(lua_State*, T& self) { return std::addressof(self[0]); } @@ -14100,6 +14144,18 @@ namespace sol { return real_pairs_traits(container_detail::has_traits_pairs(), L); } + static int real_ipairs_traits(std::true_type, lua_State* L) { + return traits::ipairs(L); + } + + static int real_ipairs_traits(std::false_type, lua_State* L) { + return default_traits::ipairs(L); + } + + static int real_ipairs_call(lua_State* L) { + return real_ipairs_traits(container_detail::has_traits_ipairs(), L); + } + static int real_size_traits(std::true_type, lua_State* L) { return traits::size(L); } @@ -14216,6 +14272,10 @@ namespace sol { return detail::typed_static_trampoline(L); } + static int ipairs_call(lua_State*L) { + return detail::typed_static_trampoline(L); + } + static int get_call(lua_State*L) { return detail::typed_static_trampoline(L); } @@ -14249,7 +14309,7 @@ namespace sol { static const char* metakey = is_shim ? &usertype_traits>>::metatable()[0] : &usertype_traits::metatable()[0]; static const std::array reg = { { { "__pairs", &meta_cumt::pairs_call }, - { "__ipairs", &meta_cumt::pairs_call }, + { "__ipairs", &meta_cumt::ipairs_call }, { "__len", &meta_cumt::length_call }, { "__index", &meta_cumt::index_call }, { "__newindex", &meta_cumt::new_index_call }, @@ -14933,7 +14993,7 @@ namespace sol { void* baseclasscheck; void* baseclasscast; bool secondarymeta; - std::array properties; + std::array properties; template >> = meta::enabler> lua_CFunction make_func() const { @@ -15484,7 +15544,7 @@ namespace sol { void* baseclasscast; bool mustindex; bool secondarymeta; - std::array properties; + std::array properties; template void insert(N&& n, object&& o) { @@ -16109,85 +16169,85 @@ namespace sol { } } - template + template auto tuple_get(types, std::index_sequence<0, 1, I...>, Keys&& keys) const -> decltype(stack::pop>(nullptr)) { typedef decltype(stack::pop>(nullptr)) Tup; return Tup( - traverse_get_optional(meta::is_optional>(), detail::forward_get<0>(keys)), - traverse_get_optional(meta::is_optional>(), detail::forward_get<1>(keys)), - traverse_get_optional(meta::is_optional>(), detail::forward_get(keys))... + traverse_get_optional(meta::is_optional>(), detail::forward_get<0>(keys)), + traverse_get_optional(meta::is_optional>(), detail::forward_get<1>(keys)), + traverse_get_optional(meta::is_optional>(), detail::forward_get(keys))... ); } - template + template decltype(auto) tuple_get(types, std::index_sequence, Keys&& keys) const { - return traverse_get_optional(meta::is_optional>(), detail::forward_get(keys)); + return traverse_get_optional(meta::is_optional>(), detail::forward_get(keys)); } - template + template void tuple_set(std::index_sequence, Pairs&& pairs) { auto pp = stack::push_pop(pairs))...>::value)>(*this); - void(detail::swallow{ (stack::set_field(base_t::lua_state(), + void(detail::swallow{ (stack::set_field(base_t::lua_state(), detail::forward_get(pairs), detail::forward_get(pairs), lua_gettop(base_t::lua_state()) ), 0)... }); } - template + template decltype(auto) traverse_get_deep(Key&& key) const { - stack::get_field(base_t::lua_state(), std::forward(key)); + stack::get_field(base_t::lua_state(), std::forward(key)); return stack::get(base_t::lua_state()); } - template + template decltype(auto) traverse_get_deep(Key&& key, Keys&&... keys) const { - stack::get_field(base_t::lua_state(), std::forward(key)); - return traverse_get_deep(std::forward(keys)...); + stack::get_field(base_t::lua_state(), std::forward(key)); + return traverse_get_deep(std::forward(keys)...); } - template + template decltype(auto) traverse_get_deep_optional(int& popcount, Key&& key) const { typedef decltype(stack::get(base_t::lua_state())) R; - auto p = stack::probe_get_field(base_t::lua_state(), std::forward(key), lua_gettop(base_t::lua_state())); + auto p = stack::probe_get_field(base_t::lua_state(), std::forward(key), lua_gettop(base_t::lua_state())); popcount += p.levels; if (!p.success) return R(nullopt); return stack::get(base_t::lua_state()); } - template + template decltype(auto) traverse_get_deep_optional(int& popcount, Key&& key, Keys&&... keys) const { auto p = I > 0 ? stack::probe_get_field(base_t::lua_state(), std::forward(key), -1) : stack::probe_get_field(base_t::lua_state(), std::forward(key), lua_gettop(base_t::lua_state())); popcount += p.levels; if (!p.success) return T(nullopt); - return traverse_get_deep_optional(popcount, std::forward(keys)...); + return traverse_get_deep_optional(popcount, std::forward(keys)...); } - template + template decltype(auto) traverse_get_optional(std::false_type, Keys&&... keys) const { detail::clean c(base_t::lua_state()); - return traverse_get_deep(std::forward(keys)...); + return traverse_get_deep(std::forward(keys)...); } - template + template decltype(auto) traverse_get_optional(std::true_type, Keys&&... keys) const { int popcount = 0; detail::ref_clean c(base_t::lua_state(), popcount); - return traverse_get_deep_optional(popcount, std::forward(keys)...); + return traverse_get_deep_optional(popcount, std::forward(keys)...); } - template + template void traverse_set_deep(Key&& key, Value&& value) const { - stack::set_field(base_t::lua_state(), std::forward(key), std::forward(value)); + stack::set_field(base_t::lua_state(), std::forward(key), std::forward(value)); } - template + template void traverse_set_deep(Key&& key, Keys&&... keys) const { - stack::get_field(base_t::lua_state(), std::forward(key)); - traverse_set_deep(std::forward(keys)...); + stack::get_field(base_t::lua_state(), std::forward(key)); + traverse_set_deep(std::forward(keys)...); } basic_table_core(lua_State* L, detail::global_tag t) noexcept : base_t(L, t) { } @@ -16260,7 +16320,7 @@ namespace sol { decltype(auto) get(Keys&&... keys) const { static_assert(sizeof...(Keys) == sizeof...(Ret), "number of keys and number of return types do not match"); auto pp = stack::push_pop::value>(*this); - return tuple_get(types(), std::make_index_sequence(), std::forward_as_tuple(std::forward(keys)...)); + return tuple_get(types(), std::make_index_sequence(), std::forward_as_tuple(std::forward(keys)...)); } template @@ -16285,20 +16345,66 @@ namespace sol { template decltype(auto) traverse_get(Keys&&... keys) const { auto pp = stack::push_pop::value>(*this); - return traverse_get_optional(meta::is_optional>(), std::forward(keys)...); + return traverse_get_optional(meta::is_optional>(), std::forward(keys)...); } template basic_table_core& traverse_set(Keys&&... keys) { auto pp = stack::push_pop::value>(*this); auto pn = stack::pop_n(base_t::lua_state(), static_cast(sizeof...(Keys)-2)); - traverse_set_deep(std::forward(keys)...); + traverse_set_deep(std::forward(keys)...); return *this; } template basic_table_core& set(Args&&... args) { - tuple_set(std::make_index_sequence(), std::forward_as_tuple(std::forward(args)...)); + tuple_set(std::make_index_sequence(), std::forward_as_tuple(std::forward(args)...)); + return *this; + } + + template + decltype(auto) raw_get(Keys&&... keys) const { + static_assert(sizeof...(Keys) == sizeof...(Ret), "number of keys and number of return types do not match"); + auto pp = stack::push_pop::value>(*this); + return tuple_get(types(), std::make_index_sequence(), std::forward_as_tuple(std::forward(keys)...)); + } + + template + decltype(auto) raw_get_or(Key&& key, T&& otherwise) const { + typedef decltype(raw_get("")) U; + optional option = raw_get>(std::forward(key)); + if (option) { + return static_cast(option.value()); + } + return static_cast(std::forward(otherwise)); + } + + template + decltype(auto) raw_get_or(Key&& key, D&& otherwise) const { + optional option = raw_get>(std::forward(key)); + if (option) { + return static_cast(option.value()); + } + return static_cast(std::forward(otherwise)); + } + + template + decltype(auto) traverse_raw_get(Keys&&... keys) const { + auto pp = stack::push_pop::value>(*this); + return traverse_get_optional(meta::is_optional>(), std::forward(keys)...); + } + + template + basic_table_core& traverse_raw_set(Keys&&... keys) { + auto pp = stack::push_pop::value>(*this); + auto pn = stack::pop_n(base_t::lua_state(), static_cast(sizeof...(Keys)-2)); + traverse_set_deep(std::forward(keys)...); + return *this; + } + + template + basic_table_core& raw_set(Args&&... args) { + tuple_set(std::make_index_sequence(), std::forward_as_tuple(std::forward(args)...)); return *this; } @@ -16371,20 +16477,40 @@ namespace sol { } template - basic_table_core& new_enum(const std::string& name, Args&&... args) { + table new_enum(const string_view& name, Args&&... args) { + table target = create_with(std::forward(args)...); if (read_only) { - table idx = create_with(std::forward(args)...); table x = create_with( meta_function::new_index, detail::fail_on_newindex, - meta_function::index, idx + meta_function::index, target ); - table target = create_named(name); - target[metatable_key] = x; + table shim = create_named(name, metatable_key, x); + return shim; } else { - create_named(name, std::forward(args)...); + set(name, target); + return target; + } + } + + template + table new_enum(const string_view& name, std::initializer_list> items) { + table target = create(items.size(), 0); + for (const auto& kvp : items) { + target.set(kvp.first, kvp.second); + } + if (read_only) { + table x = create_with( + meta_function::new_index, detail::fail_on_newindex, + meta_function::index, target + ); + table shim = create_named(name, metatable_key, x); + return shim; + } + else { + set(name, target); + return target; } - return *this; } template @@ -16515,11 +16641,7 @@ namespace sol { template table create_named(Name&& name, Args&&... args) { static const int narr = static_cast(meta::count_2_for_pack::value); - return create(std::forward(name), narr, sizeof...(Args) / 2 - narr, std::forward(args)...); - } - - ~basic_table_core() { - + return create(std::forward(name), narr, (sizeof...(Args) / 2) - narr, std::forward(args)...); } }; } // sol @@ -17076,7 +17198,7 @@ namespace sol { template protected_function_result do_string(const string_view& code, const basic_environment& env, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) { - char basechunkname[17] = {}; + detail::typical_chunk_name_t basechunkname = {}; const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname); load_status x = static_cast(luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str())); if (x != load_status::ok) { @@ -17099,7 +17221,7 @@ namespace sol { } protected_function_result do_string(const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) { - char basechunkname[17] = {}; + detail::typical_chunk_name_t basechunkname = {}; const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname); load_status x = static_cast(luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str())); if (x != load_status::ok) { @@ -17174,7 +17296,7 @@ namespace sol { template function_result unsafe_script(const string_view& code, const sol::basic_environment& env, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) { - char basechunkname[17] = {}; + detail::typical_chunk_name_t basechunkname = {}; const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname); int index = lua_gettop(L); if (luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str())) { @@ -17266,7 +17388,7 @@ namespace sol { } #endif load_result load(const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) { - char basechunkname[17] = {}; + detail::typical_chunk_name_t basechunkname = {}; const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname); load_status x = static_cast(luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str())); return load_result(L, absolute_index(L, -1), 1, 1, x); @@ -17282,7 +17404,7 @@ namespace sol { } load_result load(lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) { - char basechunkname[17] = {}; + detail::typical_chunk_name_t basechunkname = {}; const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname); #if SOL_LUA_VERSION > 501 load_status x = static_cast(lua_load(L, reader, data, chunknametarget, to_string(mode).c_str())); @@ -17437,6 +17559,12 @@ namespace sol { return *this; } + template + state_view& new_enum(const std::string& name, std::initializer_list> items) { + global.new_enum(name, std::move(items)); + return *this; + } + template void for_each(Fx&& fx) { global.for_each(std::forward(fx)); diff --git a/sol/container_traits.hpp b/sol/container_traits.hpp index aaf0df7d..b58c6e65 100644 --- a/sol/container_traits.hpp +++ b/sol/container_traits.hpp @@ -1233,6 +1233,10 @@ namespace sol { return 3; } + static int ipairs(lua_State* L) { + return pairs(L); + } + static iterator begin(lua_State*, T& self) { return std::addressof(self[0]); }