Ansgar Esztermann
Ansgar Esztermann

Reputation: 251

Rules for formal incomplete types in Ada 2012

According to AI05-213, generics can now be instantiated with incomplete types. I would like to use this to build opaque containers: several packages define private types and matching containers. However, I would like the containers to derive from a common Containers.Container type that would provide some simple subprograms (e.g. Clear, Is_Empty, Iterate). For the latter, the type of elements to be stored in the container is needed, so package Containers has to be generic.

I couldn't get my code to compile, so I've experimented a bit. It seems that I can use a tagged type, but not a class-wide type, nor a child of a tagged type.

Why is this so? Any idea how to implement a simple container abstraction that works with private elements, and with various concrete containers (e.g. Map, Linked List, Set)?

Code used for testing:

actual.ads

with Containers;

package Actual is
   type Element is tagged private;
   type Sub_Element is new Element with private;
   package List is new Containers (Element_Type => Element'class); --error
   package Another is new Containers (Element_Type => Element); --ok
   package Still_Another is new Containers (Element_Type => Sub_Element); --error
private
   type Element is tagged null record;
   type Sub_Element is new Element with null record;
end Actual;

containers.ads

generic
   type Element_Type (<>) is tagged;
package Containers is
   type Container is abstract tagged null record;
end Containers;

Upvotes: 2

Views: 858

Answers (1)

manuBriot
manuBriot

Reputation: 2715

Moving the Element type to another package changes the whole issue, since there is then no longer an issue with a premature use of type with private component. It might be a compiler error (and the current Pro version still shows the two errors), but I am not so sure.

In practice, though, using incomplete types like you do is unlikely to be very useful I think. There is basically nothing you can do about the Element_Type in the containers package, since you know exactly nothing about it except that it is tagged. You can't store such an element (which is indefinite).

Using dynamic dispatching is also pretty bad for performance. I have recently spent a lot of time measuring things, and I recommend that you do early in your design as well. You will see that the cost of the dynamic dispatching is pretty costly. My own experience is that it is best to use generics for that approach. If I may be allowed a shameless plug, you might find a recent blog post interesting if you are designing containers: http://blog.adacore.com/traits-based-containers

Upvotes: 2

Related Questions