diff options
author | reactormonk <hafnersimon@gmail.com> | 2015-02-01 05:19:47 +0500 |
---|---|---|
committer | reactormonk <hafnersimon@gmail.com> | 2015-02-01 05:19:47 +0500 |
commit | 014be3a29c7c4691cde5b446a04fe522e008ea34 (patch) | |
tree | 7a69e58657270b029982c4e2796fb6c3219e120b | |
parent | ab5b8f53914c92875d72b278f966092426d57323 (diff) | |
parent | 69d96b604bd953011749fa01af4363130c0ecd0f (diff) | |
download | Nim-014be3a29c7c4691cde5b446a04fe522e008ea34.tar.gz |
Merge pull request #2020 from def-/mitems
mitems and mpairs
-rw-r--r-- | lib/pure/collections/lists.nim | 16 | ||||
-rw-r--r-- | lib/pure/collections/queues.nim | 9 | ||||
-rw-r--r-- | lib/pure/json.nim | 14 | ||||
-rw-r--r-- | lib/pure/poly.nim | 2 | ||||
-rw-r--r-- | lib/pure/xmltree.nim | 10 | ||||
-rw-r--r-- | lib/system.nim | 90 | ||||
-rw-r--r-- | tests/stdlib/tmitems.nim | 136 |
7 files changed, 276 insertions, 1 deletions
diff --git a/lib/pure/collections/lists.nim b/lib/pure/collections/lists.nim index 2770a3950..095775cbb 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 fb4d35310..af5e7b6cd 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/poly.nim b/lib/pure/poly.nim index 286e5a8fd..58dcdc1ad 100644 --- a/lib/pure/poly.nim +++ b/lib/pure/poly.nim @@ -58,7 +58,7 @@ proc `[]=` *(p:var Poly;idx:int,v:float)= iterator items*(p:Poly):float= - ## Iterates through the corfficients of the polynomial. + ## Iterates through the coefficients of the polynomial. var i=p.degree while i>=0: yield p[i] 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..12c5c6303 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 @@ -1680,6 +1696,13 @@ iterator items*(a: cstring): char {.inline.} = yield a[i] inc(i) +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) + iterator items*(E: typedesc[enum]): E = ## iterates over the values of the enum ``E``. for v in low(E)..high(E): @@ -1692,6 +1715,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 +1732,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 +1749,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 +1764,29 @@ 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) + +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) + +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) + proc isNil*[T](x: seq[T]): bool {.noSideEffect, magic: "IsNil".} proc isNil*[T](x: ref T): bool {.noSideEffect, magic: "IsNil".} @@ -2992,6 +3064,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 +3082,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.} diff --git a/tests/stdlib/tmitems.nim b/tests/stdlib/tmitems.nim new file mode 100644 index 000000000..2297f0ee9 --- /dev/null +++ b/tests/stdlib/tmitems.nim @@ -0,0 +1,136 @@ +discard """ + output: '''@[11, 12, 13] +@[11, 12, 13] +@[1, 3, 5] +@[1, 3, 5] +gppcbs +gppcbs +fpqeew +fpqeew +[11, 12, 13] +[11, 12, 13] +[11, 12, 13] +[11, 12, 13] +{ "key1": 11, "key2": 12, "key3": 13} +[ 11, 12, 13] +<Students> + <Student Name="Aprilfoo" /> + <Student Name="bar" /> +</Students>''' +""" + +block: + var xs = @[1,2,3] + for x in xs.mitems: + x += 10 + echo xs + +block: + var xs = [1,2,3] + for x in xs.mitems: + x += 10 + echo(@xs) + +block: + var xs = @[1,2,3] + for i, x in xs.mpairs: + x += i + echo xs + +block: + var xs = [1,2,3] + for i, x in xs.mpairs: + x += i + echo(@xs) + +block: + var x = "foobar" + for c in x.mitems: + inc c + echo x + +block: + var x = "foobar" + var y = cast[cstring](addr x[0]) + for c in y.mitems: + inc c + echo x + +block: + var x = "foobar" + for i, c in x.mpairs: + inc c, i + echo x + +block: + var x = "foobar" + var y = cast[cstring](addr x[0]) + for i, c in y.mpairs: + inc c, i + echo x + +import lists + +block: + var sl = initSinglyLinkedList[int]() + sl.prepend(3) + sl.prepend(2) + sl.prepend(1) + for x in sl.mitems: + x += 10 + echo sl + +block: + var sl = initDoublyLinkedList[int]() + sl.append(1) + sl.append(2) + sl.append(3) + for x in sl.mitems: + x += 10 + echo sl + +block: + var sl = initDoublyLinkedRing[int]() + sl.append(1) + sl.append(2) + sl.append(3) + for x in sl.mitems: + x += 10 + echo sl + +import queues + +block: + var q = initQueue[int]() + q.add(1) + q.add(2) + q.add(3) + for x in q.mitems: + x += 10 + echo q + +import json + +block: + var j = parseJson """{"key1": 1, "key2": 2, "key3": 3}""" + for key,val in j.pairs: + val.num += 10 + echo j + +block: + var j = parseJson """[1, 2, 3]""" + for x in j.mitems: + x.num += 10 + echo j + +import xmltree, xmlparser, streams, strtabs + +block: + var d = parseXml(newStringStream """<Students> + <Student Name="April" Gender="F" DateOfBirth="1989-01-02" /> + <Student Name="Bob" Gender="M" DateOfBirth="1990-03-04" /> + </Students>""") + for x in d.mitems: + x = <>Student(Name=x.attrs["Name"] & "foo") + d.mget(1).attrs["Name"] = "bar" + echo d |