This package provides facilities for manipulating simple list structures.
Note that safety is a key feature of this package - so, for example,
any attempt to access a deleted list element will be detected and an
An empty list is created by declaring a variable of type List_Type. Data
elements can then be added to the list via the subprograms Prepend and
Append. Note that data is copied into the list - pointers are not
retained to the original data.
All data elements can be removed from a list via subprogram Delete_All.
When applied to an empty list, Is_Empty will return True.
A list can be assigned to another. The target list will be emptied then loaded with
a copy of each data element in the source list. The copying will be done such that
the ordering of the data elements in each list will be the same.
Two lists can be compared for equality. To be equal they must have equal data elements
at corresponding positions. Two empty lists are considered equal.
The elements in a list can be accessed via an enumerator: the client software
declares a variable of type Enumerator_Type which it then attaches to a list via
the function New_Enumerator. A list can have any number of enumerators.
At any one time an enumerator denotes a single element in its associated list. This
element is termed the "current" element. Initially current will be set to the first
element in the list; the following subprograms allow current to move to a different
element: Goto_Next, Goto_Previous, Goto_First, Goto_Last.
The following subprograms allow an enumerator's current element to be retrieved,
changed, or deleted: Current, Update and Delete. Note that after Delete, current
still denotes the same point in the list, even though the associated data
element no longer exists.
The subprogram Insert allows a new data element to be added to the list either
before or after the current element. After the insertion, current will be set to
the new data element.
When current is at the start of a list, Is_First will return True,.
When current is at the end of a list, Is_Last will return True.
If current exists Current_Exists will return True (current will not exist if
the element denoted by current has been deleted, or if the associated list is empty).
If the list associated with an enumerator exists List_Exists will return True
(a list can cease to exist if the list's variable goes out of scope).
An enumerator can be assigned to another enumerator. The target enumerator will then
be associated with the same list and denote the same current element.
Two enumerators can be compared for equality. They must be associated with the same
list and their current elements must be the same element.
Note that two or more enumerators can change the same list; changes made via one
enumerator will be visible to the other enumerators. However, concurrent access
from more than one task is not supported; concurrent access may well lead to list
and enumerator corruption.
Note also that the storage associated with lists and enumerators is automatically deallocated
when their variables go out of scope.
Stream input/output can be used with lists via the stream oriented attributes List_Type'Write
See 'doubly_linked_list.ads' for further details on how to use the package. Also see
'list_examples.adb' for examples of its use.
doubly_linked_list.ads + doubly_linked_list.adb spec + body for the package.
list_examples.ads + list_examples.adb spec + body for the examples.
run_list_examples.adb procedure to run the examples.
Compile the files in the normal way and, for the examples, run gnatmake on
The package uses only standard Ada features so should be widely portable.
It has been successfully run on Debian GNU/Linux 2.2 using GNAT 3.12p.
A previous version ran successfully on Windows 95.
Contributed by: Robert A. Matthews
Contributed on: November 22, 2001
License: The GNAT-modified GPL is used for doubly_linked_list.ads/adb. The other files use the GPL.