lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Wed, Jun 23, 2010 at 2:50 PM, Florian Weimer <fw@deneb.enyo.de> wrote:
> * Juris Kalnins:
>> Main issue is that automatically maintaining the hidden "n" has a
>> runtime cost that is not acceptable for all users.
>
> The proposal linked to by David avoids that because the explicit
> length is never decreased automatically.  This should be good enough
> in many cases (including {...}).

Expressed in Lua 5.1, it might look like this:


local lengths = setmetatable({}, {__mode='k'})

function table.len(t)
  return lengths[t] or 0
end

function table.setlen(t, n)
  lengths[t] = n ~= 0 and n or nil
  -- maybe clear elements at index > n too, in which case
  -- table.setlen(t, 0) might be an efficient way to clear the array
end

local oldinsert = table.insert
function table.insert(t, ...)
  if select('#', ...) >= 2 then
    oldinsert(t, ...)
  else
    local value = ...
    t[table.len(t)+1] = value
  end
  table.setlen(t, table.len(t) + 1)
end

local oldremove = table.remove
function table.remove(t, pos)
  pos = pos or table.len(t)
  oldremove(t, pos)
  table.setlen(t, table.len(t) - 1)
end

function table.pack(...)
  local t = {...}
  table.setlen(t, select('#', ...))
  return t
end


-- example:

local function printtable(t)
  io.stdout:write(tostring(table.len(t)), ": ")
  for i=1,table.len(t) do io.stdout:write(tostring(t[i]), " ") end
  io.stdout:write("\n")
end

-- example:

local function printtable(t)
  io.stdout:write(tostring(table.len(t)), ": ")
  for i=1,table.len(t) do io.stdout:write(tostring(t[i]), " ") end
  io.stdout:write("\n")
end

t = table.pack(2,3,4,nil,nil)  printtable(t)
table.insert(t,5)              printtable(t)
t[6] = nil                     printtable(t)
table.remove(t)                printtable(t)
table.remove(t,1)              printtable(t)
table.setlen(t,1)              printtable(t)
table.setlen(t,0)              printtable(t)
--[[
5: 2 3 4 nil nil
6: 2 3 4 nil nil 5
6: 2 3 4 nil nil nil
5: 2 3 4 nil nil
4: 3 4 nil nil
1: 3
0:
]]