Auto-initialize deques (#12879)
This commit is contained in:
parent
b081166685
commit
28466ce6fc
1 changed files with 17 additions and 3 deletions
|
|
@ -62,6 +62,19 @@ type
|
||||||
data: seq[T]
|
data: seq[T]
|
||||||
head, tail, count, mask: int
|
head, tail, count, mask: int
|
||||||
|
|
||||||
|
const
|
||||||
|
defaultInitialSize* = 4
|
||||||
|
|
||||||
|
template initImpl(result: typed, initialSize: int) =
|
||||||
|
assert isPowerOfTwo(initialSize)
|
||||||
|
result.mask = initialSize-1
|
||||||
|
newSeq(result.data, initialSize)
|
||||||
|
|
||||||
|
template checkIfInitialized(deq: typed) =
|
||||||
|
when compiles(defaultInitialSize):
|
||||||
|
if deq.mask == 0:
|
||||||
|
initImpl(deq, defaultInitialSize)
|
||||||
|
|
||||||
proc initDeque*[T](initialSize: int = 4): Deque[T] =
|
proc initDeque*[T](initialSize: int = 4): Deque[T] =
|
||||||
## Create a new empty deque.
|
## Create a new empty deque.
|
||||||
##
|
##
|
||||||
|
|
@ -73,9 +86,7 @@ proc initDeque*[T](initialSize: int = 4): Deque[T] =
|
||||||
## If you need to accept runtime values for this you could use the
|
## If you need to accept runtime values for this you could use the
|
||||||
## `nextPowerOfTwo proc<math.html#nextPowerOfTwo,int>`_ from the
|
## `nextPowerOfTwo proc<math.html#nextPowerOfTwo,int>`_ from the
|
||||||
## `math module<math.html>`_.
|
## `math module<math.html>`_.
|
||||||
assert isPowerOfTwo(initialSize)
|
result.initImpl(initialSize)
|
||||||
result.mask = initialSize-1
|
|
||||||
newSeq(result.data, initialSize)
|
|
||||||
|
|
||||||
proc len*[T](deq: Deque[T]): int {.inline.} =
|
proc len*[T](deq: Deque[T]): int {.inline.} =
|
||||||
## Return the number of elements of `deq`.
|
## Return the number of elements of `deq`.
|
||||||
|
|
@ -134,6 +145,7 @@ proc `[]=`*[T](deq: var Deque[T], i: Natural, val: T) {.inline.} =
|
||||||
a[3] = 66
|
a[3] = 66
|
||||||
assert $a == "[99, 20, 30, 66, 50]"
|
assert $a == "[99, 20, 30, 66, 50]"
|
||||||
|
|
||||||
|
checkIfInitialized(deq)
|
||||||
xBoundsCheck(deq, i)
|
xBoundsCheck(deq, i)
|
||||||
deq.data[(deq.head + i) and deq.mask] = val
|
deq.data[(deq.head + i) and deq.mask] = val
|
||||||
|
|
||||||
|
|
@ -179,6 +191,7 @@ proc `[]=`*[T](deq: var Deque[T], i: BackwardsIndex, x: T) {.inline.} =
|
||||||
a[^3] = 77
|
a[^3] = 77
|
||||||
assert $a == "[10, 20, 77, 40, 99]"
|
assert $a == "[10, 20, 77, 40, 99]"
|
||||||
|
|
||||||
|
checkIfInitialized(deq)
|
||||||
xBoundsCheck(deq, deq.len - int(i))
|
xBoundsCheck(deq, deq.len - int(i))
|
||||||
deq[deq.len - int(i)] = x
|
deq[deq.len - int(i)] = x
|
||||||
|
|
||||||
|
|
@ -256,6 +269,7 @@ proc contains*[T](deq: Deque[T], item: T): bool {.inline.} =
|
||||||
return false
|
return false
|
||||||
|
|
||||||
proc expandIfNeeded[T](deq: var Deque[T]) =
|
proc expandIfNeeded[T](deq: var Deque[T]) =
|
||||||
|
checkIfInitialized(deq)
|
||||||
var cap = deq.mask + 1
|
var cap = deq.mask + 1
|
||||||
if unlikely(deq.count >= cap):
|
if unlikely(deq.count >= cap):
|
||||||
var n = newSeq[T](cap * 2)
|
var n = newSeq[T](cap * 2)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue