Ada Reference Manual (Ada 2022)Legal Information
Contents   Index   References   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.

Syntax

2
variant_part ::= 
   case discriminant_direct_name is
       variant
      {variant}
   end case;
3
variant ::= 
   when discrete_choice_list =>
      component_list
4/5
discrete_choice_list ::= discrete_choice {'|' discrete_choice}
5/3
discrete_choice ::= 
   choice_expression | discrete_subtype_indication | 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/3
The choice_expressions, subtype_indications, and 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/3
A discrete_choice that is a choice_expression covers a value if the value equals the value of the choice_expression converted to the expected type.
10.1/4
A discrete_choice that is a subtype_indication covers all values (possibly none) that belong to the subtype and that satisfy the static predicates of the subtype (see 3.2.4).
11/3
A discrete_choice that is a 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/4
If the discriminant is of a static constrained scalar subtype then, except within an instance of a generic unit, each non-others discrete_choice shall cover only values in that subtype that satisfy its predicates, and each value of that subtype that satisfies its predicates shall be covered by some discrete_choice (either explicitly or by others);
16/3
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.
21.1/3
  When an object of a discriminated type T is initialized by default, Constraint_Error is raised if no discrete_choice_list of any variant of a variant_part of T covers the value of the discriminant that governs the variant_part. When a variant_part appears in the component_list of another variant V, this test is only applied if the value of the discriminant governing V is covered by the discrete_choice_list of V. 
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;

Contents   Index   References   Search   Previous   Next 
Ada-Europe Ada 2005 and 2012 Editions sponsored in part by Ada-Europe