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.

Reply via email to