Workaround for SIGSEGV failures when using Iter[Natural]
This commit is contained in:
parent
11eaebfd77
commit
51c2a930e3
|
@ -103,29 +103,33 @@ proc map*[T, U](iter: Iter[T], fn: Function[T, U]): Iter[U] =
|
|||
)
|
||||
|
||||
proc mapFilter*[T, U](iter: Iter[T], mapPredicate: Function[T, Option[U]]): Iter[U] =
|
||||
var nextUOrErr: Option[Result[U, ref CatchableError]]
|
||||
var
|
||||
hasNext = false
|
||||
nextUOrErr: Result[U, ref CatchableError]
|
||||
|
||||
proc tryFetch(): void =
|
||||
nextUOrErr = Result[U, ref CatchableError].none
|
||||
hasNext = false
|
||||
while not iter.finished:
|
||||
try:
|
||||
let t = iter.next()
|
||||
if u =? mapPredicate(t):
|
||||
nextUOrErr = some(success(u))
|
||||
hasNext = true
|
||||
nextUOrErr = success(u)
|
||||
break
|
||||
except CatchableError as err:
|
||||
nextUOrErr = some(U.failure(err))
|
||||
hasNext = true
|
||||
nextUOrErr = U.failure(err)
|
||||
|
||||
proc genNext(): U {.raises: [CatchableError].} =
|
||||
# at this point nextUOrErr should always be some(..)
|
||||
without u =? nextUOrErr.unsafeGet, err:
|
||||
# at this point hasNext is always true
|
||||
without u =? nextUOrErr, err:
|
||||
raise err
|
||||
|
||||
tryFetch()
|
||||
return u
|
||||
|
||||
proc isFinished(): bool =
|
||||
nextUOrErr.isNone
|
||||
not hasNext
|
||||
|
||||
tryFetch()
|
||||
Iter[U].new(genNext, isFinished)
|
||||
|
|
|
@ -158,3 +158,21 @@ asyncchecksuite "Test AsyncIter":
|
|||
check:
|
||||
collected == @["0", "1"]
|
||||
iter2.finished
|
||||
|
||||
test "Should not crash with range type":
|
||||
let
|
||||
iter1 = AsyncIter[Natural].new(0.Natural..<5.Natural).delayBy(10.millis)
|
||||
iter2 = await filter[Natural](iter1,
|
||||
proc (i: Natural): Future[bool] {.async.} =
|
||||
(i mod 2) == 1
|
||||
)
|
||||
|
||||
var collected: seq[Natural]
|
||||
|
||||
for fut in iter2:
|
||||
collected.add(await fut)
|
||||
|
||||
check:
|
||||
collected == @[Natural 1, 3]
|
||||
|
||||
GC_fullCollect()
|
||||
|
|
|
@ -127,3 +127,13 @@ checksuite "Test Iter":
|
|||
check:
|
||||
collected == @["0", "1", "2"]
|
||||
iter2.finished
|
||||
|
||||
test "Should not crash with range type":
|
||||
let
|
||||
iter = Iter.new(0.Natural..<5.Natural)
|
||||
.filter((i: Natural) => (i mod 2) == 1)
|
||||
|
||||
check:
|
||||
iter.toSeq() == @[Natural 1, 3]
|
||||
|
||||
GC_fullCollect()
|
||||
|
|
Loading…
Reference in New Issue