local setmetatable = setmetatable local assert = assert local list = {} list.__index = list function list:new() return setmetatable({length = 0}, self) end setmetatable(list, {__call = list.new}) function list:clear() self.length = 0 self.first = nil self.last = nil end function list:push(v) local t = {value = v} if self.last then self.last._next = t t._prev = self.last self.last = t else self.first = t self.last = t end self.length = self.length + 1 end function list:pop() if not self.last then return end local t = self.last if t._prev then t._prev._next = nil self.last = t._prev t._prev = nil else self.first = nil self.last = nil end self.length = self.length - 1 return t.value end function list:unshift(v) local t = {value = v} if self.first then self.first._prev = t t._next = self.first self.first = t else self.first = t self.last = t end self.length = self.length + 1 end function list:shift() if not self.first then return end local t = self.first if t._next then t._next._prev = nil self.first = t._next t._next = nil else self.first = nil self.last = nil end self.length = self.length - 1 return t.value end function list:remove(iter) if iter._next then if iter._prev then iter._next._prev = iter._prev iter._prev._next = iter._next else assert(iter == self.first) iter._next._prev = nil self.first = iter._next end elseif iter._prev then assert(iter == self.last) iter._prev._next = nil self.last = iter._prev else assert(iter == self.first and iter == self.last) self.first = nil self.last = nil end self.length = self.length - 1 return iter end function list:find(v, iter) if iter == nil then iter = self.first end while iter do if v == iter.value then return iter end iter = iter._next end return nil end function list:findlast(v, iter) if iter == nil then iter = self.last end while iter do if v == iter.value then return iter end iter = iter._prev end return nil end function list:next(iter) if iter then if iter._next ~= nil then return iter._next, iter._next.value end elseif self.first then return self.first, self.first.value end return nil end function list:items() return self.next, self end function list:prev(iter) if iter then if iter._prev ~= nil then return iter._prev, iter._prev.value end elseif self.last then return self.last, self.last.value end return nil end function list:reverse_items() return self.prev, self end function list:erase(value) local iter = self:find(value) if iter then self:remove(iter) end end function list:insert(v, iter) assert(v) if not iter then return self:push(value) end local t = {value = v} if iter._next then iter._next._prev = t t._next = iter._next else self.last = t end t._prev = iter iter._next = t self.length = self.length + 1 end function list:head() if self.first ~= nil then return self.first.value end return nil end function list:tail() if self.last ~= nil then return self.last.value end return nil end function list:clone() local t = list:New() for item in self.items() do t:push(item.value) end return t end ilist = list.items -- rilist = list.reverse_items return list