diff options
author | Ico Doornekamp <ico@pruts.nl> | 2019-12-21 21:01:34 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2019-12-21 21:01:34 +0100 |
commit | 28466ce6fca801f0e0c5dd6145506a3fc6d53fa7 (patch) | |
tree | aad33ec8c49822ffe3ec1a2dda3585e361bd376a | |
parent | b08116668531f8959de9d54009956f9ed21cbab9 (diff) | |
download | Nim-28466ce6fca801f0e0c5dd6145506a3fc6d53fa7.tar.gz |
Auto-initialize deques (#12879)
-rw-r--r-- | lib/pure/collections/deques.nim | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/lib/pure/collections/deques.nim b/lib/pure/collections/deques.nim index 0995b082b..1aa525bd6 100644 --- a/lib/pure/collections/deques.nim +++ b/lib/pure/collections/deques.nim @@ -62,6 +62,19 @@ type data: seq[T] 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] = ## 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 ## `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`. @@ -134,6 +145,7 @@ proc `[]=`*[T](deq: var Deque[T], i: Natural, val: T) {.inline.} = a[3] = 66 assert $a == "[99, 20, 30, 66, 50]" + checkIfInitialized(deq) xBoundsCheck(deq, i) 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 assert $a == "[10, 20, 77, 40, 99]" + checkIfInitialized(deq) xBoundsCheck(deq, deq.len - int(i)) deq[deq.len - int(i)] = x @@ -256,6 +269,7 @@ proc contains*[T](deq: Deque[T], item: T): bool {.inline.} = return false proc expandIfNeeded[T](deq: var Deque[T]) = + checkIfInitialized(deq) var cap = deq.mask + 1 if unlikely(deq.count >= cap): var n = newSeq[T](cap * 2) |