4.3. Aggregates

[PREVIOUS][UP][NEXT]

An aggregate is a basic operation that combines component values into a composite value of a record or array type.

    aggregate ::=
       (component_association {, component_association}) 

    component_association ::=
       [choice {| choice} => ] expression 

Each component association associates an expression with components (possibly none). A component association is said to be named if the components are specified explicitly by choices; it is otherwise said to be positional. For a positional association, the (single) component is implicitly specified by position, in the order of the corresponding component declarations for record components, in index order for array components.

Named associations can be given in any order (except for the choice others), but if both positional and named associations are used in the same aggregate, then positional associations must occur first, at their normal position. Hence once a named association is used, the rest of the aggregate must use only named associations. Aggregates containing a single component association must always be given in named notation. Specific rules concerning component associations exist for record aggregates and array aggregates.

Choices in component associations have the same syntax as in variant parts (see 3.7.3). A choice that is a component simple name is only allowed in a record aggregate. For a component association, a choice that is a simple expression or a discrete range is only allowed in an array aggregate; a choice that is a simple expression specifies the component at the corresponding index value; similarly a discrete range specifies the components at the index values in the range. The choice others is only allowed in a component association if the association appears last and has this single choice; it specifies all remaining components, if any.

Each component of the value defined by an aggregate must be represented once and only once in the aggregate. Hence each aggregate must be complete and a given component is not allowed to be specified by more than one choice.

The type of an aggregate must be determinable solely from the context in which the aggregate appears, excluding the aggregate itself, but using the fact that this type must be composite and not limited. The type of an aggregate in turn determines the required type for each of its components.

Notes:

The above rule implies that the determination of the type of an aggregate cannot use any information from within the aggregate. In particular, this determination cannot use the type of the expression of a component association, or the form or the type of a choice. An aggregate can always be distinguished from an expression enclosed by parentheses: this is a consequence of the fact that named notation is required for an aggregate with a single component.

References: array aggregate, array type, basic operation, choice, component, composite type, composite value, discrete range, expression, index, limited type, primary, record aggregate, record type, simple expression, simple name, type, variant part.

Sub-topics:

4.3.1. Record Aggregates

[UP][NEXT]

If the type of an aggregate is a record type, the component names given as choices must denote components (including discriminants) of the record type. If the choice others is given as a choice of a record aggregate, it must represent at least one component. A component association with the choice others or with more than one choice is only allowed if the represented components are all of the same type. The expression of a component association must have the type of the associated record components.

The value specified for a discriminant that governs a variant part must be given by a static expression (note that this value determines which dependent components must appear in the record value).

For the evaluation of a record aggregate, the expressions given in the component associations are evaluated in some order that is not defined by the language. The expression of a named association is evaluated once for each associated component. A check is made that the value of each subcomponent of the aggregate belongs to the subtype of this subcomponent.

The exception CONSTRAINT_ERROR is raised if this check fails.

Example of a record aggregate with positional associations:

    (4, JULY, 1776)                      --  see 3.7 

Examples of record aggregates with named associations:

    (DAY => 4, MONTH => JULY, YEAR => 1776)
    (MONTH => JULY, DAY => 4, YEAR => 1776) 

    (DISK, CLOSED, TRACK => 5, CYLINDER => 12)       --  see 3.7.3
    (UNIT => DISK, STATUS => CLOSED, CYLINDER => 9, TRACK => 1) 

