Go to the first, previous, next, last section, table of contents.
-
In addition to the various language-defined classes of types, types can
be grouped into derivation classes.
Static Semantics
-
A derived type is derived from its parent type directly; it is derived
indirectly from any type from which its parent type is derived. The
derivation class of types for a type T (also called the class rooted at
T) is the set consisting of T (the root type of the class) and all types
derived from T (directly or indirectly) plus any associated universal or
class-wide types (defined below).
-
Every type is either a specific type, a class-wide type, or a universal
type. A specific type is one defined by a type_declaration, a
formal_type_declaration, or a full type definition embedded in a
declaration for an object. Class-wide and universal types are implicitly
defined, to act as representatives for an entire class of types, as
follows:
-
Class-wide types
Class-wide types are defined for (and belong to) each derivation class
rooted at a tagged type, See section 3.9 Tagged Types and Type Extensions. Given a subtype S of a tagged type
T, S'Class is the subtype_mark for a corresponding subtype of the tagged
class-wide type T'Class. Such types are called "class-wide" because
when a formal parameter is defined to be of a class-wide type T'Class,
an actual parameter of any type in the derivation class rooted at T is
acceptable, See section 8.6 The Context of Overload Resolution.
-
The set of values for a class-wide type T'Class is the discriminated
union of the set of values of each specific type in the derivation class
rooted at T (the tag acts as the implicit discriminant -- See section 3.9 Tagged Types and Type Extensions.).
Class-wide types have no primitive subprograms of their own. However, as
explained in See section 3.9.2 Dispatching Operations of Tagged Types, operands of a class-wide type T'Class can be
used as part of a dispatching call on a primitive subprogram of the type
T. The only components (including discriminants) of T'Class that are
visible are those of T. If S is a first subtype, then S'Class is a first
subtype.
-
Universal types
Universal types are defined for (and belong to) the integer, real, and
fixed point classes, and are referred to in this standard as
respectively, universal_integer, universal_real, and universal_fixed.
These are analogous to class-wide types for these language-defined
numeric classes. As with class-wide types, if a formal parameter is of a
universal type, then an actual parameter of any type in the
corresponding class is acceptable. In addition, a value of a universal
type (including an integer or real numeric_literal) is "universal" in
that it is acceptable where some particular type in the class is
expected, See section 8.6 The Context of Overload Resolution.
-
The set of values of a universal type is the undiscriminated union of
the set of values possible for any definable type in the associated
class. Like class-wide types, universal types have no primitive
subprograms of their own. However, their "universality" allows them to
be used as operands with the primitive subprograms of any type in the
corresponding class.
-
The integer and real numeric classes each have a specific root type in
addition to their universal type, named respectively root_integer and
root_real.
-
A class-wide or universal type is said to cover all of the types in its
class. A specific type covers only itself.
-
A specific type T2 is defined to be a descendant of a type T1 if T2 is
the same as T1, or if T2 is derived (directly or indirectly) from T1. A
class-wide type T2'Class is defined to be a descendant of type T1 if T2
is a descendant of T1. Similarly, the universal types are defined to be
descendants of the root types of their classes. If a type T2 is a
descendant of a type T1, then T1 is called an ancestor of T2. The
ultimate ancestor of a type is the ancestor of the type that is not a
descendant of any other type.
-
An inherited component (including an inherited discriminant) of a
derived type is inherited from a given ancestor of the type if the
corresponding component was inherited by each derived type in the chain
of derivations going back to the given ancestor.
NOTES
-
(18) Because operands of a universal type are acceptable to the
predefined operators of any type in their class, ambiguity can result.
For universal_integer and universal_real, this potential ambiguity is
resolved by giving a preference, See section 8.6 The Context of Overload Resolution to the predefined operators
of the corresponding root types (root_integer and root_real,
respectively). Hence, in an apparently ambiguous expression like
-
1 + 4 < 7
-
where each of the literals is of type universal_integer, the predefined
operators of root_integer will be preferred over those of other specific
integer types, thereby resolving the ambiguity.
Go to the first, previous, next, last section, table of contents.