note

	description:

		"Cursors for data structure traversals"

	library: "Gobo Eiffel Structure Library"
	copyright: "Copyright (c) 1999-2001, Eric Bezault and others"
	license: "MIT License"
	date: "$Date$"
	revision: "$Revision$"

deferred class DS_CURSOR [G]

inherit

	ANY
		redefine
			copy,
			is_equal
		end

	KL_IMPORTED_ANY_ROUTINES
		undefine
			copy,
			is_equal
		end

feature -- Access

	item: G
			-- Item at cursor position
		require
			not_off: not off
		do
			Result := container.cursor_item (Current)
		end

	container: DS_TRAVERSABLE [G]
			-- Data structure traversed
		deferred
		end

feature -- Status report

	off: BOOLEAN
			-- Is there no item at cursor position?
		do
			Result := container.cursor_off (Current)
		end

	same_position (other: like Current): BOOLEAN
			-- Is current cursor at same position as `other'?
		require
			other_not_void: other /= Void
		do
			Result := container.cursor_same_position (Current, other)
		end

	valid_cursor (other: like Current): BOOLEAN
			-- Is `other' a valid cursor according
			-- to current traversal strategy?
		require
			other_not_void: other /= Void
		do
			Result := container.valid_cursor (other)
		ensure
			Result implies container.valid_cursor (other)
		end

feature -- Cursor movement

	go_to (other: like Current)
			-- Move cursor to `other''s position.
		require
			other_not_void: other /= Void
			other_valid: valid_cursor (other)
		do
			container.cursor_go_to (Current, other)
		ensure
			same_position: same_position (other)
		end

feature -- Duplication

	copy (other: like Current)
			-- Copy `other' to current cursor.
		do
			if container /= Void and then not off then
				container.remove_traversing_cursor (Current)
			end
			standard_copy (other)
			next_cursor := Void
			if not off then
				container.add_traversing_cursor (Current)
			end
		end

feature -- Comparison

	is_equal (other: like Current): BOOLEAN
			-- Are `other' and current cursor at the same position?
		do
			if ANY_.same_types (Current, other) then
				Result := same_position (other)
			end
		end

feature {DS_TRAVERSABLE} -- Implementation

	next_cursor: DS_CURSOR [G]
			-- Next cursor
			-- (Used by `container' to keep track of traversing
			-- cursors (i.e. cursors associated with `container'
			-- and which are not currently `off').)

	set_next_cursor (a_cursor: like next_cursor)
			-- Set `next_cursor' to `a_cursor'.
		do
			next_cursor := a_cursor
		ensure
			next_cursor_set: next_cursor = a_cursor
		end

invariant

	container_not_void: container /= Void
	empty_constraint: container.is_empty implies off

end