|
|
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
|