You can refer to
[https://forum.nim-lang.org/t/1188#7366](https://forum.nim-lang.org/t/1188#7366)
template ptrMath*(body: untyped) =
template `+`*[T](p: ptr T, off: int): ptr T =
cast[ptr type(p[])](cast[ByteAddress](p) +% off * sizeof(p[]))
template `+=`*[T](p: ptr T, off: int) =
p = p + off
template `-`*[T](p: ptr T, off: int): ptr T =
cast[ptr type(p[])](cast[ByteAddress](p) -% off * sizeof(p[]))
template `-=`*[T](p: ptr T, off: int) =
p = p - off
template `[]`*[T](p: ptr T, off: int): T =
(p + off)[]
template `[]=`*[T](p: ptr T, off: int, val: T) =
(p + off)[] = val
body
when isMainModule:
ptrMath:
var a: array[0..3, int]
for i in a.low..a.high:
a[i] += i
var p = addr(a[0])
p += 1
p[0] -= 2
echo p[0], " ", p[1]
Run
Alternatively I've also resorted to emitting C:
func `+`*(p: ptr, offset: int): type(p) {.inline.}=
## Pointer increment
{.emit: "`result` = `p` + `offset`;".}
Run
I strongly suggest not to define += though. Normally it should be defined with
the following signature:
func `+`*(p: var ptr, offset: int) {.inline.}=
## Pointer increment
{.emit: "`p` += `offset`;".}
Run
But in Nim a var is passed by hidden pointer and you will increment this hidden
pointer instead of the actual pointer, so you need to dereference it in the
code.
func `+`*(p: var ptr, offset: int) {.inline.}=
## Pointer increment
{.emit: "*`p` += `offset`;".}
Run
But as @doofenstein said, ptr UncheckedArray[T] covers a lot of need by giving
you array indexing on arbitrary ranges.