Generalized Loop Iteration
Author: JTC1/SC22/WG9/ARG, by Randall Brukardt, ARG Editor

Ada Reference Manual — Legal Information

# 5.5.2 Generalized Loop Iteration

1/3
Generalized forms of loop iteration are provided by an iterator_specification.

#### Syntax

2/3
iterator_specification ::=
defining_identifier in [reverse] iterator_ name
| defining_identifier [: subtype_indication] of [reverse] iterable_ name

#### Name Resolution Rules

3/3
For the first form of iterator_specification, called a generalized iterator, the expected type for the iterator_ name is any iterator type. For the second form of iterator_specification, the expected type for the iterable_ name is any array or iterable container type. If the iterable_ name denotes an array object, the iterator_specification is called an array component iterator; otherwise it is called a container element iterator.

#### Legality Rules

4/3
If the reserved word reverse appears, the iterator_specification is a reverse iterator; otherwise it is a forward iterator. In a reverse generalized iterator, the iterator_ name shall be of a reversible iterator type. In a reverse container element iterator, the default iterator type for the type of the iterable_ name shall be a reversible iterator type.
5/3
The type of the subtype_indication, if any, of an array component iterator shall cover the component type of the type of the iterable_ name. The type of the subtype_indication, if any, of a container element iterator shall cover the default element type for the type of the iterable_ name.
6/3
In a container element iterator whose iterable_ name has type T, if the iterable_ name denotes a constant or the Variable_Indexing aspect is not specified for T, then the Constant_Indexing aspect shall be specified for T.

#### Static Semantics

7/3
An iterator_specification declares a loop parameter. In a generalized iterator, the nominal subtype of the loop parameter is the iteration cursor subtype. In an array component iterator or a container element iterator, if a subtype_indication is present, it determines the nominal subtype of the loop parameter. In an array component iterator, if a subtype_indication is not present, the nominal subtype of the loop parameter is the component subtype of the type of the iterable_ name. In a container element iterator, if a subtype_indication is not present, the nominal subtype of the loop parameter is the default element subtype for the type of the iterable_ name.
8/3
In a generalized iterator, the loop parameter is a constant. In an array component iterator, the loop parameter is a constant if the iterable_ name denotes a constant; otherwise it denotes a variable. In a container element iterator, the loop parameter is a constant if the iterable_ name denotes a constant, or if the Variable_Indexing aspect is not specified for the type of the iterable_ name; otherwise it is a variable.

#### Dynamic Semantics

9/3
For the execution of a loop_statement with an iterator_specification, the iterator_specification is first elaborated. This elaboration elaborates the subtype_indication, if any.
10/3
For a generalized iterator, the loop parameter is created, the iterator_ name is evaluated, and the denoted iterator object becomes the loop iterator. In a forward generalized iterator, the operation First of the iterator type is called on the loop iterator, to produce the initial value for the loop parameter. If the result of calling Has_Element on the initial value is False, then the execution of the loop_statement is complete. Otherwise, the sequence_of_statements is executed and then the Next operation of the iterator type is called with the loop iterator and the current value of the loop parameter to produce the next value to be assigned to the loop parameter. This repeats until the result of calling Has_Element on the loop parameter is False, or the loop is left as a consequence of a transfer of control. For a reverse generalized iterator, the operations Last and Previous are called rather than First and Next.
11/3
For an array component iterator, the iterable_ name is evaluated and the denoted array object becomes the array for the loop. If the array for the loop is a null array, then the execution of the loop_statement is complete. Otherwise, the sequence_of_statements is executed with the loop parameter denoting each component of the array for the loop, using a canonical order of components, which is last dimension varying fastest (unless the array has convention Fortran, in which case it is first dimension varying fastest). For a forward array component iterator, the iteration starts with the component whose index values are each the first in their index range, and continues in the canonical order. For a reverse array component iterator, the iteration starts with the component whose index values are each the last in their index range, and continues in the reverse of the canonical order. The loop iteration proceeds until the sequence_of_statements has been executed for each component of the array for the loop, or until the loop is left as a consequence of a transfer of control.
12/3
For a container element iterator, the iterable_ name is evaluated and the denoted iterable container object becomes the iterable container object for the loop. The default iterator function for the type of the iterable container object for the loop is called on the iterable container object and the result is the loop iterator. An object of the default cursor subtype is created (the loop cursor).
13/3
For a forward container element iterator, the operation First of the iterator type is called on the loop iterator, to produce the initial value for the loop cursor. If the result of calling Has_Element on the initial value is False, then the execution of the loop_statement is complete. Otherwise, the sequence_of_statements is executed with the loop parameter denoting an indexing (see 4.1.6) into the iterable container object for the loop, with the only parameter to the indexing being the current value of the loop cursor; then the Next operation of the iterator type is called with the loop iterator and the loop cursor to produce the next value to be assigned to the loop cursor. This repeats until the result of calling Has_Element on the loop cursor is False, or until the loop is left as a consequence of a transfer of control. For a reverse container element iterator, the operations Last and Previous are called rather than First and Next. If the loop parameter is a constant (see above), then the indexing uses the default constant indexing function for the type of the iterable container object for the loop; otherwise it uses the default variable indexing function.

#### Examples

14/3
-- Array component iterator example:
for Element of Board loop -- See 3.6.1.
Element := Element * 2.0; -- Double each element of Board, a two-dimensional array.
end loop;
15/3
For examples of use of generalized iterators, see A.18.32 and the corresponding container packages in A.18.2 and A.18.3.

Ada 2005 and 2012 Editions sponsored in part by Ada-Europe