It can work for pointers too, assuming CVI/MKI can properly store pointers.
Here's a version that uses pointers with New/Delete:
Code: Select all
#define stacksize(s) (len(s) \ sizeof(cvi(s)))
#define push(s, n) s &= mki(n)
#define top(s) cvi(right(s, sizeof(cvi(s))))
#define pop(s) s = left(s, len(s) - sizeof(cvi(s)))
#define fastpop(s) cptr(integer ptr, varptr(s))[1] -= sizeof(cvi(s))
#define push_T(s, n, T) push(s, cint(new T(n)))
#define push_aT(s, n) push_T(s, n, typeof((n)))
#define top_T(s, T) *cptr(T ptr, top(s))
#define pop_T(s, T) delete @top_T(s, T): pop(s)
#define fastpop_T(s, T) delete @top_T(s, T): fastpop(s)
type MyUDT
declare constructor ()
declare constructor (byref as MyUDT)
as integer elt
end type
constructor MyUDT(): elt = 0: end constructor
constructor MyUDT(byref rhs as MyUDT): elt = rhs.elt: end constructor
assert( sizeof(MyUDT ptr) = sizeof(cvi("")) )
dim as string s
dim as MyUDT u
for i as integer = 1 to 10
u.elt = i
push_aT(s, u)
next
while stacksize(s)
print top_T(s, MyUDT).elt
pop_T(s, MyUDT)
wend
(Note: new UDT(u) doesn't seem to copy-construct properly on simple structs, so you may want to give it an explicit copy-constructor.)
And here's a special String version (apparently we don't support New/Delete with Strings.)
Code: Select all
#define stacksize(s) (len(s) \ sizeof(cvi(s)))
#define push(s, n) s &= mki(n)
#define top(s) cvi(right(s, sizeof(cvi(s))))
#define pop(s) s = left(s, len(s) - sizeof(cvi(s)))
#define fastpop(s) cptr(integer ptr, varptr(s))[1] -= sizeof(cvi(s))
#define push_S(s, x) push(s, cint(callocate(sizeof(string)))): top_S(s) = x
#define top_S(s) *cptr(string ptr, top(s))
#define pop_S(s) Top_S(s) = "": pop(s)
#define fastpop_S(s) Top_S(s) = "": fastpop(s)
assert( sizeof(any ptr) = sizeof(cvi("")) )
dim as string s
for i as integer = 1 to 10
push_S(s, i & " :)")
next
while stacksize(s) > 0
print top_S(s)
pop_S(s)
wend