I am sorry if my comments cause disturbance in current disscusion. I try to 
keep this one short.

@cblake `std/deques` is built upon 
[seq](https://github.com/nim-lang/Nim/blob/version-2-0/lib/pure/collections/deques.nim#L61)
 which is not stable/pinned/mobile

If the cap is pre-defined, the address of data can be calculated directly and 
access with 2 in-directions. The follow shows implementation with growth factor 
of 2. It is also do-able with 1.5, but 2 is simpler.
    
    
    # todo: make this cross-platform
    proc clzll(x: cuint): cint {.header:"math.h", importc:"__builtin_clzll".}
    proc log2(x: int): int = 63 - clzll(x.cuint)
    
    type
      StableSeq*[T] = object
        len: int
        # sizeof(data[i]) == 1 shl i
        data: seq[ptr UncheckedArray[T]]
    
    proc add*[T](s: var StableSeq[T], v: sink T): ptr T =
      let i = log2(s.len+1)
      let j = s.len+1 - (1 shl i)
      while i >= s.data.len:
        let p = cast[ptr UncheckedArray[T]](alloc0(sizeof(T)*(1 shl 
s.data.len)))
        s.data.add p
      s.len += 1
      result = s.data[i][j].addr
      result[] = ensureMove(v)
    
    proc `[]`*[T](s: var StableSeq[T], k: int): var T =
      let i = log2(k+1)
      let j = k+1 - (1 shl i)
      return s.data[i][j]
    
    when isMainModule:
      var s: StableSeq[int]
      for i in 0 .. 10:
        discard s.add(i)
      for i in 0 ..< s.len:
        echo s[i]
    
    
    Run

Reply via email to