summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2018-09-16 21:37:11 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-09-16 21:37:11 +0200
commitc554c2a581dacbde7f85c19a066b68ca0c68da3e (patch)
tree7eae404cbea4df72587012912a20b243670db687 /tests
parenta622291be46b7e580aad6b853f4b90340bbd5479 (diff)
downloadNim-c554c2a581dacbde7f85c19a066b68ca0c68da3e.tar.gz
closes #3837
Diffstat (limited to 'tests')
-rw-r--r--tests/iter/tchainediterators2.nim81
1 files changed, 81 insertions, 0 deletions
diff --git a/tests/iter/tchainediterators2.nim b/tests/iter/tchainediterators2.nim
new file mode 100644
index 000000000..c2e5e6170
--- /dev/null
+++ b/tests/iter/tchainediterators2.nim
@@ -0,0 +1,81 @@
+discard """
+  output: '''start
+false
+0
+1
+2
+end
+@[2, 4, 6, 8, 10]
+@[4, 8, 12, 16, 20]'''
+"""
+
+# bug #3837
+
+proc iter1(): (iterator: int) =
+  let coll = [0,1,2]
+  result = iterator: int {.closure.} =
+    for i in coll:
+      yield i
+
+proc iter2(it: (iterator: int)): (iterator: int)  =
+  result = iterator: int {.closure.} =
+    echo finished(it)
+    for i in it():
+      yield i
+
+echo "start"
+let myiter1 = iter1()
+let myiter2 = iter2(myiter1)
+for i in myiter2():
+  echo i
+echo "end"
+# start
+# false
+# end
+
+
+from sequtils import toSeq
+
+type Iterable*[T] = (iterator: T) | Slice[T]
+  ## Everything that can be iterated over, iterators and slices so far.
+
+proc toIter*[T](s: Slice[T]): iterator: T =
+  ## Iterate over a slice.
+  iterator it: T {.closure.} =
+    for x in s.a..s.b:
+      yield x
+  return it
+
+proc toIter*[T](i: iterator: T): iterator: T =
+  ## Nop
+  i
+
+iterator map*[T,S](i: Iterable[T], f: proc(x: T): S): S =
+  let i = toIter(i)
+  for x in i():
+    yield f(x)
+
+proc filter*[T](i: Iterable[T], f: proc(x: T): bool): iterator: T =
+  ## Iterates through an iterator and yields every item that fulfills the
+  ## predicate `f`.
+  ##
+  ## .. code-block:: nim
+  ##   for x in filter(1..11, proc(x): bool = x mod 2 == 0):
+  ##     echo x
+  let i = toIter(i)
+  iterator it: T {.closure.} =
+    for x in i():
+      if f(x):
+        yield x
+  result = it
+
+iterator filter*[T](i: Iterable[T], f: proc(x: T): bool): T =
+  let i = toIter(i)
+  for x in i():
+    if f(x):
+      yield x
+
+var it = toSeq(filter(2..10, proc(x: int): bool = x mod 2 == 0))
+echo it # @[2, 4, 6, 8, 10]
+it = toSeq(map(filter(2..10, proc(x: int): bool = x mod 2 == 0), proc(x: int): int = x * 2))
+echo it # Expected output: @[4, 8, 12, 16, 20], Actual output: @[]