---@type Tinkr local Tinkr, ---@class Bastion Bastion = ... ---@class Bastion.List: { _list: I[] } ---@operator add(any): Bastion.List ---@operator sub(any): Bastion.List local List = { -- Add overload ---@param self Bastion.List ---@generic I ---@param value I ---@return Bastion.List __add = function(self, value) self:push(value) return self end, -- Subtract overload ---@param self Bastion.List ---@generic I ---@param value I ---@return Bastion.List __sub = function(self, value) self:remove(value) return self end, } List.__index = List ---@generic I : table ---@param from? I[] ---@return Bastion.List | Bastion.List function List:New(from) local self = setmetatable({}, List) self._list = from or {} return self end ---@param value any function List:push(value) table.insert(self._list, value) end ---@return any function List:pop() return table.remove(self._list) end ---@return any function List:peek() return self._list[#self._list] end ---@return number function List:count() return #self._list end ---@return nil function List:clear() self._list = {} end ---@generic I : any ---@param value I ---@return boolean function List:contains(value) for _, v in ipairs(self._list) do if v == value then return true end end return false end ---@generic I : any ---@param value I ---@return boolean function List:remove(value) for i, v in ipairs(self._list) do if v == value then table.remove(self._list, i) return true end end return false end ---@generic I : any ---@param callback fun(value: I): boolean function List:each(callback) for _, v in ipairs(self._list) do if callback(v) then break end end end ---@generic I : any ---@param callback fun(value: I): I ---@return Bastion.List | Bastion.List function List:map(callback) local newList = List:New() for _, v in ipairs(self._list) do newList:push(callback(v)) end return newList end ---@generic I : any ---@param callback fun(value: I): boolean ---@return Bastion.List | Bastion.List function List:filter(callback) local newList = List:New() for _, v in ipairs(self._list) do if callback(v) then newList:push(v) end end return newList end ---@generic R : any ---@generic V : any ---@param callback fun(result: R, value: V): R, boolean? ---@param initialValue R ---@return R function List:reduce(callback, initialValue) local result = initialValue local done = false for _, v in ipairs(self._list) do result, done = callback(result, v) if done then break end end return result end ---@generic I ---@param callback fun(value: I): boolean ---@return I function List:find(callback) for _, v in ipairs(self._list) do if callback(v) then return v end end return nil end ---@generic I ---@param callback fun(value: I): boolean ---@return number | nil function List:findIndex(callback) for i, v in ipairs(self._list) do if callback(v) then return i end end return nil end ---@generic I : any ---@param callback fun(a: I, b: I): boolean ---@return nil function List:sort(callback) table.sort(self._list, callback) end function List:reverse() local newList = List:New() for i = #self._list, 1, -1 do newList:push(self._list[i]) end return newList end function List:clone() local newList = List:New() for _, v in ipairs(self._list) do newList:push(v) end return newList end ---@param list Bastion.List function List:concat(list) local newList = List:New() for _, v in ipairs(self._list) do newList:push(v) end for _, v in ipairs(list._list) do newList:push(v) end return newList end ---@param separator string ---@return string function List:join(separator) local result = "" for i, v in ipairs(self._list) do result = result .. v if i < #self._list then result = result .. separator end end return result end ---@return string function List:toString() return self:join(", ") end ---@return string function List:__tostring() return self:toString() end Bastion.List = List