package stable import ( "runtime" "unsafe" "git.brut.systems/judah/xx/mem" ) type Pointer[T any] struct { base unsafe.Pointer pinner runtime.Pinner } func PointerPin[T any](ptr *T) (r Pointer[T]) { r.pinner.Pin(ptr) r.base = unsafe.Pointer(ptr) return } func PointerCast[TOut, TIn any](p Pointer[TIn]) Pointer[TOut] { return Pointer[TOut]{ base: unsafe.Pointer(p.base), pinner: p.pinner, } } func (p Pointer[T]) Unpin() { p.pinner.Unpin() p.base = nil } func (p Pointer[T]) Pointer() unsafe.Pointer { return p.base } func (p Pointer[T]) Address() uintptr { return uintptr(p.base) } func (p Pointer[T]) Nil() bool { return p.base == nil } func (p Pointer[T]) Add(amount uintptr) Pointer[T] { return Pointer[T]{ base: unsafe.Pointer(uintptr(p.base) + amount), pinner: p.pinner, } } func (p Pointer[T]) Sub(amount uintptr) Pointer[T] { return Pointer[T]{ base: unsafe.Pointer(uintptr(p.base) - amount), pinner: p.pinner, } } func (p Pointer[T]) AlignForward(alignment uintptr) Pointer[T] { return Pointer[T]{ base: unsafe.Pointer(mem.AlignForward(uintptr(p.base), alignment)), pinner: p.pinner, } } func (p Pointer[T]) AlignBackward(alignment uintptr) Pointer[T] { return Pointer[T]{ base: unsafe.Pointer(mem.AlignBackward(uintptr(p.base), alignment)), pinner: p.pinner, } } func (p Pointer[T]) Load() T { return *(*T)(p.base) } func (p Pointer[T]) Store(value T) { *(*T)(p.base) = value } func (p Pointer[T]) Nth(index int) T { return p.Add(uintptr(index) * mem.SizeOf[T]()).Load() }