summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/pure/collections/lists.nim16
-rw-r--r--lib/pure/collections/queues.nim9
-rw-r--r--lib/pure/json.nim14
-rw-r--r--lib/pure/xmltree.nim10
-rw-r--r--lib/system.nim68
5 files changed, 117 insertions, 0 deletions
diff --git a/lib/pure/collections/lists.nim b/lib/pure/collections/lists.nim
index 929de5973..150e48217 100644
--- a/lib/pure/collections/lists.nim
+++ b/lib/pure/collections/lists.nim
@@ -122,6 +122,22 @@ iterator items*[T](L: DoublyLinkedRing[T]): T =
   ## yields every value of `L`.
   itemsRingImpl()
 
+iterator mitems*[T](L: var DoublyLinkedList[T]): var T =
+  ## yields every value of `L` so that you can modify it.
+  itemsListImpl()
+
+iterator mitems*[T](L: var SinglyLinkedList[T]): var T =
+  ## yields every value of `L` so that you can modify it.
+  itemsListImpl()
+
+iterator mitems*[T](L: var SinglyLinkedRing[T]): var T =
+  ## yields every value of `L` so that you can modify it.
+  itemsRingImpl()
+
+iterator mitems*[T](L: var DoublyLinkedRing[T]): var T =
+  ## yields every value of `L` so that you can modify it.
+  itemsRingImpl()
+
 iterator nodes*[T](L: SinglyLinkedList[T]): SinglyLinkedNode[T] = 
   ## iterates over every node of `x`. Removing the current node from the
   ## list during traversal is supported.
diff --git a/lib/pure/collections/queues.nim b/lib/pure/collections/queues.nim
index defce657f..61f0d14b5 100644
--- a/lib/pure/collections/queues.nim
+++ b/lib/pure/collections/queues.nim
@@ -39,6 +39,15 @@ iterator items*[T](q: Queue[T]): T =
     yield q.data[i]
     i = (i + 1) and q.mask
 
+iterator mitems*[T](q: var Queue[T]): var 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 Queue[T], item: T) =
   ## adds an `item` to the end of the queue `q`.
   var cap = q.mask+1
diff --git a/lib/pure/json.nim b/lib/pure/json.nim
index 733516bea..873e4b78e 100644
--- a/lib/pure/json.nim
+++ b/lib/pure/json.nim
@@ -872,12 +872,26 @@ iterator items*(node: JsonNode): JsonNode =
   for i in items(node.elems):
     yield i
 
+iterator mitems*(node: var JsonNode): var JsonNode =
+  ## Iterator for the items of `node`. `node` has to be a JArray. Items can be
+  ## modified.
+  assert node.kind == JArray
+  for i in mitems(node.elems):
+    yield i
+
 iterator pairs*(node: JsonNode): tuple[key: string, val: JsonNode] =
   ## Iterator for the child elements of `node`. `node` has to be a JObject.
   assert node.kind == JObject
   for key, val in items(node.fields):
     yield (key, val)
 
+iterator mpairs*(node: var JsonNode): var tuple[key: string, val: JsonNode] =
+  ## Iterator for the child elements of `node`. `node` has to be a JObject.
+  ## Items can be modified
+  assert node.kind == JObject
+  for keyVal in mitems(node.fields):
+    yield keyVal
+
 proc eat(p: var JsonParser, tok: TTokKind) = 
   if p.tok == tok: discard getTok(p)
   else: raiseParseErr(p, tokToStr[tok])
diff --git a/lib/pure/xmltree.nim b/lib/pure/xmltree.nim
index 3c789d841..c783158ea 100644
--- a/lib/pure/xmltree.nim
+++ b/lib/pure/xmltree.nim
@@ -115,11 +115,21 @@ proc `[]`* (n: XmlNode, i: int): XmlNode {.inline.} =
   assert n.k == xnElement
   result = n.s[i]
 
+proc mget* (n: var XmlNode, i: int): var XmlNode {.inline.} = 
+  ## returns the `i`'th child of `n` so that it can be modified
+  assert n.k == xnElement
+  result = n.s[i]
+
 iterator items*(n: XmlNode): XmlNode {.inline.} = 
   ## iterates over any child of `n`.
   assert n.k == xnElement
   for i in 0 .. n.len-1: yield n[i]
 
+iterator mitems*(n: var XmlNode): var XmlNode {.inline.} = 
+  ## iterates over any child of `n`.
+  assert n.k == xnElement
+  for i in 0 .. n.len-1: yield mget(n, i)
+
 proc attrs*(n: XmlNode): XmlAttributes {.inline.} = 
   ## gets the attributes belonging to `n`.
   ## Returns `nil` if attributes have not been initialised for this node.
diff --git a/lib/system.nim b/lib/system.nim
index 69a77b89b..8008cfe84 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1653,6 +1653,13 @@ iterator items*[T](a: openArray[T]): T {.inline.} =
     yield a[i]
     inc(i)
 
+iterator mitems*[T](a: var openArray[T]): var T {.inline.} =
+  ## iterates over each item of `a` so that you can modify the yielded value.
+  var i = 0
+  while i < len(a):
+    yield a[i]
+    inc(i)
+
 iterator items*[IX, T](a: array[IX, T]): T {.inline.} =
   ## iterates over each item of `a`.
   var i = low(IX)
@@ -1662,6 +1669,15 @@ iterator items*[IX, T](a: array[IX, T]): T {.inline.} =
       if i >= high(IX): break
       inc(i)
 
+iterator mitems*[IX, T](a: var array[IX, T]): var T {.inline.} =
+  ## iterates over each item of `a` so that you can modify the yielded value.
+  var i = low(IX)
+  if i <= high(IX):
+    while true:
+      yield a[i]
+      if i >= high(IX): break
+      inc(i)
+
 iterator items*[T](a: set[T]): T {.inline.} =
   ## iterates over each element of `a`. `items` iterates only over the
   ## elements that are really in the set (and not over the ones the set is
@@ -1692,6 +1708,14 @@ iterator pairs*[T](a: openArray[T]): tuple[key: int, val: T] {.inline.} =
     yield (i, a[i])
     inc(i)
 
+iterator mpairs*[T](a: var openArray[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):
+    yield (i, a[i])
+    inc(i)
+
 iterator pairs*[IX, T](a: array[IX, T]): tuple[key: IX, val: T] {.inline.} =
   ## iterates over each item of `a`. Yields ``(index, a[index])`` pairs.
   var i = low(IX)
@@ -1701,6 +1725,16 @@ iterator pairs*[IX, T](a: array[IX, T]): tuple[key: IX, val: T] {.inline.} =
       if i >= high(IX): break
       inc(i)
 
+iterator mpairs*[IX, T](a: var array[IX, T]): tuple[key: IX, val: var T] {.inline.} =
+  ## iterates over each item of `a`. Yields ``(index, a[index])`` pairs.
+  ## ``a[index]`` can be modified.
+  var i = low(IX)
+  if i <= high(IX):
+    while true:
+      yield (i, a[i])
+      if i >= high(IX): break
+      inc(i)
+
 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
@@ -1708,6 +1742,14 @@ iterator pairs*[T](a: seq[T]): tuple[key: int, val: T] {.inline.} =
     yield (i, a[i])
     inc(i)
 
+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):
+    yield (i, a[i])
+    inc(i)
+
 iterator pairs*(a: string): tuple[key: int, val: char] {.inline.} =
   ## iterates over each item of `a`. Yields ``(index, a[index])`` pairs.
   var i = 0
@@ -1715,6 +1757,14 @@ iterator pairs*(a: string): tuple[key: int, val: char] {.inline.} =
     yield (i, a[i])
     inc(i)
 
+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):
+    yield (i, a[i])
+    inc(i)
+
 
 proc isNil*[T](x: seq[T]): bool {.noSideEffect, magic: "IsNil".}
 proc isNil*[T](x: ref T): bool {.noSideEffect, magic: "IsNil".}
@@ -2992,6 +3042,15 @@ iterator items*[T](a: seq[T]): T {.inline.} =
     inc(i)
     assert(len(a) == L, "seq modified 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.
+  var i = 0
+  let L = len(a)
+  while i < L:
+    yield a[i]
+    inc(i)
+    assert(len(a) == L, "seq modified while iterating over it")
+
 iterator items*(a: string): char {.inline.} =
   ## iterates over each item of `a`.
   var i = 0
@@ -3001,6 +3060,15 @@ iterator items*(a: string): char {.inline.} =
     inc(i)
     assert(len(a) == L, "string modified 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.
+  var i = 0
+  let L = len(a)
+  while i < L:
+    yield a[i]
+    inc(i)
+    assert(len(a) == L, "string modified while iterating over it")
+
 when not defined(nimhygiene):
   {.pragma: inject.}