parsav  Diff

Differences From Artifact [e41dd1991a]:

To Artifact [15de92d877]:


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
..
43
44
45
46
47
48
49

50
51
52
53
54
55
56
...
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
149
150
151
152
153
m.heapa = macro(function(ty, sz)
	local p = m.ptr(ty:astype())
	return `p {
		ptr = [&ty:astype()](m.heapa_raw(sizeof(ty) * sz));
		ct = sz;
	}
end)



























local function mkptr(ty, dyn)
	local t = terralib.types.newstruct(string.format('%s<%s>', dyn and 'ptr' or 'ref', ty))
	t.entries = {
		{'ptr', &ty};
		{'ct', intptr};
	}
	t.ptr_basetype = ty
	local recurse = false
	if ty:isstruct() then
		if ty.methods.free then recurse = true end
	end
	t.metamethods.__not = macro(function(self)
		return `self.ptr
	end)
	if dyn then
		t.methods = {
			free = terra(self: &t): bool
				[recurse and quote
................................................................................
					m.heapf(self.ptr)
					self.ct = 0
					return true
				end
				return false
			end;
			init = terra(self: &t, newct: intptr): bool

				var nv = [&ty](m.heapa_raw(sizeof(ty) * newct))
				if nv ~= nil then
					self.ptr = nv
					self.ct = newct
					return true
				else return false end
			end;
................................................................................
		{field = 'storage', type = m.ptr(ty)};
		{field = 'sz', type = intptr};
		{field = 'run', type = intptr};
	}
	local terra biggest(a: intptr, b: intptr)
		if a > b then return a else return b end
	end
	terra v:assure(n: intptr)
		if self.storage.ct < n then
			self.storage:resize(biggest(n, self.storage.ct + self.run))
		end
	end
	v.methods = {
		init = terra(self: &v, run: intptr): bool
			if not self.storage:init(run) then return false end
			self.run = run
			self.sz = 0
			return true
		end;
		new = terra(self: &v): &ty






			self:assure(self.sz + 1)
			self.sz = self.sz + 1
			return self.storage.ptr + (self.sz - 1)
		end;
		push = terra(self: &v, val: ty)

			self:assure(self.sz + 1)
			self.storage.ptr[self.sz] = val
			self.sz = self.sz + 1
		end;
		free = terra(self: &v) self.storage:free() end;
		last = terra(self: &v, idx: intptr): &ty
			if self.sz > idx then
				return self.storage.ptr + (self.sz - (idx+1))
			else lib.bail('vector underrun!') end
		end;
		crush = terra(self: &v)

			self.storage:resize(self.sz)
			return self.storage
		end;
	}
	v.metamethods.__apply = terra(self: &v, idx: intptr): &ty -- no index??
		if self.sz > idx then
			return self.storage.ptr + idx
		else lib.bail('vector overrun!') end
	end
	return v 
end)

return m







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









|
|
|







 







>







 







<
<
<
<
<
<
|
|
|
|
|
|
<
>
>
>
>
>
>
|
|
|
|
<
>
|
|
|
|
|
|
|
|
|
|
<
>
|
|
|
<









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
..
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
...
132
133
134
135
136
137
138






139
140
141
142
143
144

145
146
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162
163
164
165

166
167
168
169

170
171
172
173
174
175
176
177
178
m.heapa = macro(function(ty, sz)
	local p = m.ptr(ty:astype())
	return `p {
		ptr = [&ty:astype()](m.heapa_raw(sizeof(ty) * sz));
		ct = sz;
	}
end)

function m.cache(ty,sz)
	sz = sz or 32
	local struct c {
		store: ty[sz]
		top: intptr
		cur: intptr
	}
	c.name = string.format('cache<%s,%u>', tostring(ty), sz)
	terra c:insert(v: ty)
		if [ty.ptr_basetype ~= nil] then
			if self.cur < self.top then self.store[self.cur]:free() end
		end
		self.store[self.cur] = v
		self.top = lib.math.biggest(self.top, self.cur + 1)
		self.cur = (self.cur + 1) % sz
		return v
	end
	c.metamethods.__apply = terra(self: &c, idx: intptr) return &self.store[idx] end
	if ty.ptr_basetype then
		terra c:free()
			for i=0,self.top do self.store[i]:free() end
		end
	end
	return c
end

local function mkptr(ty, dyn)
	local t = terralib.types.newstruct(string.format('%s<%s>', dyn and 'ptr' or 'ref', ty))
	t.entries = {
		{'ptr', &ty};
		{'ct', intptr};
	}
	t.ptr_basetype = ty
	local recurse = false
	--if ty:isstruct() then
		--if ty.methods.free then recurse = true end
	--end
	t.metamethods.__not = macro(function(self)
		return `self.ptr
	end)
	if dyn then
		t.methods = {
			free = terra(self: &t): bool
				[recurse and quote
................................................................................
					m.heapf(self.ptr)
					self.ct = 0
					return true
				end
				return false
			end;
			init = terra(self: &t, newct: intptr): bool
				if newct == 0 then self.ct = 0 self.ptr = nil return false end
				var nv = [&ty](m.heapa_raw(sizeof(ty) * newct))
				if nv ~= nil then
					self.ptr = nv
					self.ct = newct
					return true
				else return false end
			end;
................................................................................
		{field = 'storage', type = m.ptr(ty)};
		{field = 'sz', type = intptr};
		{field = 'run', type = intptr};
	}
	local terra biggest(a: intptr, b: intptr)
		if a > b then return a else return b end
	end






	terra v:init(run: intptr): bool
		if not self.storage:init(run) then return false end
		self.run = run
		self.sz = 0
		return true
	end;

	terra v:assure(n: intptr)
		if self.storage.ct < n then
			self.storage:resize(biggest(n, self.storage.ct + self.run))
		end
	end
	terra v:new(): &ty
		self:assure(self.sz + 1)
		self.sz = self.sz + 1
		return self.storage.ptr + (self.sz - 1)
	end;

	terra v:push(val: ty)
		self:assure(self.sz + 1)
		self.storage.ptr[self.sz] = val
		self.sz = self.sz + 1
	end;
	terra v:free() self.storage:free() end;
	terra v:last(idx: intptr): &ty
		if self.sz > idx then
			return self.storage.ptr + (self.sz - (idx+1))
		else lib.bail('vector underrun!') end
	end;

	terra v:crush()
		self.storage:resize(self.sz)
		return self.storage
	end;

	v.metamethods.__apply = terra(self: &v, idx: intptr): &ty -- no index??
		if self.sz > idx then
			return self.storage.ptr + idx
		else lib.bail('vector overrun!') end
	end
	return v 
end)

return m