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
							 |