stdlib work
This commit is contained in:
parent
ee16e62061
commit
7ab1aafc6b
3 changed files with 66 additions and 9 deletions
|
|
@ -38,7 +38,7 @@
|
|||
## Note: For inter thread communication use
|
||||
## a `Channel <channels.html>`_ instead.
|
||||
|
||||
import math
|
||||
import math, typetraits
|
||||
|
||||
type
|
||||
Deque*[T] = object
|
||||
|
|
@ -160,16 +160,18 @@ proc peekLast*[T](deq: Deque[T]): T {.inline.} =
|
|||
emptyCheck(deq)
|
||||
result = deq.data[(deq.tail - 1) and deq.mask]
|
||||
|
||||
template default[T](t: typedesc[T]): T =
|
||||
var v: T
|
||||
v
|
||||
template destroy(x: untyped) =
|
||||
when defined(nimNewRuntime) and not supportsCopyMem(type(x)):
|
||||
`=destroy`(x)
|
||||
else:
|
||||
reset(x)
|
||||
|
||||
proc popFirst*[T](deq: var Deque[T]): T {.inline, discardable.} =
|
||||
## Remove and returns the first element of the `deq`.
|
||||
emptyCheck(deq)
|
||||
dec deq.count
|
||||
result = deq.data[deq.head]
|
||||
deq.data[deq.head] = default(type(result))
|
||||
destroy(deq.data[deq.head])
|
||||
deq.head = (deq.head + 1) and deq.mask
|
||||
|
||||
proc popLast*[T](deq: var Deque[T]): T {.inline, discardable.} =
|
||||
|
|
@ -178,7 +180,34 @@ proc popLast*[T](deq: var Deque[T]): T {.inline, discardable.} =
|
|||
dec deq.count
|
||||
deq.tail = (deq.tail - 1) and deq.mask
|
||||
result = deq.data[deq.tail]
|
||||
deq.data[deq.tail] = default(type(result))
|
||||
destroy(deq.data[deq.tail])
|
||||
|
||||
proc clear*[T](deq: var Deque[T]) {.inline.} =
|
||||
## Resets the deque so that it is empty.
|
||||
for el in mitems(deq): destroy(el)
|
||||
deq.count = 0
|
||||
deq.tail = deq.head
|
||||
|
||||
proc shrink*[T](deq: var Deque[T], fromFirst = 0, fromLast = 0) =
|
||||
## Remove `fromFirst` elements from the front of the deque and
|
||||
## `fromLast` elements from the back. If the supplied number of
|
||||
## elements exceeds the total number of elements in the deque,
|
||||
## the deque will remain empty.
|
||||
##
|
||||
## Any user defined destructors
|
||||
if fromFirst + fromLast > deq.count:
|
||||
clear(deq)
|
||||
return
|
||||
|
||||
for i in 0 ..< fromFirst:
|
||||
destroy(deq.data[deq.head])
|
||||
deq.head = (deq.head + 1) and deq.mask
|
||||
|
||||
for i in 0 ..< fromLast:
|
||||
destroy(deq.data[deq.tail])
|
||||
deq.tail = (deq.tail - 1) and deq.mask
|
||||
|
||||
dec deq.count, fromFirst + fromLast
|
||||
|
||||
proc `$`*[T](deq: Deque[T]): string =
|
||||
## Turn a deque into its string representation.
|
||||
|
|
@ -215,6 +244,22 @@ when isMainModule:
|
|||
assert deq.find(6) >= 0
|
||||
assert deq.find(789) < 0
|
||||
|
||||
block:
|
||||
var d = initDeque[int](1)
|
||||
d.addLast 7
|
||||
d.addLast 8
|
||||
d.addLast 10
|
||||
d.addFirst 5
|
||||
d.addFirst 2
|
||||
d.addFirst 1
|
||||
d.addLast 20
|
||||
d.shrink(fromLast = 2)
|
||||
doAssert($d == "[1, 2, 5, 7, 8]")
|
||||
d.shrink(2, 1)
|
||||
doAssert($d == "[5, 7]")
|
||||
d.shrink(2, 2)
|
||||
doAssert d.len == 0
|
||||
|
||||
for i in -2 .. 10:
|
||||
if i in deq:
|
||||
assert deq.contains(i) and deq.find(i) >= 0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue