local doc = require "wslua.doc" local fndef = require "wslua.fndef" local ty = require "wslua.ty" local list = require "wslua.list" local table = setmetatable({}, {__index = table}) doc.module{ name = "wslua.table", what = "Additional table functionality", descr = "This module also contains all functions from the default `table` library, and can be used as a drop-in replacement.", see = { {module = "wslua.list"}, } } table.count = fndef({ name = "table.cont", what = "Get number of key-value pairs in the table.", descr = "O(n)", args = { {name = "tbl", type = ty.table}, }, ret = { {type = ty.number}, }, tests = { function() return 0, table.count{} end, function() return 1, table.count{1} end, function() return 1, table.count{a = 1} end, function() return 2, table.count{a = 1, 1} end, }, }, function(tbl) local ret = 0 for _, __ in pairs(tbl) do ret = ret + 1 end return ret end) table.deepcpy = fndef({ name = "table.deepcpy", what = "Returns a recursive copy of `t`.", descr = "Also assigns the metatable of `t` to the result, if it exists.", args = { {name = "t", type = ty.table}, }, ret = { {type = ty.table}, }, }, function(t) local ret = {} for k, v in pairs(t) do ret[k] = type(v) == "table" and table.deepcpy(v) or v end return setmetatable(ret, getmetatable(t)) end) table.flatcpy = fndef({ name = "table.flatcpy", what = "Returns a flat copy of `t`.", descr = "Also assigns the metatable of `t` to the result, if it exists.", args = { {name = "t", type = ty.table}, }, ret = { {type = ty.table}, }, }, function(t) local ret = {} for k, v in pairs(t) do ret[k] = v end return setmetatable(ret, getmetatable(t)) end) doc.todo "tests for flatcpy and deepcpy" table.keys = fndef({ name = "table.keys", what = "Get a list of all keys in the table.", args = { {name = "tbl", type = ty.table}, }, ret = { {type = ty.class(list)}, }, tests = { function() return "{}", table.keys{}:sort():__tostring() end, function() return "{a, b}", table.keys{a = 1, b = 2}:sort():__tostring() end, function() return "{1, 2}", table.keys{3, 4}:sort():__tostring() end, }, }, function(tbl) local ret = list() for k, _ in pairs(tbl) do ret:insert(k) end return ret end) table.update = fndef({ name = "table.update", what = "Update entries in a table from another table.", args = { {name = "t1", type = ty.table, what = "Table to be updated."}, {name = "t2", type = ty.table, what = "Table to take updated key-value pairs from."}, }, ret = { {type = ty.table, what = "Updated `t1`."}, }, }, function(t1, t2) for k, v in pairs(t2) do t1[k] = v end return t1 end) table.values = fndef({ name = "table.values", what = "Get a list of all values in the table.", args = { {name = "tbl", type = ty.table}, }, ret = { {type = ty.class(list)}, }, tests = { function() return "{}", table.values{}:sort():__tostring() end, function() return "{1, 2}", table.values{a = 1, b = 2}:sort():__tostring() end, function() return "{3, 4}", table.values{3, 4}:sort():__tostring() end, }, }, function(tbl) local ret = list() for _, v in pairs(tbl) do ret:insert(v) end return ret end) return table