foreword

examples

index

contents

structure


Dispensers

STACK_

QUEUE_

PRIORITY_QUEUE_

KEY_PRIORITY_QUEUE_

Dispensers are containers with access to only one entry, the "active entry". To access another entry the state of the dispenser must be changed. If for the same reason the dispenser must "be read out" the whole content can be copied into another container structure. Note that a dispenser can be only read from - that is exactly the opposite functionality of the other containers (lists and tables). This category of containers have four different dispensers being described by the following classes STACK_, QUEUE_, PRIORITY_QUEUE_, KEY_PRIORITY_QUEUE_. The effective dispensers are very simple. They differ mainly in the underlaying semantics. In any case functions 'list_of_elements' or 'table_of_elements' deliver the elements in the sequence they would be removed if this happened. The corresponding extracts from the short (a kind of) forms are put below.


SIMPLE_DISPENSER_

top

index

contents

structure

indexing
	title: "The project-wide universal properties: the class is%
		%an ancestor to all the dispensers"

deferred class interface

	SIMPLE_DISPENSER_[G]

feature -- Operations

	remove
			-- deletes the "active entry" and sets 'item' and possibly 'key'
			-- to another entry (algorithms of selecting a new "active entry"
			-- differ in all dispensers) or - Void if there are no more
			-- entries
		require
			not_empty: not empty
		deferred

feature -- Queries

	empty: BOOLEAN
			-- is the dispenser empty ?
		deferred

	item: G
			-- the "active entry" of the dispenser - in dispensers with two
			-- element entries attribute 'key' will be also considered as a
			-- part of the "active entry"

invariant

	correct_emptiness:
		(empty implies item = Void) and then
		(item = Void implies empty);
	proper_tuning:
		(not empty implies item /= Void) and then
		(item /= Void implies not empty)
end

DISPENSER_

top

index

contents

structure

indexing
	title: "Facilities for all the dispensers with one element entries"

deferred class interface

	DISPENSER_[G]

inherit
	CONTAINER_[G]
		export {NONE}
			make
	SIMPLE_DISPENSER_[G]

feature -- Queries

	capacity: INTEGER
			-- gives the number of all the slots allocated in the dispenser
			-- (all the dispensers may have not only slots occupied by the
			-- entries already put into but unused ones also)

	count: INTEGER
			-- gives the number of entries in the dispenser or equally
			-- the number of the slots used for storing the entries

	list_of_elements: LIST_[G]
			-- delivers all the entries of the dispenser in the order in
			-- which they would be repeatedly removed if it really happened
		deferred
		ensure
			well_done: not empty implies Result /= Void

end

KEYED_DISPENSER_

top

index

contents

structure

indexing
	title: "Facilities for the dispensers with two element entries"

deferred class interface

	KEYED_DISPENSER_[G, H]

inherit
	KEYED_CONTAINER_[G, H]
		export {NONE}
			make
	SIMPLE_DISPENSER_[G]

feature -- Queries

	key: H
			-- the other part of the "active entry" of the dispenser

	capacity: INTEGER
			-- gives the number of all the slots allocated in the dispenser
			-- (all the dispensers may have not only slots occupied by the
			-- entries already put into but unused ones also)

	count: INTEGER
			-- gives the number of entries in the dispenser or equally
			-- the number of the slots used for storing the entries

	table_of_elements: TABLE_[G, H]
			-- delivers all the entries of the dispenser in the order in
			-- which they would be repeatedly removing if it really happened
		deferred
		ensure
			well_done: not empty implies Result /= Void

end

STACK_

top

index

contents

structure

indexing
	title: "Stacks: dispensers implementing a last-in, first-out policy"

class interface

	STACK_[G]

inherit
	DISPENSER_[G]

feature -- Operations

	put (x: G)
			-- adds the new entry into the dispenser which immediately after
			-- becomes the "active entry" of the dispenser
		require else
			valid_argument: x /= Void
		ensure then
			well_done: count = old count + 1 and then x = item

	remove
			-- deletes the "active entry" and sets 'item' to the one most
			-- recently put into if at least one entry exists after the
			-- removal - if it does not then 'item' is set to Void

