165 lines
4.6 KiB
Lua
Executable File
165 lines
4.6 KiB
Lua
Executable File
--------------------------------------------------------------------------------
|
|
---------------------- ## ##### ##### ###### -----------------------
|
|
---------------------- ## ## ## ## ## ## ## -----------------------
|
|
---------------------- ## ## ## ## ## ###### -----------------------
|
|
---------------------- ## ## ## ## ## ## -----------------------
|
|
---------------------- ###### ##### ##### ## -----------------------
|
|
---------------------- -----------------------
|
|
----------------------- Lua Object-Oriented Programming ------------------------
|
|
--------------------------------------------------------------------------------
|
|
-- Project: LOOP Class Library --
|
|
-- Release: 2.3 beta --
|
|
-- Title : Ordered Set Optimized for Insertions and Removals --
|
|
-- Author : Renato Maia <maia@inf.puc-rio.br> --
|
|
--------------------------------------------------------------------------------
|
|
-- Notes: --
|
|
-- Storage of strings equal to the name of one method prevents its usage. --
|
|
--------------------------------------------------------------------------------
|
|
|
|
local oo = require "loop.base"
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- key constants ---------------------------------------------------------------
|
|
--------------------------------------------------------------------------------
|
|
|
|
local FIRST = newproxy()
|
|
local LAST = newproxy()
|
|
|
|
module("loop.collection.OrderedSet", oo.class)
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- basic functionality ---------------------------------------------------------
|
|
--------------------------------------------------------------------------------
|
|
|
|
local function iterator(self, previous)
|
|
return self[previous], previous
|
|
end
|
|
|
|
function sequence(self)
|
|
return iterator, self, FIRST
|
|
end
|
|
|
|
function contains(self, element)
|
|
return element ~= nil and (self[element] ~= nil or element == self[LAST])
|
|
end
|
|
|
|
function first(self)
|
|
return self[FIRST]
|
|
end
|
|
|
|
function last(self)
|
|
return self[LAST]
|
|
end
|
|
|
|
function empty(self)
|
|
return self[FIRST] == nil
|
|
end
|
|
|
|
function insert(self, element, previous)
|
|
if element ~= nil and not contains(self, element) then
|
|
if previous == nil then
|
|
previous = self[LAST]
|
|
if previous == nil then
|
|
previous = FIRST
|
|
end
|
|
elseif not contains(self, previous) and previous ~= FIRST then
|
|
return
|
|
end
|
|
if self[previous] == nil
|
|
then self[LAST] = element
|
|
else self[element] = self[previous]
|
|
end
|
|
self[previous] = element
|
|
return element
|
|
end
|
|
end
|
|
|
|
function previous(self, element, start)
|
|
if contains(self, element) then
|
|
local previous = (start == nil and FIRST or start)
|
|
repeat
|
|
if self[previous] == element then
|
|
return previous
|
|
end
|
|
previous = self[previous]
|
|
until previous == nil
|
|
end
|
|
end
|
|
|
|
function remove(self, element, start)
|
|
local prev = previous(self, element, start)
|
|
if prev ~= nil then
|
|
self[prev] = self[element]
|
|
if self[LAST] == element
|
|
then self[LAST] = prev
|
|
else self[element] = nil
|
|
end
|
|
return element, prev
|
|
end
|
|
end
|
|
|
|
function replace(self, old, new, start)
|
|
local prev = previous(self, old, start)
|
|
if prev ~= nil and new ~= nil and not contains(self, new) then
|
|
self[prev] = new
|
|
self[new] = self[old]
|
|
if old == self[LAST]
|
|
then self[LAST] = new
|
|
else self[old] = nil
|
|
end
|
|
return old, prev
|
|
end
|
|
end
|
|
|
|
function pushfront(self, element)
|
|
if element ~= nil and not contains(self, element) then
|
|
if self[FIRST] ~= nil
|
|
then self[element] = self[FIRST]
|
|
else self[LAST] = element
|
|
end
|
|
self[FIRST] = element
|
|
return element
|
|
end
|
|
end
|
|
|
|
function popfront(self)
|
|
local element = self[FIRST]
|
|
self[FIRST] = self[element]
|
|
if self[FIRST] ~= nil
|
|
then self[element] = nil
|
|
else self[LAST] = nil
|
|
end
|
|
return element
|
|
end
|
|
|
|
function pushback(self, element)
|
|
if element ~= nil and not contains(self, element) then
|
|
if self[LAST] ~= nil
|
|
then self[ self[LAST] ] = element
|
|
else self[FIRST] = element
|
|
end
|
|
self[LAST] = element
|
|
return element
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- function aliases ------------------------------------------------------------
|
|
--------------------------------------------------------------------------------
|
|
|
|
-- set operations
|
|
add = pushback
|
|
|
|
-- stack operations
|
|
push = pushfront
|
|
pop = popfront
|
|
top = first
|
|
|
|
-- queue operations
|
|
enqueue = pushback
|
|
dequeue = popfront
|
|
head = first
|
|
tail = last
|
|
|
|
firstkey = FIRST
|