[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Standard libraries (was Re: Virgin tables)
- From: Quae Quack <quae@...>
- Date: Mon, 3 Jan 2011 00:40:06 +0000
So... in lack of this magical site for working on common code, I
submit for consideration a suitable array implementation:
local list_mt = { }
local table_pack = table.pack or function ( ... ) return { n = select
( "#" , ... ) , ... } end
function list ( ... )
return setmetatable ( table_pack ( ... ) , list_mt )
end
local function check_list ( l )
return assert ( getmetatable ( l ) == list_mt , "Not a list" )
end
local function insert ( l , i , v )
check_list ( l )
local sz = #l
local new_sz = sz + 1
assert ( type ( i ) == "number" and i > 0 and i <= new_sz , "Invalid index" )
for k = sz , i , -1 do
rawset ( l , k + 1 , rawget ( l , k ) )
end
rawset ( l , i , v )
l.n = new_sz
return l
end
local function append ( l , ... )
check_list ( l )
local args = table_pack ( ... )
local sz = #l
for i = 1 , args.n do
rawset ( l , sz + i , rawget ( args , i ) )
end
l.n = sz + args.n
return l
end
local function remove ( l , i )
check_list ( l )
local sz = #l
assert ( type ( i ) == "number" and i > 0 and i <= sz )
local v = rawget ( l , i )
for k = i , sz do
rawset ( l , k , rawget ( l , k + 1 ) )
end
l.n = sz - 1
return l
end
local function concat ( l1 , l2 )
check_list ( l1 )
check_list ( l2 )
local r = list ( l1:unpack ( 1 , #l1 ) )
r:append ( l2:unpack ( 1 , #l2 ) )
return r
end
local function length ( l )
check_list ( l )
return rawget ( l , "n" )
end
list_mt.__index = {
insert = insert ;
append = append ;
remove = remove ;
length = length ;
unpack = unpack ;
tostring = table.concat ;
sort = table.sort ;
}
list_mt.__len = length ;
list_mt.__ipairs = function ( l )
local sz = #l
return function ( l , last_i )
local i = last_i + 1
if i > sz then return nil end
return i , rawget ( l , i )
end
end ;
list_mt.__pairs = list_mt.__ipairs
list_mt.__newindex = function ( l , i , v )
assert ( type ( i ) == "number" and i > 0 and i < #l + 1 )
rawset ( l , i , v )
end ;
list_mt.__add = append
list_mt.__sub = remove
list_mt.__concat = concat