Skip to content

Vectors#

The language-defined generic package Containers.Vectors provides private types Vector and Cursor, and a set of operations for each type. A vector container allows insertion and deletion at any position, but it is specifically optimized for insertion and deletion at the high end (the end with the higher index) of the container. A vector container also provides random access to its elements.

A vector container behaves conceptually as an array that expands as necessary as items are inserted. The length of a vector is the number of elements that the vector contains. The capacity of a vector is the maximum number of elements that can be inserted into the vector prior to it being automatically expanded.

Elements in a vector container can be referred to by an index value of a generic formal type. The first element of a vector always has its index value equal to the lower bound of the formal type.

A vector container may contain empty elements. Empty elements do not have a specified value.

with Ada.Iterator_Interfaces;

generic
   type Index_Type   is range <>;
   type Element_Type is private;
   with function "="(Left, Right: Element_Type) return Boolean is <>;
package Ada.Containers.Vectors is
   with Preelaborate, Remote_Types, Nonblocking,
        Global => in out synchronized is

   subtype Extended_Index is Index_Type'Base range
      Index_Type'First - 1 ..
      Index_Type'Min(Index_Type'Base'Last - 1, Index_Type'Last) + 1;
   No_Index: constant Extended_Index := Extended_Index'First;

   type Vector is tagged private;
   type Cursor is private;
   Empty_Vector: constant Vector;
   No_Element  : constant Cursor;

   function Has_Element(Position: Cursor) return Boolean;
   function Has_Element(Container: Vector; Position: Cursor) return Boolean;

   package Vector_Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, Has_Element);
   
   function "="(Left, Right: Vector) return Boolean;

   function Tampering_With_Cursors_Prohibited (Container: Vector) return Boolean;
   function Tampering_With_Elements_Prohibited(Container: Vector) return Boolean;

   function Maximum_Length return Count_Type;
   function Empty(Capacity: Count_Type := <implementation-defined>) return Vector;

   function To_Vector(                        Length: Count_Type) return Vector;
   function To_Vector(New_Item: Element_Type; Length: Count_Type) return Vector;

   function New_Vector(First, Last: Index_Type) return Vector is
      (To_Vector(Count_Type(Last - First + 1)));

   function "&"(Left, Right: Vector)                     return Vector;
   function "&"(Left, Right: Element_Type)               return Vector;
   function "&"(Left: Vector      ; Right: Element_Type) return Vector;
   function "&"(Left: Element_Type; Right: Vector)       return Vector;

   function Capacity(Container: Vector) return Count_Type;
   function Length  (Container: Vector) return Count_Type;

   procedure Reserve_Capacity(Container: in out Vector; Capacity: Count_Type);
   
   procedure Set_Length(Container: in out Vector; Length: Count_Type);
   procedure Clear     (Container: in out Vector);

   function Is_Empty(Container: Vector) return Boolean;

   function To_Cursor(Container: Vector; Index: Extended_Index) return Cursor;
   function To_Index(Position: Cursor) return Extended_Index;
   function To_Index(Container: Vector; Position: Cursor) return Extended_Index;

   function Element(Container: Vector; Index: Index_Type) return Element_Type;
   function Element(Position : Cursor)                    return Element_Type;
   function Element(Container: Vector; Position: Cursor)  return Element_Type;

   procedure Replace_Element(Container: in out Vector; Index: Index_Type; New_Item: Element_Type);
   procedure Replace_Element(Container: in out Vector; Position: Cursor ; New_item: Element_Type);
   procedure Query_Element(Container: Vector;
                           Index    : Index_Type;
                           Process  : not null access procedure(Element: Element_Type));
   procedure Query_Element(Position: Cursor;
                           Process : not null access procedure(Element: Element_Type));
   procedure Query_Element(Container: Vector;
                           Position : Cursor;
                           Process  : not null access procedure(Element: Element_Type));
   procedure Update_Element(Container: in out Vector;
                            Index    : Index_Type;
                            Process  : not null access procedure(Element: in out Element_Type));
   procedure Update_Element(Container: in out Vector;
                            Position : Cursor;
                            Process  : not null access procedure(Element: in out Element_Type));

   type Constant_Reference_Type(Element: not null access constant Element_Type) is private;
   type Reference_Type(Element: not null access Element_Type) is private;

   function Constant_Reference(Container: aliased Vector       ; Index: Index_Type) return Constant_Reference_Type;
   function Reference         (Container: aliased in out Vector; Index: Index_Type) return Reference_Type;
   function Constant_Reference(Container: aliased Vector       ; Position: Cursor)  return Constant_Reference_Type;
   function Reference         (Container: aliased in out Vector; Position: Cursor)  return Reference_Type;
   function Copy(Source: Vector; Capacity: Count_Type := 0) return Vector;

   procedure Assign(Target: in out Vector; Source: Vector);
   procedure Move  (Target: in out Vector; Source: in out Vector);

   procedure Insert_Vector(Container: in out Vector; Before: Extended_Index; New_Item: Vector);
   procedure Insert_Vector(Container: in out Vector; Before: Cursor        ; New_Item: Vector);
   procedure Insert_Vector(Container: in out Vector; Before: Cursor        ; New_Item: Vector; Position: out Cursor);

   procedure Insert(Container: in out Vector; Before: Extended_Index; New_Item: Element_Type; Count: Count_Type := 1);
   procedure Insert(Container: in out Vector; Before: Cursor        ; New_Item: Element_Type; Count: Count_Type := 1);
   procedure Insert(Container: in out Vector; Before: Extended_Index                        ; Count: Count_Type := 1);
   procedure Insert(Container: in out Vector; Before: Cursor; Position: out Cursor          ; Count: Count_Type := 1);
   procedure Insert(Container: in out Vector;
                    Before   : Cursor;
                    New_Item : Element_Type;
                    Position : out Cursor;
                    Count    : Count_Type := 1);

   procedure Prepend_Vector  (Container: in out Vector; New_Item: Vector);
   procedure Append_Vector   (Container: in out Vector; New_Item: Vector);
   procedure Prepend         (Container: in out Vector; New_Item: Element_Type; Count: Count_Type := 1);
   procedure Append          (Container: in out Vector; New_Item: Element_Type; Count: Count_Type := 1);
   procedure Append          (Container: in out Vector; New_Item: Element_Type);
   procedure Insert_Space    (Container: in out Vector; Before: Extended_Index; Count: Count_Type := 1);
   procedure Insert_Space    (Container: in out Vector; Before: Cursor; Position: out Cursor; Count: Count_Type := 1);
   procedure Delete          (Container: in out Vector; Index: Extended_Index; Count: Count_Type := 1);
   procedure Delete          (Container: in out Vector; Position: in out Cursor; Count: Count_Type := 1);
   procedure Delete_First    (Container: in out Vector; Count: Count_Type := 1);
   procedure Delete_Last     (Container: in out Vector; Count: Count_Type := 1);
   procedure Reverse_Elements(Container: in out Vector);
   procedure Swap            (Container: in out Vector; I, J: Index_Type);
   procedure Swap            (Container: in out Vector; I, J: Cursor);

   function First_Index  (Container: Vector) return Index_Type;
   function First        (Container: Vector) return Cursor;
   function First_Element(Container: Vector) return Element_Type;
   function Last_Index   (Container: Vector) return Extended_Index;
   function Last         (Container: Vector) return Cursor;
   function Last_Element (Container: Vector) return Element_Type;

   function Next(                   Position: Cursor) return Cursor;
   function Next(Container: Vector; Position: Cursor) return Cursor;

   procedure Next(                   Position: in out Cursor);
   procedure Next(Container: Vector; Position: in out Cursor);

   function Previous(                   Position: Cursor) return Cursor;
   function Previous(Container: Vector; Position: Cursor) return Cursor;

   procedure Previous(                   Position: in out Cursor);
   procedure Previous(Container: Vector; Position: in out Cursor);

   function Find_Index(Container: Vector;
                       Item     : Element_Type;
                       Index    : Index_Type := Index_Type'First) return Extended_Index;
   function Find(Container: Vector;
                 Item     : Element_Type;
                 Position : Cursor := No_Element) return Cursor;
   function Reverse_Find_Index(Container: Vector;
                               Item     : Element_Type;
                               Index    : Index_Type := Index_Type'Last) return Extended_Index;
   function Reverse_Find(Container: Vector;
                         Item     : Element_Type;
                         Position : Cursor := No_Element) return Cursor;

   function Contains(Container: Vector; Item: Element_Type) return Boolean;
   
   procedure Iterate        (Container: Vector; Process: not null access procedure(Position: Cursor));
   procedure Reverse_Iterate(Container: Vector; Process: not null access procedure(Position: Cursor));

   function Iterate(Container: Vector)
      return Vector_Iterator_Interfaces.Parallel_Reversible_Iterator'Class;
   function Iterate(Container: Vector; Start: Cursor)
      return Vector_Iterator_Interfaces.Reversible_Iterator'Class;

   generic
      with function "<"(Left, Right: Element_Type) return Boolean is <>;
   package Generic_Sorting
      with Nonblocking, Global => null is

      function Is_Sorted(Container: Vector) return Boolean;

      procedure Sort (Container: in out Vector);
      procedure Merge(Target   : in out Vector; Source: in out Vector);
   end Generic_Sorting;

   package Stable is
      type Vector(Base: not null access Vectors.Vector) is tagged limited private;
      type Cursor is private;

      Empty_Vector: constant Vector;
      No_Element  : constant Cursor;

      function Has_Element(Position: Cursor) return Boolean;

      package Vector_Iterator_Interfaces is new Ada.Iterator_Interfaces(Cursor, Has_Element);

      procedure Assign(Target: in out Vectors.Vector; Source: Vector);

      function Copy(Source: Vectors.Vector) return Vector;

      type Constant_Reference_Type(Element: not null access constant Element_Type) is private;
      type Reference_Type         (Element: not null access          Element_Type) is private;
   end Stable;
end Ada.Containers.Vectors;

Bounded (Run-Time) Errors

Reading the value of an empty element by calling Element, Query_Element, Update_Element, Constant_Reference, Reference, Swap, Is_Sorted, Sort, Merge, "=", Find, or Reverse_Find is a bounded error. The implementation may treat the element as having any normal value (see 13.9.1) of the element type, or raise Constraint_Error or Program_Error before modifying the vector.

Calling Merge in an instance of Generic_Sorting with either Source or Target not ordered smallest first using the provided generic formal "<" operator is a bounded error. Either Program_Error is raised after Target is updated as described for Merge, or the operation works as defined.

It is a bounded error for the actual function associated with a generic formal subprogram, when called as part of an operation of this package, to tamper with elements of any Vector parameter of the operation. Either Program_Error is raised, or the operation works as defined on the value of the Vector either prior to, or subsequent to, some or all of the modifications to the Vector.

It is a bounded error to call any subprogram declared in the visible part of Containers.Vectors when the associated container has been finalized. If the operation takes Container as an in out parameter, then it raises Constraint_Error or Program_Error. Otherwise, the operation either proceeds as it would for an empty container, or it raises Constraint_Error or Program_Error.

A Cursor value is ambiguous if any of the following have occurred since it was created:

  • Insert, Insert_Space, Insert_Vector, or Delete has been called on the vector that contains the element the cursor designates with an index value (or a cursor designating an element at such an index value) less than or equal to the index value of the element designated by the cursor.
  • The vector that contains the element it designates has been passed to the Sort or Merge procedures of an instance of Generic_Sorting, or to the Reverse_Elements procedure.
  • It is a bounded error to call any subprogram other than "=" or Has_Element declared in Containers.Vectors with an ambiguous (but not invalid, see below) cursor parameter. Possible results are:
    • The cursor may be treated as if it were No_Element.
    • The cursor may designate some element in the vector (but not necessarily the element that it originally designated).
    • Constraint_Error may be raised.
    • Program_Error may be raised.

Erroneous Execution

A Cursor value is invalid if any of the following have occurred since it was created:

  • The vector that contains the element it designates has been finalized.
  • The vector that contains the element it designates has been used as the Target of a call to Assign, or as the target of an assignment_statement.
  • The vector that contains the element it designates has been used as the Source or Target of a call to Move.
  • The element it designates has been deleted or removed from the vector that previously contained the element.
  • The result of "=" or Has_Element is unspecified if it is called with an invalid cursor parameter. Execution is erroneous if any other subprogram declared in Containers.Vectors is called with an invalid cursor parameter.
  • Execution is erroneous if the vector associated with the result of a call to Reference or Constant_Reference is finalized before the result object returned by the call to Reference or Constant_Reference is finalized.

Bounded Vectors#

The language-defined generic package Containers.Bounded_Vectors provides a private type Vector and a set of operations. It provides the same operations as the package Containers.Vectors (see A.18.2), with the difference that the maximum storage is bounded.

Containers.Bounded_Vectors
type Vector(Capacity: Count_Type) is tagged private...

Bounded (Run-Time) Errors

It is a bounded error to assign from a bounded vector object while tampering with elements [or cursors] of that object is prohibited. Either Program_Error is raised by the assignment, execution proceeds with the target object prohibiting tampering with elements [or cursors], or execution proceeds normally.

Erroneous Execution

When a bounded vector object V is finalized, if tampering with cursors is prohibited for V other than due to an assignment from another vector, then execution is erroneous.

Indefinite Vectors#

The language-defined generic package Containers.Indefinite_Vectors provides a private type Vector and a set of operations. It provides the same operations as the package Containers.Vectors (see A.18.2), with the difference that the generic formal Element_Type is indefinite.

Omitted Subprograms
procedure Insert(Container: in out Vector;
                 Before   : Extended_Index;
                 Count    : Count_Type := 1);
procedure Insert(Container: in out Vector;
                 Before   : Cursor;
                 Position : out Cursor;
                 Count    : Count_Type := 1);