Differences From
Artifact [a251bec86e]:
108 108 end
109 109 terra t.methods.null(): t return t { ptr = nil, ct = 0 } end -- maybe should be a macro?
110 110 terra t:ref() return self.ptr ~= nil end
111 111 t.metamethods.__not = macro(function(self) return `not self:ref() end)
112 112 t.metamethods.__apply = macro(function(self,idx) return `self.ptr[ [idx or 0] ] end)
113 113 t.metamethods.__update = macro(function(self,idx,rhs)
114 114 return quote self.ptr[idx] = rhs end end)
115 + t.metamethods.__cast = function(from,to,exp)
116 + if to == t then
117 + if from == niltype then return `t.null()
118 + elseif from == &ty then return `t {ptr = exp, ct = 1}
119 + elseif from == ty then return `t {ptr = &exp, ct = 1}
120 + elseif from.N and from.type == ty then
121 + return `t {ptr = &exp[0], ct = from.N }
122 + end
123 + error('invalid cast to ' .. t.name .. ' from ' .. tostring(from))
124 + elseif from == t then
125 + if to == &ty then return `exp.ptr
126 + elseif to == ty then return `@exp.ptr
127 + elseif to == bool then return `exp:ref() end
128 + error('invalid cast from ' .. t.name .. ' to ' .. tostring(to))
129 + end
130 + error('invalid pointer cast')
131 + end
115 132
116 133 if not ty:isstruct() then
117 134 terra t:cmp_raw(other: &ty)
118 135 for i=0, self.ct do
119 136 if self.ptr[i] ~= other[i] then return false end
120 137 end
121 138 return true