Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Use of abstract tagged types without access types -- again and complete

111 views
Skip to first unread message

Prof. Dr. Carl Weierstrass

unread,
Jun 9, 2011, 1:50:12 PM6/9/11
to
Hi,

I have a question to all Ada gurus:

I want to do something like:

package Test is

type Parent_Type is new Ada.Finalization.Controlled with private;
type Child_Type is abstract new Ada.Finalization.Controlled with
private;
type Child_Type_1 is new Child_Type with private;
type Child_Type_N is new Child_Type with private;

private

type Parent_Type is new Ada.Finalization.Controlled with record
Child : Child_Type'Class;
end record;
type Child_Type is abstract new Ada.Finalization.Controlled with
null record;
type Child_Type_1 is new Child_Type with null record;
type Child_Type_N is new Child_Type with null record;

end Test;

This doesn't work, because:
class-wide subtype with unknown discriminants in component declaration

Of course I could use an access type to avoid the error but is there a
way to
do something like this without access types.


Regards

Ludovic Brenta

unread,
Jun 9, 2011, 4:19:19 PM6/9/11
to
"Prof. Dr. Carl Weierstrass" writes on comp.lang.ada:

> type Parent_Type is new Ada.Finalization.Controlled with record
> Child : Child_Type'Class;
> end record;
>
> This doesn't work, because:
> class-wide subtype with unknown discriminants in component declaration
>
> Of course I could use an access type to avoid the error but is there a
> way to do something like this without access types.

No. The reason is that the size of Child is unknown, so you cannot
encapsulate a Child into a Parent_Type, which has a fixed size. In
contrast, the size of an access value is fixed at comile time, so you
can encapsulate an access value in the Parent_Type.

What is it exactly that you want to achieve? Why do you think you need
a record of a specific type to contain a record of a class-wide type?
The reason I ask is because the usefulness of Parent_Type escapes me,
since you can simply pass objects of type Child_Type'Class to
subprograms so they dispatch dynamically.

Also, why do you want to avoid access values in this case? Would you be
happy with a reference-counted smart pointer instead?

--
Ludovic Brenta.

Georg Bauhaus

unread,
Jun 9, 2011, 4:41:57 PM6/9/11
to
On 6/9/11 7:50 PM, Prof. Dr. Carl Weierstrass wrote:
> This doesn't work, because:
> class-wide subtype with unknown discriminants in component declaration
>
> Of course I could use an access type to avoid the error but is there a
> way to
> do something like this without access types.

You can defer access types if this helps. An outline is below.
Maybe the SPARK people know how one may add polymorphic types
without pointers, or not.


with Test;
package Test_Test is

generic
type Expanded_Child_Type is new Test.Child_Type with private;
package Child_Pick is
type Some_Parent is new Test.Parent_Type with record
Child : Expanded_Child_Type;
end record;
end Child_Pick;

package Pick_1 is new Child_Pick (Test.Child_Type_1);

package Pick_N is new Child_Pick (Test.Child_Type_N);

end Test_Test;


with Test, Test_Test;
procedure Test_Test_Test is
type Ref is access Test.Parent_Type'Class;

X : Ref := new Test_Test.Pick_1.Some_Parent;
Y : Ref := new Test_Test.Pick_N.Some_Parent;
begin
X := Y;
end Test_Test_Test;


Randy Brukardt

unread,
Jun 9, 2011, 5:06:40 PM6/9/11
to
"Ludovic Brenta" <lud...@ludovic-brenta.org> wrote in message
news:87hb7yn...@ludovic-brenta.org...

> "Prof. Dr. Carl Weierstrass" writes on comp.lang.ada:
>> type Parent_Type is new Ada.Finalization.Controlled with record
>> Child : Child_Type'Class;
>> end record;
>>
>> This doesn't work, because:
>> class-wide subtype with unknown discriminants in component declaration
>>
>> Of course I could use an access type to avoid the error but is there a
>> way to do something like this without access types.
>
> No. The reason is that the size of Child is unknown, so you cannot
> encapsulate a Child into a Parent_Type, which has a fixed size. In
> contrast, the size of an access value is fixed at comile time, so you
> can encapsulate an access value in the Parent_Type.

Not quite accurrate -- an access type is necessary somewhere, but it doesn't
have to be visible.

Specifically, use the Holder container for this purpose:

package Child_Holder is new Ada.Containers.Indefinite_Holders
(Child_Type'Class);

type Parent_Type is new Ada.Finalization.Controlled with record

Child : Child_Holder.Holder;
end record;

This is a slight complication when using the component (you have to use
Element and Replace_Element to access the contents), but it is usually
better than writing all of this storage management yourself.

The only downside is whether your Ada compiler supports this container (it
was added after Ada 2005 was finished, early in the Ada 2012 process). It's
used in the latest ASIS (that's why it was invented), so a compiler
supporting ASIS for Ada 2005 probably supports the container.

If your compiler doesn't yet support this container, it's easy enough to
create it yourself rather than using explicit access types.

Randy.


Prof. Dr. Carl Weierstrass

unread,
Jun 10, 2011, 11:43:45 AM6/10/11
to
On 9 Jun., 23:06, "Randy Brukardt" <ra...@rrsoftware.com> wrote:
> "Ludovic Brenta" <ludo...@ludovic-brenta.org> wrote in message

Thank you very much. I think that this could be the solution that I
was looking for.
In case of many children I considered using an
Ada.Containers.Indefinite_Vectors type,
but I was looking for a solution when the is only one child.
Unfortunately I'am using
GNAT GPL 2010 and can't find that container in the library.

Any idea, where I can find an implementation? I hope it will be in the
next GNAT GPL 2011
version.

Regards

Alex R. Mosteo

unread,
Jun 12, 2011, 8:05:09 AM6/12/11
to
Prof. Dr. Carl Weierstrass wrote:

I've been using this 'holder' approach for years. If you don't have the
official, the simplest way is to make your own with any other of the
standard containers, and a simplified spec.

Migration to the true Holder would later be a matter of seconds with a
single search/replace if you take care to respect the subprogram names.

>
> Regards

0 new messages