comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Loosing tagged type via linked list
Date: Sat, 9 Feb 2008 10:38:14 +0100
Date: 2008-02-09T10:38:14+01:00	[thread overview]
Message-ID: <33o7snkk4nse$.hlciu95e5jkn.dlg@40tude.net> (raw)
In-Reply-To: aaa2346c-2135-48cb-9cb3-3e19dfb0e9c4@i29g2000prf.googlegroups.com

On Fri, 8 Feb 2008 17:05:58 -0800 (PST), jason.height@gmail.com wrote:

> I have an interesting problem where i need to store a bunch of
> procedure calls (for graphics displays) and the associated parameters
> for later calling (much like a macro call).
> 
> I am attempting this in Ada95, with my own Linked_List container impl,
> which seems to be destroying the type information. If anyone knows a
> Ada95 list implementation that can store items of different types
> (derived from a base type) then please let me know.
> 
> Ideally i would like the following method to always print B_Type:
> --------------------------------------------------------------------------------------------
> with Text_Io;
> with Ada.Tags; use Ada.Tags;
> with Linked_List;
> 
> procedure Test is
>   type A_Type is tagged record
>     null;
>   end record;
>   type B_Type is new A_Type with record
>     Int : Integer;
>   end record;
> 
>   A : A_Type;
>   B : B_Type := (Int => 1);
> 
>   package MyList is new Linked_List(A_Type);

This is the problem (or else a question) with your design. What is *the*
type of list items? Are they from A_Type or from A_Type'Class? Note that
these aren't same. (Unlikely to Java Ada is properly typed, so any object
has just one type)

My guess is that you wanted A_Type'Class. In that case the package
Linked_List need to be designed correspondingly and instantiated as

    package MyList is new Linked_List (A_Type'Class);

[ It can also be designed so that an instantiation looked

    package MyList is new Linked_List (A_Type);
       -- We say A_Type but actually mean A_Type'Class ]

>   The_List : MyList.List_Type;
>   Itr : MyList.List_Iterator;
> 
>   procedure DoPrint(Input : A_Type'Class) is
>   begin
>     Text_Io.Put_Line("Tag is "&Expanded_Name(Input'Tag));
>   end;
>   procedure DoPrintTypeCast(Input : A_Type) is
>   begin
>     DoPrint(Input);
>   end;
> begin
> 
>   --These all print TEST.B_Type
>   DoPrint(B);
>   DoPrint(A_Type(B));
>   DoPrintTypeCast(A_Type(B));
> 
>   --This prints TEST.A_Type!
>   --BAD List Impl?
>   MyList.Add(The_List, A_Type(B));
>   Itr := MyList.First(The_List);
>   DoPrint(MyList.Value(Itr));
> end;
> ------------------------------------------------------------------------------------
> 
> Here is the list spec. I was hoping that someone could spot my trouble
> right off. I must admit i am more at home with Java and C#, where the
> containers are built into the platform, so this one has had me stumped
> for a few days.
> 
> ------------------------------------------------------------------------------------------------------------------------------
> with Ada.Finalization; use Ada.Finalization;
> generic
>    type Item_Type is tagged private;
> package Linked_List is
>    type List_Type is new Limited_Controlled with private;
>    type List_Iterator is private;
> 
>    function First (List : List_Type) return List_Iterator;
> 
>    function Value (Iterator : List_Iterator) return Item_Type'Class;
> 
>    procedure Add (List : in out List_Type; Item : in Item_Type);
> 
> private
>    type Item_Record;
>    type Item_Access is access Item_Record;
> 
>    type Item_Record is record
>       Item : Item_Type;

This causes your problem. The type of Item is Item_Type and it becomes
A_Type upon instantiation. Note that semantically it should be:

       Item : Item_Type'Class;

which were illegal in Ada. Note that the following is also illegal:

   generic
       type Item_Type is (<>) private; -- This can take A_Type'Class
   package Linked_List is
       type Item_Record is record
           Item : Item_Type;

In both cases Item_Record were unconstrained and the compiler has no idea
where to get the constraint from. For this reason (with this particular
design) you have to use a pointer to Item_Type'Class (or to Item_Type when
unconstrained) instead. Upon copying a copy has to be allocated on the heap
and the list item should keep a pointer to it. When the item gets deleted
the copy it points to has to be freed.

Simple Components provide an Ada 95 implementation of lists. The items can
be of any type, including unconstrained ones (A_Type'Class is
unconstrained):

http://www.dmitry-kazakov.de/ada/components.htm#Generic_Doubly_Linked_Web

Differently to conventional designs like yours Simple Components do not
copy list items, but allocates them only once.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



      parent reply	other threads:[~2008-02-09  9:38 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-09  1:05 Loosing tagged type via linked list jason.height
2008-02-09  3:48 ` Georg Bauhaus
2008-02-09 11:40   ` Simon Wright
2008-02-10 17:11     ` Simon Wright
2008-02-09  9:38 ` Dmitry A. Kazakov [this message]
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox