summary refs log tree commit diff stats
path: root/lib/system
diff options
context:
space:
mode:
authorMiran <narimiran@disroot.org>2019-05-04 23:02:50 +0200
committerAndreas Rumpf <rumpf_a@web.de>2019-05-04 23:02:50 +0200
commitce152ed91f85c45909e0f76854fcc28d3c6a550d (patch)
tree4b2050f35f9e46ae502345a3f0036f77ca22e7b1 /lib/system
parentd2e1936cf20605579e9e80a1e56644e42e508120 (diff)
downloadNim-ce152ed91f85c45909e0f76854fcc28d3c6a550d.tar.gz
iterators: several small fixes (#11162)
* fix pairs, mpairs, mitems for cstring for JS backend
* add mutation check for pairs and mpairs for strings and seqs
* change the assertion message - modifying (changing elements) is not
  a problem, changing the length is
Diffstat (limited to 'lib/system')
-rw-r--r--lib/system/iterators.nim75
1 files changed, 51 insertions, 24 deletions
diff --git a/lib/system/iterators.nim b/lib/system/iterators.nim
index 0bdd7a2e2..dafd56cb3 100644
--- a/lib/system/iterators.nim
+++ b/lib/system/iterators.nim
@@ -55,20 +55,27 @@ iterator items*(a: cstring): char {.inline.} =
 
 iterator mitems*(a: var cstring): var char {.inline.} =
   ## Iterates over each item of `a` so that you can modify the yielded value.
-  var i = 0
-  while a[i] != '\0':
-    yield a[i]
-    inc(i)
+  when defined(js):
+    var i = 0
+    var L = len(a)
+    while i < L:
+      yield a[i]
+      inc(i)
+  else:
+    var i = 0
+    while a[i] != '\0':
+      yield a[i]
+      inc(i)
 
 iterator items*(E: typedesc[enum]): E =
   ## Iterates over the values of the enum ``E``.
-  for v in low(E)..high(E):
+  for v in low(E) .. high(E):
     yield v
 
 iterator items*[T](s: HSlice[T, T]): T =
   ## Iterates over the slice `s`, yielding each value between `s.a` and `s.b`
   ## (inclusively).
-  for x in s.a..s.b:
+  for x in s.a .. s.b:
     yield x
 
 iterator pairs*[T](a: openArray[T]): tuple[key: int, val: T] {.inline.} =
@@ -108,47 +115,69 @@ iterator mpairs*[IX, T](a:var array[IX, T]):tuple[key:IX,val:var T] {.inline.} =
 iterator pairs*[T](a: seq[T]): tuple[key: int, val: T] {.inline.} =
   ## Iterates over each item of `a`. Yields ``(index, a[index])`` pairs.
   var i = 0
-  while i < len(a):
+  let L = len(a)
+  while i < L:
     yield (i, a[i])
     inc(i)
+    assert(len(a) == L, "the length of the seq changed while iterating over it")
 
 iterator mpairs*[T](a: var seq[T]): tuple[key: int, val: var T] {.inline.} =
   ## Iterates over each item of `a`. Yields ``(index, a[index])`` pairs.
   ## ``a[index]`` can be modified.
   var i = 0
-  while i < len(a):
+  let L = len(a)
+  while i < L:
     yield (i, a[i])
     inc(i)
+    assert(len(a) == L, "the length of the seq changed while iterating over it")
 
 iterator pairs*(a: string): tuple[key: int, val: char] {.inline.} =
   ## Iterates over each item of `a`. Yields ``(index, a[index])`` pairs.
   var i = 0
-  while i < len(a):
+  let L = len(a)
+  while i < L:
     yield (i, a[i])
     inc(i)
+    assert(len(a) == L, "the length of the string changed while iterating over it")
 
 iterator mpairs*(a: var string): tuple[key: int, val: var char] {.inline.} =
   ## Iterates over each item of `a`. Yields ``(index, a[index])`` pairs.
   ## ``a[index]`` can be modified.
   var i = 0
-  while i < len(a):
+  let L = len(a)
+  while i < L:
     yield (i, a[i])
     inc(i)
+    assert(len(a) == L, "the length of the string changed while iterating over it")
 
 iterator pairs*(a: cstring): tuple[key: int, val: char] {.inline.} =
   ## Iterates over each item of `a`. Yields ``(index, a[index])`` pairs.
-  var i = 0
-  while a[i] != '\0':
-    yield (i, a[i])
-    inc(i)
+  when defined(js):
+    var i = 0
+    var L = len(a)
+    while i < L:
+      yield (i, a[i])
+      inc(i)
+  else:
+    var i = 0
+    while a[i] != '\0':
+      yield (i, a[i])
+      inc(i)
 
 iterator mpairs*(a: var cstring): tuple[key: int, val: var char] {.inline.} =
   ## Iterates over each item of `a`. Yields ``(index, a[index])`` pairs.
   ## ``a[index]`` can be modified.
-  var i = 0
-  while a[i] != '\0':
-    yield (i, a[i])
-    inc(i)
+  when defined(js):
+    var i = 0
+    var L = len(a)
+    while i < L:
+      yield (i, a[i])
+      inc(i)
+  else:
+    var i = 0
+    while a[i] != '\0':
+      yield (i, a[i])
+      inc(i)
 
 
 iterator items*[T](a: seq[T]): T {.inline.} =
@@ -158,7 +187,7 @@ iterator items*[T](a: seq[T]): T {.inline.} =
   while i < L:
     yield a[i]
     inc(i)
-    assert(len(a) == L, "seq modified while iterating over it")
+    assert(len(a) == L, "the length of the seq changed while iterating over it")
 
 iterator mitems*[T](a: var seq[T]): var T {.inline.} =
   ## Iterates over each item of `a` so that you can modify the yielded value.
@@ -167,7 +196,7 @@ iterator mitems*[T](a: var seq[T]): var T {.inline.} =
   while i < L:
     yield a[i]
     inc(i)
-    assert(len(a) == L, "seq modified while iterating over it")
+    assert(len(a) == L, "the length of the seq changed while iterating over it")
 
 iterator items*(a: string): char {.inline.} =
   ## Iterates over each item of `a`.
@@ -176,7 +205,7 @@ iterator items*(a: string): char {.inline.} =
   while i < L:
     yield a[i]
     inc(i)
-    assert(len(a) == L, "string modified while iterating over it")
+    assert(len(a) == L, "the length of the string changed while iterating over it")
 
 iterator mitems*(a: var string): var char {.inline.} =
   ## Iterates over each item of `a` so that you can modify the yielded value.
@@ -185,7 +214,7 @@ iterator mitems*(a: var string): var char {.inline.} =
   while i < L:
     yield a[i]
     inc(i)
-    assert(len(a) == L, "string modified while iterating over it")
+    assert(len(a) == L, "the length of the string changed while iterating over it")
 
 
 iterator fields*[T: tuple|object](x: T): RootObj {.
@@ -244,5 +273,3 @@ iterator fieldPairs*[S: tuple|object, T: tuple|object](x: S, y: T): tuple[
   ## **Warning**: This really transforms the 'for' and unrolls the loop.
   ## The current implementation also has a bug that affects symbol binding
   ## in the loop body.
-
-