with Monitor;
generic
    type Item is private;
package Ring_Multiple_Bounded_Managed_Iterator is

    type Ring (The_Size : Positive) is limited private;

    type Direction is (Forward, Backward);

    procedure Copy (From_The_Ring : in Ring; To_The_Ring : in out Ring);
    procedure Clear (The_Ring : in out Ring);
    procedure Insert (The_Item : in Item; In_The_Ring : in out Ring);
    procedure Pop (The_Ring : in out Ring);
    procedure Rotate (The_Ring : in out Ring; In_The_Direction : in Direction);
    procedure Mark (The_Ring : in out Ring);
    procedure Rotate_To_Mark (The_Ring : in out Ring);

    function Is_Equal (Left : in Ring; Right : in Ring) return Boolean;
    function Extent_Of (The_Ring : in Ring) return Natural;
    function Is_Empty (The_Ring : in Ring) return Boolean;
    function Top_Of (The_Ring : in Ring) return Item;
    function At_Mark (The_Ring : in Ring) return Boolean;

    generic
        with procedure Process (The_Item : in Item; Continue : out Boolean);
    procedure Iterate (Over_The_Ring : in Ring);

    Overflow : exception;
    Underflow : exception;
    Rotate_Error : exception;

private
    type Items is array (Positive range <>) of Item;
    type Ring (The_Size : Positive) is
        record
            Guard : Monitor.Kind;
            The_Top : Natural := 0;
            The_Back : Natural := 0;
            The_Mark : Natural := 0;
            The_Items : Items (1 .. The_Size);
        end record;
end Ring_Multiple_Bounded_Managed_Iterator;