Go to the first, previous, next, last section, table of contents.
-
A composite type (other than an array type) can have discriminants,
which parameterize the type. A known_discriminant_part specifies the
discriminants of a composite type. A discriminant of an object is a
component of the object, and is either of a discrete type or an access
type. An unknown_discriminant_part in the declaration of a partial view
of a type specifies that the discriminants of the type are unknown for
the given view; all subtypes of such a partial view are indefinite
subtypes.
Syntax
-
discriminant_part ::=
unknown_discriminant_part | known_discriminant_part
-
unknown_discriminant_part ::= (<>)
-
known_discriminant_part ::=
(discriminant_specification {; discriminant_specification})
-
discriminant_specification ::=
defining_identifier_list : subtype_mark
[:= default_expression]
| defining_identifier_list : access_definition
[:= default_expression]
-
default_expression ::= expression
Name Resolution Rules
-
The expected type for the default_expression of a
discriminant_specification is that of the corresponding discriminant.
Legality Rules
-
A known_discriminant_part is only permitted in a declaration for a
composite type that is not an array type (this includes generic formal
types); a type declared with a known_discriminant_part is called a
discriminated type, as is a type that inherits (known) discriminants.
-
The subtype of a discriminant may be defined by a subtype_mark, in which
case the subtype_mark shall denote a discrete or access subtype, or it
may be defined by an access_definition (in which case the subtype_mark
of the access_definition may denote any kind of subtype). A discriminant
that is defined by an access_definition is called an access discriminant
and is of an anonymous general access-to-variable type whose designated
subtype is denoted by the subtype_mark of the access_definition.
-
A discriminant_specification for an access discriminant shall appear
only in the declaration for a task or protected type, or for a type with
the reserved word limited in its (full) definition or in that of one of
its ancestors. In addition to the places where Legality Rules normally
apply, See section 12.3 Generic Instantiation, this rule applies also in the private part of an
instance of a generic unit.
-
Default_expressions shall be provided either for all or for none of the
discriminants of a known_discriminant_part. No default_expressions are
permitted in a known_discriminant_part in a declaration of a tagged type
or a generic formal type.
-
For a type defined by a derived_type_definition, if a
known_discriminant_part is provided in its declaration, then:
-
The parent subtype shall be constrained;
-
If the parent type is not a tagged type, then each discriminant of the
derived type shall be used in the constraint defining the parent
subtype;
-
If a discriminant is used in the constraint defining the parent subtype,
the subtype of the discriminant shall be statically compatible,
See section 4.9.1 Statically Matching Constraints and Subtypes, with the subtype of the corresponding parent discriminant.
-
The type of the default_expression, if any, for an access discriminant
shall be convertible to the anonymous access type of the discriminant,
See section 4.6 Type Conversions.
Static Semantics
-
A discriminant_specification declares a discriminant; the subtype_mark
denotes its subtype unless it is an access discriminant, in which case
the discriminant's subtype is the anonymous access-to-variable subtype
defined by the access_definition.
-
For a type defined by a derived_type_definition, each discriminant of
the parent type is either inherited, constrained to equal some new
discriminant of the derived type, or constrained to the value of an
expression. When inherited or constrained to equal some new
discriminant, the parent discriminant and the discriminant of the
derived type are said to correspond. Two discriminants also correspond
if there is some common discriminant to which they both correspond. A
discriminant corresponds to itself as well. If a discriminant of a
parent type is constrained to a specific value by a
derived_type_definition, then that discriminant is said to be specified
by that derived_type_definition.
-
A constraint that appears within the definition of a discriminated type
depends on a discriminant of the type if it names the discriminant as a
bound or discriminant value. A component_definition depends on a
discriminant if its constraint depends on the discriminant, or on a
discriminant that corresponds to it.
-
A component depends on a discriminant if:
-
Its component_definition depends on the discriminant; or
-
It is declared in a variant_part that is governed by the discriminant;
or
-
It is a component inherited as part of a derived_type_definition, and
the constraint of the parent_subtype_indication depends on the
discriminant; or
-
It is a subcomponent of a component that depends on the
discriminant.
-
Each value of a discriminated type includes a value for each component
of the type that does not depend on a discriminant; this includes the
discriminants themselves. The values of discriminants determine which
other component values are present in the value of the discriminated
type.
-
A type declared with a known_discriminant_part is said to have known
discriminants; its first subtype is unconstrained. A type declared with
an unknown_discriminant_part is said to have unknown discriminants. A
type declared without a discriminant_part has no discriminants, unless
it is a derived type; if derived, such a type has the same sort of
discriminants (known, unknown, or none) as its parent (or ancestor)
type. A tagged class-wide type also has unknown discriminants. Any
subtype of a type with unknown discriminants is an unconstrained and
indefinite subtype, See section 3.2 Types and Subtypes, and See section 3.3 Objects and Named Numbers.
Dynamic Semantics
-
An access_definition is elaborated when the value of a corresponding
access discriminant is defined, either by evaluation of its
default_expression or by elaboration of a discriminant_constraint. The
elaboration of an access_definition creates the anonymous access type.
When the expression defining the access discriminant is evaluated, it is
converted to this anonymous access type, See section 4.6 Type Conversions.
NOTES
-
(50) If a discriminated type has default_expressions for its
discriminants, then unconstrained variables of the type are permitted,
and the values of the discriminants can be changed by an assignment to
such a variable. If defaults are not provided for the discriminants,
then all variables of the type are constrained, either by explicit
constraint or by their initial value; the values of the discriminants of
such a variable cannot be changed after initialization.
-
(51) The default_expression for a discriminant of a type is evaluated
when an object of an unconstrained subtype of the type is created.
-
(52) Assignment to a discriminant of an object (after its
initialization) is not allowed, since the name of a discriminant is a
constant; neither assignment_statements nor assignments inherent in
passing as an in out or out parameter are allowed. Note however that the
value of a discriminant can be changed by assigning to the enclosing
object, presuming it is an unconstrained variable.
-
(53) A discriminant that is of a named access type is not called an
access discriminant; that term is used only for discriminants defined by
an access_definition.
Examples
-
Examples of discriminated types:
-
type Buffer(Size : Buffer_Size := 100) is -- See section 3.5.4 Integer Types
record
Pos : Buffer_Size := 0;
Value : String(1 .. Size);
end record;
-
type Matrix_Rec(Rows, Columns : Integer) is
record
Mat : Matrix(1 .. Rows, 1 .. Columns); -- See section 3.6 Array Types
end record;
-
type Square(Side : Integer) is new
Matrix_Rec(Rows => Side, Columns => Side);
-
type Double_Square(Number : Integer) is
record
Left : Square(Number);
Right : Square(Number);
end record;
type Item(Number : Positive) is
record
Content : Integer;
-- no component depends on the discriminant
end record;
- 3.7.1: Discriminant Constraints
- 3.7.2: Operations of Discriminated Types
Go to the first, previous, next, last section, table of contents.