foreword

index

contents

structure


Containers of type LIST_

SIMPLE_LIST_

LIST_

HASH_LIST_

SORTED_LIST_

Classes SIMPLE_LIST_, LIST_, HASH_LIST_ and SORTED_LIST_ describe the containers of type LIST_ - the data structures in which the elements are arranged in a linear order: we know how they follow each other. Unlike an array, in which the linear order is determined by the array indices, the order in lists is determined by either an order in which the elements (items) are put into (SIMPLE_LIST_ and LIST_) or a total order relation based on the comparison of the elements (SORTED_LIST_) or their hash values - hash codes - (HASH_LIST_).

All the lists differ only in how their elements follow each other and that is why all of them have the same interface - only SORTED_LIST_ has some more additional features and SIMPLE_LIST_ has not features for backward traversing.

The instances of class SIMPLE_LIST_ represent so called singly linked lists - we can traverse these objects only in one direction: from the first element to the last one. Any new element is added to the end of the container (and becomes the last one at that time). The first element is the one put into a list earlier than all the others currently stored in the list. So, SIMPLE_LIST_ is based on a first_in, first-out, or FIFO, policy.

The instances of class LIST_ represent so called doubly linked lists. They differ from singly linked lists (SIMPLE_LIST_) only in one point: they can be traversed in the both directions: not only towards the last element but towards the first element also. In all other respects LIST_ and SIMPLE_LIST_ are the same (a new element is added to the end of the container also ...)

The instances of class HASH_LIST_ represent lists in which direct addressing into ordinary array takes place. Instead of requesting an array index directly, the array index is computed from the element. It is evident that the elements with smaller indices are ordered before those with bigger ones. The following algorithm for computing these indices are used in HASH_LIST_:

hash_index := x.hash_code \\ capacity + 1

where x is a descendant of class HASHABLE (part of the Eiffel Kernel), capacity is a feature of all the containers and \\ - integer remainder in Eiffel.

Class HASH_LIST_ describes a data structure which can give the programmer extremely fast operations of type search, put or remove. The efficiency of these operations depends solely on how well x.hash_code \\ capacity + 1 distributes the set of the elements to be stored among capacity slots. Formally the answer is very simple - 'hash_code' of class HASHABLE should be proper defined but, unfortunately, how to do that is beyond our discussion here ...

The instances of class SORTED_LIST_ represent data structures in which the elements are arranged according to the total order relation based on the comparing features - like `<` (less than) - defined or introduced in class COMPARABLE (part of the Eiffel Kernel). The smallest element is the first element in the linear order of SORTED_LIST_ and the largest one is the last element - all the others are surely put between them.

A FIFO policy is used for duplicates if they are allowed to be stored in a container of type LIST_.

While handling any list the programmer can get in return not only the exceptions issued or raised by the Eiffel Kernel classes but also the container ones. These exceptions are being explained separately. The rest of the chapter are some extracts from the short (a kind of) forms of the classes.


SIMPLE_CONTAINER_

top

index

contents

structure

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

deferred class interface

	SIMPLE_CONTAINER_

feature -- Operations

	make (is_unique: BOOLEAN)
			-- tells the container if its entries must be unique
		deferred

feature -- Queries

	empty: BOOLEAN
			-- is the container empty ?

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

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

invariant

	no_miracle: count >= 0 and then count <= capacity

end

CONTAINER_

top

index

contents

structure

indexing
	title: "The manner of adding entries into non-keyed containers"

deferred class interface

	CONTAINER_[G]

inherit
	SIMPLE_CONTAINER_

feature -- Operations

	put (x: G)
			-- adds the new entry into the structure
		require
			dummy: False -- the real require's are to be defined later ...
		deferred

end

SIMPLE_LIST_

top

index

contents

structure

indexing
	title: "Simple lists: containers with one element entries%
		%implementing a first-in, first-out policy and supporting%
		%only restricted traversal in one direction"

class intarface

	SIMPLE_LIST_[G]

inherit
	CONTAINER_[G]
	SIMPLE_TRAVERSABLE_

creation
	make

feature -- Operations

	allocate_automatically
			-- switches the list to the mode of automatic memory allocation
			-- for new slots; it can be necessary only if 'allocate_manually'
			-- was called before because, by default, all types of the lists
			-- allocate memory automatically

	allocate_manually (new_capacity: INTEGER)
			-- forbids the list to allocate memory for new slots automatically
			-- and sets the total amount of slots allocated in the list to be
			-- equal to 'new_capacity' - being negligent after that in manual
			-- allocating extra slots for new entries to be put might lead to
			-- the exception of type SCFL ("container is full")
		require
			no_obstacle:     not is_protected;
			proper_capacity:
				new_capacity >= count and then
				new_capacity > 0

	make (is_unique: BOOLEAN)
			-- tells the container if its entries must be unique

	merge (other: like Current)
			-- puts all entries from 'other' into the list
		require
			no_obstacle:    not is_protected;
			valid_argument: other /= Void
		ensure
			well_done: count = old count + other.count

	put (x: G)
			-- adds the entry into the list
		require else
			valid_argument: x /= Void;
			no_obstacle:    not is_protected;
			uniqueness:     unique_items implies not has_item (x)
		ensure then
			well_done: not empty and then has_item (x)

	remove (x: G)
			-- deletes the entry from the list
		require
			no_obstacle:    not is_protected;
			valid_argument: x /= Void;
			valid_target:   has_item (x)
		ensure
			well_done: count = old count - 1

	remove_all (x: G)
			-- deletes the entry from the list together with all its
			-- duplicates if more than one copy is currently stored
		require
			no_obstacle:    not is_protected;
			valid_argument: x /= Void;
			valid_target:   has_item (x)
		ensure
			well_done: old count > count and then not has_item (x)

	search (x: G)
			-- looks for the element: after every successful attempt 'found'
			-- is set to True and 'found_item' - to the found element;
			-- in case of failure 'found' is set to False
		require
			valid_argument: x /= Void

	wipe_out
			-- removes all entries from the list
		require
			no_obstacle: not is_protected
		ensure
			well_done: empty

