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.2 required=5.0 tests=BAYES_00,INVALID_MSGID, REPLYTO_WITHOUT_TO_CC,T_FILL_THIS_FORM_SHORT autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,5b86cfa15b273e36,start X-Google-Attributes: gid103376,public From: woodruff@tanana.llnl.gov (John Woodruff) Subject: Protected types made of ADT's, and Passive Iterators Date: 1998/09/04 Message-ID: #1/1 X-Deja-AN: 388012554 Organization: Lawrence Livermore National Lab Reply-To: woodruff1@llnl.gov Newsgroups: comp.lang.ada Date: 1998-09-04T00:00:00+00:00 List-Id: I like to ask advice about an Ada programming problem I've been working. By good fortune, I possess an inventory of well-made abstract data types. And I want to use the objects provided by these ADT's in a tasking-safe environment. So I determined that I might wrap the ADT into a protected type. Here's what I started with: generic type Item is private; package List is type Instance is private; procedure Insert (Into_List : in out Instance; The_Item : in Item); -- and lots more private type Instance is new Integer; -- of course not (but it compiles!) end List; I can make a generic package that encapsulates a protected instance of List in a fairly straightforward way: with List; generic with package Inner_List is new List (<>); package Prot_List is protected type Safe_List is entry Insert (The_Item : in Inner_List.Item); private In_Use : Boolean := False; Store : Inner_List.Instance; end Safe_List; end Prot_List; package body Prot_List is protected body Safe_List is entry Insert (The_Item : in Inner_List.Item) when not In_Use is begin In_Use := True; Inner_List.Insert (Into_List => Store, The_Item => The_Item); In_Use := False; exception when others => In_Use := False; end Insert; end Safe_List; end Prot_List; So far, so good! BUT the base list ADT provided a passive iterator, and I'd like to offer that capability to the clients of my protected ADT as well. Here is the way the base ADT specifies this ability: generic type Item is private; package List is type Instance is private; procedure Insert (Into_List : in out Instance; The_Item : in Item); generic with procedure Process (The_Item : in Item; Continue : in out Boolean); procedure Iterate (Over_List : in Instance); private -- as before end List; So my question is "How shall I enhance my Prot_List so it can define a passive iterator?" The only way I have found to now is to specify an additional parameter when instantiating Prot_List - and let this parameter be a procedure to be the iterating action: with List; generic with package Inner_List is new List (<>); with procedure Action (The_Item : in Inner_List.Item; Continue : in out Boolean) is <>; package Prot_List is protected type Safe_List is -- only change from before is to provide: procedure Iterate; end Safe_List; end Prot_List; This might be good for "partial credit" but I'm not satisfied: Iterate in the protected list is more tightly bound to the abstract data type than was the case in List. Only *exactly one* iterator Action can ever be specified for an instance of the protected list. Unlike the base ADT, it is not possible to use an instance of the protected list object *without* specifying an Action (that might never be used!). And the "procedure iterate" is a part of the package Prot_List, unlike in the base ADT where I am able to specify an Action is some far-away scope. Any advice that will make the full facility of passive iterator available in the task-safe environment? -- John Woodruff N I F \ ^ / Lawrence Livermore National Lab =====---- < 0 > 925 422 4661 / v \