A structural_generic_instance_name denotes the instance that is the
product of the structural instantiation of a generic unit on the specified
actual parameters. This instance is unique to a partition, except when a
generic subprogram instantiation is automatically demoted to a local
instantiation as described under Legality Rules.
Example:
with Ada.Containers.Vectors;
procedure P is
V : Ada.Containers.Vectors(Positive,Integer).Vector;
begin
V.Append (1);
V.Append (0);
Ada.Containers.Vectors(Positive,Integer).Generic_Sorting("<").Sort (V);
end;
This procedure references two structural instantiations of two different generic
units: Ada.Containers.Vectors(Positive,Integer) is the structural instance
of the generic unit Ada.Containers.Vectors on Positive and Integer
and Ada.Containers.Vectors(Positive,Integer).Generic_Sorting("<") is the
structural instance of the nested generic unit
Ada.Containers.Vectors(Positive,Integer).Generic_Sorting on "<".
Note that the following example is illegal:
with Ada.Containers.Vectors;
package Q is
type T is record
I : Integer;
end record;
V : Ada.Containers.Vectors(Positive,T).Vector;
end Q;
The reason is that Ada.Containers.Vectors, Positive and Q.T
being library-level entities, the structural instance Ada.Containers.Vectors(Positive,T) is a library unit with a dependence
on Q and, therefore, cannot be referenced from within Q. This
restriction applies to structural instantiations of generic packages. The simple
way out is to declare a traditional instantiation in this case:
with Ada.Containers.Vectors;
package Q is
type T is record
I : Integer;
end record;
package Vectors_Of_T is new Ada.Containers.Vectors(Positive,T);
V : Vectors_Of_T.Vector;
end Q;
But the following example is legal:
with Ada.Containers.Vectors;
procedure P is
type T is record
I : Integer;
end record;
V : Ada.Containers.Vectors(Positive,T).Vector;
end;
because the structural instance Ada.Containers.Vectors(Positive,T) is
not a library unit.
For generic subprograms, the restriction does not apply: if a local entity of a library-level package is used as an actual, the structural instantiation is automatically demoted to a local instantiation. For example:
with Ada.Unchecked_Deallocation;
package Q is
type T is record
I : Integer;
end record;
type T_Access is access T;
end Q;
package body Q is
procedure Free_T (X : in out T_Access) is
begin
Ada.Unchecked_Deallocation(T, T_Access)(X);
end Free_T;
end Q;
is legal: since T and T_Access are local entities of Q,
the structural instantiation of Ada.Unchecked_Deallocation is demoted
to a local instantiation rather than producing an error. Note that the
uniqueness guarantee no longer holds in this case and several instances of
the generic subprogram may be present in a single partition.
The first example can be rewritten in a less verbose manner:
with Ada.Containers.Vectors; use Ada.Containers.Vectors(Positive,Integer);
procedure P is
V : Vector;
begin
V.Append (1);
V.Append (0);
Generic_Sorting("<").Sort (V);
end;
Another example, which additionally uses the inference of dependent types:
with Ada.Unchecked_Deallocation; procedure P is type Integer_Access is access all Integer; A : Integer_Access := new Integer'(1); begin Ada.Unchecked_Deallocation(Name => Integer_Access) (A); end;