bugfix: 'set' overloadable; further steps for multi threading support
This commit is contained in:
parent
170573a87f
commit
99bcc233cd
34 changed files with 934 additions and 459 deletions
89
lib/pure/collections/queues.nim
Normal file
89
lib/pure/collections/queues.nim
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2011 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
## Implementation of a queue. The underlying implementation uses a ``seq``.
|
||||
|
||||
import math
|
||||
|
||||
type
|
||||
TQueue* {.pure, final.}[T] = object ## a queue
|
||||
data: seq[T]
|
||||
rd, wr, count, mask: int
|
||||
|
||||
proc initQueue*[T](initialSize=4): TQueue[T] =
|
||||
## creates a new queue. `initialSize` needs to be a power of 2.
|
||||
assert IsPowerOfTwo(initialSize)
|
||||
result.mask = initialSize-1
|
||||
newSeq(result.data, initialSize)
|
||||
|
||||
proc len*[T](q: TQueue[T]): int =
|
||||
## returns the number of elements of `q`.
|
||||
result = q.count
|
||||
|
||||
iterator items*[T](q: TQueue[T]): T =
|
||||
## yields every element of `q`.
|
||||
var i = q.rd
|
||||
var c = q.count
|
||||
while c > 0:
|
||||
dec c
|
||||
yield q.data[i]
|
||||
i = (i + 1) and q.mask
|
||||
|
||||
proc add*[T](q: var TQueue[T], item: T) =
|
||||
## adds an `item` to the end of the queue `q`.
|
||||
var cap = q.mask+1
|
||||
if q.count >= cap:
|
||||
var n: seq[T]
|
||||
newSeq(n, cap*2)
|
||||
var i = 0
|
||||
for x in items(q):
|
||||
shallowCopy(n[i], x)
|
||||
inc i
|
||||
shallowCopy(q.data, n)
|
||||
q.mask = cap*2 - 1
|
||||
q.wr = q.count
|
||||
q.rd = 0
|
||||
inc q.count
|
||||
q.data[q.wr] = item
|
||||
q.wr = (q.wr + 1) and q.mask
|
||||
|
||||
proc enqueue*[T](q: var TQueue[T], item: T) =
|
||||
## alias for the ``add`` operation.
|
||||
add(q, item)
|
||||
|
||||
proc dequeue*[T](q: var TQueue[T]): T =
|
||||
## removes and returns the first element of the queue `q`.
|
||||
assert q.count > 0
|
||||
dec q.count
|
||||
result = q.data[q.rd]
|
||||
q.rd = (q.rd + 1) and q.mask
|
||||
|
||||
proc `$`*[T](q: TQueue[T]): string =
|
||||
## turns a queue into its string representation.
|
||||
result = "["
|
||||
for x in items(q):
|
||||
if result.len > 1: result.add(", ")
|
||||
result.add($x)
|
||||
result.add("]")
|
||||
|
||||
when isMainModule:
|
||||
var q = initQueue[int]()
|
||||
q.add(123)
|
||||
q.add(9)
|
||||
q.add(4)
|
||||
var first = q.dequeue
|
||||
q.add(56)
|
||||
q.add(6)
|
||||
var second = q.dequeue
|
||||
q.add(789)
|
||||
|
||||
assert first == 123
|
||||
assert second == 9
|
||||
assert($q == "[4, 56, 6, 789]")
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue