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,8385fc6e4bf20336 X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news4.google.com!news.germany.com!texta.sil.at!newsfeed01.chello.at!newsfeed.arcor.de!newsspool2.arcor-online.net!news.arcor.de.POSTED!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: Generics with concrete and class-wide types 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: <279b6f4f-36cf-446f-8b54-fd72b957b22f@i7g2000prf.googlegroups.com> <10v8f09pvzjs6$.1r7fruma1fer5$.dlg@40tude.net> <881a8e2c-01b2-462d-907b-f0887943acf4@a70g2000hsh.googlegroups.com> Date: Tue, 1 Apr 2008 12:53:04 +0200 Message-ID: <79hzafn3nee9$.kwqz0ce89qar.dlg@40tude.net> NNTP-Posting-Date: 01 Apr 2008 12:53:04 CEST NNTP-Posting-Host: 37fd89b0.newsspool4.arcor-online.net X-Trace: DXC=Vf8diUcaoW;85[]]\]T0814IUK2@TTZJdZT8`8[6LHn;2LCV>7enW;^6ZC`4IXm65S@:3>?;?CY6ZcfYR; X-Complaints-To: usenet-abuse@arcor.de Xref: g2news1.google.com comp.lang.ada:20710 Date: 2008-04-01T12:53:04+02:00 List-Id: On Tue, 1 Apr 2008 02:51:19 -0700 (PDT), Maciej Sobczak wrote: > On 1 Kwi, 11:42, "Dmitry A. Kazakov" > wrote: > >> Just a small side note. If you care about performance you should do exactly >> the opposite you tried to, i.e. you should instantiate it with a specific >> type rather than with a class of. > > This is exactly what I want to do. > If I have the knowledge of the specific iterator type, I want to > instantiate the subprogram with this specific type to facilitate > direct dispatch and code inlining. > When the only this I have is 'Class, then I want to instantiate the > subprogram with what I have and agree for indirect dispatch to > iterator operations within the subprogram body. > > The question is whether it is possible in Ada without walking on the > edge of compiler conformance - and in particular without accidentally > benefiting from any compiler bug that will bite me later on when it's > fixed. > Yes, some bugs can be harmful after they are fixed. :-) > > I will try the scheme proposed by Georg. You could also do: generic type Element_Type is private; -- element type package Iterators is type Iterator_Type is interface; function Get (I : Iterator_Type) return Element_Type is abstract; -- and so on for other operations... end Iterators; with Iterators; generic with package Root_Iterators is new Iterators (<>); type Base_Iterator_Type is new Root_Iterators.Iterator_Type with private; package Some_Procedure is type Iterator_Type is new Base_Iterator_Type with null record; procedure Foo (I : Iterator_Type); -- Primitive operation when tagged end Some_Procedure; You have to derive from Iterator_Type in order to declare another primitive operation Foo. The element type comes with the instance of Iterators which is the first formal parameter. The second formal parameter is a non-abstract iterator type implementing the iterator interface. This schema allows to cascade packages like Some_Procedure taking Some_Procedure_1_Instance.Iterator_Type as the parameter for Some_Procedure_2_Instance. Base_Iterator_Type could also be abstract, but that would more difficult to trace instantiation problems. Example: with Ada.Finalization; with Iterators, Some_Procedure; procedure Test_Iterators is ------ Iterators to tagged elements ----------- type My_Element is new Ada.Finalization.Controlled with null record; package My_Element_Iterators is new Iterators (My_Element); package Firewall_1 is type My_Iterator is new My_Element_Iterators.Iterator_Type with null record; function Get (I : My_Iterator) return My_Element; end Firewall_1; package My_Element_SP is new Some_Procedure (My_Element_Iterators, Firewall_1.My_Iterator); ------- Iterators to integer elements ------- package Integer_Iterators is new Iterators (Integer); package Firewall_2 is type Integer_Iterator is new Integer_Iterators.Iterator_Type with null record; function Get (I : Integer_Iterator) return Integer; end Firewall_2; package Integer_SP is new Some_Procedure (Integer_Iterators, Firewall_2.Integer_Iterator); --------------------------------------------------------- package body Firewall_1 is function Get (I : My_Iterator) return My_Element is begin return (Ada.Finalization.Controlled with null record); end Get; end Firewall_1; package body Firewall_2 is function Get (I : Integer_Iterator) return Integer is begin return 5; end Get; end Firewall_2; begin null; end Test_Iterators; The packages like Firewall are needed to freeze the element type. Otherwise, the compiler would yell that function Get (I : My_Iterator) return My_Element; is doubly dispatching. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de