diff --git a/func.lua b/func.lua index da9d601..a2c1a54 100644 --- a/func.lua +++ b/func.lua @@ -49,18 +49,6 @@ function memoize(func) }) end --- Does not use select magic, stops at the first nil value -function aggregate(binary_func, total, ...) - if total == nil then return end - local function _aggregate(value, ...) - if value == nil then return end - total = binary_func(total, value) - return _aggregate(...) - end - _aggregate(...) - return total -end - function override_chain(func, override) return function(...) func(...) diff --git a/init.lua b/init.lua index 7ee18ff..755e9d2 100644 --- a/init.lua +++ b/init.lua @@ -43,6 +43,7 @@ for _, file in pairs{ "iterator", "math", "table", + "vararg", "text", "vector", "quaternion", diff --git a/vararg.lua b/vararg.lua new file mode 100644 index 0000000..86c5a68 --- /dev/null +++ b/vararg.lua @@ -0,0 +1,64 @@ +local select, setmetatable, unpack = select, setmetatable, unpack + +local vararg = {} + +function vararg.aggregate(binary_func, initial, ...) + local total = initial + for i = 1, select("#", ...) do + total = binary_func(total, select(i, ...)) + end + return total +end + +local metatable = {__index = {}} + +function vararg.pack(...) + return setmetatable({["#"] = select("#", ...); ...}, metatable) +end + +local va = metatable.__index + +function va:unpack() + return unpack(self, 1, self["#"]) +end + +function va:select(n) + if n > self["#"] then return end + return self[n] +end + +local function inext(self, i) + i = i + 1 + if i > self["#"] then return end + return i, self[i] +end + +function va:ipairs() + return inext, self, 0 +end + +function va:concat(other) + local self_len, other_len = self["#"], other["#"] + local res = {["#"] = self_len + other_len} + for i = 1, self_len do + res[i] = self[i] + end + for i = 1, other_len do + res[self_len + i] = other[i] + end + return setmetatable(res, metatable) +end +metatable.__concat = va.concat + +function va:equals(other) + if self["#"] ~= other["#"] then return false end + for i = 1, self["#"] do if self[i] ~= other[i] then return false end end + return true +end +metatable.__eq = va.equals + +function va:aggregate(binary_func, initial) + return vararg.aggregate(binary_func, initial, self:unpack()) +end + +return vararg \ No newline at end of file