comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Access to function returning class-wide type
Date: Thu, 21 Aug 2008 15:34:39 +0200
Date: 2008-08-21T15:34:42+02:00	[thread overview]
Message-ID: <tslrrr8w3j63.zp28ykzgmr23.dlg@40tude.net> (raw)
In-Reply-To: g8jl5o$oj8$1@registered.motzarella.org

On Thu, 21 Aug 2008 13:56:35 +0200, Pawe� 'Nivertius' P�azie�ski wrote:

> Dmitry A. Kazakov wrote:
> 
>>> What I need is a access type to 'constructor' of an derivate of abstract
>>> object.
>>> As I presented, there is a workaround, but that's not the 'right' way to
>>> do it. I really want to do it without some tricky wrapping.
>>> How do I define The_Access_Type to do what I want?
>> See Ada.Tags.Generic_Dispatching_Constructor. It gives you a function
>> constructing an object from the type tag, the parameters (Natural in your
>> case) using the function you want (Proc). It goes as follows:
>> 
>> with Ada.Tags.Generic_Dispatching_Constructor;
>> package A is
>>    type Abstracted is abstract tagged null record;
>>    function Proc (N : not null access Natural)
>>       return Abstracted is abstract;
>>    function Constructor is
>>       new Ada.Tags.Generic_Dispatching_Constructor
>>              (Abstracted, Natural, Proc);
>> end A;
> 
> I belive that would work too, but at the cost of defining function Proc (N :
> not null access Natural) return ... for each descendant type.

Yes, it is the body of the "constructor".

> That would be
> another wrapper, so it's the same resolution to the problem as Proc_Wrapper
> in my original code, assuming that I need Proc (N : Natural) as well.

Not really, because it would replace old Proc completely. The idea is:

with Ada.Tags;  use Ada.Tags;
package A is
   type Abstracted is abstract tagged null record;
      -- To be used
   function Factory (T : Tag; N : Natural) return Abstracted'Class;
      -- Implementation detail, to be provided by each derived type
   function Proc (N : not null access Natural)
      return Abstracted is abstract;
end A;

with Ada.Tags.Generic_Dispatching_Constructor;
package body A is 
   function Make_It is
      new Generic_Dispatching_Constructor (Abstracted, Natural, Proc);
   function Factory (T : Tag; N : Natural) return Abstracted'Class is
      Parameters : aliased Natural := N;
   begin
      return Make_It (T, Parameters'Access);
   end Factory;
end A;

Now, when you derive from Abstracted you override Proc and that's all you
need to keep Factory working:

   type Concrete is new Abstracted with private;
   overriding Proc (N : not null access Natural return Concrete;

In short, the solution replaces pointer->constructor with tag->constructor.
Both enforced to be overridden.

P.S. I don't know reasons why it was decided to use an access type in
Ada.Tags.Generic_Dispatching_Constructor profile. One could always pass a
pointer there if a side effect on the parameters were desired. But that is
another issue, and in any case Proc is thought as an implementation detail,
so its exact profile should not really matter.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



  reply	other threads:[~2008-08-21 13:34 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-21 10:13 Access to function returning class-wide type Paweł 'Nivertius' Płazieński
2008-08-21 10:33 ` Paweł 'Nivertius' Płazieński
2008-08-21 11:02 ` Dmitry A. Kazakov
2008-08-21 11:56   ` Paweł 'Nivertius' Płazieński
2008-08-21 13:34     ` Dmitry A. Kazakov [this message]
2008-08-22  4:53       ` Randy Brukardt
2008-08-22 23:50         ` Randy Brukardt
2008-08-21 12:01 ` Georg Bauhaus
2008-08-21 13:01   ` Paweł 'Nivertius' Płazieński
2008-08-21 13:50     ` Dmitry A. Kazakov
2008-08-21 19:30       ` Paweł 'Nivertius' Płazieński
2008-08-21 20:56         ` Dmitry A. Kazakov
2008-08-22  7:34           ` Paweł 'Nivertius' Płazieński
2008-08-21 17:02 ` Adam Beneschan
2008-08-21 19:22   ` Paweł 'Nivertius' Płazieński
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox