Contents   Index   Search   Previous   Next


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
11
12
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
16
16.a
Reason: The base range is not known statically in this case.
17
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.

Contents   Index   Search   Previous   Next   Legal