File : bag.ads


     -- A specification for the Bag abstract data type.  A bag is just like
     -- a set in that it is a container for an unordered collection of
     -- objects.  Unlike a set, however, repeated elements are allowed in a
     -- bag.  These bags have only a few operations.  They will grow
   5 -- without limit until memory is exhausted.  Elements can only be
     -- added one at a time, and the only way to access elements is with the
     -- iterator Get_Next.
     --
     -- COL Gene Ressler
  10 generic
        type Element_Type is private;
     package Bag is
     
        type Bag_Type is limited private;
  15 
        -- Add a single element to a bag.
        procedure Add(Bag : in out Bag_Type;
                      Element : in Element_Type);
     
  20    -- Given an Index that is either a valid index or zero, get the
        -- _next_ corresponding bag element and return it along with its
        -- Index. When Index is zero, return the first bag element.  This
        -- definition allows Get_Next to function as an iterator.  A loop
        -- for processing all elements in a bag will usually look like
  25    -- this:
        --
        --    Index := 0;
        --    loop
        --       Get_Next(The_Bag, Index, Element);
  30    --       exit when Index = 0;
        --       if Needs_To_Be_Deleted(Element) then
        --          Delete(The_Bag, Index);
        --       end if;
        --       -- ... Other processing of Element ...;
  35    --    end loop;
        --
        -- Note that Delete properly adjusts its index so that Get_Next
        -- following a Delete during a processing loop will return the
        -- element following the deleted item.
  40    procedure Get_Next(Bag : in Bag_Type;
                           Index : in out Natural;
                           Element : out Element_Type);
     
        -- Given an index, set the corresponding bag element to a new value.
  45    procedure Set(Bag : in out Bag_Type;
                      Index : in Natural;
                      Element : in Element_Type);
     
        -- Given an index, delete the corresponding element from a bag.
  50    -- The index is adjusted automatically to work with the iterator
        -- Get_Next as described above.
        procedure Delete(Bag : in out Bag_Type;
                         Index : in out Natural);
     
  55    -- Clear a bag of all elements; i.e., make it empty.
        procedure Clear(Bag : in out Bag_Type);
     
     private
     
  60    type Element_Vector_Type is array(Integer range <>) of Element_Type;
        type Element_Vector_Ptr_Type is access Element_Vector_Type;
        Initial_Bag_Size : constant := 16;
        type Bag_Type is
           record
  65          Elements : Element_Vector_Ptr_Type := new Element_Vector_Type(1..Initial_Bag_Size);
              N_Elements : Natural := 0;
           end record;
     
     end Bag;