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,73e5f80245e6297 X-Google-Attributes: gid103376,public From: mheaney@ni.net (Matthew Heaney) Subject: Re: Chunks of finalized Date: 1997/10/05 Message-ID: #1/1 X-Deja-AN: 278056831 References: <6129sn$n91$1@goanna.cs.rmit.edu.au> Organization: Estormza Software Newsgroups: comp.lang.ada Date: 1997-10-05T00:00:00+00:00 List-Id: In article <6129sn$n91$1@goanna.cs.rmit.edu.au>, ok@goanna.cs.rmit.edu.au (Richard A. O'Keefe) wrote: >I've been trying to figure out how to do this in Ada, and I don't think >I can. If one is trying to implement a generic container data structure, >there is nothing one can do to tell the elements 'stay alive but forget >everything', except include such an operation as one of the generic >parameters. > >What have I missed? The stack element will get finalized the next time you push an element onto the stack. If you want it to happen sooner, I'd import an Finalization operator. My stack hierarchy looks something like this generic type Stack_Item is private; package Stacks_G is type Root_Stack is abstract tagged null record; procedure Push (Item : in Stack_Item; On : in out Root_Stack); procedure Pop (Stack : in out Root_Stack); function Top (Stack : Root_Stack) return Stack_Item; end; Now let's say there's a bounded stack implementation: generic Max : Positive; package Stacks_G.Bounded_G is type Bounded_Stack is new Root_Stack with private; private subtype Top_Range is Positive range 0 .. Max; subtype Item_Array_Range is Top_Range range 1 .. Max; type Item_Array is array (Item_Array_Range) of Stack_Item; type Bounded_Stack is new Root_Stack with record Items : Item_Array; Top : Top_Range := 0; end record; end Stacks_G.Bounded_G; Now, let's say you're a stack user with a special need, to have a stack item you need finalized right away, as soon as it's popped from the stack. So we just subclass off the bounded stack: generic with procedure Finalize (Item : in out Stack_Item); package Stacks_G.Bounded_G.Finalizable_G is type Finalizable_Stack is new Bounded_Stack with null record; -- Override Pop procedure Pop (Stack : in out Finalizable_Stack); end; package body Stacks_G.Bounded_G.Finalizable_G is procedure Pop (Stack : in out Finalizable_Stack) is begin Finalize (Stack.Items (Stack.Top)); Pop (Bounded_Stack (Stack)); end; end; Another way is to import a dummy item: generic Dummy_Item : in Stack_Item; package Stacks_G.Bounded_G.Finalizable_G is type Finalizable_Stack is ... and in the body procedure Pop (Stack : in out Finalizable_Stack) is begin Stack.Items (Stack.Top) := Dummy_Item; Pop (Bounded_Stack (Stack)); end; The latter formulation would be suitable if there isn't a Finalization operation, but there is a constant that's a null version: type AVL_Set is new Root_Set with private; Empty_Set : constant AVL_Set; (Though in this case there's probably a Clear operation too). You could use Bob's idea too, implementing the stack array component as a discriminant record: procedure Pop (Stack : in out Bounded_Stack) is begin begin Stack.Items (Stack.Top) := (Available => False); exception when Constraint_Error => raise Stack_Empty; end; Stack.Top := Stack.Top - 1; end Pop; His discriminated record solution asks the user to do the least (you don't need import anything), but as he pointed out, there is a space penalty. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant (818) 985-1271