From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Generics with concrete and class-wide types
Date: Tue, 1 Apr 2008 12:53:04 +0200
Date: 2008-04-01T12:53:04+02:00 [thread overview]
Message-ID: <79hzafn3nee9$.kwqz0ce89qar.dlg@40tude.net> (raw)
In-Reply-To: 881a8e2c-01b2-462d-907b-f0887943acf4@a70g2000hsh.googlegroups.com
On Tue, 1 Apr 2008 02:51:19 -0700 (PDT), Maciej Sobczak wrote:
> On 1 Kwi, 11:42, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> 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
prev parent reply other threads:[~2008-04-01 10:53 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-03-31 20:22 Generics with concrete and class-wide types Maciej Sobczak
2008-03-31 23:38 ` Adam Beneschan
2008-04-01 20:10 ` Randy Brukardt
2008-04-01 21:17 ` Adam Beneschan
2008-04-01 0:23 ` Randy Brukardt
2008-04-01 3:57 ` Eric Hughes
2008-04-01 6:58 ` christoph.grein
2008-04-01 7:22 ` Georg Bauhaus
2008-04-01 9:42 ` Dmitry A. Kazakov
2008-04-01 9:51 ` Maciej Sobczak
2008-04-01 10:53 ` Dmitry A. Kazakov [this message]
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox