IteratorInterfaceExtensions defines a small number of extensions to the iterator interface.
This package adds a couple of extensions to the standard iterator interface in julia.
isiterable
and getiterator
The first extension is comprised of the functions isiterable
and getiterator
. isiterable(x)
will return true
or false
, indicating whether x
can be iterated. It is important to note that a true
return value does not indicate that one can call the iterate
method on x
, instead a consumer must call getiterator(x)
if isiterable(x)
returned true
, and can then call iterate
on the instance that is returned by getiterator
. The proper pattern for consumer code therefore looks like this:
if isiterable(x)
it = getiterator(x)
for i in it
# Custom code
end
end
This consumer pattern will work with iterators that don't opt into the extensions in this package and with iterators that have opted into the extended interface defined in this package.
There are two scenarios when a source might participate in this extended iterator interface.
The first scenario is one where a source could not implement a type-stable version of iterate
because the primary source type lacks the necessary type information. Such a source can add a method to getiterator
that returns an instance of a different type with enough type information for a type stable implementation of the core iterator interface that iterates the elements of the original source.
Second, sometimes such a source might not want to implement the iterate
method at all for its core type. If that is the case, this source can add a method to isiterable
that returns true
, even though the source does not have a iterate
method. As long as this source still implements the getiterator
function, it still complies with the extended iterator contract defined in this package.
IteratorSize2
IteratorSize2
extends Base.IteratorSize
with an additional return value, namely HasLengthAfterStart()
. An iterator consumer that can provide an optimized implementation for iterators that know their length after the first call to the iterate
method has, can call IteratorSize2
instead of Base.IteratorSize
. The return value will either be one of the possible return values of Base.IteratorSize
, or HasLengthAfterStart()
. If the return value is HasLengthAfterStart()
, the consumer can call length(x, state)
to obtain the number of elements the iterator will return. Here x
is the same value that iterate
was called on, and state
is the value returned by
iterate(x)
.
An iterator that implements IteratorSize2(x::MyType) = HasLengthAfterStart()
must also implement Base.IteratorSize(x::MyType) = Base.SizeUnknown()
.