# An iterator over a `Cartesian`-product collection.
class CartesianIterator[E,F]
super Iterator[Pair[E,F]]
# The associated Cartesian-product collection.
var collection: Cartesian[E,F]
# The iterator over the first collection of the Cartesian product.
# Will be used only once.
private var ice: Iterator[E] is noinit
# The iterator over the second collection of the Cartesian product.
# Will be used once for each element of the first collection.
private var icf: Iterator[F] is noinit
init do
# Initialize each iterator
ice = collection.ce.iterator
icf = collection.cf.iterator
end
redef fun is_ok do return ice.is_ok and icf.is_ok
redef fun item do
# We lazily create the pair here
var res = item_cache
if res == null then
res = new Pair[E,F](ice.item, icf.item)
item_cache = res
end
return res
end
# Cached pair created by `item` and cleared by `next`.
private var item_cache: nullable Pair[E,F] = null
redef fun next do
# Next item in the second iterator
icf.next
if not icf.is_ok then
# If it is over, then reset it and advance the first iterator
icf = collection.cf.iterator
ice.next
end
# Reset the cache
item_cache = null
end
# First member of `item`.
#
# This method shortcut the allocation of a `Pair`, thus should be more time and memory efficient.
fun item_e: E do return ice.item
# Second member of `item`.
#
# This method shortcut the allocation of a `Pair`, thus should be more time and memory efficient.
fun item_f: E do return icf.item
end
lib/cartesian/cartesian.nit:125,1--182,3