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. 
1.a
Discussion: {
cover a value [distributed]} 
Discrete_choice_lists 
and 
discrete_choices are said to 
cover 
values as defined below; which 
discrete_choice_list 
covers a value determines which of various alternatives is chosen. These 
are used in 
variant_parts, 
array_aggregates, 
and 
case_statements. 
 
Language Design Principles
1.b
The definition of “cover” in this 
subclause and the rules about discrete choices are designed so that they 
are also appropriate for array aggregates and case statements.
1.c
The rules of this subclause intentionally parallel 
those for case statements. 
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
{discriminant (of 
a variant_part)} 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. 
{expected 
type (variant_part discrete_choice) [partial]} The 
expected type for each 
discrete_choice in 
a 
variant is the type of the discriminant 
of the 
variant_part. 
 
6.a
Ramification: A full_type_declaration 
with a variant_part has to have a (new) known_discriminant_part; 
the discriminant of the variant_part cannot 
be an inherited discriminant. 
Legality Rules
7
The discriminant of the variant_part 
shall be of a discrete type. 
7.a
Ramification: It shall not be of an access 
type, named or anonymous.
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
{cover 
a value (by a discrete_choice) [partial]} 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. 
12.a
Ramification: For case_statements, 
this includes values outside the range of the static subtype (if any) 
to be covered by the choices. It even includes values outside the base 
range of the case expression's type, since values of numeric types (and 
undefined values of any scalar type?) can be outside their base range. 
13
{cover a value (by 
a discrete_choice_list) [partial]} 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;
16.a
Reason: The base range is not known statically 
in this case.
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
{govern a variant_part} 
{govern a variant} 
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
{elaboration (variant_part) 
[partial]} 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;
Extensions to Ada 83
29.a
{
extensions to Ada 83} 
In 
Ada 83, the discriminant of a 
variant_part 
is not allowed to be of a generic formal type. This restriction is removed 
in Ada 95; an 
others discrete_choice 
is required in this case. 
Wording Changes from Ada 83
29.b
The syntactic category choice 
is removed. The syntax rules for variant, 
array_aggregate, and case_statement 
now use discrete_choice_list or discrete_choice 
instead. The syntax rule for record_aggregate 
now defines its own syntax for named associations.
29.c
We have added the term Discrete Choice to the 
title since this is where they are talked about. This is analogous to 
the name of the subclause "Index Constraints and Discrete Ranges" 
in the clause on Array Types.
29.d
The rule requiring that the discriminant denote 
a discriminant of the type being defined seems to have been left implicit 
in RM83.