------------------------------------------------------------------------------
--                                                                          --
--                         GNAT LIBRARY COMPONENTS                          --
--                                                                          --
--                A D A . C O N T A I N E R S . V E C T O R S               --
--                                                                          --
--                                 S p e c                                  --
--                                                                          --
--          Copyright (C) 2004-2021, Free Software Foundation, Inc.         --
--                                                                          --
-- This specification is derived from the Ada Reference Manual for use with --
-- GNAT. The copyright notice above, and the license provisions that follow --
-- apply solely to the  contents of the part following the private keyword. --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
--                                                                          --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception,   --
-- version 3.1, as published by the Free Software Foundation.               --
--                                                                          --
-- You should have received a copy of the GNU General Public License and    --
-- a copy of the GCC Runtime Library Exception along with this program;     --
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
-- <http://www.gnu.org/licenses/>.                                          --
--                                                                          --
-- This unit was originally developed by Matthew J Heaney.                  --
------------------------------------------------------------------------------

with Ada.Iterator_Interfaces;

with Ada.Containers.Helpers;
private with Ada.Finalization;
private with Ada.Streams;
private with Ada.Strings.Text_Buffers;

--  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.

generic
   type Index_Type is range <>;
   type Element_Type is private;

   with function "=" (Left, Right : Element_Type) return Boolean is <>;
   --  The actual function for the generic formal function "=" on Element_Type
   --  values is expected to define a reflexive and symmetric relationship and
   --  return the same result value each time it is called with a particular
   --  pair of values. If it behaves in some other manner, the functions
   --  defined to use it return an unspecified value. The exact arguments and
   --  number of calls of this generic formal function by the functions defined
   --  to use it are unspecified.

package Ada.Containers.Vectors with
  SPARK_Mode => Off
