The declaration of generic parameters is not exhaustive enough to give type relationships (subtypes) and this information is simply lost… For example :
-- generic_p.ads
generic
type Index_Range_Type is range <>;
type Count_Range_Type is range <>;
procedure Generic_P (I : Index_Range_Type, C : Count_Range_Type);
-- generic_p.adb
procedure Generic_P (I : Index_Range_Type, C : Count_Range_Type) is
begin
if I = C then -- oops : cannot compare different types...
-- ...
end if;
end Generic_P;
-- main.adb
procedure Main is
type Index_Range_Type is 0 .. 512;
subtype Count_Range_Type is Index_Range_Type range 1 .. Index_Range_Type'Last;
procedure P is new Generic_P (Index_Range_Type, Count_Range_Type);
I : Index_Range_Type := 33;
C : Count_Range_Type := 42;
begin
if I = C then -- Ok : Count_Range is a subset of Index_Range, they can be compared
-- ...
end if;
P (I, C);
end Main;
Which gives the following error for the comparison in generic_p.adb : invalid operand types [...] left operand has type "Index_Range_Type" [...] right operand has "type Count_Range_Type". The subtyping is not visible in the generic procedure.
Is there any way to specify the relationship between generic parameters ?
Further Informations
I really need Count_Range_Type as a parameter of the procedure to be able to add another parameter which needs Count_Range_Type.
-- generic_p.ads
generic
type Index_Range_Type is range <>;
type Count_Range_Type is range <>;
with procedure F (C : Count_Range_Type);
procedure Generic_P (I : Index_Range_Type, C : Count_Range_Type);
I can’t directly use the type, I need P to be absolutely generic and independent.
This addresses the “Further Informations” portion of the original question, whereby a generic needs to be instantiated with a procedure containing a parameter that’s a subtype of the instantiating type.
Essentially, a generic package is employed to set up the subtype, and then a generic child package provides the desired procedure (which is instantiated with the generic formal procedure). Admittedly, this is a rather involved solution to the problem. So here we go:
The “parent” generic that creates the subtype:
All this does is declare the subtype, it needs no body (and in fact a body would be illegal).
Here’s the spec of our procedure provider, which utilizes a client-supplied formal procedure.
Just for grins, its body, which verifies that the formal procedure can be invoked and that the subtype comparison is valid:
Finally, the instantiating main program: