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=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,616091a85ff150f1 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2001-12-05 11:57:29 PST Path: archiver1.google.com!news1.google.com!sn-xit-02!supernews.com!newsfeed.direct.ca!look.ca!howland.erols.net!news-out.worldnet.att.net.MISMATCH!wn3feed!worldnet.att.net!204.127.198.203!attbi_feed3!attbi.com!rwcrnsc53.POSTED!not-for-mail From: "Mark Lundquist" Newsgroups: comp.lang.ada References: <3C0C48BE.3B20F04E@adaworks.com> Subject: Access discriminants (was Re: Ada 200X Assertions) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.50.4133.2400 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 Message-ID: Date: Wed, 05 Dec 2001 19:57:28 GMT NNTP-Posting-Host: 204.127.202.216 X-Complaints-To: abuse@attbi.com X-Trace: rwcrnsc53 1007582248 204.127.202.216 (Wed, 05 Dec 2001 19:57:28 GMT) NNTP-Posting-Date: Wed, 05 Dec 2001 19:57:28 GMT Organization: AT&T Broadband Xref: archiver1.google.com comp.lang.ada:17469 Date: 2001-12-05T19:57:28+00:00 List-Id: Hi Lutz, "Lutz Donnerhacke" wrote in message news:slrna0seip.kq.lutz@taranis.iks-jena.de... > * Matthew Heaney wrote: > >"Lutz Donnerhacke" wrote in message > >> Problem 1: Pointer of component => Pointer to aggregate > [...] > >> Of course this Conversion may return a Pointer to an invalid aggregate. > > > >What on Earth are you trying to do here? > > I've a list of degenerated compound instantiations for which only a single > component is relevant. More than this, this same fixed component is shared > by multiple compound instantiations. > > Typical example 1: A common termination node of linked lists. > Typical example 2: A head node of a linked list contains a next pointer which > should be handled exactly as the next pointer of the real > list nodes, but no payload at all. Matt is right -- access discriminants are the solution to your problem. I didn't read his example -- maybe he didn't address your specific example, or maybe he did. Anyway, I know just the problem you're talking about, and this is the solution I came up with for my generic linked lists with header nodes. Access discriminants are the way for a component to provide a view of an enclosing record, regardless of the name used to access the component. Ada already has the exact feature you are asking for, all you need is the vocabulary to "say it in Ada". Here's an example for a singly-linked list. Start with something like this: type Root_Link; type Root_Link_Access is access all Root_Link'Class; type Root_Link is tagged limited record Next : Root_Link_Access; end record; That's your "degenerate" case, containing only the "relevant" component :-). It has to be limited so that its descendants can be limited and thereby be allowed access discriminants. Note that the pointer type is declared as an access-to-classwide; that's very important, it allows a link to point either to the header node or to a "real" node. Continuing on... type Node; type Node_Link (Self : access Node) is new Root_Link with null record; type Node is record Data : Data_Type; -- Whatever Linkage : Node_Link (Self => Node'Access); -- access discriminant now denotes enclosing Node end record; type List is record Header : Root_Link; end record; subtype Iterator is Root_Link_Access; Bingo! A linked list with a degenerate header. Now you can write something like this (e.g. in your list package body): function Value (Here : Iterator) return Data_Type is pragma Suppress (Tag_Check); Linkage : Node_Link renames Node_Link (Here.All); -- a "narrowing" conversion ("downcast") begin return Linkage.Self.Data; end Value; > > It would be fine to generate a pointer from this component to a 'virtual' > aggregate of the given type. Yes, the "virtual" thing is the classwide type Root_Link'Class. BTW, the term "aggregate" has a specific meaning in Ada and this is not it :-) You should use the Ada term, "record". > > Example: > struct node { > ... data ... > struct node * next; > } > struct head { > struct node * next; > } > > struct head h; > h.next = &h - sizeof (node) + sizeof (head); > The Ada way is a lot nicer, isn't it. This also illustrates how it is possible for a non-tagged type to have inheritance. In this case, your (non-tagged) Node type inherits the property of "singly-linkedness". This might not seem like that big of a deal -- you might ask, why not just inherit directly using a derived (tagged) type? Answer: this is very cool in generics, where we don't want to have to insist that the user's base type be tagged (by declaring our formal type tagged). Cheers, Mark