/Table.lua

http://ro-rail.googlecode.com/ · Lua · 327 lines · 182 code · 55 blank · 90 comment · 52 complexity · 1529c4d8e868b71a0da8e282ae3f0acb MD5 · raw file

  1. -- Various Table Classes
  2. -- Table
  3. do
  4. Table = { }
  5. -- Private key to track the number of entries in the table
  6. local key_n = {}
  7. -- Metatable to make tables inherit from Table
  8. local metatable = {
  9. __index = Table,
  10. }
  11. -- Create a new table
  12. function Table.New(self)
  13. local ret = {
  14. [key_n] = 0,
  15. }
  16. setmetatable(ret,metatable)
  17. return ret
  18. end
  19. -- Get table size
  20. function Table.GetN(t)
  21. -- See if the table has an "n" element
  22. if t[key_n] == nil then
  23. -- If it doesn't, count until we find nil
  24. local i = 0
  25. while t[i+1] ~= nil do i=i+1 end
  26. t[key_n] = i
  27. end
  28. return t[key_n]
  29. end
  30. Table.Size = Table.GetN
  31. -- Set the table size
  32. function Table.SetN(t,size)
  33. -- Get the table size
  34. local len = Table.GetN(t)
  35. -- Check if we're reducing the size
  36. if size < len then
  37. -- Remove all elements after size
  38. for i=len,size+1,-1 do
  39. t[i]=nil
  40. end
  41. end
  42. -- Set n
  43. t[key_n]=size
  44. return t
  45. end
  46. -- Add an element to a table
  47. function Table.Insert(t,pos,item)
  48. -- Check if we were given 3 arguments
  49. if item == nil then
  50. -- Nope, only 2, 2nd one is the item
  51. item = pos
  52. pos = nil
  53. end
  54. -- Get the number of items we're adding
  55. local num = 1
  56. if type(item) == "table" and item[key_n] ~= nil then
  57. num = Table.GetN(item)
  58. end
  59. -- Save the number of items in t
  60. local tEnd = Table.GetN(t)
  61. -- Increase number of items
  62. t[key_n] = Table.GetN(t) + num
  63. -- Check if we have a position
  64. if pos == nil then
  65. -- Set pos to the end
  66. pos = tEnd + 1
  67. end
  68. -- Shift everything forward
  69. local i
  70. for i=t[key_n],pos+num,-1 do
  71. t[i]=t[i-num]
  72. end
  73. -- Insert the item(s)
  74. if type(item) == "table" and item[key_n] ~= nil then
  75. -- Loop through the table to be merged
  76. for i=1,Table.GetN(item) do
  77. -- Merge them in
  78. t[pos+i-1]=item[i]
  79. end
  80. else
  81. t[pos]=item
  82. end
  83. return t
  84. end
  85. -- Add an element to the end of a table
  86. function Table.Append(t,item)
  87. -- Just the same as insert without specifying position
  88. return Table.Insert(t,item,nil)
  89. end
  90. -- Remove an element from a table
  91. function Table.Remove(t,pos,num)
  92. -- Check if we have num
  93. if num == nil or num < 0 then
  94. num = 1
  95. elseif num == 0 then
  96. return
  97. end
  98. -- Check if the item exists
  99. if Table.GetN(t) < pos then
  100. return
  101. end
  102. -- Shift everything forward
  103. for i=pos,t[key_n]-num do
  104. t[i]=t[i+num]
  105. t[i+num]=nil
  106. end
  107. -- Remove the previous elements
  108. t[key_n]=t[key_n]-num
  109. return t
  110. end
  111. --[[
  112. -- Remove elements from the table, based on a function evaluating their values
  113. function Table.sieveValues(t,f,reversed)
  114. -- Make sure we have a sieving function
  115. if type(f) ~= "function" then
  116. return t
  117. end
  118. -- Make sure reversed is a boolean
  119. if type(reversed) ~= "boolean" then
  120. reversed = false
  121. end
  122. -- Loop through each element in the table
  123. local i,max = 1,Table.getn(t)
  124. while i <= max do
  125. -- Check if the element should be ignored
  126. local ret = f(t[i])
  127. if type(ret) ~= "boolean" then
  128. ret = false
  129. end
  130. if ret ~= reversed then
  131. -- Element should be removed
  132. Table.remove(t,i)
  133. -- Reduce the max
  134. max = Table.getn(t)
  135. else
  136. -- Element should stay
  137. i = i + 1
  138. end
  139. end
  140. return t
  141. end
  142. --]]
  143. -- Shallow copy a table (just create a new one)
  144. function Table.ShallowCopy(t,into,overwrite)
  145. local copy = into or {}
  146. -- Loop through all elements of the table
  147. for k,v in t do
  148. if copy[k] == nil or overwrite then
  149. copy[k] = v
  150. end
  151. end
  152. -- Set the same metatable
  153. local mt = getmetatable(t)
  154. if type(mt) == "table" then
  155. setmetatable(copy,mt)
  156. end
  157. return copy
  158. end
  159. -- Deep copy a table (subtables are also copied to new ones)
  160. do
  161. local function do_deep_copy(v,saved)
  162. if not saved[v] then
  163. local t = type(v)
  164. if t == "table" then
  165. -- Deep copy the table
  166. saved[v] = Table.DeepCopy(v,nil,nil,saved)
  167. else
  168. -- Everything else
  169. saved[v] = v
  170. end
  171. end
  172. return saved[v]
  173. end
  174. function Table.DeepCopy(t,copy,overwrite,saved)
  175. -- Create a saved table
  176. saved = saved or setmetatable({},{__mode="k",})
  177. -- Check if this table has already been copied
  178. if saved[t] then
  179. return saved[t]
  180. end
  181. -- Create a copy table
  182. local copy = copy or {}
  183. -- Add this table to the saved list
  184. saved[t] = copy
  185. -- Loop through all elements of the table
  186. for k,v in pairs(t) do
  187. local new_k = do_deep_copy(k,saved)
  188. if copy[new_k] == nil or overwrite then
  189. copy[new_k] = do_deep_copy(v,saved)
  190. end
  191. end
  192. -- Check for a metatable
  193. local mt = getmetatable(t)
  194. if type(mt) == "table" then
  195. local deep_mt = getmetatable(copy)
  196. setmetatable(copy,Table.DeepCopy(mt,deep_mt,overwrite,saved))
  197. end
  198. -- Return the copy
  199. return copy
  200. end
  201. end
  202. end
  203. -- List
  204. do
  205. -- List based on code from http://www.lua.org/pil/11.4.html
  206. List = {}
  207. local metatable = {
  208. __index = List
  209. }
  210. function List.New()
  211. local ret = { first = 0, last = -1 }
  212. setmetatable(ret,metatable)
  213. return ret
  214. end
  215. function List.PushLeft (list, value)
  216. list.first = list.first - 1
  217. list[list.first] = value;
  218. end
  219. function List.PushRight (list, value)
  220. list.last = list.last + 1
  221. list[list.last] = value
  222. end
  223. function List.PopLeft (list)
  224. if list.first > list.last then
  225. return nil
  226. end
  227. local value = list[list.first]
  228. list[list.first] = nil -- to allow garbage collection
  229. list.first = list.first + 1
  230. return value
  231. end
  232. function List.PopRight (list)
  233. if list.first > list.last then
  234. return nil
  235. end
  236. local value = list[list.last]
  237. list[list.last] = nil
  238. list.last = list.last - 1
  239. return value
  240. end
  241. function List.Clear (list)
  242. for i=list.first,list.last do
  243. list[i] = nil
  244. end
  245. list.first = 0
  246. list.last = -1
  247. end
  248. function List.Size (list)
  249. return list.last - list.first + 1
  250. end
  251. end
  252. -- Function to selectively return values from pairs based on index name
  253. function FindPairs(t,pattern,init,plain)
  254. -- Get the results from pairs
  255. local iter,t,first = pairs(t)
  256. -- Return a custom function with the table and first item from pairs()
  257. return function(t,idx)
  258. -- Loop through the values from iter()
  259. local value
  260. repeat
  261. -- Get the next index and skill from pairs()'s iterator
  262. idx,value = iter(t,idx)
  263. -- Loop until no pairs left or an index matches the pattern
  264. until idx == nil or string.find(tostring(idx),pattern,init,plain) ~= nil
  265. -- Return the next index and value
  266. return idx,value
  267. end,t,first
  268. end