180 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Lua
		
	
			
		
		
	
	
			180 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Lua
		
	
--------------------------------------------------------------------------------
 | 
						|
--      Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com
 | 
						|
--      All rights reserved.
 | 
						|
--      Use, modification and distribution are subject to the "MIT License"
 | 
						|
--------------------------------------------------------------------------------
 | 
						|
local setmetatable = setmetatable
 | 
						|
 | 
						|
local list = {}
 | 
						|
list.__index = list
 | 
						|
 | 
						|
function list:new()
 | 
						|
	local t = {length = 0, _prev = 0, _next = 0}
 | 
						|
	t._prev = t
 | 
						|
	t._next = t
 | 
						|
	return setmetatable(t, list)
 | 
						|
end
 | 
						|
 | 
						|
function list:clear()
 | 
						|
	self._next = self
 | 
						|
	self._prev = self
 | 
						|
	self.length = 0
 | 
						|
end
 | 
						|
 | 
						|
function list:push(value)
 | 
						|
	--assert(value)
 | 
						|
	local node = {value = value, _prev = 0, _next = 0, removed = false}
 | 
						|
 | 
						|
	self._prev._next = node
 | 
						|
	node._next = self
 | 
						|
	node._prev = self._prev
 | 
						|
	self._prev = node
 | 
						|
 | 
						|
	self.length = self.length + 1
 | 
						|
	return node
 | 
						|
end
 | 
						|
 | 
						|
function list:pushnode(node)
 | 
						|
	if not node.removed then return end
 | 
						|
 | 
						|
	self._prev._next = node
 | 
						|
	node._next = self
 | 
						|
	node._prev = self._prev
 | 
						|
	self._prev = node
 | 
						|
	node.removed = false
 | 
						|
	self.length = self.length + 1
 | 
						|
end
 | 
						|
 | 
						|
function list:pop()
 | 
						|
	local _prev = self._prev
 | 
						|
	self:remove(_prev)
 | 
						|
	return _prev.value
 | 
						|
end
 | 
						|
 | 
						|
function list:unshift(v)
 | 
						|
	local node = {value = v, _prev = 0, _next = 0, removed = false}
 | 
						|
 | 
						|
	self._next._prev = node
 | 
						|
	node._prev = self
 | 
						|
	node._next = self._next
 | 
						|
	self._next = node
 | 
						|
 | 
						|
	self.length = self.length + 1
 | 
						|
	return node
 | 
						|
end
 | 
						|
 | 
						|
function list:shift()
 | 
						|
	local _next = self._next
 | 
						|
	self:remove(_next)
 | 
						|
	return _next.value
 | 
						|
end
 | 
						|
 | 
						|
function list:remove(iter)
 | 
						|
	if iter.removed then return end
 | 
						|
 | 
						|
	local _prev = iter._prev
 | 
						|
	local _next = iter._next
 | 
						|
	_next._prev = _prev
 | 
						|
	_prev._next = _next
 | 
						|
	
 | 
						|
	self.length = math.max(0, self.length - 1)
 | 
						|
	iter.removed = true
 | 
						|
end
 | 
						|
 | 
						|
function list:find(v, iter)
 | 
						|
	iter = iter or self
 | 
						|
 | 
						|
	repeat
 | 
						|
		if v == iter.value then
 | 
						|
			return iter
 | 
						|
		else
 | 
						|
			iter = iter._next
 | 
						|
		end		
 | 
						|
	until iter == self
 | 
						|
 | 
						|
	return nil
 | 
						|
end
 | 
						|
 | 
						|
function list:findlast(v, iter)
 | 
						|
	iter = iter or self
 | 
						|
 | 
						|
	repeat
 | 
						|
		if v == iter.value then
 | 
						|
			return iter
 | 
						|
		end
 | 
						|
 | 
						|
		iter = iter._prev
 | 
						|
	until iter == self
 | 
						|
 | 
						|
	return nil
 | 
						|
end
 | 
						|
 | 
						|
function list:next(iter)
 | 
						|
	local _next = iter._next
 | 
						|
	if _next ~= self then
 | 
						|
		return _next, _next.value
 | 
						|
	end
 | 
						|
 | 
						|
	return nil
 | 
						|
end
 | 
						|
 | 
						|
function list:prev(iter)
 | 
						|
	local _prev = iter._prev
 | 
						|
	if _prev ~= self then
 | 
						|
		return _prev, _prev.value
 | 
						|
	end
 | 
						|
 | 
						|
	return nil
 | 
						|
end
 | 
						|
 | 
						|
function list:erase(v)
 | 
						|
	local iter = self:find(v)
 | 
						|
 | 
						|
	if iter then
 | 
						|
		self:remove(iter)		
 | 
						|
	end
 | 
						|
end
 | 
						|
 | 
						|
function list:insert(v, iter)	
 | 
						|
	if not iter then
 | 
						|
		return self:push(v)
 | 
						|
	end
 | 
						|
 | 
						|
	local node = {value = v, _next = 0, _prev = 0, removed = false}
 | 
						|
 | 
						|
	if iter._next then
 | 
						|
		iter._next._prev = node
 | 
						|
		node._next = iter._next
 | 
						|
	else
 | 
						|
		self.last = node
 | 
						|
	end
 | 
						|
 | 
						|
	node._prev = iter
 | 
						|
	iter._next = node
 | 
						|
	self.length = self.length + 1
 | 
						|
	return node
 | 
						|
end
 | 
						|
 | 
						|
function list:head()
 | 
						|
	return self._next.value
 | 
						|
end
 | 
						|
 | 
						|
function list:tail()
 | 
						|
	return self._prev.value
 | 
						|
end
 | 
						|
 | 
						|
function list:clone()
 | 
						|
	local t = list:new()
 | 
						|
 | 
						|
	for i, v in list.next, self, self do
 | 
						|
		t:push(v)
 | 
						|
	end
 | 
						|
 | 
						|
	return t
 | 
						|
end
 | 
						|
 | 
						|
ilist = function(_list) return list.next, _list, _list end
 | 
						|
rilist = function(_list) return list.prev, _list, _list end
 | 
						|
 | 
						|
setmetatable(list, {__call = list.new})
 | 
						|
return list |