feature -- Queries

	list_of_elements: LIST_[G]
			-- delivers all the entries of the dispenser in the order in
			-- which they would be repeatedly removed if it really happened

end

QUEUE_

top

index

contents

structure

indexing
	title: "Queues: dispensers implementing a first-in, first-out policy"

class interface

	QUEUE_[G]

inherit
	DISPENSER_[G]

feature -- Operations

	put (x: G)
			-- adds the new entry into the dispenser
		require else
			valid_argument: x /= Void
		ensure then
			well_done: count = old count + 1

	remove
			-- deletes the "active entry" and sets 'item' to the one that has
			-- been in the dispenser for the longest time if there are no
			-- more entries after the removal - 'item' is set to Void
		ensure then
			well_done: count = old count - 1

feature -- Queries

	list_of_elements: LIST_[G]
			-- delivers all the entries of the dispenser in the order in
			-- which they would be repeatedly removed if it really happened

end

PRIORITY_QUEUE_

top

index

contents

structure

indexing
	title: "Priority queues: dispensers with one element entries%
		%in which only the largest element is accessed"

class interface

	PRIORITY_QUEUE_[G -> COMPARABLE]

inherit
	DISPENSER_[G]

feature -- Operations

	put (x: G)
			-- adds the new entry into the dispenser
		require else
			valid_argument: x /= Void
		ensure then
			well_done: count = old count + 1

	remove
			-- deletes the "active entry" and sets 'item' to the largest one
			-- among those still existing in the dispenser after the removal;
			-- if there are no more entries then 'item' is set to Void
		ensure then
			well_done: count = old count - 1

feature -- Queries

	list_of_elements: LIST_[G]
			-- delivers all the entries of the dispenser in the order in
			-- which they would be repeatedly removed if it really happened

end

KEY_PRIORITY_QUEUE_

top

index

contents

structure

indexing
	title: "Key priority queues: dispensers with two element entries%
		%in which only the entry with the largest key is accessed"

class interface

	KEY_PRIORITY_QUEUE_[G, H -> COMPARABLE]

inherit
	KEYED_DISPENSER_[G, H]

feature -- Operations

	put (x: G; k: H)
			-- adds the new entry into the dispenser
		require else
			valid_item: x /= Void;
			valid_key:  k /= Void
		ensure then
			well_done: count = old count + 1

	remove
			-- deletes the "active entry" and sets 'item' to the element
			-- associated with the largest key among those still existing in
			-- the dispenser after the removal and 'key' to this key; if
			-- there are no more entries then 'item' and 'key' are both
			-- set to Void
		ensure then
			well_done: count = old count - 1

feature -- Queries

	table_of_elements: TABLE_[G, H]
			-- delivers all the entries of the dispenser in the order in
			-- which they would be repeatedly removed if it really happened

end

As it was mentioned above the effective dispensers are very simple. They differ only in the underlying semantics. In any case the functions 'list_of_elements' or 'table_of_elements' deliver the elements (items) in the sequence they would be removed should this really happened. This means that the following program parts would be equivalent:

-- some common stuff ...
x: DISPENSER;
	-- any real dispenser could be here: now
	-- it's only an example ...
cs: CURSOR_;
l: LIST_;

!!x;
--
-- putting some items into the dispenser ...
--

-- The first version
-- (note: the content of the dispenser is changed ...)

from
until
	x.empty
loop
	io.print (x.item);
	x.remove
end;
...

-- The second version
-- (note: the dispenser above remains unchanged ...)

from
	l := x.list_of_elements;
	cs := l.cursor
until
	cs.finish
loop
	io.print (l.item_at (cs));
	cs.forth
end;
...

top

index

contents

structure


© Object Tools -- info@object-tools.com -- December 1999