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.7 required=5.0 tests=BAYES_00,INVALID_MSGID, PDS_OTHER_BAD_TLD autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,9406c9586288fd40 X-Google-Attributes: gid103376,public From: Matthew Heaney Subject: Re: Data Structures of limited private types Date: 1998/08/29 Message-ID: #1/1 X-Deja-AN: 385892301 Sender: matt@mheaney.ni.net References: <6s1d17$i19$1@nnrp1.dejanews.com> NNTP-Posting-Date: Fri, 28 Aug 1998 23:15:10 PDT Newsgroups: comp.lang.ada Date: 1998-08-29T00:00:00+00:00 List-Id: rajagopalasrinivasan@my-dejanews.com writes: > I have a need to build a stack / linked_list of > "Text_Io.File_Type"s. This being a limited private type, I am not able > to perform "assignments" of a variable of this type. > > Can anyone give me some pointers or an example of how this can be > done? Below is a stack that accepts limited private types as the stack item. You have to use functions that return a pointer to the item on the stack, and manipulate the object indirectly, through a reference. Like this Op (Get_Top (Stack'Access).all); If the syntax bothers you, then use a renames to make it more familiar: declare O : LT renames Get_Top (Stack'Access).all; begin Op (O); end; The idiosyncratic thing here is that the Push operation doesn't take an item as a parameter. You have to push the stack to open up the top slot, and then operate on the top object, which is owned by the stack. Ada95 is a huge improvement over Ada83 in this area. In Ada83 you could only use this technique if o the function was exported by a state machine package (rather than as an operation on an instance of a type); or o the data structure items were put on the heap. I don't think this is a technique many Ada programmers are familiar with, so I wanted to write a long-ish post to get the word out. Hope this helps some, Matt --STX generic type Stack_Item is limited private; Max_Depth : in Positive; package Limited_Stacks is type Stack_Type is limited private; type Stack_Item_Access is access all Stack_Item; procedure Push (Stack : in out Stack_Type); procedure Pop (Stack : in out Stack_Type); function Get_Top (Stack : access Stack_Type) return Stack_Item_Access; function Get_Depth (Stack : Stack_Type) return Natural; generic with procedure Process (Item : in out Stack_Item; Quit : in out Boolean); procedure For_Every_Item (Stack : in out Stack_Type); private type Stack_Item_Array is array (Positive range 1 .. Max_Depth) of aliased Stack_Item; type Stack_Type is limited record Items : Stack_Item_Array; Top : Natural := 0; end record; end Limited_Stacks; package body Limited_Stacks is procedure Push (Stack : in out Stack_Type) is begin Stack.Top := Stack.Top + 1; end; procedure Pop (Stack : in out Stack_Type) is begin Stack.Top := Stack.Top - 1; end; function Get_Top (Stack : access Stack_Type) return Stack_Item_Access is begin return Stack.Items (Stack.Top)'Access; end; function Get_Depth (Stack : Stack_Type) return Natural is begin return Stack.Top; end; procedure For_Every_Item (Stack : in out Stack_Type) is subtype Index_Range is Positive range 1 .. Stack.Top; Quit : Boolean := False; begin for Index in reverse Index_Range loop Process (Stack.Items (Index), Quit); exit when Quit; end loop; end For_Every_Item; end Limited_Stacks; with Limited_Stacks; with Ada.Text_IO; use Ada.Text_IO; procedure Test_Stacks is package File_Stacks is new Limited_Stacks (File_Type, 10); use File_Stacks; Stack : aliased Stack_Type; procedure Display_File (File : in out File_Type; Quit : in out Boolean) is Line : String (1 .. 80); Last : Natural; begin Put ("Contents of file "); Put (Name (File)); New_Line; Reset (File, In_File); while not End_Of_File (File) loop Get_Line (File, Line, Last); Put_Line (Line (1 .. Last)); end loop; New_Line (2); end Display_File; procedure Display_Files is new For_Every_Item (Display_File); begin Push (Stack); declare File : File_Type renames Get_Top (Stack'Access).all; begin Create (File, Out_File, "first_file.txt"); Put_Line (File, "this is the first file pushed on the stack"); end; Push (Stack); declare File : File_Type renames Get_Top (Stack'Access).all; begin Create (File, Out_File, "second_file.txt"); Put_Line (File, "this is the second file pushed on the stack"); end; Display_Files (Stack); end Test_Stacks;