Differences From
Artifact [e41dd1991a]:
14 14 m.heapa = macro(function(ty, sz)
15 15 local p = m.ptr(ty:astype())
16 16 return `p {
17 17 ptr = [&ty:astype()](m.heapa_raw(sizeof(ty) * sz));
18 18 ct = sz;
19 19 }
20 20 end)
21 +
22 +function m.cache(ty,sz)
23 + sz = sz or 32
24 + local struct c {
25 + store: ty[sz]
26 + top: intptr
27 + cur: intptr
28 + }
29 + c.name = string.format('cache<%s,%u>', tostring(ty), sz)
30 + terra c:insert(v: ty)
31 + if [ty.ptr_basetype ~= nil] then
32 + if self.cur < self.top then self.store[self.cur]:free() end
33 + end
34 + self.store[self.cur] = v
35 + self.top = lib.math.biggest(self.top, self.cur + 1)
36 + self.cur = (self.cur + 1) % sz
37 + return v
38 + end
39 + c.metamethods.__apply = terra(self: &c, idx: intptr) return &self.store[idx] end
40 + if ty.ptr_basetype then
41 + terra c:free()
42 + for i=0,self.top do self.store[i]:free() end
43 + end
44 + end
45 + return c
46 +end
21 47
22 48 local function mkptr(ty, dyn)
23 49 local t = terralib.types.newstruct(string.format('%s<%s>', dyn and 'ptr' or 'ref', ty))
24 50 t.entries = {
25 51 {'ptr', &ty};
26 52 {'ct', intptr};
27 53 }
28 54 t.ptr_basetype = ty
29 55 local recurse = false
30 - if ty:isstruct() then
31 - if ty.methods.free then recurse = true end
32 - end
56 + --if ty:isstruct() then
57 + --if ty.methods.free then recurse = true end
58 + --end
33 59 t.metamethods.__not = macro(function(self)
34 60 return `self.ptr
35 61 end)
36 62 if dyn then
37 63 t.methods = {
38 64 free = terra(self: &t): bool
39 65 [recurse and quote
................................................................................
43 69 m.heapf(self.ptr)
44 70 self.ct = 0
45 71 return true
46 72 end
47 73 return false
48 74 end;
49 75 init = terra(self: &t, newct: intptr): bool
76 + if newct == 0 then self.ct = 0 self.ptr = nil return false end
50 77 var nv = [&ty](m.heapa_raw(sizeof(ty) * newct))
51 78 if nv ~= nil then
52 79 self.ptr = nv
53 80 self.ct = newct
54 81 return true
55 82 else return false end
56 83 end;
................................................................................
105 132 {field = 'storage', type = m.ptr(ty)};
106 133 {field = 'sz', type = intptr};
107 134 {field = 'run', type = intptr};
108 135 }
109 136 local terra biggest(a: intptr, b: intptr)
110 137 if a > b then return a else return b end
111 138 end
139 + terra v:init(run: intptr): bool
140 + if not self.storage:init(run) then return false end
141 + self.run = run
142 + self.sz = 0
143 + return true
144 + end;
112 145 terra v:assure(n: intptr)
113 146 if self.storage.ct < n then
114 147 self.storage:resize(biggest(n, self.storage.ct + self.run))
115 148 end
116 149 end
117 - v.methods = {
118 - init = terra(self: &v, run: intptr): bool
119 - if not self.storage:init(run) then return false end
120 - self.run = run
121 - self.sz = 0
122 - return true
123 - end;
124 - new = terra(self: &v): &ty
125 - self:assure(self.sz + 1)
126 - self.sz = self.sz + 1
127 - return self.storage.ptr + (self.sz - 1)
128 - end;
129 - push = terra(self: &v, val: ty)
130 - self:assure(self.sz + 1)
131 - self.storage.ptr[self.sz] = val
132 - self.sz = self.sz + 1
133 - end;
134 - free = terra(self: &v) self.storage:free() end;
135 - last = terra(self: &v, idx: intptr): &ty
136 - if self.sz > idx then
137 - return self.storage.ptr + (self.sz - (idx+1))
138 - else lib.bail('vector underrun!') end
139 - end;
140 - crush = terra(self: &v)
141 - self.storage:resize(self.sz)
142 - return self.storage
143 - end;
144 - }
150 + terra v:new(): &ty
151 + self:assure(self.sz + 1)
152 + self.sz = self.sz + 1
153 + return self.storage.ptr + (self.sz - 1)
154 + end;
155 + terra v:push(val: ty)
156 + self:assure(self.sz + 1)
157 + self.storage.ptr[self.sz] = val
158 + self.sz = self.sz + 1
159 + end;
160 + terra v:free() self.storage:free() end;
161 + terra v:last(idx: intptr): &ty
162 + if self.sz > idx then
163 + return self.storage.ptr + (self.sz - (idx+1))
164 + else lib.bail('vector underrun!') end
165 + end;
166 + terra v:crush()
167 + self.storage:resize(self.sz)
168 + return self.storage
169 + end;
145 170 v.metamethods.__apply = terra(self: &v, idx: intptr): &ty -- no index??
146 171 if self.sz > idx then
147 172 return self.storage.ptr + idx
148 173 else lib.bail('vector overrun!') end
149 174 end
150 175 return v
151 176 end)
152 177
153 178 return m