feature -- Queries

	count: INTEGER
			-- number of the entries currently stored in the list or
			-- equally the number of slots used

	found: BOOLEAN
			-- was the last search successful ?

	found_item: G
			-- the entry found by the very last call to search;
			-- the value is valid if and only if 'found' = True

	unique_items: BOOLEAN
			-- must the entries be unique ?

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

	count_of (x: G): INTEGER
			-- gives the number of the duplicates of the entry inclusive; if
			-- 'unique_items' = True then the number can be only zero or one
		require
			valid_argument: x /= Void
		ensure
			well_done: Result <= count

	cursor_at (x: G): SIMPLE_CURSOR_
			-- delivers a new cursor positioned to the entry; if there is no
			-- such entry currently stored in the list Void is delivered
		require
			valid_argument: x /= Void
		ensure
			well_done: Result /= Void implies is_protected

	has_item (x: G): BOOLEAN
			-- is the entry currently stored in the list ?
		require
			valid_argument: x /= Void

	item_at (cs: SIMPLE_CURSOR_): G
			-- delivers the entry of the list the cursor is positioned to
		require
			proper_cursor: is_inside (cs)

feature {SIMPLE_CURSOR_}

	first (cs: SIMPLE_CURSOR_)
			-- positions on the first item
		ensure then
			well_done: not empty implies has_item (item_at (cs))

	forth (cs: SIMPLE_CURSOR_)
			-- moves one item forward
		ensure then
			well_done: not cs.is_finished implies has_item (item_at (cs))

end

LIST_

top

index

contents

structure

indexing
	title: "Lists: containers with one element entries implementing%
		%a first-in, first-out policy and supporting traversal in%
		%the both directions"

class interface

	LIST_[G]

inherit
	SIMPLE_LIST_[G]
		undefine
			cursor
		redefine
			cursor_at, item_at, make
	TRAVERSABLE_

creation
	make

feature -- Operations

	make (is_unique: BOOLEAN)
			-- tells the container if its entries must be unique

feature -- Queries

	item_at (cs: CURSOR_): G
			-- delivers the entry of the list the cursor is positioned to

	cursor_at (x: G): CURSOR_
			-- delivers a new cursor positioned to the entry; if there is no
			-- such entry currently stored in the list Void is delivered

feature {CURSOR_}

	last (cs: CURSOR_)
			-- positions on the last item
		ensure then
			well_done: not empty implies has_item (item_at (cs))

	back (cs: CURSOR_)
			-- moves one item backwards
		ensure then
			well_done: not cs.is_finished implies has_item (item_at (cs))

end

HASH_LIST_

top

index

contents

structure

indexing
	title: "Hash lists: containers which store its one element entries%
		%widely using their ability to be associated with integers"

class interface

	HASH_LIST_[G -> HASHABLE]

inherit
	LIST_[G]
		rename
			make as list_make
		export {NONE}
			list_make
		redefine
			list_make

creation
	make

feature -- Operations

	make (is_unique: BOOLEAN; initial_capacity: INTEGER)
			-- tells the container if its entries must be unique and sets
			-- the initial amount of slots to be allocated for storing entries
		require
			proper_initial_slots: initial_capacity > 0

end

SORTED_LIST_

top

index

contents

structure

indexing
	title: "Sorted lists: containers which store their one element entries%
		%in a total relation order (ascending) based on the operations%
		%of class COMPARABLE from the Eiffel Kernel"

class interface

	SORTED_LIST_[G -> COMPARABLE]

inherit
	LIST_[G]
		redefine
			make

creation
	make

feature -- Operations

	make (is_unique: BOOLEAN)
			-- tells the container if its entries must be unique

feature -- Queries

	cursor_after (x: G): CURSOR_
			-- delivers a new cursor positioned to the entry closest to and
			-- greater than 'x' - the presence of entry 'x' is not essential
			-- but if currently there are at all no such entries in the list
			-- then Void is delivered
		require
			valid_argument: x /= Void
		ensure
			well_done: Result /= Void implies is_protected

	cursor_before (x: G): CURSOR_
			-- delivers a new cursor positioned to the entry closest to and
			-- less than 'x' - the presence of entry 'x' is not essential
			-- but if currently there are at all no such entries in the list
			-- then Void is delivered
		require
			valid_argument: x /= Void
		ensure
			well_done: Result /= Void implies is_protected

end

top

index

contents

structure


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