comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: tagged type as generic parameter
Date: Thu, 3 Jan 2008 16:51:24 +0100
Date: 2008-01-03T16:51:27+01:00	[thread overview]
Message-ID: <xgdnrdjferbj.nn9l327fp4xn.dlg@40tude.net> (raw)
In-Reply-To: fliudg$14v$1@news2.u-psud.fr

On Thu, 03 Jan 2008 16:20:48 +0100, Philippe Tarroux wrote:

> I wrote the following packages:
> 
> generic
>    type Data is tagged private;  -- In order to be able to build lists 
> of items of this type
> package List is
> 
>    type List (<>) is private;
> 
> private
>    type Item;
>    type Item_Ptr is access Item;
>    type Item is new Data with record      -- Line 22
>       Next : Item_Ptr;
>    end record;
>   
>    type List_Head is tagged record
>       Head : Item_Ptr := null;
>    end record;
> 
>    type List is access List_Head;
> end List;
> 
> -----------------------------------
> package data_handler is
> 
>    type Data is tagged private;
>   
>    function A_Data(V : Integer) return Data;
>    procedure Print (D : Data);
>   
> private
>   
>    type Data is tagged record
>       Value : Integer;
>    end record;
> 
> end data_handler;

[...] 
> I suspect the problem is due to the derivation of Item from Data at line 
> 22 of list.ads during the instantiation of the generic but I don't 
> really understand why and i don't understand why the problem arises with 
> the function A_Data and not with the procedure Print.

The function A_Data returns Data. It is a primitive operation of Data and
thus covariant in the result. So when you derive anything from Data, you
have to override it in order to provide a correct implementation that would
return the derived type rather than the base.

There are many ways to resolve the issue, the choice depends on other
factors:

1. Class-wide A_Data:

   function A_Data (V : Integer) return Data'Class;

This will be same (contravariant) for all descendants of A_Data and thus
need not to overridden.

2. Data-specific List package:

generic
   type Data is abstract new Data_Handler.Data with private;
package Data_List is
   ...
   type Item is new Data with record
      Next : Item_Ptr;
   end record;
   function A_Data (V : Integer) return Item;

We know here that Data is a descendant of Data_Handler.Data, so we can
provide an override for A_Data.

3. Aggregation instead of inheritance:

   type Item is record
      Next  : Item_Ptr;
      Value : Data;
   end record;

No inheritance, no problem.

4. Non-generic implementation of lists. You can define a list interface and
derive Data_Handler.Data from a list item. (In Ada 2005 it is easier to do
than it was in Ada 95) That would reverse the inheritance order and thus
solve the problem with A_Data.

5. Storage-pool based implementation of lists. You can design a storage
pool that would maintain lists of allocated there items. In this case,
unlikely to all other variants, the list item is not a fully separate type
but just a pool-specific access to Data type. Because there again is no
inheritance involved, the problem is solved.

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



  reply	other threads:[~2008-01-03 15:51 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-01-03 15:20 tagged type as generic parameter Philippe Tarroux
2008-01-03 15:51 ` Dmitry A. Kazakov [this message]
2008-01-03 16:22   ` Adam Beneschan
2008-01-03 16:58     ` Dmitry A. Kazakov
2008-01-03 17:47       ` Jean-Pierre Rosen
2008-01-03 18:13         ` Pascal Obry
2008-01-03 19:20         ` Dmitry A. Kazakov
2008-01-03 21:37         ` Jeffrey R. Carter
2008-01-04 13:08           ` Philippe Tarroux
2008-01-04 15:03             ` Jean-Pierre Rosen
2008-01-04 13:08   ` Philippe Tarroux
2008-01-04 13:22     ` Georg Bauhaus
2008-01-04 15:38       ` Philippe Tarroux
2008-01-04 14:17     ` Dmitry A. Kazakov
replies disabled

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