File : bc-containers-rings.ads
-- Copyright (C) 1994-1999 Grady Booch and Simon Wright.
-- All Rights Reserved.
--
-- This program is free software; you can redistribute it
-- and/or modify it under the terms of the Ada Community
-- License which comes with this Library.
--
-- This program is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the Ada Community License for more details.
-- You should have received a copy of the Ada Community
-- License with this library, in the file named "Ada Community
-- License" or "ACL". If not, contact the author of this library
-- for a copy.
--
-- $Id: bc-containers-rings.ads,v 1.2.2.4 1999/12/31 15:08:30 simon Exp $
generic
package BC.Containers.Rings is
pragma Elaborate_Body;
type Ring is abstract new Container with private;
-- A ring denotes a sequence in which items may be added and removed
-- from the top of a circular structure. Since this structure has no
-- beginning or ending, a client can mark one particular item to
-- designate a point of reference in the structure.
type Direction is (Forward, Backward);
function Are_Equal (Left, Right : Ring'Class) return Boolean;
-- Return True if and only if both rings have the same extent and the
-- same items in the same order; return False otherwise. The
-- identity of the top and mark of both rings does not participate
-- in this test of equality.
-- Can't call this "=" because of the standard one for Ring.
procedure Copy (From : Ring'Class; To : in out Ring'Class);
-- This operation MUST be called for dissimilar Rings in place of
-- assignment.
procedure Clear (R : in out Ring) is abstract;
-- Empty the ring of all items. The mark is cleared.
procedure Insert (R : in out Ring; Elem : Item) is abstract;
-- If the ring was empty, set the ring's mark and top to designate
-- this item.
-- Otherwise,
-- this item becomes the new top;
-- the previous top is located one place forward of the new top;
-- the mark remains on the previously marked item.
procedure Pop (R : in out Ring) is abstract;
-- Remove the top item from the ring.
-- If the ring is still not empty, the new top is the item that was
-- previously one place forward from the top.
-- If the removed item was the marked item, the mark now designates
-- the new top.
procedure Rotate (R : in out Ring; Dir : Direction := Forward) is abstract;
-- Rotate the top of the ring in the given direction. The ring's
-- mark is unaffected. If there is exactly one item in the ring,
-- rotating either direction always returns to the same item.
procedure Mark (R : in out Ring);
-- Designate the item at the top of the ring (if not empty) as
-- marked.
procedure Rotate_To_Mark (R : in out Ring);
-- Rotate the ring so that the ring's mark is at the top.
function Extent (R : Ring) return Natural is abstract;
-- Return the number of items in the ring.
function Is_Empty (R : Ring) return Boolean is abstract;
-- Return True if and only if there are no items in the ring.
function Top (R : Ring) return Item is abstract;
-- Return a copy of the item at the top of the ring.
function At_Mark (R : Ring) return Boolean;
-- Return True if and only if the item at the top of the ring is
-- marked; otherwise, return False. This member function will return
-- True if the ring is empty, since the ring's top and mark both do
-- not designate any item.
private
type Ring is abstract new Container with record
Top : Natural; -- 0 implies not set
Mark : Natural; -- 0 implies not set
end record;
procedure Initialize (R : in out Ring);
-- derivations will need to call this
procedure Add (R : in out Ring; Elem : Item);
procedure Lock (R : in out Ring);
procedure Unlock (R : in out Ring);
type Ring_Iterator (R : access Ring'Class)
is new Actual_Iterator (R) with record
Index : Natural;
end record;
-- Overriding primitive supbrograms of the concrete actual Iterator.
procedure Initialize (It : in out Ring_Iterator);
procedure Reset (It : in out Ring_Iterator);
procedure Next (It : in out Ring_Iterator);
function Is_Done (It : Ring_Iterator) return Boolean;
function Current_Item (It : Ring_Iterator) return Item;
function Current_Item (It : Ring_Iterator) return Item_Ptr;
procedure Delete_Item_At (It : Ring_Iterator);
end BC.Containers.Rings;