According to the manual:
An inline iterator is an iterator that's always inlined by the compiler leading to zero overhead for the abstraction, but may result in a heavy increase in code size. Inline iterators are second class citizens; They can be passed as parameters only to other inlining code facilities like templates, macros and other inline iterators.
In the end, all solutions resorted to using closure iterators instead. So is it possible to pass inline iterator to other inline iterator, if yes how? If no, I think manual should be updated.
Test case with Python-like enumerate:
let s = @[1, 2, 3, 4, 5]
iterator values[T](s: seq[T]): T {.inline.}=
# copy of `items` to test without its special meaning
for val in s:
yield val
iterator enumerate[T](it: iterator {. inline .}): auto {.inline.}=
var i = 0
for val in it:
yield (i, val)
inc i
iterator enumerate2[T](s: seq[T], it: iterator(a: seq[T]): T {. inline .}): T {.inline.}=
var i = 0
for val in s.it:
yield (i, val)
inc i
# for tup in s.values.enumerate:
# echo tup
# inline_it.nim(21, 20) Error: type mismatch: got (int)
# but expected one of:
# iterator enumerate[T](it: iterator): auto
for tup in enumerate2(s, values):
echo tup
# inline_it.nim(27, 22) template/generic instantiation from here
# inline_it.nim(16, 15) Error: type mismatch: got (int)
# but expected one of:
# iterator items[IX, T](a: array[IX, T]): T
# iterator items(E: typedesc[enum]): E:type
# iterator items(a: string): char
# iterator items[T](s: Slice[T]): T
# iterator items[T](a: openArray[T]): T
# iterator items[T](a: set[T]): T
# iterator items[T](a: seq[T]): T
# iterator items(a: cstring): char
Hi,
Unfortunately I am on vacation without access to my workstation with nim, so code will be schematic. This kind of approach works for me:
type InlineIterator[T] = iterator: T {.inline.}
let s = @[1, 2, 3, 4, 5]
iterator values: type(s[0]) {.inline.} =
# Make argumentless iterator
for val in s:
yield val
iterator enumerate[T](it: InlineIterator[T]): (int,T) {.inline.} =
var i = 0
for val in it():
yield (i, val)
inc i
for tup in enumerate(values):
echo tup
Indeed, I get this error:
playground_it.nim(17, 21) template/generic instantiation from here
playground_it.nim(13, 16) Error: type mismatch: got (int)
but expected one of:
iterator items[IX, T](a: array[IX, T]): T
iterator items(E: typedesc[enum]): E:type
iterator items(a: string): char
iterator items[T](s: Slice[T]): T
iterator items[T](a: openArray[T]): T
iterator items[T](a: set[T]): T
iterator items[T](a: seq[T]): T
iterator items(a: cstring): char
I am not comfortable with modifying the compiler yet, I'll raise an issue on the bug tracker (or check if one is already existing)
Edit: issue already reported: https://github.com/nim-lang/Nim/issues/4516