with Semaphore;
generic
    type Item is private;
package Stack_Guarded_Bounded_Managed_Iterator is

    type Stack (The_Size : Positive) is limited private;

    procedure Seize (The_Stack : in Stack);
    procedure Release (The_Stack : in Stack);
    procedure Copy (From_The_Stack : in Stack; To_The_Stack : in out Stack);
    procedure Clear (The_Stack : in out Stack);
    procedure Push (The_Item : in Item; On_The_Stack : in out Stack);
    procedure Pop (The_Stack : in out Stack);

    function Is_Equal (Left : in Stack; Right : in Stack) return Boolean;
    function Depth_Of (The_Stack : in Stack) return Natural;
    function Is_Empty (The_Stack : in Stack) return Boolean;
    function Top_Of (The_Stack : in Stack) return Item;

    generic
        with procedure Process (The_Item : in Item; Continue : out Boolean);
    procedure Iterate (Over_The_Stack : in Stack);

    Overflow : exception;
    Underflow : exception;

private
    type Items is array (Positive range <>) of Item;
    type Stack (The_Size : Positive) is
        record
            Guard : Semaphore.Kind;
            The_Top : Natural := 0;
            The_Items : Items (1 .. The_Size);
        end record;
end Stack_Guarded_Bounded_Managed_Iterator;