Property definitions

pipeline $ Iterator2 :: defaultinit
# Concatenates a sequence of iterators.
#
# Wraps an iterator of sub-iterators and iterates over the elements of the
# sub-iterators.
#
# ~~~nit
# var i: Iterator[Int]
# var empty = new Array[Int]
#
# i = new Iterator2[Int]([
# 	[1, 2, 3].iterator,
# 	empty.iterator,
# 	[4, 5].iterator
# ].iterator)
# assert i.to_a == [1, 2, 3, 4, 5]
#
# i = new Iterator2[Int]([
# 	empty.iterator,
# 	[42].iterator,
# 	empty.iterator
# ].iterator)
# assert i.to_a == [42]
# ~~~
#
# SEE: `Iterator::+`
class Iterator2[E]
	super Iterator[E]

	# The inner iterator over sub-iterators.
	var inner: Iterator[Iterator[E]]

	redef fun finish
	do
		var i = current_iterator
		if i != null then i.finish
	end

	redef fun is_ok
	do
		var i = current_iterator
		if i == null then return false
		return i.is_ok
	end

	redef fun item
	do
		var i = current_iterator
		assert i != null
		return i.item
	end

	redef fun next
	do
		var i = current_iterator
		assert i != null
		i.next
	end

	redef fun start
	do
		var i = current_iterator
		if i != null then i.start
	end

	private var previous_iterator: nullable Iterator[E] = null

	private fun current_iterator: nullable Iterator[E]
	do
		if previous_iterator == null then
			# Get the first sub-iterator.
			if inner.is_ok then
				previous_iterator = inner.item
				previous_iterator.start
				inner.next
			else
				return null
			end
		end
		# Get the first sub-iterator that has a current item.
		while inner.is_ok and not previous_iterator.is_ok do
			previous_iterator.finish
			previous_iterator = inner.item
			previous_iterator.start
			inner.next
		end
		return previous_iterator
	end
end
lib/pipeline/pipeline.nit:164,1--251,3