diff --git a/src/cpp/lua-module.cpp b/src/cpp/lua-module.cpp index 8a95eb8..1f0e008 100644 --- a/src/cpp/lua-module.cpp +++ b/src/cpp/lua-module.cpp @@ -119,6 +119,7 @@ int luaopen_effil(lua_State* L) { "type", getLuaTypename, "pairs", SharedTable::globalLuaPairs, "ipairs", SharedTable::globalLuaIPairs, + "next", SharedTable::globalLuaNext, "size", luaSize, "dump", luaDump, "hardware_threads", std::thread::hardware_concurrency, diff --git a/src/cpp/shared-table.cpp b/src/cpp/shared-table.cpp index 89a3674..f1ed309 100644 --- a/src/cpp/shared-table.cpp +++ b/src/cpp/shared-table.cpp @@ -241,7 +241,7 @@ sol::object SharedTable::luaLength(sol::this_state state) { return sol::make_object(state, len); } -SharedTable::PairsIterator SharedTable::getNext(const sol::object& key, sol::this_state lua) { +SharedTable::PairsIterator SharedTable::getNext(const sol::object& key, sol::this_state lua) const { SharedLock g(ctx_->lock); if (key) { auto obj = createStoredObject(key); @@ -349,6 +349,13 @@ SharedTable::PairsIterator SharedTable::globalLuaIPairs(sol::this_state state, c return tbl.luaIPairs(state); } +SharedTable::PairsIterator SharedTable::globalLuaNext(sol::this_state state, const sol::stack_object& obj, const sol::stack_object& key) { + REQUIRE(isSharedTable(obj)) << "bad argument #1 to 'effil.next' (effil.table expected, got " << luaTypename(obj) << ")"; + const auto& tbl = obj.as(); + return tbl.getNext(key, state); +} + + #undef DEFFINE_METAMETHOD_CALL_0 #undef DEFFINE_METAMETHOD_CALL #undef PROXY_METAMETHOD_IMPL diff --git a/src/cpp/shared-table.h b/src/cpp/shared-table.h index 267cde5..1fc6fde 100644 --- a/src/cpp/shared-table.h +++ b/src/cpp/shared-table.h @@ -68,9 +68,10 @@ public: static size_t luaSize(const sol::stack_object& tbl); static PairsIterator globalLuaPairs(sol::this_state state, const sol::stack_object& obj); static PairsIterator globalLuaIPairs(sol::this_state state, const sol::stack_object& obj); + static PairsIterator globalLuaNext(sol::this_state state, const sol::stack_object& obj, const sol::stack_object& key); private: - PairsIterator getNext(const sol::object& key, sol::this_state lua); + PairsIterator getNext(const sol::object& key, sol::this_state lua) const; private: SharedTable() = default; diff --git a/tests/lua/metatable.lua b/tests/lua/metatable.lua index a372701..c5f7e79 100644 --- a/tests/lua/metatable.lua +++ b/tests/lua/metatable.lua @@ -181,3 +181,16 @@ test.shared_table_with_metatable.as_shared_table = function() share.table_key = "table_value" test.equal(share.table_key, "mt_table_value") end + +test.shared_table_with_metatable.next_iterator = function() + local visited = {a = 1, [2] = 3, [true] = "asd", [2.2] = "qwe"} + local share = effil.table(visited) + + local key, value = effil.next(share) + while key do + test.equal(visited[key], value) + visited[key] = nil + key, value = effil.next(share, key) + end + test.is_true(next(visited) == nil) -- table is empty +end