Containers#
Container Contracts
Many aspects have been excluded from the container specifications because of the verbosity of the contracts. Check the respective AARM pages for the full declarations and subprogram descriptions.
package Ada.Containers is
with Pure is
type Hash_Type is mod <implementation-defined>;
type Count_Type is range 0 .. <implementation-defined>;
Capacity_Error: exception;
end Ada.Containers;
Language-defined containers:
- Vectors
- Maps (hashed and ordered)
- Sets (hashed and ordered)
- Queues (synchronised and priority)
- Holders
- Doubly-Linked Lists
- Multiway Trees
Array Sorting#
The language-defined generic procedures Containers.Generic_Array_Sort
,
Containers.Generic_Constrained_Array_Sort
, and Containers.Generic_Sort
provide sorting on arbitrary
array types.
Ada.Containers.Generic_Array_Sort
generic
type Index_Type is (<>);
type Element_Type is private;
type Array_Type is array(Index_Type range <>) of Element_Type;
with function "<"(Left, Right: Element_Type) return Boolean is <>;
procedure Ada.Containers.Generic_Array_Sort(Container: in out Array_Type)
with Pure, Nonblocking, Global => null;
Ada.Containers.Generic_Constrained_Array_Sort
generic
type Index_Type is (<>);
type Element_Type is private;
type Array_Type is array(Index_Type) of Element_Type;
with function "<"(Left, Right: Element_Type) return Boolean is <>;
procedure Ada.Containers.Generic_Constrained_Array_Sort(Container: in out Array_Type)
with Pure, Nonblocking, Global => null;
Ada.Containers.Generic_Sort
generic
type Index_Type is (<>);
with function Before(Left, Right: Index_Type) return Boolean;
with procedure Swap (Left, Right: Index_Type);
procedure Ada.Containers.Generic_Sort(First, Last: Index_Type'Base)
with Pure, Nonblocking, Global => null;
Examples#
Dijkstra’s Shortest Path Algorithm
The following example is an implementation of Dijkstra’s shortest path algorithm in a directed graph with positive distances. The graph is represented by a map from nodes to sets of edges.
with Ada.Containers.Vectors;
with Ada.Containers.Doubly_Linked_Lists;
use Ada.Containers;
generic
type Node is range <>;
package Shortest_Paths is
type Distance is new Float range 0.0 .. Float'Last;
type Edge is record
To, From: Node;
Length : Distance;
end record;
package Node_Maps is new Vectors(Node, Node);
-- The algorithm builds a map to indicate the node used to reach a given
-- node in the shortest distance.
package Adjacency_Lists is new Doubly_Linked_Lists(Edge);
use Adjacency_Lists;
package Graphs is new Vectors(Node, Adjacency_Lists.List);
package Paths is new Doubly_Linked_Lists(Node);
function Shortest_Path(G: Graphs.Vector; Source: Node; Target: Node) return Paths.List
with Pre => G(Source) /= Adjacency_Lists.Empty_List;
end Shortest_Paths;
package body Shortest_Paths is
function Shortest_Path(G: Graphs.Vector; Source: Node; Target: Node) return Paths.List
is
use Adjacency_Lists, Node_Maps, Paths, Graphs;
Reached: array(Node) of Boolean := (others => False);
-- The set of nodes whose shortest distance to the source is known.
Reached_From : array(Node) of Node;
So_Far : array(Node) of Distance := (others => Distance'Last);
The_Path : Paths.List := Paths.Empty_List;
Nearest_Distance: Distance;
Next : Node;
begin
So_Far(Source) := 0.0;
while not Reached(Target) loop
Nearest_Distance := Distance'Last;
-- Find closest node not reached yet, by iterating over all nodes.
-- A more efficient algorithm uses a priority queue for this step.
Next := Source;
for N in Node'First .. Node'Last loop
if not Reached(N) and then So_Far(N) < Nearest_Distance then
Next := N;
Nearest_Distance := So_Far(N);
end if;
end loop;
if Nearest_Distance = Distance'Last then
-- No next node found, graph is not connected
return Paths.Empty_List;
else
Reached(Next) := True;
end if;
-- Update minimum distance to newly reachable nodes.
for E of G (Next) loop
if not Reached(E.To) then
Nearest_Distance := E.Length + So_Far(Next);
if Nearest_Distance < So_Far(E.To) then
Reached_From(E.To) := Next;
So_Far(E.To) := Nearest_Distance;
end if;
end if;
end loop;
end loop;
-- Rebuild path from target to source.
declare
N: Node := Target;
begin
Prepend(The_Path, N);
while N /= Source loop
N := Reached_From(N);
Prepend(The_Path, N);
end loop;
end;
return The_Path;
end;
end Shortest_Paths;