File: list.lua

package info (click to toggle)
spring 106.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 55,260 kB
  • sloc: cpp: 543,946; ansic: 44,800; python: 12,575; java: 12,201; awk: 5,889; sh: 1,796; asm: 1,546; xml: 655; perl: 405; php: 211; objc: 194; makefile: 76; sed: 2
file content (148 lines) | stat: -rw-r--r-- 3,287 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- A Lua List Object


--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Usage:
--   local list = CreateList("name")
--   list:Insert(owner, data)
--   for owner, data in list:iter() do ... end

	--// use array indices for most used entries (faster & less mem usage)
	local DATA  = 1
	local NEXT  = 2
	local PREV  = 3

	local function List_InsertNewListItem(self, owner, data, prev, next)
		local newItem = {
			owner  = owner; --// external code uses this too, so don't hide it behind a magic index
			[DATA]  = data;
			[NEXT]  = next;
			[PREV]  = prev
		}
		if (prev) then prev[NEXT] = newItem end
		if (next) then next[PREV] = newItem end
		if (prev == self.last)  then self.last  = newItem end
		if (next == self.first) then self.first = newItem end
		--return newItem
	end


	local function List_InsertItem(self, owner, data)
		local layer = owner._info.layer
		local item = self.first

		while (item) do
			if (item.owner == owner) then
				return --// already in table
			end

			if self._sortfunc(owner._info, item.owner._info) then
				break
			end
			item = item[NEXT]
		end

		if (item) then
			List_InsertNewListItem(self, owner, data, item[PREV], item)
		else
			List_InsertNewListItem(self, owner, data, self.last, nil) --// end of the pack
		end

		return true
	end


	local function List_RemoveListItem(self, item)
		local prev = item[PREV]
		local next = item[NEXT]

		if (prev) then
			prev[NEXT] = next
		end
		if (next) then
			next[PREV] = prev
		end

		if (self.last == item) then
			self.last = prev
		end
		if (self.first == item) then
			self.first = next
		end
	end


	local function List_RemoveItem(self, owner)
		local item = self.first
		if (not item) then
			return --// list is empty
		end

		while (item) do
			if (item.owner == owner) then
				List_RemoveListItem(self, item)
				return true
			end
			item = item[NEXT]
		end
	end


	local function List_Iter(self, item)
		--// ATTENTION
		--// This iterator works fine when elements get removed during looping
		--// AS LONG AS you don't remove both the current and its succeeding one!!!
		if (item == nil) then
			item = self.first
		else
			item = item[NEXT]
		end
		if (item) then
			return item, item[DATA]
		else
			return nil
		end
	end


	local function List_GetIter(self, it)
		return List_Iter, self, it
	end


	local function List_ReverseIter(self, item)
		--// ATTENTION
		--// This iterator works fine when elements get removed during looping
		--// AS LONG AS you don't remove both the current and its succeeding one!!!
		if (item == nil) then
			item = self.last
		else
			item = item[PREV]
		end
		if (item) then
			return item, item[DATA]
		else
			return nil
		end
	end


	local function List_GetReverseIter(self, it)
		return List_ReverseIter, self, it
	end

CreateList = function(name, sortfunc)
	return {
		name   = name,
		first  = nil,
		last   = nil,
		Insert = List_InsertItem,
		Remove = List_RemoveItem,
		iter      = List_GetIter,
		rev_iter  = List_GetReverseIter,
		_sortfunc = sortfunc,
	}
end