is
   pragma Annotate (CodePeer, Skip_Analysis);
   pragma Preelaborate;
   pragma Remote_Types;

   subtype Extended_Index is Index_Type'Base
     range Index_Type'First - 1 ..
           Index_Type'Min (Index_Type'Base'Last - 1, Index_Type'Last) + 1;
   --  The subtype Extended_Index includes the indices covered by Index_Type
   --  plus the value No_Index and, if it exists, the successor to the
   --  Index_Type'Last.

   No_Index : constant Extended_Index := Extended_Index'First;
   --  No_Index represents a position that does not correspond to any element.

   type Vector is tagged private
   with
      Constant_Indexing => Constant_Reference,
      Variable_Indexing => Reference,
      Default_Iterator  => Iterate,
      Iterator_Element  => Element_Type,
      Aggregate         => (Empty          => Empty,
                            Add_Unnamed    => Append,
                            New_Indexed    => New_Vector,
                            Assign_Indexed => Replace_Element);

   pragma Preelaborable_Initialization (Vector);
   --  Vector type, to be instantiated by users of this package. If an object
   --  of type Vector is not otherwise initialized, it is initialized to
   --  Empty_Vector.

   type Cursor is private;
   pragma Preelaborable_Initialization (Cursor);
   --  Cursor pointing into an instance of vector. If an object of type Cursor
   --  is not otherwise initialized, it is initialized to No_Element

   No_Element : constant Cursor;
   --  No_Element represents a cursor that designates no element.

   function Has_Element (Position : Cursor) return Boolean;
   --  Returns True if Position designates an element, and returns False
   --  otherwise.

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

   Empty_Vector : constant Vector;
   --  Empty_Vector represents the empty vector object. It has a length of 0.

   function Empty (Capacity : Count_Type := 10) return Vector;

   overriding function "=" (Left, Right : Vector) return Boolean;
   --  If Left and Right denote the same vector object, then the function
   --  returns True. If Left and Right have different lengths, then the
   --  function returns False. Otherwise, it compares each element in Left to
   --  the corresponding element in Right using the generic formal equality
   --  operator. If any such comparison returns False, the function returns
   --  False; otherwise it returns True. Any exception raised during evaluation
   --  of element equality is propagated.

   function To_Vector (Length : Count_Type) return Vector;
   --  Returns a vector with a length of Length, filled with empty elements.

   function To_Vector
     (New_Item : Element_Type;
      Length   : Count_Type) return Vector;
   --  Returns a vector with a length of Length, filled with elements
   --  initialized to the value New_Item.

   function "&" (Left, Right : Vector) return Vector;
   --  Returns a vector comprising the elements of Left followed by the
   --  elements of Right.

   function "&" (Left : Vector; Right : Element_Type) return Vector;
   --  Returns a vector comprising the elements of Left followed by the element
   --  Right.

   function "&" (Left : Element_Type; Right : Vector) return Vector;
   --  Returns a vector comprising the element Left followed by the elements of
   --  Right.

   function "&" (Left, Right : Element_Type) return Vector;
   --  Returns a vector comprising the element Left followed by the element
   --  Right.

   function Capacity (Container : Vector) return Count_Type;
   --  Returns the capacity of Container.

   procedure Reserve_Capacity
     (Container : in out Vector;
      Capacity  : Count_Type);
   --  Reserve_Capacity allocates new internal data structures such that the
   --  length of the resulting vector can become at least the value Capacity
   --  without requiring an additional call to Reserve_Capacity, and is large
   --  enough to hold the current length of Container. Reserve_Capacity then
   --  copies the elements into the new data structures and deallocates the old
   --  data structures. Any exception raised during allocation is propagated
   --  and Container is not modified.

   function Length (Container : Vector) return Count_Type;
   --  Returns the number of elements in Container.

   procedure Set_Length
     (Container : in out Vector;
      Length    : Count_Type);
   --  If Length is larger than the capacity of Container, Set_Length calls
   --  Reserve_Capacity (Container, Length), then sets the length of the
   --  Container to Length. If Length is greater than the original length of
   --  Container, empty elements are added to Container; otherwise elements are
   --  removed from Container.

   function Is_Empty (Container : Vector) return Boolean;
   --  Equivalent to Length (Container) = 0.

   procedure Clear (Container : in out Vector);
   --  Removes all the elements from Container. The capacity of Container does
   --  not change.

   function To_Cursor
     (Container : Vector;
      Index     : Extended_Index) return Cursor;
   --  If Index is not in the range First_Index (Container) .. Last_Index
   --  (Container), then No_Element is returned. Otherwise, a cursor
   --  designating the element at position Index in Container is returned.

   function To_Index (Position : Cursor) return Extended_Index;
   --  If Position is No_Element, No_Index is returned. Otherwise, the index
   --  (within its containing vector) of the element designated by Position is
   --  returned.

   function Element
     (Container : Vector;
      Index     : Index_Type) return Element_Type;
   --  If Index is not in the range First_Index (Container) .. Last_Index
   --  (Container), then Constraint_Error is propagated. Otherwise, Element
   --  returns the element at position Index.

   function Element (Position : Cursor) return Element_Type;
   --  If Position equals No_Element, then Constraint_Error is propagated.
   --  Otherwise, Element returns the element designated by Position.

   procedure Replace_Element
     (Container : in out Vector;
      Index     : Index_Type;
      New_Item  : Element_Type);
   --  If Index is not in the range First_Index (Container) .. Last_Index
   --  (Container), then Constraint_Error is propagated. Otherwise
   --  Replace_Element assigns the value New_Item to the element at position
   --  Index. Any exception raised during the assignment is propagated. The
   --  element at position Index is not an empty element after successful call
   --  to Replace_Element.

   procedure Replace_Element
     (Container : in out Vector;
      Position  : Cursor;
      New_Item  : Element_Type);
   --  If Position equals No_Element, then Constraint_Error is propagated; if
   --  Position does not designate an element in Container, then Program_Error
   --  is propagated. Otherwise Replace_Element assigns New_Item to the element
   --  designated by Position. Any exception raised during the assignment is
   --  propagated. The element at Position is not an empty element after
   --  successful call to Replace_Element.

   procedure Query_Element
     (Container : Vector;
      Index     : Index_Type;
      Process   : not null access procedure (Element : Element_Type));
   --  If Index is not in the range First_Index (Container) .. Last_Index
   --  (Container), then Constraint_Error is propagated. Otherwise,
   --  Query_Element calls Process.all with the element at position Index as
   --  the argument. Program_Error is propagated if Process.all tampers with
   --  the elements of Container. Any exception raised by Process.all is
   --  propagated.

   procedure Query_Element
     (Position : Cursor;
      Process  : not null access procedure (Element : Element_Type));
   --  If Position equals No_Element, then Constraint_Error is propagated.
   --  Otherwise, Query_Element calls Process.all with the element designated
   --  by Position as the argument. Program_Error is propagated if Process.all
   --  tampers with the elements of Container. Any exception raised by
   --  Process.all is propagated.

   procedure Update_Element
     (Container : in out Vector;
      Index     : Index_Type;
      Process   : not null access procedure (Element : in out Element_Type));
   --  If Index is not in the range First_Index (Container) .. Last_Index
   --  (Container), then Constraint_Error is propagated. Otherwise,
   --  Update_Element calls Process.all with the element at position Index as
   --  the argument. Program_Error is propagated if Process.all tampers with
   --  the elements of Container. Any exception raised by Process.all is
   --  propagated.
   --
   --  If Element_Type is unconstrained and definite, then the actual Element
   --  parameter of Process.all shall be unconstrained.
   --
   --  The element at position Index is not an empty element after successful
   --  completion of this operation.

   procedure Update_Element
     (Container : in out Vector;
      Position  : Cursor;
      Process   : not null access procedure (Element : in out Element_Type));
   --  If Position equals No_Element, then Constraint_Error is propagated; if
   --  Position does not designate an element in Container, then Program_Error
   --  is propagated. Otherwise Update_Element calls Process.all with the
   --  element designated by Position as the argument. Program_Error is
   --  propagated if Process.all tampers with the elements of Container. Any
   --  exception raised by Process.all is propagated.
   --
   --  If Element_Type is unconstrained and definite, then the actual Element
   --  parameter of Process.all shall be unconstrained.
   --
   --  The element designated by Position is not an empty element after
   --  successful completion of this operation.

   type Constant_Reference_Type
      (Element : not null access constant Element_Type) is
   private
   with
      Implicit_Dereference => Element;

   type Reference_Type (Element : not null access Element_Type) is private
   with
      Implicit_Dereference => Element;

   function Constant_Reference
     (Container : aliased Vector;
      Position  : Cursor) return Constant_Reference_Type;
   pragma Inline (Constant_Reference);

   function Reference
     (Container : aliased in out Vector;
      Position  : Cursor) return Reference_Type;
   pragma Inline (Reference);

   function Constant_Reference
     (Container : aliased Vector;
      Index     : Index_Type) return Constant_Reference_Type;
   pragma Inline (Constant_Reference);

   function Reference
     (Container : aliased in out Vector;
      Index     : Index_Type) return Reference_Type;
   pragma Inline (Reference);

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

   function Copy (Source : Vector; Capacity : Count_Type := 0) return Vector;

   procedure Move (Target : in out Vector; Source : in out Vector);
   --  If Target denotes the same object as Source, then Move has no effect.
   --  Otherwise, Move first calls Clear (Target); then, each element from
   --  Source is removed from Source and inserted into Target in the original
   --  order. The length of Source is 0 after a successful call to Move.

   function New_Vector (First, Last : Index_Type) return Vector
     with Pre => First = Index_Type'First;
   --  Ada 2022 aggregate operation.

   procedure Insert_Vector
     (Container : in out Vector;
      Before    : Extended_Index;
      New_Item  : Vector);
   --  If Before is not in the range First_Index (Container) .. Last_Index
   --  (Container) + 1, then Constraint_Error is propagated. If
   --  Length(New_Item) is 0, then Insert_Vector does nothing. Otherwise, it
   --  computes the new length NL as the sum of the current length and Length
   --  (New_Item); if the value of Last appropriate for length NL would be
   --  greater than Index_Type'Last then Constraint_Error is propagated.
   --
   --  If the current vector capacity is less than NL, Reserve_Capacity
   --  (Container, NL) is called to increase the vector capacity. Then
   --  Insert_Vector slides the elements in the range Before .. Last_Index
   --  (Container) up by Length(New_Item) positions, and then copies the
   --  elements of New_Item to the positions starting at Before. Any exception
   --  raised during the copying is propagated.

   procedure Insert
     (Container : in out Vector;
      Before    : Extended_Index;
      New_Item  : Vector) renames Insert_Vector;
   --  Retained for now for compatibility; AI12-0400 will remove this.

   procedure Insert_Vector
     (Container : in out Vector;
      Before    : Cursor;
      New_Item  : Vector);
   --  If Before is not No_Element, and does not designate an element in
   --  Container, then Program_Error is propagated. Otherwise, if
   --  Length(New_Item) is 0, then Insert_Vector does nothing. If Before is
   --  No_Element, then the call is equivalent to Insert_Vector (Container,
   --  Last_Index (Container) + 1, New_Item); otherwise the call is equivalent
   --  to Insert_Vector (Container, To_Index (Before), New_Item);

   procedure Insert
     (Container : in out Vector;
      Before    : Cursor;
      New_Item  : Vector) renames Insert_Vector;
   --  Retained for now for compatibility; AI12-0400 will remove this.

   procedure Insert_Vector
     (Container : in out Vector;
      Before    : Cursor;
      New_Item  : Vector;
      Position  : out Cursor);
   --  If Before is not No_Element, and does not designate an element in
   --  Container, then Program_Error is propagated. If Before equals
   --  No_Element, then let T be Last_Index (Container) + 1; otherwise, let T
   --  be To_Index (Before). Insert_Vector (Container, T, New_Item) is called,
   --  and then Position is set to To_Cursor (Container, T).

   procedure Insert
     (Container : in out Vector;
      Before    : Cursor;
      New_Item  : Vector;
      Position  : out Cursor) renames Insert_Vector;
   --  Retained for now for compatibility; AI12-0400 will remove this.

   procedure Insert
     (Container : in out Vector;
      Before    : Extended_Index;
      New_Item  : Element_Type;
      Count     : Count_Type := 1);
   --  Equivalent to:
   --  Insert_Vector (Container, Before, To_Vector (New_Item, Count));

   procedure Insert
     (Container : in out Vector;
      Before    : Cursor;
      New_Item  : Element_Type;
      Count     : Count_Type := 1);
   --  Equivalent to:
   --  Insert_Vector (Container, Before, To_Vector (New_Item, Count));

   procedure Insert
     (Container : in out Vector;
      Before    : Cursor;
      New_Item  : Element_Type;
      Position  : out Cursor;
      Count     : Count_Type := 1);
   --  Equivalent to
   --  Insert_Vector (Container, Before, To_Vector (New_Item, Count), Position)

   procedure Insert
     (Container : in out Vector;
      Before    : Extended_Index;
      Count     : Count_Type := 1);
   --  If Before is not in the range First_Index (Container) .. Last_Index
   --  (Container) + 1, then Constraint_Error is propagated. If Count is 0,
   --  then Insert does nothing. Otherwise, it computes the new length NL as
   --  the sum of the current length and Count; if the value of Last
   --  appropriate for length NL would be greater than Index_Type'Last then
   --  Constraint_Error is propagated.
   --
   --  If the current vector capacity is less than NL, Reserve_Capacity
   --  (Container, NL) is called to increase the vector capacity. Then Insert
   --  slides the elements in the range Before .. Last_Index (Container) up by
   --  Count positions, and then inserts elements that are initialized by
   --  default (see 3.3.1) in the positions starting at Before.

   procedure Insert
     (Container : in out Vector;
      Before    : Cursor;
      Position  : out Cursor;
      Count     : Count_Type := 1);
   --  If Before is not No_Element, and does not designate an element in
   --  Container, then Program_Error is propagated. If Before equals
   --  No_Element, then let T be Last_Index (Container) + 1; otherwise, let T
   --  be To_Index (Before). Insert (Container, T, Count) is called, and then
   --  Position is set to To_Cursor (Container, T).

   procedure Prepend_Vector
     (Container : in out Vector;
      New_Item  : Vector);
   --  Equivalent to Insert (Container, First_Index (Container), New_Item).

   procedure Prepend
     (Container : in out Vector;
      New_Item  : Vector) renames Prepend_Vector;
   --  Retained for now for compatibility; AI12-0400 will remove this.

   procedure Prepend
     (Container : in out Vector;
      New_Item  : Element_Type;
      Count     : Count_Type := 1);
   --  Equivalent to Insert (Container, First_Index (Container), New_Item,
   --  Count).

   procedure Append_Vector
     (Container : in out Vector;
      New_Item  : Vector);
   --  Equivalent to Insert (Container, Last_Index (Container) + 1, New_Item).

   procedure Append
     (Container : in out Vector;
      New_Item  : Vector) renames Append_Vector;
   --  Retained for now for compatibility; AI12-0400 will remove this.

   procedure Append
     (Container : in out Vector;
      New_Item  : Element_Type;
      Count     : Count_Type);
   --  Equivalent to Insert (Container, Last_Index (Container) + 1, New_Item,
   --  Count).

   procedure Append (Container : in out Vector;
                     New_Item  :        Element_Type);

   procedure Insert_Space
     (Container : in out Vector;
      Before    : Extended_Index;
      Count     : Count_Type := 1);
   --  If Before is not in the range First_Index (Container) .. Last_Index
   --  (Container) + 1, then Constraint_Error is propagated. If Count is 0,
   --  then Insert_Space does nothing. Otherwise, it computes the new length NL
   --  as the sum of the current length and Count; if the value of Last
   --  appropriate for length NL would be greater than Index_Type'Last then
   --  Constraint_Error is propagated.
   --
   --  If the current vector capacity is less than NL, Reserve_Capacity
   --  (Container, NL) is called to increase the vector capacity. Then
   --  Insert_Space slides the elements in the range Before .. Last_Index
   --  (Container) up by Count positions, and then inserts empty elements in
   --  the positions starting at Before.

   procedure Insert_Space
     (Container : in out Vector;
      Before    : Cursor;
      Position  : out Cursor;
      Count     : Count_Type := 1);
   --  If Before is not No_Element, and does not designate an element in
   --  Container, then Program_Error is propagated. If Before equals
   --  No_Element, then let T be Last_Index (Container) + 1; otherwise, let T
   --  be To_Index (Before). Insert_Space (Container, T, Count) is called, and
   --  then Position is set to To_Cursor (Container, T).

   procedure Delete
     (Container : in out Vector;
      Index     : Extended_Index;
      Count     : Count_Type := 1);
   --  If Index is not in the range First_Index (Container) .. Last_Index
   --  (Container) + 1, then Constraint_Error is propagated. If Count is 0,
   --  Delete has no effect. Otherwise Delete slides the elements (if any)
   --  starting at position Index + Count down to Index. Any exception raised
   --  during element assignment is propagated.

   procedure Delete
     (Container : in out Vector;
      Position  : in out Cursor;
      Count     : Count_Type := 1);
   --  If Position equals No_Element, then Constraint_Error is propagated. If
   --  Position does not designate an element in Container, then Program_Error
   --  is propagated. Otherwise, Delete (Container, To_Index (Position), Count)
   --  is called, and then Position is set to No_Element.

   procedure Delete_First
     (Container : in out Vector;
      Count     : Count_Type := 1);
   --  Equivalent to Delete (Container, First_Index (Container), Count).

   procedure Delete_Last
     (Container : in out Vector;
      Count     : Count_Type := 1);
   --  If Length (Container) <= Count then Delete_Last is equivalent to Clear
   --  (Container). Otherwise it is equivalent to Delete (Container,
   --  Index_Type'Val(Index_Type'Pos(Last_Index (Container)) - Count + 1),
   --  Count).

   procedure Reverse_Elements (Container : in out Vector);
   --  Reorders the elements of Container in reverse order.

   procedure Swap (Container : in out Vector; I, J : Index_Type);
   --  If either I or J is not in the range First_Index (Container) ..
   --  Last_Index (Container), then Constraint_Error is propagated. Otherwise,
   --  Swap exchanges the values of the elements at positions I and J.

   procedure Swap (Container : in out Vector; I, J : Cursor);
   --  If either I or J is No_Element, then Constraint_Error is propagated. If
   --  either I or J do not designate an element in Container, then
   --  Program_Error is propagated. Otherwise, Swap exchanges the values of the
   --  elements designated by I and J.

   function First_Index (Container : Vector) return Index_Type;
   --  Returns the value Index_Type'First.

   function First (Container : Vector) return Cursor;
   --  If Container is empty, First returns No_Element. Otherwise, it returns a
   --  cursor that designates the first element in Container.

   function First_Element (Container : Vector) return Element_Type;
   --  Equivalent to Element (Container, First_Index (Container)).

   function Last_Index (Container : Vector) return Extended_Index;
   --  If Container is empty, Last_Index returns No_Index. Otherwise, it
   --  returns the position of the last element in Container.

   function Last (Container : Vector) return Cursor;
   --  If Container is empty, Last returns No_Element. Otherwise, it returns a
   --  cursor that designates the last element in Container.

   function Last_Element (Container : Vector) return Element_Type;
   --  Equivalent to Element (Container, Last_Index (Container)).

   function Next (Position : Cursor) return Cursor;
   --  If Position equals No_Element or designates the last element of the
   --  container, then Next returns the value No_Element. Otherwise, it returns
   --  a cursor that designates the element with index To_Index (Position) + 1
   --  in the same vector as Position.

   procedure Next (Position : in out Cursor);
   --  Equivalent to Position := Next (Position).

   function Previous (Position : Cursor) return Cursor;
   --  If Position equals No_Element or designates the first element of the
   --  container, then Previous returns the value No_Element. Otherwise, it
   --  returns a cursor that designates the element with index To_Index
   --  (Position) - 1 in the same vector as Position.

   procedure Previous (Position : in out Cursor);
   --  Equivalent to Position := Previous (Position).

   function Find_Index
     (Container : Vector;
      Item      : Element_Type;
      Index     : Index_Type := Index_Type'First) return Extended_Index;
   --  Searches the elements of Container for an element equal to Item (using
   --  the generic formal equality operator). The search starts at position
   --  Index and proceeds towards Last_Index (Container). If no equal
   --  element is found, then Find_Index returns No_Index. Otherwise, it
   --  returns the index of the first equal element encountered.

   function Find
     (Container : Vector;
      Item      : Element_Type;
      Position  : Cursor := No_Element) return Cursor;
   --  If Position is not No_Element, and does not designate an element in
   --  Container, then Program_Error is propagated. Otherwise Find searches
   --  the elements of Container for an element equal to Item (using the
   --  generic formal equality operator). The search starts at the first
   --  element if Position equals No_Element, and at the element designated
   --  by Position otherwise. It proceeds towards the last element of
   --  Container. If no equal element is found, then Find returns
   --  No_Element. Otherwise, it returns a cursor designating the first
   --  equal element encountered.

   function Reverse_Find_Index
     (Container : Vector;
      Item      : Element_Type;
      Index     : Index_Type := Index_Type'Last) return Extended_Index;
   --  Searches the elements of Container for an element equal to Item (using
   --  the generic formal equality operator). The search starts at position
   --  Index or, if Index is greater than Last_Index (Container), at
   --  position Last_Index (Container). It proceeds towards First_Index
   --  (Container). If no equal element is found, then Reverse_Find_Index
   --  returns No_Index. Otherwise, it returns the index of the first equal
   --  element encountered.

   function Reverse_Find
     (Container : Vector;
      Item      : Element_Type;
      Position  : Cursor := No_Element) return Cursor;
   --  If Position is not No_Element, and does not designate an element in
   --  Container, then Program_Error is propagated. Otherwise Reverse_Find
   --  searches the elements of Container for an element equal to Item
   --  (using the generic formal equality operator). The search starts at
   --  the last element if Position equals No_Element, and at the element
   --  designated by Position otherwise. It proceeds towards the first
   --  element of Container. If no equal element is found, then Reverse_Find
   --  returns No_Element. Otherwise, it returns a cursor designating the
   --  first equal element encountered.

   function Contains
     (Container : Vector;
      Item      : Element_Type) return Boolean;
   --  Equivalent to Has_Element (Find (Container, Item)).

   procedure Iterate
     (Container : Vector;
      Process   : not null access procedure (Position : Cursor));
   --  Invokes Process.all with a cursor that designates each element in
   --  Container, in index order. Program_Error is propagated if Process.all
   --  tampers with the cursors of Container. Any exception raised by Process
   --  is propagated.

   procedure Reverse_Iterate
     (Container : Vector;
      Process   : not null access procedure (Position : Cursor));
   --  Iterates over the elements in Container as per Iterate, except that
   --  elements are traversed in reverse index order.
   --

   function Iterate (Container : Vector)
      return Vector_Iterator_Interfaces.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 <>;
      --  The actual function for the generic formal function "<" of
      --  Generic_Sorting is expected to return the same value each time it is
      --  called with a particular pair of element values. It should define a
      --  strict ordering relationship, that is, be irreflexive, asymmetric,
      --  and transitive; it should not modify Container. If the actual for "<"
      --  behaves in some other manner, the behavior of the subprograms of
      --  Generic_Sorting are unspecified. How many times the subprograms of
      --  Generic_Sorting call "<" is unspecified.
   package Generic_Sorting is

      function Is_Sorted (Container : Vector) return Boolean;
      --  Returns True if the elements are sorted smallest first as determined
      --  by the generic formal "<" operator; otherwise, Is_Sorted returns
      --  False. Any exception raised during evaluation of "<" is propagated.

      procedure Sort (Container : in out Vector);
      --  Reorders the elements of Container such that the elements are sorted
      --  smallest first as determined by the generic formal "<" operator
      --  provided. Any exception raised during evaluation of "<" is
      --  propagated.

      procedure Merge (Target : in out Vector; Source : in out Vector);
      --  Merge removes elements from Source and inserts them into Target;
      --  afterwards, Target contains the union of the elements that were
      --  initially in Source and Target; Source is left empty. If Target and
      --  Source are initially sorted smallest first, then Target is ordered
      --  smallest first as determined by the generic formal "<" operator;
      --  otherwise, the order of elements in Target is unspecified. Any
      --  exception raised during evaluation of "<" is propagated.

   end Generic_Sorting;

private

   pragma Inline (Append);
   pragma Inline (First_Index);
   pragma Inline (Last_Index);
   pragma Inline (Element);
   pragma Inline (First_Element);
   pragma Inline (Last_Element);
   pragma Inline (Query_Element);
   pragma Inline (Update_Element);
   pragma Inline (Replace_Element);
   pragma Inline (Is_Empty);
   pragma Inline (Contains);
   pragma Inline (Next);
   pragma Inline (Previous);

   use Ada.Containers.Helpers;
   package Implementation is new Generic_Implementation;
   use Implementation;

   type Elements_Array is array (Index_Type range <>) of aliased Element_Type;
   function "=" (L, R : Elements_Array) return Boolean is abstract;

   type Elements_Type (Last : Extended_Index) is limited record
      EA : Elements_Array (Index_Type'First .. Last);
   end record;

   type Elements_Access is access all Elements_Type;

   use Finalization;
   use Streams;

   type Vector is new Controlled with record
      Elements : Elements_Access := null;
      Last     : Extended_Index := No_Index;
      TC       : aliased Tamper_Counts;
   end record with Put_Image => Put_Image;

   procedure Put_Image
     (S : in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class; V : Vector);

   overriding procedure Adjust (Container : in out Vector);
   overriding procedure Finalize (Container : in out Vector);

   procedure Write
     (Stream    : not null access Root_Stream_Type'Class;
      Container : Vector);

   for Vector'Write use Write;

   procedure Read
     (Stream    : not null access Root_Stream_Type'Class;
      Container : out Vector);

   for Vector'Read use Read;

   type Vector_Access is access all Vector;
   for Vector_Access'Storage_Size use 0;

   type Cursor is record
      Container : Vector_Access;
      Index     : Index_Type := Index_Type'First;
   end record;

   procedure Read
     (Stream   : not null access Root_Stream_Type'Class;
      Position : out Cursor);

   for Cursor'Read use Read;

   procedure Write
     (Stream   : not null access Root_Stream_Type'Class;
      Position : Cursor);

   for Cursor'Write use Write;

   subtype Reference_Control_Type is Implementation.Reference_Control_Type;
   --  It is necessary to rename this here, so that the compiler can find it

   type Constant_Reference_Type
     (Element : not null access constant Element_Type) is
      record
         Control : Reference_Control_Type :=
           raise Program_Error with "uninitialized reference";
         --  The RM says, "The default initialization of an object of
         --  type Constant_Reference_Type or Reference_Type propagates
         --  Program_Error."
      end record;

   procedure Write
     (Stream : not null access Root_Stream_Type'Class;
      Item   : Constant_Reference_Type);

   for Constant_Reference_Type'Write use Write;

   procedure Read
     (Stream : not null access Root_Stream_Type'Class;
      Item   : out Constant_Reference_Type);

   for Constant_Reference_Type'Read use Read;

   type Reference_Type
     (Element : not null access Element_Type) is
      record
         Control : Reference_Control_Type :=
           raise Program_Error with "uninitialized reference";
         --  The RM says, "The default initialization of an object of
         --  type Constant_Reference_Type or Reference_Type propagates
         --  Program_Error."
      end record;

   procedure Write
     (Stream : not null access Root_Stream_Type'Class;
      Item   : Reference_Type);

   for Reference_Type'Write use Write;

   procedure Read
     (Stream : not null access Root_Stream_Type'Class;
      Item   : out Reference_Type);

   for Reference_Type'Read use Read;

   --  Three operations are used to optimize in the expansion of "for ... of"
   --  loops: the Next(Cursor) procedure in the visible part, and the following
   --  Pseudo_Reference and Get_Element_Access functions. See Exp_Ch5 for
   --  details.

   function Pseudo_Reference
     (Container : aliased Vector'Class) return Reference_Control_Type;
   pragma Inline (Pseudo_Reference);
   --  Creates an object of type Reference_Control_Type pointing to the
   --  container, and increments the Lock. Finalization of this object will
   --  decrement the Lock.

   type Element_Access is access all Element_Type;

   function Get_Element_Access
     (Position : Cursor) return not null Element_Access;
   --  Returns a pointer to the element designated by Position.

   No_Element : constant Cursor := Cursor'(null, Index_Type'First);

   Empty_Vector : constant Vector := (Controlled with others => <>);

   type Iterator is new Limited_Controlled and
     Vector_Iterator_Interfaces.Reversible_Iterator with
   record
      Container : Vector_Access;
      Index     : Index_Type'Base;
   end record
     with Disable_Controlled => not T_Check;

   overriding procedure Finalize (Object : in out Iterator);

   overriding function First (Object : Iterator) return Cursor;
   overriding function Last  (Object : Iterator) return Cursor;

   overriding function Next
     (Object   : Iterator;
      Position : Cursor) return Cursor;

   overriding function Previous
     (Object   : Iterator;
      Position : Cursor) return Cursor;

end Ada.Containers.Vectors;
