# 3.8.1 Variant Parts and Discrete Choices

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.

## Contents

## Syntax

variant_part ::=casediscriminant_direct_nameisvariant {variant}endcase;

variant ::=whendiscrete_choice_list => component_list

discrete_choice_list ::= discrete_choice {| discrete_choice}

discrete_choice ::= expression | discrete_range |others

## Name Resolution Rules

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

The discriminant of the variant_part shall be of a discrete type.

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.

A discrete_choice is defined to *cover a value* in the following cases:

- A discrete_choice that is an expression covers a value if the value equals the value of the expression converted to the expected type.
- A discrete_choice that is a discrete_range covers all values (possibly none) that belong to the range.
- The discrete_choice
**others**covers all values of its expected type that are not covered by previous discrete_choice_lists of the same construct.

A discrete_choice_list covers a value if one of its discrete_choices covers the value.

The possible values of the discriminant of a variant_part shall be covered as follows:

- 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**); - 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; - Otherwise, each value of the base range of the type of the discriminant shall be covered (either explicitly or by
**others**).

Two distinct discrete_choices of a variant_part shall not cover the same value.

## Static Semantics

If the component_list of a variant is specified by **null**, the variant has no components.

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

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.

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

*Example of record type with a variant part:*

```
type Device is (Printer, Disk, Drum);
type State is (Open, Closed);
```

```
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;
```

*Examples of record subtypes:*

```
subtype Drum_Unit is Peripheral(Drum);
subtype Disk_Unit is Peripheral(Disk);
```

*Examples of constrained record variables:*

```
Writer : Peripheral(Unit => Printer);
Archive : Disk_Unit;
```

Copyright © 1992,1993,1994,1995 Intermetrics, Inc.

Copyright © 2000 The MITRE Corporation, Inc.
Ada Reference Manual