From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,f4a284296951c45f X-Google-Attributes: gid103376,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news4.google.com!feeder1-2.proxad.net!proxad.net!feeder2-2.proxad.net!newsfeed.arcor.de!newsspool1.arcor-online.net!news.arcor.de.POSTED!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: Loosing tagged type via linked list Newsgroups: comp.lang.ada User-Agent: 40tude_Dialog/2.0.15.1 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Reply-To: mailbox@dmitry-kazakov.de Organization: cbb software GmbH References: Date: Sat, 9 Feb 2008 10:38:14 +0100 Message-ID: <33o7snkk4nse$.hlciu95e5jkn.dlg@40tude.net> NNTP-Posting-Date: 09 Feb 2008 10:38:14 CET NNTP-Posting-Host: 19eebee9.newsspool2.arcor-online.net X-Trace: DXC=1_hl2Kg51fXf8j24CD<3lPA9EHlD;3YcR4Fo<]lROoRQ^YC2XCjHcbYaaBEcCe=P9[WRXZ37ga[7ZjTA67ckJ=XURO6hcd[a0hRn2 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