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!mx02.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Generic Embedded List Nodes Date: Sun, 19 Jun 2016 21:04:03 +0200 Organization: Aioe.org NNTP Server Message-ID: References: <66c14298-c62d-4f4b-b0c0-e969454f9334@googlegroups.com> <2e39857a-7121-476b-807a-d2bff1e598f4@googlegroups.com> <431af616-7df3-4e4d-9262-26ed68cb74c7@googlegroups.com> <037df2b8-b9c4-4447-87ee-cc89d7072b30@googlegroups.com> <15914c54-191c-4f37-b754-282855d1aeaf@googlegroups.com> NNTP-Posting-Host: w/2xSGckQeJEFvqsQFNodA.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.1.1 X-Notice: Filtered by postfilter v. 0.8.2 Xref: news.eternal-september.org comp.lang.ada:30817 Date: 2016-06-19T21:04:03+02:00 List-Id: On 2016-06-19 20:27, Warren wrote: > On Sunday, 19 June 2016 00:45:54 UTC-4, Simon Wright wrote: >> Warren writes: >> >> type Node_Type(Obj: access Object_Type) is new Emb_Node >> with null record; > > I've come to the conclusion that my original idea in Ada terms is too half baked. > > What it will come down to in the end is doing an offset calculation > from the Node back to the Object when its access is required (through a > function). > > Even in C/C++ this is a bit of a problem. While there is an > offsetof(type,member) macro, this is only usable on non-dynamic types. > Calculating an offset of a struct is trivial when you have it allocated. > But when the class has a constructor, then you may not want to invoke > that overhead only to create one for offset calculations. > > In Ada for some record Type R.M where R is the record and M is the > member, you cannot do R.M'Position when R is just a type. But you can > cheat this, similar to how I have done it in C/C++: > > with System; > with Ada.Integer_Text_IO; > > procedure T is > use Ada.Integer_Text_IO; > > type R_Type is > record > I : Integer; > F : Float; > end record; > > A: System.Address; > > R: R_Type; > for R'Address use A; > > begin > Put(R.I'Position); > Put(R.F'Position); > end; > > This never allocates the object, but assumes it already exists at > address A.. Since the record and its members are never actually used, it > is possible to have the compiler do the necessary calculations. This > will complain "warning: variable "A" is read but never assigned", however. > > I suppose a tagged R.Initialize could also establish an 'Access value > in all Emb_Node members, using some other procedure call for Emb_Node > (perhaps Set_Object). But it is desireable not to have to carry the > object reference in the Emb_Node at all. Maybe I don't understand the problem, but it seems you want externally linked objects that themselves were of any type. The best way to do it is IMO a custom memory pool. My implementation of linked list uses this approach. http://www.dmitry-kazakov.de/ada/components.htm#Generic_Doubly_Linked_Web The object is allocated in the custom pool, which actually takes memory from another, e.g. standard, pool. But before that adds links just in front of the object. The pool-specific pointer carries the operations Next, Previous etc. Yes, it uses address arithmetic to get to the links, but no record member offsets or other crazy stuff because you deal with pointers to the objects, not the pointers to the list elements. The only problem you must be aware of is that X'Address attribute is broken in Ada when X is an array: X'Address = X (X'First)'Address which if of course not the address of the array. If you are going to instantiate your package with an array type, you must calculate the offset to the array object beginning. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de