note
	description: "Concrete version of an external iteration cursor for {READABLE_INDEXABLE}."
	library: "EiffelBase: Library of reusable components for Eiffel."
	status: "See notice at end of class."
	legal: "See notice at end of class."
	date: "$Date: 2017-02-09 12:11:51 +0000 (Thu, 09 Feb 2017) $"
	revision: "$Revision: 99809 $"

class 
	READABLE_INDEXABLE_ITERATION_CURSOR [G]

inherit
	TYPED_INDEXABLE_ITERATION_CURSOR [G, READABLE_INDEXABLE [G]]

create 
	make

feature {NONE} -- Initialization

	make (t: like target)
			-- Initialize cursor for target t.
		require
			t_attached: attached t
		do
			target := t
			if attached {VERSIONABLE} t as l_versionable then
				version := l_versionable.version
			else
				version := 0
			end
			step := 1
			is_reversed := False
		ensure
			target_set: target = t
			is_valid: is_valid
			default_step: step = 1
			ascending_traversal: not is_reversed
		end
	
feature -- Access

	cursor_index: INTEGER_32
			-- Index position of cursor in the iteration.
		do
			Result := ((target_index - first_index).abs + step - 1) // step + 1
		end

	target_index: INTEGER_32
			-- Index position of target structure for current iteration.

	first_index: INTEGER_32
			-- First valid index of target structure for current iteration.
			-- Note that if is_reversed, first_index might be greater than last_index.

	last_index: INTEGER_32
			-- Last valid index of target structure for current iteration.
			-- Note that if is_reversed, first_index might be greater than last_index.

	step: INTEGER_32
			-- Distance between successive iteration elements.

	new_cursor: like Current
			-- Restarted cursor of the iteration.
		do
			Result := twin;
			Result.start
		end

	reversed alias "-": like Current
			-- Reversed cursor of the iteration.
		do
			Result := twin;
			Result.reverse
		end

	incremented alias "+" (n: like step): like Current
			-- Cursor for the iteration with step increased by n.
		do
			Result := twin;
			Result.set_step (step + n)
		end

	decremented alias "-" (n: like step): like Current
			-- Cursor for the iteration with step decreased by n.
		do
			Result := twin;
			Result.set_step (step - n)
		end

	with_step (n: like step): like Current
			-- Cursor for the iteration with step set to n.
		do
			Result := twin;
			Result.set_step (n)
		end
	
feature -- Measurement

	version: NATURAL_32
			-- Current version.
		note
			option: transient
		attribute
		end
	
feature -- Status report

	after: BOOLEAN
			-- Are there no more items to iterate over?
		do
			Result := not is_valid or not target.valid_index (target_index)
		end

	is_reversed: BOOLEAN
			-- Are we traversing target structure backwards?

	is_valid: BOOLEAN
			-- Is the cursor still compatible with the associated underlying object?
		do
			Result := attached {VERSIONABLE} target as l_versionable implies l_versionable.version = version
		end

	is_first: BOOLEAN
			-- Is cursor at first position?
		do
			Result := target_index = first_index and then is_valid
		end

	is_last: BOOLEAN
			-- Is cursor at last position?
		do
			Result := target_index = last_index and then is_valid
		end
	
feature -- Status setting

	reverse
			-- Flip traversal order.
		do
			is_reversed := not is_reversed
		ensure
			is_reversed: is_reversed = not old is_reversed
		end

	set_step (v: like step)
			-- Set increment step to v.
		require
			v_positive: v > 0
		do
			step := v
		ensure
			step_set: step = v
		end
	
feature -- Cursor movement

	start
			-- Move to first position.
		local
			l_target: like target
		do
			l_target := target
			if is_reversed then
				first_index := l_target.upper
				last_index := l_target.lower
			else
				last_index := l_target.upper
				first_index := l_target.lower
			end
			target_index := first_index
		end

	forth
			-- Move to next position.
		do
			if is_reversed then
				target_index := target_index - step
			else
				target_index := target_index + step
			end
		ensure then
			cursor_index_advanced: cursor_index = old cursor_index + 1
		end
	
feature {TYPED_INDEXABLE_ITERATION_CURSOR}{TYPED_INDEXABLE_ITERATION_CURSOR} -- Access

	target: READABLE_INDEXABLE [G]
			-- Associated structure used for iteration.
	
note
	copyright: "Copyright (c) 1984-2017, Eiffel Software and others"
	license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
	source: "[
		Eiffel Software
		5949 Hollister Ave., Goleta, CA 93117 USA
		Telephone 805-685-1006, Fax 805-685-6869
		Website http://www.eiffel.com
		Customer support http://support.eiffel.com
	]"

end -- class READABLE_INDEXABLE_ITERATION_CURSOR

Generated by ISE EiffelStudio