This is the interface for iterator objects. They implement an
interface to a collection or stream of data items and a cursor
that can be used to iterate over and examine individual items in
the data set.
Iterators are typically created to access a data set in some
specific object, array, mapping, multiset or string. An object can
have several iterators that access different data sets in it, or
the same in different ways. E.g. strings have both an iterator for
access char-by-char (String.Iterator ), and another for access
over splitted substrings (String.SplitIterator ).
lfun::_get_iterator may be defined in an object to get an
instance of the canonical iterator type for it. It's used by e.g.
foreach to iterate over objects conveniently.
It's not an error to advance an iterator past the beginning or end
of the data set; `!() will only return true then, and index
and value will return UNDEFINED . An iterator in that state
need not keep track of positions, so it's undefined what happens
if it's "moved back" into the set of items.
Backward movement for iterators is optional. It's supported if and
only if `-() is defined, but even then it's undefined how far
back the iterator can move. Therefore iterators may support only a
limited amount of backward movement, e.g. when they access a
stream through a limited buffer. If such an iterator is moved back
past the limit then it'll behave as if it's pointing entirely
outside the data set (see above).
An iterator that doesn't support backward movement at all should
throw an error if it's attempted.