83 lines
2.0 KiB
Lua
Executable File
83 lines
2.0 KiB
Lua
Executable File
require 'classlib'
|
|
|
|
class.Tuple()
|
|
|
|
function Tuple:__init(...) -- construct with initial elements
|
|
self.elem = {...}
|
|
self.n = #self.elem
|
|
end
|
|
|
|
function Tuple:__tostring() -- string representation
|
|
local function ascii(e)
|
|
return type(e) == 'string' and string.format('%q', e) or tostring(e)
|
|
end
|
|
local s = ''
|
|
for i, v in ipairs(self.elem) do
|
|
s = #s == 0 and ascii(v) or s .. ', ' .. ascii(v)
|
|
end
|
|
return '(' .. s .. ')'
|
|
end
|
|
|
|
local function checkrange(i, max)
|
|
assert(i >= 1 and i <= max,
|
|
'Index must be >= 1 and <= ' .. max)
|
|
end
|
|
|
|
local function checkindex(i, max)
|
|
assert(type(i) == 'number', 'Index must be a number')
|
|
checkrange(i, max)
|
|
end
|
|
|
|
function Tuple:push(i, v) -- push an element anywhere
|
|
if v == nil then
|
|
v = i
|
|
i = self.n + 1 -- by default push at the end
|
|
end
|
|
if v == nil then return end -- pushing nil has no effect
|
|
checkindex(i, self.n + 1) -- allow appending
|
|
table.insert(self.elem, i, v) -- insert it
|
|
self.n = self.n + 1 -- count it
|
|
end
|
|
|
|
function Tuple:pop(i) -- pop an element anywhere
|
|
if i == nil then
|
|
i = self.n -- by default pop at the end
|
|
if i == 0 then return nil end
|
|
end
|
|
local e = self[i]
|
|
self[i] = nil -- remove it
|
|
return e -- return it
|
|
end
|
|
|
|
function Tuple:clear() -- empty tuple
|
|
self.elem = {}
|
|
self.n = 0
|
|
end
|
|
|
|
function Tuple:size() -- tuple size
|
|
return self.n
|
|
end
|
|
|
|
function Tuple:__get(i) -- read an element
|
|
if type(i) ~= 'number' then return nil end
|
|
checkrange(i, self.n + 1) -- allow reading one past the end
|
|
return self.elem[i] -- read it
|
|
end
|
|
|
|
function Tuple:__set(i, v) -- assign an element
|
|
if type(i) ~= 'number' then return false end
|
|
checkrange(i, self.n + 1) -- allow assigning one past the end
|
|
if v == nil then
|
|
if i <= self.n then -- if removing, count it
|
|
table.remove(self.elem, i)
|
|
self.n = self.n - 1
|
|
end
|
|
return true
|
|
end
|
|
if i == self.n + 1 then -- if appending, count it
|
|
self.n = i
|
|
end
|
|
self.elem[i] = v -- assign it
|
|
return true
|
|
end
|