Skip to content

Commit

Permalink
Auto-initialize deques
Browse files Browse the repository at this point in the history
  • Loading branch information
zevv committed Dec 12, 2019
1 parent 9428916 commit 9929805
Showing 1 changed file with 13 additions and 3 deletions.
16 changes: 13 additions & 3 deletions lib/pure/collections/deques.nim
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ type
data: seq[T]
head, tail, count, mask: int

proc initImpl[T](deq: var Deque[T], initialSize: int = 4) =
if deq.mask == 0:
assert isPowerOfTwo(initialSize)
deq.mask = initialSize-1
newSeq(deq.data, initialSize)

proc initDeque*[T](initialSize: int = 4): Deque[T] =
## Create a new empty deque.
##
Expand All @@ -73,15 +79,14 @@ proc initDeque*[T](initialSize: int = 4): Deque[T] =
## If you need to accept runtime values for this you could use the
## `nextPowerOfTwo proc<math.html#nextPowerOfTwo,int>`_ from the
## `math module<math.html>`_.
assert isPowerOfTwo(initialSize)
result.mask = initialSize-1
newSeq(result.data, initialSize)
result.initImpl(initialSize)

proc len*[T](deq: Deque[T]): int {.inline.} =
## Return the number of elements of `deq`.
result = deq.count

template emptyCheck(deq) =
initImpl(deq)
# Bounds check for the regular deque access.
when compileOption("boundChecks"):
if unlikely(deq.count < 1):
Expand Down Expand Up @@ -121,6 +126,7 @@ proc `[]`*[T](deq: var Deque[T], i: Natural): var T {.inline.} =
assert a[3] == 40
doAssertRaises(IndexError, echo a[8])

initImpl(deq)
xBoundsCheck(deq, i)
return deq.data[(deq.head + i) and deq.mask]

Expand All @@ -134,6 +140,7 @@ proc `[]=`*[T](deq: var Deque[T], i: Natural, val: T) {.inline.} =
a[3] = 66
assert $a == "[99, 20, 30, 66, 50]"

initImpl(deq)
xBoundsCheck(deq, i)
deq.data[(deq.head + i) and deq.mask] = val

Expand Down Expand Up @@ -164,6 +171,7 @@ proc `[]`*[T](deq: var Deque[T], i: BackwardsIndex): var T {.inline.} =
assert a[^4] == 20
doAssertRaises(IndexError, echo a[^9])

initImpl(deq)
xBoundsCheck(deq, deq.len - int(i))
return deq[deq.len - int(i)]

Expand All @@ -179,6 +187,7 @@ proc `[]=`*[T](deq: var Deque[T], i: BackwardsIndex, x: T) {.inline.} =
a[^3] = 77
assert $a == "[10, 20, 77, 40, 99]"

initImpl(deq)
xBoundsCheck(deq, deq.len - int(i))
deq[deq.len - int(i)] = x

Expand Down Expand Up @@ -256,6 +265,7 @@ proc contains*[T](deq: Deque[T], item: T): bool {.inline.} =
return false

proc expandIfNeeded[T](deq: var Deque[T]) =
initImpl(deq)
var cap = deq.mask + 1
if unlikely(deq.count >= cap):
var n = newSeq[T](cap * 2)
Expand Down

0 comments on commit 9929805

Please sign in to comment.