mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Add table.copy_with_metatables
(#15754)
This commit is contained in:
parent
8717c7bd00
commit
077828d0d9
4 changed files with 63 additions and 10 deletions
|
@ -22,7 +22,7 @@ read_globals = {
|
||||||
"PerlinNoise", "PerlinNoiseMap",
|
"PerlinNoise", "PerlinNoiseMap",
|
||||||
|
|
||||||
string = {fields = {"split", "trim"}},
|
string = {fields = {"split", "trim"}},
|
||||||
table = {fields = {"copy", "getn", "indexof", "keyof", "insert_all"}},
|
table = {fields = {"copy", "copy_with_metatables", "getn", "indexof", "keyof", "insert_all"}},
|
||||||
math = {fields = {"hypot", "round"}},
|
math = {fields = {"hypot", "round"}},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -457,18 +457,37 @@ do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
function table.copy(t, seen)
|
local function table_copy(value, preserve_metatables)
|
||||||
local n = {}
|
local seen = {}
|
||||||
seen = seen or {}
|
local function copy(val)
|
||||||
seen[t] = n
|
if type(val) ~= "table" then
|
||||||
for k, v in pairs(t) do
|
return val
|
||||||
n[(type(k) == "table" and (seen[k] or table.copy(k, seen))) or k] =
|
end
|
||||||
(type(v) == "table" and (seen[v] or table.copy(v, seen))) or v
|
local t = val
|
||||||
|
if seen[t] then
|
||||||
|
return seen[t]
|
||||||
|
end
|
||||||
|
local res = {}
|
||||||
|
seen[t] = res
|
||||||
|
for k, v in pairs(t) do
|
||||||
|
res[copy(k)] = copy(v)
|
||||||
|
end
|
||||||
|
if preserve_metatables then
|
||||||
|
setmetatable(res, getmetatable(t))
|
||||||
|
end
|
||||||
|
return res
|
||||||
end
|
end
|
||||||
return n
|
return copy(value)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function table.copy(value)
|
||||||
|
return table_copy(value, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
function table.copy_with_metatables(value)
|
||||||
|
return table_copy(value, true)
|
||||||
|
end
|
||||||
|
|
||||||
function table.insert_all(t, other)
|
function table.insert_all(t, other)
|
||||||
if table.move then -- LuaJIT
|
if table.move then -- LuaJIT
|
||||||
|
|
|
@ -178,6 +178,35 @@ describe("table", function()
|
||||||
assert.equal(2, table.keyof({[2] = "foo", [3] = "bar"}, "foo"))
|
assert.equal(2, table.keyof({[2] = "foo", [3] = "bar"}, "foo"))
|
||||||
assert.equal(3, table.keyof({[1] = "foo", [3] = "bar"}, "bar"))
|
assert.equal(3, table.keyof({[1] = "foo", [3] = "bar"}, "bar"))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
describe("copy()", function()
|
||||||
|
it("strips metatables", function()
|
||||||
|
local v = vector.new(1, 2, 3)
|
||||||
|
local w = table.copy(v)
|
||||||
|
assert.are_not.equal(v, w)
|
||||||
|
assert.same(v, w)
|
||||||
|
assert.equal(nil, getmetatable(w))
|
||||||
|
end)
|
||||||
|
it("preserves referential structure", function()
|
||||||
|
local t = {{}, {}}
|
||||||
|
t[1][1] = t[2]
|
||||||
|
t[2][1] = t[1]
|
||||||
|
local copy = table.copy(t)
|
||||||
|
assert.same(t, copy)
|
||||||
|
assert.equal(copy[1][1], copy[2])
|
||||||
|
assert.equal(copy[2][1], copy[1])
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe("copy_with_metatables()", function()
|
||||||
|
it("preserves metatables", function()
|
||||||
|
local v = vector.new(1, 2, 3)
|
||||||
|
local w = table.copy_with_metatables(v)
|
||||||
|
assert.equal(getmetatable(v), getmetatable(w))
|
||||||
|
assert(vector.check(w))
|
||||||
|
assert.equal(v, w) -- vector overrides ==
|
||||||
|
end)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe("formspec_escape", function()
|
describe("formspec_escape", function()
|
||||||
|
|
|
@ -4142,6 +4142,11 @@ Helper functions
|
||||||
* returns time with microsecond precision. May not return wall time.
|
* returns time with microsecond precision. May not return wall time.
|
||||||
* `table.copy(table)`: returns a table
|
* `table.copy(table)`: returns a table
|
||||||
* returns a deep copy of `table`
|
* returns a deep copy of `table`
|
||||||
|
* strips metatables, but this may change in the future
|
||||||
|
* `table.copy_with_metatables(table)`
|
||||||
|
* since 5.12
|
||||||
|
* `table` can also be non-table value, which will be returned as-is
|
||||||
|
* preserves metatables as they are
|
||||||
* `table.indexof(list, val)`: returns the smallest numerical index containing
|
* `table.indexof(list, val)`: returns the smallest numerical index containing
|
||||||
the value `val` in the table `list`. Non-numerical indices are ignored.
|
the value `val` in the table `list`. Non-numerical indices are ignored.
|
||||||
If `val` could not be found, `-1` is returned. `list` must not have
|
If `val` could not be found, `-1` is returned. `list` must not have
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue