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.3 required=5.0 tests=BAYES_00,FREEMAIL_FROM, INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,83a22b00dc8daff3,start X-Google-Attributes: gid103376,public From: "Vladimir Olensky" Subject: Generic Instances Scope control ??? Date: 2000/02/22 Message-ID: #1/1 X-Deja-AN: 588365292 Organization: Posted via Supernews, http://www.supernews.com X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.3 Newsgroups: comp.lang.ada X-Complaints-To: newsabuse@supernews.com Date: 2000-02-22T00:00:00+00:00 List-Id: I encountered a problem that need control over scope and accessibility depth for instance of generic procedure. ------------------------------------- There is some object controller. It can use some OS asynchronous operation. The last one upon it's completion calls controller provided completion procedure and pass it OS async operation return code. This return code should be used to update controller async status field so that it could be queried by the controller client to see the status of async operation. OS callback procedure signature does not contain information about which object it should update, so to bind that procedure to the particular controller one need to use generic procedure with updated object as generic formal object . At the end of the message is a working example (GNAT specific) that does all that. The problem is that I want to hide instantiation of generic callback procedure and its registration to controller from client of that controller but I can not do that now. Instance of generic callback procedure and pointer to it should have the same scope and accessibility level as controller instance. So I can not create callback procedure instance and bind it to the controller in any inner scope (let's say in Ada.Finalization.Initialize procedure). As a result of that this operations should be performed by the client in spite that all that could be performed automatically (theoretically). If there would be something (e.g. Scope Attribute or some compiler pragma) that tell compiler that code for the instance of generic procedure declared in some inner scope should have some defined outer scope (and life span) that would solve that problem. Something like this: for proc_name'Scope use concrete_object'Scope; The other part of the problem in automatic generic procedure instantiation is ability to dynamically set or extend name for such procedure instance to avoid name clashes between several controller instances. May be there are ways to do all that now and I just do not know them ? Regards, Vladimir Olensky Here is an working example with some public declarations that I want to hide from package clients: -- ================================= with Ada.Finalization; use Ada.Finalization; package G is type Callback_Proc_Ptr is access procedure (ret_code : Integer); -- OS signature for callback procedure -- which is called upon completion of -- OS asyncronous operation -- This pointer will be passes as parameter -- to some OS API call. -- When OS call that procedure it should -- update status_code field of -- the Controller_Type instance. -- The problem is that this procedure does -- not know anything about controller -- which field it should update type Controller_Type is new Limited_Controlled with record status_code : Integer :=0; callback_proc : Callback_Proc_Ptr := null; end record; procedure Register_Callback ( C : in out Controller_Type; CBP : in Callback_Proc_Ptr); -- To bind OS callback routine to the -- particular Controller instance -- we declare generic procedure with -- Controller as a formal generic -- parameter generic Controller : in out Controller_Type; procedure GStat (OS_Ret_Code : Integer); end G; --------------------------------------- package body G is procedure Register_Callback ( C : in out Controller_Type; CBP : in Callback_Proc_Ptr) is begin C.callback_proc := CBP; end Register_Callback; procedure GStat (OS_ret_code : Integer) is begin Controller.Status_Code := OS_ret_code; end GStat; end G; ------------------------------ with G; use G; with Gnat.IO; use GNAT.IO; procedure tst_Gen is c1 : Controller_Type; procedure c1_stat is new GStat (Controller => c1); --> want to hide c1_stat from client c2 : Controller_Type; procedure c2_stat is new GStat (Controller => c2); --> want to hide c2_stat from client procedure OS_API_Emulation command : integer; callback_proc : Callback_Proc_Ptr ) is begin callback_proc (command+10); end OS_API_Emulation; begin Register_Callback (c1, c1_stat'Unrestricted_Access); Register_Callback (c2, c2_stat'Unrestricted_Access); --> want to hide Register_Callback from client -- Controller 1 is calling OS API OS_API_Emulation ( command => 1, callback_proc => c1.callback_proc ); -- Controller 2 is calling OS API OS_API_Emulation ( command => 2, callback_proc => c2.callback_proc ); Put ( c1.status_code); -- prints 11 New_Line; Put ( c2.status_code); -- prints 12 end;