Example of component association with several choices:

    (VALUE => 0, SUCC|PRED => new CELL'(0, null, null))   --  see 3.8.1

    --  The allocator is evaluated twice:  SUCC and PRED designate
        different cells

Note:

For an aggregate with positional associations, discriminant values appear first since the discriminant part is given first in the record type declaration; they must be in the same order as in the discriminant part.

References: aggregate, allocator, choice, component association, component name, constraint, constraint_error exception, depend on a discriminant, discriminant, discriminant part, evaluate, expression, in some order, program, raising of exceptions, record component, record type, satisfy, static expression, subcomponent, subtype, type, variant part.

4.3.2. Array Aggregates

[PREVIOUS][UP]

If the type of an aggregate is a one-dimensional array type, then each choice must specify values of the index type, and the expression of each component association must be of the component type.

If the type of an aggregate is a multidimensional array type, an n-dimensional aggregate is written as a one-dimensional aggregate, in which the expression specified for each component association is itself written as an (n-1)-dimensional aggregate which is called a subaggregate; the index subtype of the one-dimensional aggregate is given by the first index position of the array type. The same rule is used to write a subaggregate if it is again multidimensional, using successive index positions. A string literal is allowed in a multidimensional aggregate at the place of a one-dimensional array of a character type. In what follows, the rules concerning array aggregates are formulated in terms of one-dimensional aggregates.

Apart from a final component association with the single choice others, the rest (if any) of the component associations of an array aggregate must be either all positional or all named. A named association of an array aggregate is only allowed to have a choice that is not static, or likewise a choice that is a null range, if the aggregate includes a single component association and this component association has a single choice. An others choice is static if the applicable index constraint is static.

The bounds of an array aggregate that has an others choice are determined by the applicable index constraint. An others choice is only allowed if the aggregate appears in one of the following contexts (which defines the applicable index constraint):

  1. The aggregate is an actual parameter, a generic actual parameter, the result expression of a function, or the expression that follows an assignment compound delimiter. Moreover, the subtype of the corresponding formal parameter, generic formal parameter, function result, or object is a constrained array subtype.

    For an aggregate that appears in such a context and contains an association with an others choice, named associations are allowed for other associations only in the case of a (nongeneric) actual parameter or function result. If the aggregate is a multidimensional array, this restriction also applies to each of its subaggregates.

  2. The aggregate is the operand of a qualified expression whose type mark denotes a constrained array subtype.

  3. The aggregate is the expression of the component association of an enclosing (array or record) aggregate. Moreover, if this enclosing aggregate is a multidimensional array aggregate then it is itself in one of these three contexts.

The bounds of an array aggregate that does not have an others choice are determined as follows. For an aggregate that has named associations, the bounds are determined by the smallest and largest choices given. For a positional aggregate, the lower bound is determined by the applicable index constraint if the aggregate appears in one of the contexts (a) through (c); otherwise, the lower bound is given by S'FIRST where S is the index subtype; in either case, the upper bound is determined by the number of components.

The evaluation of an array aggregate that is not a subaggregate proceeds in two steps. First, the choices of this aggregate and of its subaggregates, if any, are evaluated in some order that is not defined by the language. Second, the expressions of the component associations of the array aggregate are evaluated in some order that is not defined by the language; the expression of a named association is evaluated once for each associated component. The evaluation of a subaggregate consists of this second step (the first step is omitted since the choices have already been evaluated).

For the evaluation of an aggregate that is not a null array, a check is made that the index values defined by choices belong to the corresponding index subtypes, and also that the value of each subcomponent of the aggregate belongs to the subtype of this subcomponent. For an n-dimensional multidimensional aggregate, a check is made that all (n-1)-dimensional subaggregates have the same bounds. The exception CONSTRAINT_ERROR is raised if any of these checks fails.

Note:

The allowed contexts for an array aggregate including an others choice are such that the bounds of such an aggregate are always known from the context.

Examples of array aggregates with positional associations:

    (7, 9, 5, 1, 3, 2, 4, 8, 6, 0)
    TABLE'(5, 8, 4, 1, others => 0)  --  see 3.6 

Examples of array aggregates with named associations:

    (1 .. 5 => (1 .. 8 => 0.0))     --  two-dimensional
    (1 .. N => new CELL)            --  N new cells, in particular for N =  0

    TABLE'(2 | 4 | 10 => 1, others => 0)
    SCHEDULE'(MON .. FRI => TRUE,  others => FALSE)  --  see 3.6
    SCHEDULE'(WED | SUN  => FALSE, others => TRUE)

Examples of two-dimensional array aggregates:

    -- Three aggregates for the same value of type MATRIX (see 3.6):

    ((1.1, 1.2, 1.3), (2.1, 2.2, 2.3))
    (1 => (1.1, 1.2, 1.3), 2 => (2.1, 2.2, 2.3))
    (1 => (1 => 1.1, 2 => 1.2, 3 => 1.3), 2 => (1 => 2.1, 2 => 2.2, 3 => 2.3)) 

Examples of aggregates as initial values:

  A : TABLE := (7, 9, 5, 1, 3, 2, 4, 8, 6, 0);        -- A(1)=7, A(10)= 8
  B : TABLE := TABLE'(2 | 4 | 10 => 1, others => 0);  -- B(1)=0, B(10)=1
  C : constant MATRIX := (1 .. 5 => (1 .. 8 => 0.0));
                                                 -- C'FIRST(1)=1, C'LAST(2)=8

  D : BIT_VECTOR(M .. N) := (M .. N => TRUE);  -- see 3.6
  E : BIT_VECTOR(M .. N) := (others => TRUE);
  F : STRING(1 .. 1) := (1 => 'F');  -- a one component aggregate: same as "F"

References: actual parameter, aggregate, array type, assignment compound delimiter, choice, component, component association, component type, constrained array subtype, constraint, constraint_error exception, dimension, evaluate, expression, formal parameter, function, in some order, index constraint, index range, index subtype, index type, named component association, null array, object, positional component association, qualified expression, raising of exceptions, static expression, subcomponent, type.


[INDEX][CONTENTS]