Extend the location_set module to support set operators, custom index operators, and a tostring metamethod
Also adds set difference and symmetric difference functions, and a clone function.
This commit is contained in:
parent
9da5d4adfd
commit
4b9f5d4485
1 changed files with 83 additions and 5 deletions
|
@ -12,7 +12,59 @@ local function revindex(p)
|
|||
end
|
||||
|
||||
local methods = {}
|
||||
local locset_meta = { __index = methods }
|
||||
local locset_meta = {}
|
||||
|
||||
function locset_meta:__call(x, y)
|
||||
return self:get(x, y)
|
||||
end
|
||||
|
||||
function locset_meta:__index(loc)
|
||||
if type(loc) == 'string' then
|
||||
return methods[loc]
|
||||
elseif loc.x and loc.y then
|
||||
return self:get(loc.x, lov.y)
|
||||
else
|
||||
return self:get(loc[1], loc[2])
|
||||
end
|
||||
end
|
||||
|
||||
function locset_meta:__newindex(loc, val)
|
||||
if loc.x and loc.y then
|
||||
self:insert(loc.x, loc.y, val)
|
||||
else
|
||||
self:insert(loc[1], loc[2], val)
|
||||
end
|
||||
end
|
||||
|
||||
function locset_meta:__bor(other)
|
||||
local new = self:clone()
|
||||
new:union(other)
|
||||
return new
|
||||
end
|
||||
|
||||
function locset_meta:__band(other)
|
||||
local new = self:clone()
|
||||
new:inter(other)
|
||||
return new
|
||||
end
|
||||
|
||||
function locset_meta:__bxor(other)
|
||||
local new = self:clone()
|
||||
new:symm(other)
|
||||
return new
|
||||
end
|
||||
|
||||
function locset_meta:__sub(other)
|
||||
local new = self:clone()
|
||||
new:diff(other)
|
||||
return new
|
||||
end
|
||||
|
||||
function locset_meta:__tostring()
|
||||
local res = {}
|
||||
self:iter(function(x, y, v) res[string.format('(%d,%d)', x, y)] = tostring(v) end)
|
||||
return '{' .. stringx.join_map(res, '; ', ' = ') .. '}'
|
||||
end
|
||||
|
||||
function methods:empty()
|
||||
return (not next(self.values))
|
||||
|
@ -42,6 +94,14 @@ function methods:remove(x, y)
|
|||
self.values[index(x, y)] = nil
|
||||
end
|
||||
|
||||
function methods:clone()
|
||||
local new = location_set.create()
|
||||
for p,v in pairs(self.values) do
|
||||
new.values[p] = v
|
||||
end
|
||||
return new
|
||||
end
|
||||
|
||||
function methods:union(s)
|
||||
local values = self.values
|
||||
for p,v in pairs(s.values) do
|
||||
|
@ -76,6 +136,24 @@ function methods:inter_merge(s, f)
|
|||
self.values = nvalues
|
||||
end
|
||||
|
||||
function methods:diff(s)
|
||||
local values = self.values
|
||||
for p,v in pairs(s.values) do
|
||||
values[p] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function methods:symm(s)
|
||||
local values = self.values
|
||||
for p,v in pairs(s.values) do
|
||||
if values[p] then
|
||||
values[p] = nil
|
||||
else
|
||||
values[p] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function methods:filter(f)
|
||||
local nvalues = {}
|
||||
for p,v in pairs(self.values) do
|
||||
|
@ -99,16 +177,16 @@ function methods:iter(f)
|
|||
end
|
||||
|
||||
function methods:stable_iter(f)
|
||||
local indices = {}
|
||||
for p,v in pairs(self.values) do
|
||||
table.insert(indices, p)
|
||||
end
|
||||
if f == nil then
|
||||
local locs = self
|
||||
return coroutine.wrap(function()
|
||||
locs:stable_iter(coroutine.yield)
|
||||
end)
|
||||
end
|
||||
local indices = {}
|
||||
for p,v in pairs(self.values) do
|
||||
table.insert(indices, p)
|
||||
end
|
||||
table.sort(indices)
|
||||
for i,p in ipairs(indices) do
|
||||
local x, y = revindex(p)
|
||||
|
|
Loading…
Add table
Reference in a new issue