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
next prev parent 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