Property definitions

cartesian $ CartesianIterator :: defaultinit
# 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