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=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Simon Wright Newsgroups: comp.lang.ada Subject: Re: Getting the index for an element in mutually referencing containers Date: Sat, 11 Mar 2017 08:40:15 +0000 Organization: A noiseless patient Spider Message-ID: References: <86o9xa36oq.fsf@gaheris.avalon.lan> <86k27xpikd.fsf@gaheris.avalon.lan> <86wpbxneuz.fsf@gaheris.avalon.lan> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: mx02.eternal-september.org; posting-host="e0d0b3f1bf9184545c3b313ce0263385"; logging-data="28531"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+AsixMm6vTkF4UQ/qsCKpwHKW4bvPES4Y=" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (darwin) Cancel-Lock: sha1:6A0M9IXSOQBz20i4o2TlYrnLP40= sha1:tnlEEdRosOAng9xsbgnlrYDVXBY= Xref: news.eternal-september.org comp.lang.ada:27833 Date: 2017-03-11T08:40:15+00:00 List-Id: "Randy Brukardt" writes: > "Mart van de Wege" wrote in message > news:86wpbxneuz.fsf@gaheris.avalon.lan... >> Simon Wright writes: > ... >>> But, I really think you're going to need to use access types here. A >>> Person is a unique object, and should only exist once in your data >>> structures. A Child should hold references to its Parent(s) and vice >>> versa; if a Child holds *copies* of its Parents, what happens when >>> you change the Parent's data in one place? how are you going to find >>> all the copies and change all of them? >>> >> That was what I was afraid of. I like the way Ada usually takes care >> of this for you, but I've been trying to work it out during downtime >> today at work, and I'm afraid it's indeed time to grab the access >> types out of the toolbox. > > The trick in such cases is to have a global "person" vector, which > contains all of the actual Person objects. Then use the cursors into > that array in your other data structures. That's gives the needed > level of indirection without involving any actual access types > (meaning that you let Ada do the storage management, and depending on > your container implementation, also reduce/eliminate the danger of > dangling access types). In the general case, you'd need to cope with deleting (the equivalent of) Person objects. And wouldn't even appending a new Person risk invalidating any existing cursors? AARM A18(5.k) says "Cursors *generally* remain valid as long as the container exists and the element referenced is not deleted", emphasis added. AdaCore's Vector implementation would be OK with inserting elements _after_ the Cursor concerned, since the Cursor is based on an index into an array. See discussion at AARM A18.2(240) ff. I quite like the idea of using an indefinite container to hold the Person objects, but I think I'd use a Map with the key an integer (Natural?), with the next key held in a private global, incremented as each new Person is created. The reference to a Person would be the associated key. One disadvantage to this design is that Containers hold non-limited types. Your users run the risk of writing code that gets hold of a copy of the object and modifies that, rather than modifying the actual object.