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=-0.9 required=5.0 tests=BAYES_00,FORGED_GMAIL_RCVD, FREEMAIL_FROM autolearn=no 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 Received: by 10.224.213.1 with SMTP id gu1mr9829856qab.7.1349553814255; Sat, 06 Oct 2012 13:03:34 -0700 (PDT) MIME-Version: 1.0 Received: by 10.236.175.1 with SMTP id y1mr1463466yhl.9.1349553814204; Sat, 06 Oct 2012 13:03:34 -0700 (PDT) Path: e10ni211270746qan.0!nntp.google.com!l8no28631379qao.0!postnews.google.com!l32g2000yqb.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Sat, 6 Oct 2012 13:03:34 -0700 (PDT) Complaints-To: groups-abuse@google.com Injection-Info: l32g2000yqb.googlegroups.com; posting-host=157.127.124.14; posting-account=Trm_OQoAAABCO0PHK-TqWioYjr8e-azv NNTP-Posting-Host: 157.127.124.14 References: <51f8461d-d362-4e5f-a188-ac96a699a211@googlegroups.com> User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; MS-RTC LM 8),gzip(gfe) Message-ID: <527f8487-a578-406c-86c3-b3b0596cda71@l32g2000yqb.googlegroups.com> Subject: Re: How to get generic formal parameter type into base class From: kevin andrew Injection-Date: Sat, 06 Oct 2012 20:03:34 +0000 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Date: 2012-10-06T13:03:34-07:00 List-Id: On Oct 5, 8:28=A0pm, Adam Beneschan wrote: > 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 s= o that I can dispatch to a function with that type in the function signatur= e? Below is what I am trying to achieve, and of course the main procedure w= ill not compile. > > > Thanks, > > > package Classes is > > > =A0 =A0type Value_Type is range -2 ** 31 .. 2 ** 31 - 1; > > > =A0 =A0generic > > =A0 =A0 =A0 type Data_Type is (<>); > > =A0 =A0package Translate_Base is > > > =A0 =A0 =A0 type Xlate_Base_Type is abstract tagged record > > =A0 =A0 =A0 =A0 =A0Value : Data_Type :=3D Data_Type'first; > > =A0 =A0 =A0 end record; > > > =A0 =A0 =A0 procedure Decode =A0 (Xlate_Class : in out Xlate_Base_Type; > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Value : in Value_Ty= pe) is abstract; > > =A0 =A0 =A0 function =A0Encode =A0 (Xlate_Class : in =A0 =A0 Xlate_Base= _Type) > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return Value_Type i= s abstract; > > =A0 =A0 =A0 function =A0Get_Value(Xlate_Class : in =A0 =A0 Xlate_Base_T= ype) > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return Data_Type is= abstract; > > =A0 =A0 =A0 procedure Set_Value(Xlate_Class : in out Xlate_Base_Type; > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Value : in Data_Typ= e) is abstract; > > > =A0 =A0end Translate_Base; > > > =A0 =A0generic > > =A0 =A0 =A0 type Data_Type is (<>); > > =A0 =A0package Translate_Integer is > > > =A0 =A0 =A0 package base is new Translate_Base(Data_Type); > > =A0 =A0 =A0 type Xlate_Type is new base.Xlate_Base_Type with record > > =A0 =A0 =A0 =A0 =A0Signed =A0 =A0 : Boolean =A0 :=3D False; > > =A0 =A0 =A0 end record; > > > =A0 =A0 =A0 procedure Decode =A0 (Xlate_Class : in out Xlate_Type; > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Value : in Value_Ty= pe); > > =A0 =A0 =A0 function =A0Encode =A0 (Xlate_Class : in =A0 =A0 Xlate_Type= ) return Value_Type; > > =A0 =A0 =A0 function =A0Get_Value(Xlate_Class : in =A0 =A0 Xlate_Type) = return Data_Type; > > =A0 =A0 =A0 procedure Set_Value(Xlate_Class : in out Xlate_Type; > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Value : in Data_Typ= e); > > > =A0 =A0end Translate_Integer; > > > =A0 =A0-- define Translate_Enumuration > > =A0 =A0-- define Translate_Float > > =A0 =A0-- ... > > > end Classes; > > > package body Classes is > > > =A0 =A0package body Translate_Integer is > > > =A0 =A0 =A0 procedure Decode =A0 (Xlate_Class : in out Xlate_Type; > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Value : in Value_Ty= pe) is > > =A0 =A0 =A0 begin > > =A0 =A0 =A0 =A0 =A0Xlate_Class.Value :=3D Data_Type'val(Value); > > =A0 =A0 =A0 end Decode; > > > =A0 =A0 =A0 function =A0Encode =A0 (Xlate_Class : in =A0 =A0 Xlate_Type= ) return Value_Type is > > =A0 =A0 =A0 begin > > =A0 =A0 =A0 =A0 =A0return Data_Type'pos(Xlate_Class.Value); > > =A0 =A0 =A0 end Encode; > > > =A0 =A0 =A0 function =A0Get_Value(Xlate_Class : in =A0 =A0 Xlate_Type) = return Data_Type is > > =A0 =A0 =A0 begin > > =A0 =A0 =A0 =A0 =A0return Xlate_Class.Value; > > =A0 =A0 =A0 end Get_Value; > > > =A0 =A0 =A0 procedure Set_Value(Xlate_Class : in out Xlate_Type; > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Value : in Data_Typ= e) is > > =A0 =A0 =A0 begin > > =A0 =A0 =A0 =A0 =A0 Xlate_Class.Value :=3D Value; > > =A0 =A0 =A0 end Set_Value; > > =A0 =A0end Translate_Integer; > > > end Classes; > > > with Classes; > > > package Objects is > > > =A0 =A0type Int_100_Type is range -100 .. 100; > > > =A0 =A0package Int_100 is new Classes.Translate_Integer(Int_100_Type); > > > end Objects; > > > with Classes; > > with Objects; > > with Ada.Text_IO; > > > procedure main is > > =A0 =A0procedure PrintLn(Item : String) renames Ada.Text_IO.Put_Line; > > > =A0 =A0type Message_ID_Type is (type1); > > > =A0 =A0function Factory_Get (Message_ID : in Message_ID_Type) > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return Classes.Xlate= _Base_Type'class is > > =A0 =A0begin > > > =A0 =A0 =A0 case Message_ID is > > =A0 =A0 =A0 when type1 =3D> > > =A0 =A0 =A0 =A0 =A0declare > > =A0 =A0 =A0 =A0 =A0 =A0 This : Objects.Int_100.Xlate_Type; > > =A0 =A0 =A0 =A0 =A0begin > > =A0 =A0 =A0 =A0 =A0 =A0 return This; > > =A0 =A0 =A0 =A0 =A0end; > > =A0 =A0 =A0 end case; > > > =A0 =A0end Factory_Get; > > > =A0 =A0This : Classes.Xlate_Base_Type'class :=3D Factory_Get(type1); > > =A0 =A0Value : Classes.Value_Type; > > =A0 =A0My_Value : Objects.Int_100_Type; > > begin > > > =A0 =A0Value :=3D 255; =A0-- get FF from input stream. > > =A0 =A0Classes.Translate_Base.Decode(This, Value); > > =A0 =A0My_Value :=3D Classes.Translate_Base.Get_Value(This); > > > =A0 =A0-- do something > > > =A0 =A0Classes.Translate_Base.Set_Value(This, My_Value); > > =A0 =A0Value :=3D Classes.Translate_Base.Encode(This); > > end main; > > Since you're trying to use Xlate_Type'Class, it looks like you're thinkin= g that the types involved are all related. =A0They're not. =A0A generic pac= kage isn't useful until you instantiate it, and instantiating the package h= as pretty much the same effect as writing it all over again, substituting s= omething different for the formal parameters. =A0It's something like a macr= o substitution. =A0And if you had two types with the same name in different= packages, e.g. > > =A0 =A0package Instantiation_1 is > =A0 =A0 =A0 type Xlate_Type is tagged record ... > =A0 =A0end Instantiation_1; > > =A0 =A0package Instantiation_2 is > =A0 =A0 =A0 type Xlate_Type is tagged record ... > =A0 =A0end Instantiation_2; > > you wouldn't expect the two Xlate_Type types to be related at all, and yo= u wouldn't expect a 'Class type to be able to represent both. =A0Well, that= 's pretty much what you're getting when you define the type in the instanti= ation. > > What I think you want to do is declare an abstract root type *outside* an= y generic, and declare abstract procedures/functions Decode, Encode, etc., = in the same package outside the generic. =A0Then, in Translate_Base (which = could still be generic), make your Xlate_Type a type extension of that root= type. =A0Now you can declare something as Your_Root_Type'Class and this ob= ject could represent any type derived from Your_Root_Type, including those = in generic instantiations, and it could dispatch to those procedures and fu= nctions. > > Hope this helps, > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0-- Adam- H= ide quoted text - > > - Show quoted text - Thanks for the responses. I still don't see how to get a dynamic type into base class so that I can dispatch to a function with that type in the function signature. If I do a Root_Type then I don't see how I can include the Get/ Set_Value function because Data_Type is unknown? Any help getting my ignorant mine understanding Ada will be greatly appreciated. I have included a better Main procedure which more accurately shows what I am trying to do. Thanks, Kevin. with Classes; package Objects is type Mod_12_Type is mod 2 ** 12; type Int_100_Type is range -100 .. 100; type Enum_One_Type is (Minus_0ne, Zero, One); type External_Type is record theMode : Mod_12_Type; theInt : Int_100_Type; theEnum : Enum_One_Type; end record; package Mod_12 is new Classes.Translate_Integer(Mod_12_Type); package Int_100 is new Classes.Translate_Integer(Int_100_Type); package Enum_One is new Classes.Translate_Integer(Enum_One_Type); end Objects; with Classes; with Objects; with Ada.Text_IO; procedure main is procedure PrintLn(Item : String) renames Ada.Text_IO.Put_Line; type Message_ID_Type is (Int_100, Mod_12, Enum_One); function Factory_Get (Message_ID : in Message_ID_Type) return Classes.Xlate_Base_Type'class is begin case Message_ID is when Int_100 =3D> declare This : Objects.Int_100.Xlate_Type; begin return This; end; when Mod_12 =3D> declare This : Objects.Mod_12.Xlate_Type; begin return This; end; when Enum_One =3D> declare This : Objects.Enum_One.Xlate_Type; begin return This; end; end case; end Factory_Get; Procedure Get_Values(Message_ID : in Message_ID_Type; Class : in Classes.Xlate_Base_Type'class; Msg : in out Objects.External_Type) is begin case Message_ID is when Int_100 =3D> Msg.theInt :=3D Classes.Translate_Base.Get_Value(Class); -- Dispatch to Get_Value when Mod_12 =3D> Msg.theMode :=3D Classes.Translate_Base.Get_Value(Class); -- Dispatch to Get_Value when Enum_One =3D> Msg.theEnum :=3D Classes.Translate_Base.Get_Value(Class); -- Dispatch to Get_Value end case; end Get_Values; procedure Decode(Message_ID : in Message_ID_Type; Value : in Classes.Value_Type; Msg : in out Objects.External_Type) is This : Classes.Xlate_Base_Type'class :=3D Factory_Get(Message_ID); begin Classes.Translate_Base.Decode(This, Value); -- Dispatch to Decode Get_Values(Message_ID, This, Msg); end Decode; Value : Classes.Value_Type; Message : Objects.External_Type; begin Value :=3D 255; -- get FF from input stream. Decode(Int_100, Value, Message); Value :=3D 240; -- get F0 from input stream. Decode(Mod_12, Value, Message); Value :=3D 0; -- get 00 from input stream. Decode(Enum_One, Value, Message); -- print Message. end main;