3.8.1 Variant Parts and Discrete Choices
1
A record type with a variant_part
specifies alternative lists of components. Each variant
defines the components for the value or values of the discriminant covered
by its discrete_choice_list.
Syntax
2
variant_part ::=
case discriminant_direct_name is
variant
{
variant}
end case;
3
variant ::=
when discrete_choice_list =>
component_list
4
discrete_choice_list ::= discrete_choice {|
discrete_choice}
5
discrete_choice ::= expression |
discrete_range |
others
Name Resolution Rules
6
The
discriminant_direct_name
shall resolve to denote a discriminant (called the
discriminant of
the variant_part) specified in
the
known_discriminant_part of the
full_type_declaration
that contains the
variant_part.
The
expected type for each
discrete_choice in
a
variant is the type of the discriminant
of the
variant_part.
Legality Rules
7
The discriminant of the variant_part
shall be of a discrete type.
8
The expressions and discrete_ranges
given as discrete_choices in a variant_part
shall be static. The discrete_choice others
shall appear alone in a discrete_choice_list,
and such a discrete_choice_list, if it appears,
shall be the last one in the enclosing construct.
9
A
discrete_choice is defined to
cover a value
in the following cases:
10
- A discrete_choice
that is an expression covers a value if the
value equals the value of the expression converted
to the expected type.
11
- A discrete_choice
that is a discrete_range covers all values
(possibly none) that belong to the range.
12
- The discrete_choice
others covers all values of its expected type that are not covered
by previous discrete_choice_lists of the same
construct.
13
A
discrete_choice_list
covers a value if one of its
discrete_choices
covers the value.
14
The possible values
of the discriminant of a variant_part shall
be covered as follows:
15
- If the discriminant is of a static
constrained scalar subtype, then each non-others discrete_choice
shall cover only values in that subtype, and each value of that subtype
shall be covered by some discrete_choice (either
explicitly or by others);
16
- If the type of the discriminant is
a descendant of a generic formal scalar type then the variant_part
shall have an others discrete_choice;
17
- Otherwise, each value of the base
range of the type of the discriminant shall be covered (either explicitly
or by others).
18
Two distinct discrete_choices
of a variant_part shall not cover the same
value.
Static Semantics
19
If the component_list
of a variant is specified by null,
the variant has no components.
20
The discriminant
of a
variant_part is said to
govern
the
variant_part and its
variants.
In addition, the discriminant of a derived type governs a
variant_part
and its
variants if it corresponds (see
3.7)
to the discriminant of the
variant_part.
Dynamic Semantics
21
A record value contains the values of the components
of a particular variant only if the value
of the discriminant governing the variant
is covered by the discrete_choice_list of
the variant. This rule applies in turn to
any further variant that is, itself, included
in the component_list of the given variant.
22
The elaboration of a
variant_part
consists of the elaboration of the
component_list
of each
variant in the order in which they
appear.
Examples
23
Example of record
type with a variant part:
24
type Device is (Printer, Disk, Drum);
type State is (Open, Closed);
25
type Peripheral(Unit : Device := Disk) is
record
Status : State;
case Unit is
when Printer =>
Line_Count : Integer range 1 .. Page_Size;
when others =>
Cylinder : Cylinder_Index;
Track : Track_Number;
end case;
end record;
26
Examples of record
subtypes:
27
subtype Drum_Unit is Peripheral(Drum);
subtype Disk_Unit is Peripheral(Disk);
28
Examples of constrained
record variables:
29
Writer : Peripheral(Unit => Printer);
Archive : Disk_Unit;