mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 01:14:41 +00:00
289 lines
8.6 KiB
Nim
289 lines
8.6 KiB
Nim
iterator items*[T](a: openArray[T]): T {.inline.} =
|
|
## Iterates over each item of `a`.
|
|
var i = 0
|
|
while i < len(a):
|
|
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)
|
|
if i <= high(IX):
|
|
while true:
|
|
yield a[i]
|
|
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
|
|
## able to hold).
|
|
var i = low(T).int
|
|
while i <= high(T).int:
|
|
if T(i) in a: yield T(i)
|
|
inc(i)
|
|
|
|
iterator items*(a: cstring): char {.inline.} =
|
|
## Iterates over each item of `a`.
|
|
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 mitems*(a: var cstring): var char {.inline.} =
|
|
## Iterates over each item of `a` so that you can modify the yielded value.
|
|
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):
|
|
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:
|
|
yield x
|
|
|
|
iterator pairs*[T](a: openArray[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):
|
|
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)
|
|
if i <= high(IX):
|
|
while true:
|
|
yield (i, a[i])
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
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.} =
|
|
## Iterates over each item of `a`.
|
|
var i = 0
|
|
let L = len(a)
|
|
while i < L:
|
|
yield a[i]
|
|
inc(i)
|
|
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.
|
|
var i = 0
|
|
let L = len(a)
|
|
while i < L:
|
|
yield a[i]
|
|
inc(i)
|
|
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`.
|
|
var i = 0
|
|
let L = len(a)
|
|
while i < L:
|
|
yield a[i]
|
|
inc(i)
|
|
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.
|
|
var i = 0
|
|
let L = len(a)
|
|
while i < L:
|
|
yield a[i]
|
|
inc(i)
|
|
assert(len(a) == L, "the length of the string changed while iterating over it")
|
|
|
|
|
|
iterator fields*[T: tuple|object](x: T): RootObj {.
|
|
magic: "Fields", noSideEffect.} =
|
|
## Iterates over every field of `x`.
|
|
##
|
|
## **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.
|
|
runnableExamples:
|
|
var t = (1, "foo")
|
|
for v in fields(t): v = default(type(v))
|
|
doAssert t == (0, "")
|
|
|
|
iterator fields*[S:tuple|object, T:tuple|object](x: S, y: T): tuple[key: string, val: RootObj] {.
|
|
magic: "Fields", noSideEffect.} =
|
|
## Iterates over every field of `x` and `y`.
|
|
##
|
|
## **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.
|
|
runnableExamples:
|
|
var t1 = (1, "foo")
|
|
var t2 = default(type(t1))
|
|
for v1, v2 in fields(t1, t2): v2 = v1
|
|
doAssert t1 == t2
|
|
|
|
iterator fieldPairs*[T: tuple|object](x: T): tuple[key: string, val: RootObj] {.
|
|
magic: "FieldPairs", noSideEffect.} =
|
|
## Iterates over every field of `x` returning their name and value.
|
|
##
|
|
## When you iterate over objects with different field types you have to use
|
|
## the compile time ``when`` instead of a runtime ``if`` to select the code
|
|
## you want to run for each type. To perform the comparison use the `is
|
|
## operator <manual.html#generics-is-operator>`_.
|
|
## Another way to do the same without ``when`` is to leave the task of
|
|
## picking the appropriate code to a secondary proc which you overload for
|
|
## each field type and pass the `value` to.
|
|
##
|
|
## **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.
|
|
runnableExamples:
|
|
type
|
|
Custom = object
|
|
foo: string
|
|
bar: bool
|
|
proc `$`(x: Custom): string =
|
|
result = "Custom:"
|
|
for name, value in x.fieldPairs:
|
|
when value is bool:
|
|
result.add("\n\t" & name & " is " & $value)
|
|
else:
|
|
result.add("\n\t" & name & " '" & value & "'")
|
|
|
|
iterator fieldPairs*[S: tuple|object, T: tuple|object](x: S, y: T): tuple[
|
|
key: string, a, b: RootObj] {.
|
|
magic: "FieldPairs", noSideEffect.} =
|
|
## Iterates over every field of `x` and `y`.
|
|
##
|
|
## **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.
|
|
runnableExamples:
|
|
type Foo = object
|
|
x1: int
|
|
x2: string
|
|
var a1 = Foo(x1: 12, x2: "abc")
|
|
var a2: Foo
|
|
for name, v1, v2 in fieldPairs(a1, a2):
|
|
when name == "x2": v2 = v1
|
|
doAssert a2 == Foo(x1: 0, x2: "abc")
|