indexing
	description: "Objects that are able to iterate over linear structures"
	status: "See notice at end of class"
	names: iterators, iteration, linear_iterators, linear_iteration
	date: "$Date$"
	revision: "$Revision$"

class interface
	LINEAR_ITERATOR [G]

create 

	set (s: like target)
			-- Make s the new target of iterations.
		require -- from ITERATOR
			target_exists: s /= void
		ensure -- from ITERATOR
			target = s
			target /= void

feature -- Initialization

	set (s: like target)
			-- Make s the new target of iterations.
		require -- from ITERATOR
			target_exists: s /= void
		ensure -- from ITERATOR
			target = s
			target /= void
	
feature -- Access

	item: G
			-- The item at cursor position in target
		require
			traversable_exists: target /= void

	item_tuple: TUPLE [G]
			-- Tuple containing a single element,
			-- the item at cursor position in target''

	target: LINEAR [G]
			-- The structure to which iteration features will apply.
	
feature -- Status report

	invariant_value: BOOLEAN
			-- Is the invariant satisfied?
			-- (Redefinitions of this feature will usually involve
			-- target; if so, make sure that the result is defined
			-- when `target = Void'.)
			-- (from ITERATOR)
	
feature -- Cursor movement

	exhausted: BOOLEAN
			-- Is target exhausted?

	forth
			-- Move to next position of target.

	off: BOOLEAN
			-- Is position of target off?

	start
			-- Move to first position of target.
	
feature -- Implementation

	internal_item_tuple: TUPLE [G]
			-- Field holding the last item of target
	
feature -- Iteration

	continue_for (action: PROCEDURE [ANY, TUPLE [G]]; n, k: INTEGER)
			-- Apply action to every k-th item,
			-- n times if possible.
		require
			valid_repetition: n >= 0
			valid_skip: k >= 1

	continue_search (test: FUNCTION [ANY, TUPLE [G], BOOLEAN]; b: BOOLEAN)
			-- Search the first item of target
			-- satisfying: test equals to b
			-- (from the current position of target).
		ensure then
			found: not exhausted = (b = test.item (item_tuple))

	continue_until (action: PROCEDURE [ANY, TUPLE [G]]; test: FUNCTION [ANY, TUPLE [G], BOOLEAN])
			-- Apply action to every item of target up to
			-- and including first one satisfying test.
			-- (from the current position of target).
		require
			invariant_satisfied: invariant_value
		ensure then
			achieved: not exhausted implies test.item (item_tuple)

	continue_while (action: PROCEDURE [ANY, TUPLE [G]]; test: FUNCTION [ANY, TUPLE [G], BOOLEAN])
			-- Apply action to every item of target up to
			-- and including first one not satisfying test
			-- (from the current position of target).
		require else
			invariant_satisfied: invariant_value
		ensure then
			finished: not exhausted implies not test.item (item_tuple)

	do_all (action: PROCEDURE [ANY, TUPLE [G]])
			-- Apply action to every item of target.
			-- (from ITERATOR)
		require -- from ITERATOR
			action_exists: action /= void

	do_for (action: PROCEDURE [ANY, TUPLE [G]]; i, n, k: INTEGER)
			-- Apply action to every k-th item,
			-- n times if possible, starting from i-th.
		require
			valid_start: i >= 1
			valid_repetition: n >= 0
			valid_skip: k >= 1

	do_if (action: PROCEDURE [ANY, TUPLE [G]]; test: FUNCTION [ANY, TUPLE [G], BOOLEAN])
			-- Apply action to every item of target satisfying test.
			-- (from ITERATOR)
		require -- from ITERATOR
			action_exists: action /= void
			test_exists: test /= void

	do_until (action: PROCEDURE [ANY, TUPLE [G]]; test: FUNCTION [ANY, TUPLE [G], BOOLEAN])
			-- Apply action to every item of target up to
			-- and including first one satisfying test.
		require -- from ITERATOR
			action_exists: action /= void
			test_exists: test /= void
		ensure then
			achieved: not exhausted implies test.item (item_tuple)

	do_while (action: PROCEDURE [ANY, TUPLE [G]]; test: FUNCTION [ANY, TUPLE [G], BOOLEAN])
			-- Apply action to every item of target up to
			-- and including first one not satisfying test.
			-- (from the start of target)
		require -- from ITERATOR
			action_exists: action /= void
			test_exists: test /= void
		ensure then
			finished: not exhausted implies not test.item (item_tuple)

	for_all (test: FUNCTION [ANY, TUPLE [G], BOOLEAN]): BOOLEAN
			-- Does test return true for
			-- all items of target?
		require -- from ITERATOR
			test_exists: test /= void

	search (test: FUNCTION [ANY, TUPLE [G], BOOLEAN]; b: BOOLEAN)
			-- Search the first item of target for which test
			-- has the same value as b (both true or both false).

	there_exists (test: FUNCTION [ANY, TUPLE [G], BOOLEAN]): BOOLEAN
			-- Does test return true for
			-- at least one item of target?
		require -- from ITERATOR
			test_exists: test /= void

	until_continue (action: PROCEDURE [ANY, TUPLE [G]]; test: FUNCTION [ANY, TUPLE [G], BOOLEAN])
			-- Apply action to every item of target from current
			-- position, up to but excluding first one satisfying test.
		require
			invariant_satisfied: invariant_value
		ensure
			achieved: exhausted or else test.item (item_tuple)
			invariant_satisfied: invariant_value

	until_do (action: PROCEDURE [ANY, TUPLE [G]]; test: FUNCTION [ANY, TUPLE [G], BOOLEAN])
			-- Apply action to every item of target up to
			-- but excluding first one satisfying test.
			-- (Apply to full list if no item satisfies test.)
		require -- from ITERATOR
			action_exists: action /= void
			test_exists: test /= void
		ensure then
			achieved: not exhausted implies test.item (item_tuple)

	while_continue (action: PROCEDURE [ANY, TUPLE [G]]; test: FUNCTION [ANY, TUPLE [G], BOOLEAN])
			-- Apply action to every item of target up to
			-- but excluding first one not satisfying test.
		ensure
			finished: not exhausted implies not test.item (item_tuple)

	while_do (action: PROCEDURE [ANY, TUPLE [G]]; test: FUNCTION [ANY, TUPLE [G], BOOLEAN])
			-- Apply action to every item of target up to
			-- but excluding first one not satisfying test.
			-- (Apply to full list if all items satisfy test.)
		require -- from ITERATOR
			action_exists: action /= void
			test_exists: test /= void
		ensure then
			finished: not exhausted implies not test.item (item_tuple)
	
invariant

	target_exists: target /= void
	item_tuple_exists: item_tuple /= void
	internal_item_tuple_exists: internal_item_tuple /= void
		-- from ANY
	reflexive_equality: standard_is_equal (Current)
	reflexive_conformance: conforms_to (Current)
		-- from ITERATOR
	traversable_exists: target /= void

end -- class LINEAR_ITERATOR