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=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: a07f3367d7,18684ed750c9b60f X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII-7-bit Received: by 10.224.70.131 with SMTP id d3mr8653119qaj.0.1349494119470; Fri, 05 Oct 2012 20:28:39 -0700 (PDT) Received: by 10.236.115.33 with SMTP id d21mr1312525yhh.12.1349494119430; Fri, 05 Oct 2012 20:28:39 -0700 (PDT) Path: e10ni211270746qan.0!nntp.google.com!l8no27506530qao.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Fri, 5 Oct 2012 20:28:39 -0700 (PDT) In-Reply-To: <51f8461d-d362-4e5f-a188-ac96a699a211@googlegroups.com> Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=68.4.246.214; posting-account=duW0ogkAAABjRdnxgLGXDfna0Gc6XqmQ NNTP-Posting-Host: 68.4.246.214 References: <51f8461d-d362-4e5f-a188-ac96a699a211@googlegroups.com> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: Subject: Re: How to get generic formal parameter type into base class From: Adam Beneschan Injection-Date: Sat, 06 Oct 2012 03:28:39 +0000 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Date: 2012-10-05T20:28:39-07:00 List-Id: On Friday, October 5, 2012 3:23:01 PM UTC-7, (unknown) wrote: > Is there a way to get a generic formal parameter type into base class so = that I can dispatch to a function with that type in the function signature?= Below is what I am trying to achieve, and of course the main procedure wil= l not compile. >=20 > Thanks, >=20 >=20 >=20 > package Classes is >=20 > type Value_Type is range -2 ** 31 .. 2 ** 31 - 1; >=20 > generic > type Data_Type is (<>); > package Translate_Base is >=20 > type Xlate_Base_Type is abstract tagged record > Value : Data_Type :=3D Data_Type'first; > end record;=20 >=20 > procedure Decode (Xlate_Class : in out Xlate_Base_Type;=20 > Value : in Value_Type) is abstract; > function Encode (Xlate_Class : in Xlate_Base_Type)=20 > return Value_Type is abstract; > function Get_Value(Xlate_Class : in Xlate_Base_Type)=20 > return Data_Type is abstract; > procedure Set_Value(Xlate_Class : in out Xlate_Base_Type;=20 > Value : in Data_Type) is abstract; > > end Translate_Base; >=20 >=20 > generic > type Data_Type is (<>); > package Translate_Integer is=20 >=20 > package base is new Translate_Base(Data_Type); > type Xlate_Type is new base.Xlate_Base_Type with record > Signed : Boolean :=3D False; > end record; >=20 > procedure Decode (Xlate_Class : in out Xlate_Type;=20 > Value : in Value_Type); > function Encode (Xlate_Class : in Xlate_Type) return Value_T= ype; > function Get_Value(Xlate_Class : in Xlate_Type) return Data_Ty= pe; > procedure Set_Value(Xlate_Class : in out Xlate_Type;=20 > Value : in Data_Type); >=20 > end Translate_Integer; >=20 > -- define Translate_Enumuration > -- define Translate_Float > -- ... >=20 > end Classes; >=20 > package body Classes is >=20 > package body Translate_Integer is >=20 > procedure Decode (Xlate_Class : in out Xlate_Type;=20 > Value : in Value_Type) is > begin > Xlate_Class.Value :=3D Data_Type'val(Value); > end Decode; >=20 > function Encode (Xlate_Class : in Xlate_Type) return Value_T= ype is > begin > return Data_Type'pos(Xlate_Class.Value); > end Encode; >=20 > function Get_Value(Xlate_Class : in Xlate_Type) return Data_Ty= pe is > begin > return Xlate_Class.Value; > end Get_Value; >=20 > procedure Set_Value(Xlate_Class : in out Xlate_Type;=20 > Value : in Data_Type) is > begin > Xlate_Class.Value :=3D Value; > end Set_Value; > end Translate_Integer; >=20 > end Classes; >=20 > with Classes; >=20 > package Objects is >=20 > type Int_100_Type is range -100 .. 100; >=20 > package Int_100 is new Classes.Translate_Integer(Int_100_Type); >=20 > end Objects;=20 >=20 > with Classes; > with Objects; > with Ada.Text_IO; >=20 > procedure main is > procedure PrintLn(Item : String) renames Ada.Text_IO.Put_Line; >=20 > type Message_ID_Type is (type1); >=20 > function Factory_Get (Message_ID : in Message_ID_Type) =20 > return Classes.Xlate_Base_Type'class is > begin > > case Message_ID is > when type1 =3D> > declare > This : Objects.Int_100.Xlate_Type; > begin > return This; > end; > end case; >=20 > end Factory_Get; >=20 > This : Classes.Xlate_Base_Type'class :=3D Factory_Get(type1); > Value : Classes.Value_Type; > My_Value : Objects.Int_100_Type; > begin >=20 > Value :=3D 255; -- get FF from input stream. > Classes.Translate_Base.Decode(This, Value); > My_Value :=3D Classes.Translate_Base.Get_Value(This); >=20 > -- do something >=20 > Classes.Translate_Base.Set_Value(This, My_Value); > Value :=3D Classes.Translate_Base.Encode(This); > end main; Since you're trying to use Xlate_Type'Class, it looks like you're thinking = that the types involved are all related. They're not. A generic package i= sn't useful until you instantiate it, and instantiating the package has pre= tty much the same effect as writing it all over again, substituting somethi= ng different for the formal parameters. It's something like a macro substi= tution. And if you had two types with the same name in different packages,= e.g. package Instantiation_1 is type Xlate_Type is tagged record ... end Instantiation_1; package Instantiation_2 is type Xlate_Type is tagged record ... end Instantiation_2; you wouldn't expect the two Xlate_Type types to be related at all, and you = wouldn't expect a 'Class type to be able to represent both. Well, that's p= retty much what you're getting when you define the type in the instantiatio= n. What I think you want to do is declare an abstract root type *outside* any = generic, and declare abstract procedures/functions Decode, Encode, etc., in= the same package outside the generic. Then, in Translate_Base (which coul= d still be generic), make your Xlate_Type a type extension of that root typ= e. Now you can declare something as Your_Root_Type'Class and this object c= ould represent any type derived from Your_Root_Type, including those in gen= eric instantiations, and it could dispatch to those procedures and function= s. Hope this helps, -- Adam