OSDN Git Service

* config/mips/mips.c (TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P): Undef.
[pf3gnuchains/gcc-fork.git] / gcc / ada / a-convec.adb
index c98c58a..64b1b07 100644 (file)
@@ -2,33 +2,27 @@
 --                                                                          --
 --                         GNAT LIBRARY COMPONENTS                          --
 --                                                                          --
---                          ADA.CONTAINERS.VECTORS                          --
+--                A D A . C O N T A I N E R S . V E C T O R S               --
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---             Copyright (C) 2004 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. --
+--          Copyright (C) 2004-2009, Free Software Foundation, Inc.         --
 --                                                                          --
 -- 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 2,  or (at your option) any later ver- --
+-- 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.  See the GNU General Public License --
--- for  more details.  You should have  received  a copy of the GNU General --
--- Public License  distributed with GNAT;  see file COPYING.  If not, write --
--- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
--- MA 02111-1307, USA.                                                      --
+-- 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.               --
 --                                                                          --
--- As a special exception,  if other files  instantiate  generics from this --
--- unit, or you link  this unit with other files  to produce an executable, --
--- this  unit  does not  by itself cause  the resulting  executable  to  be --
--- covered  by the  GNU  General  Public  License.  This exception does not --
--- however invalidate  any other reasons why  the executable file  might be --
--- covered by the  GNU Public License.                                      --
+-- 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.                  --
 ------------------------------------------------------------------------------
@@ -41,6 +35,7 @@ with System; use type System.Address;
 package body Ada.Containers.Vectors is
 
    type Int is range System.Min_Int .. System.Max_Int;
+   type UInt is mod System.Max_Binary_Modulus;
 
    procedure Free is
      new Ada.Unchecked_Deallocation (Elements_Type, Elements_Access);
@@ -60,48 +55,61 @@ package body Ada.Containers.Vectors is
          end if;
 
          declare
-            RE : Elements_Type renames
-                   Right.Elements (Index_Type'First .. Right.Last);
+            RE : Elements_Array renames
+                   Right.Elements.EA (Index_Type'First .. Right.Last);
 
             Elements : constant Elements_Access :=
-                         new Elements_Type'(RE);
+                         new Elements_Type'(Right.Last, RE);
 
          begin
-            return (Controlled with Elements, Right.Last);
+            return (Controlled with Elements, Right.Last, 0, 0);
          end;
       end if;
 
       if RN = 0 then
          declare
-            LE : Elements_Type renames
-                   Left.Elements (Index_Type'First .. Left.Last);
+            LE : Elements_Array renames
+                   Left.Elements.EA (Index_Type'First .. Left.Last);
 
             Elements : constant Elements_Access :=
-                         new Elements_Type'(LE);
+                         new Elements_Type'(Left.Last, LE);
 
          begin
-            return (Controlled with Elements, Left.Last);
+            return (Controlled with Elements, Left.Last, 0, 0);
          end;
 
       end if;
 
       declare
-         Last_As_Int : constant Int'Base :=
-                         Int (Index_Type'First) + Int (LN) + Int (RN) - 1;
+         N           : constant Int'Base := Int (LN) + Int (RN);
+         Last_As_Int : Int'Base;
 
-         Last : constant Index_Type := Index_Type (Last_As_Int);
+      begin
+         if Int (No_Index) > Int'Last - N then
+            raise Constraint_Error with "new length is out of range";
+         end if;
 
-         LE : Elements_Type renames
-                Left.Elements (Index_Type'First .. Left.Last);
+         Last_As_Int := Int (No_Index) + N;
 
-         RE : Elements_Type renames
-                Right.Elements (Index_Type'First .. Right.Last);
+         if Last_As_Int > Int (Index_Type'Last) then
+            raise Constraint_Error with "new length is out of range";
+         end if;
 
-         Elements : constant Elements_Access :=
-                         new Elements_Type'(LE & RE);
+         declare
+            Last : constant Index_Type := Index_Type (Last_As_Int);
 
-      begin
-         return (Controlled with Elements, Last);
+            LE : Elements_Array renames
+                   Left.Elements.EA (Index_Type'First .. Left.Last);
+
+            RE : Elements_Array renames
+                   Right.Elements.EA (Index_Type'First .. Right.Last);
+
+            Elements : constant Elements_Access :=
+                         new Elements_Type'(Last, LE & RE);
+
+         begin
+            return (Controlled with Elements, Last, 0, 0);
+         end;
       end;
    end "&";
 
@@ -111,32 +119,44 @@ package body Ada.Containers.Vectors is
    begin
       if LN = 0 then
          declare
-            subtype Elements_Subtype is
-              Elements_Type (Index_Type'First .. Index_Type'First);
-
             Elements : constant Elements_Access :=
-                         new Elements_Subtype'(others => Right);
+                         new Elements_Type'
+                               (Last => Index_Type'First,
+                                EA   => (others => Right));
 
          begin
-            return (Controlled with Elements, Index_Type'First);
+            return (Controlled with Elements, Index_Type'First, 0, 0);
          end;
       end if;
 
       declare
-         Last_As_Int : constant Int'Base :=
-                         Int (Index_Type'First) + Int (LN);
+         Last_As_Int : Int'Base;
 
-         Last : constant Index_Type := Index_Type (Last_As_Int);
+      begin
+         if Int (Index_Type'First) > Int'Last - Int (LN) then
+            raise Constraint_Error with "new length is out of range";
+         end if;
+
+         Last_As_Int := Int (Index_Type'First) + Int (LN);
+
+         if Last_As_Int > Int (Index_Type'Last) then
+            raise Constraint_Error with "new length is out of range";
+         end if;
 
-         LE : Elements_Type renames
-                Left.Elements (Index_Type'First .. Left.Last);
+         declare
+            Last : constant Index_Type := Index_Type (Last_As_Int);
 
-         subtype ET is Elements_Type (Index_Type'First .. Last);
+            LE : Elements_Array renames
+                   Left.Elements.EA (Index_Type'First .. Left.Last);
 
-         Elements : constant Elements_Access := new ET'(LE & Right);
+            Elements : constant Elements_Access :=
+                         new Elements_Type'
+                               (Last => Last,
+                                EA   => LE & Right);
 
-      begin
-         return (Controlled with Elements, Last);
+         begin
+            return (Controlled with Elements, Last, 0, 0);
+         end;
       end;
    end "&";
 
@@ -146,52 +166,71 @@ package body Ada.Containers.Vectors is
    begin
       if RN = 0 then
          declare
-            subtype Elements_Subtype is
-              Elements_Type (Index_Type'First .. Index_Type'First);
-
             Elements : constant Elements_Access :=
-                         new Elements_Subtype'(others => Left);
+                         new Elements_Type'
+                               (Last => Index_Type'First,
+                                EA   => (others => Left));
 
          begin
-            return (Controlled with Elements, Index_Type'First);
+            return (Controlled with Elements, Index_Type'First, 0, 0);
          end;
       end if;
 
       declare
-         Last_As_Int : constant Int'Base :=
-                         Int (Index_Type'First) + Int (RN);
+         Last_As_Int : Int'Base;
 
-         Last : constant Index_Type := Index_Type (Last_As_Int);
+      begin
+         if Int (Index_Type'First) > Int'Last - Int (RN) then
+            raise Constraint_Error with "new length is out of range";
+         end if;
 
-         RE : Elements_Type renames
-                Right.Elements (Index_Type'First .. Right.Last);
+         Last_As_Int := Int (Index_Type'First) + Int (RN);
 
-         subtype ET is Elements_Type (Index_Type'First .. Last);
+         if Last_As_Int > Int (Index_Type'Last) then
+            raise Constraint_Error with "new length is out of range";
+         end if;
 
-         Elements : constant Elements_Access := new ET'(Left & RE);
+         declare
+            Last : constant Index_Type := Index_Type (Last_As_Int);
 
-      begin
-         return (Controlled with Elements, Last);
+            RE : Elements_Array renames
+                   Right.Elements.EA (Index_Type'First .. Right.Last);
+
+            Elements : constant Elements_Access :=
+                         new Elements_Type'
+                               (Last => Last,
+                                EA   => Left & RE);
+
+         begin
+            return (Controlled with Elements, Last, 0, 0);
+         end;
       end;
    end "&";
 
-   function "&" (Left, Right  : Element_Type) return Vector is
-      subtype IT is Index_Type'Base range
-        Index_Type'First .. Index_Type'Succ (Index_Type'First);
+   function "&" (Left, Right : Element_Type) return Vector is
+   begin
+      if Index_Type'First >= Index_Type'Last then
+         raise Constraint_Error with "new length is out of range";
+      end if;
 
-      subtype ET is Elements_Type (IT);
+      declare
+         Last : constant Index_Type := Index_Type'First + 1;
 
-      Elements : constant Elements_Access := new ET'(Left, Right);
+         Elements : constant Elements_Access :=
+                      new Elements_Type'
+                            (Last => Last,
+                             EA   => (Left, Right));
 
-   begin
-      return Vector'(Controlled with Elements, Elements'Last);
+      begin
+         return (Controlled with Elements, Last, 0, 0);
+      end;
    end "&";
 
    ---------
    -- "=" --
    ---------
 
-   function "=" (Left, Right : Vector) return Boolean is
+   overriding function "=" (Left, Right : Vector) return Boolean is
    begin
       if Left'Address = Right'Address then
          return True;
@@ -202,7 +241,7 @@ package body Ada.Containers.Vectors is
       end if;
 
       for J in Index_Type range Index_Type'First .. Left.Last loop
-         if Left.Elements (J) /= Right.Elements (J) then
+         if Left.Elements.EA (J) /= Right.Elements.EA (J) then
             return False;
          end if;
       end loop;
@@ -216,25 +255,28 @@ package body Ada.Containers.Vectors is
 
    procedure Adjust (Container : in out Vector) is
    begin
-      if Container.Elements = null then
-         return;
-      end if;
-
-      if Container.Elements'Length = 0
-        or else Container.Last < Index_Type'First
-      then
+      if Container.Last = No_Index then
          Container.Elements := null;
          return;
       end if;
 
       declare
-         X : constant Elements_Access := Container.Elements;
-         L : constant Index_Type'Base := Container.Last;
-         E : Elements_Type renames X (Index_Type'First .. L);
+         L  : constant Index_Type := Container.Last;
+         EA : Elements_Array renames
+                Container.Elements.EA (Index_Type'First .. L);
+
       begin
          Container.Elements := null;
-         Container.Last := Index_Type'Pred (Index_Type'First);
-         Container.Elements := new Elements_Type'(E);
+         Container.Busy := 0;
+         Container.Lock := 0;
+
+         --  Note: it may seem that the following assignment to Container.Last
+         --  is useless, since we assign it to L below. However this code is
+         --  used in case 'new Elements_Type' below raises an exception, to
+         --  keep Container in a consistent state.
+
+         Container.Last := No_Index;
+         Container.Elements := new Elements_Type'(L, EA);
          Container.Last := L;
       end;
    end Adjust;
@@ -249,9 +291,13 @@ package body Ada.Containers.Vectors is
          return;
       end if;
 
+      if Container.Last = Index_Type'Last then
+         raise Constraint_Error with "vector is already at its maximum length";
+      end if;
+
       Insert
         (Container,
-         Index_Type'Succ (Container.Last),
+         Container.Last + 1,
          New_Item);
    end Append;
 
@@ -265,44 +311,17 @@ package body Ada.Containers.Vectors is
          return;
       end if;
 
+      if Container.Last = Index_Type'Last then
+         raise Constraint_Error with "vector is already at its maximum length";
+      end if;
+
       Insert
         (Container,
-         Index_Type'Succ (Container.Last),
+         Container.Last + 1,
          New_Item,
          Count);
    end Append;
 
-   ------------
-   -- Assign --
-   ------------
-
-   procedure Assign
-     (Target : in out Vector;
-      Source : Vector)
-   is
-      N : constant Count_Type := Length (Source);
-
-   begin
-      if Target'Address = Source'Address then
-         return;
-      end if;
-
-      Clear (Target);
-
-      if N = 0 then
-         return;
-      end if;
-
-      if N > Capacity (Target) then
-         Reserve_Capacity (Target, Capacity => N);
-      end if;
-
-      Target.Elements (Index_Type'First .. Source.Last) :=
-        Source.Elements (Index_Type'First .. Source.Last);
-
-      Target.Last := Source.Last;
-   end Assign;
-
    --------------
    -- Capacity --
    --------------
@@ -313,7 +332,7 @@ package body Ada.Containers.Vectors is
          return 0;
       end if;
 
-      return Container.Elements'Length;
+      return Container.Elements.EA'Length;
    end Capacity;
 
    -----------
@@ -322,7 +341,12 @@ package body Ada.Containers.Vectors is
 
    procedure Clear (Container : in out Vector) is
    begin
-      Container.Last := Index_Type'Pred (Index_Type'First);
+      if Container.Busy > 0 then
+         raise Program_Error with
+           "attempt to tamper with elements (vector is busy)";
+      end if;
+
+      Container.Last := No_Index;
    end Clear;
 
    --------------
@@ -347,39 +371,55 @@ package body Ada.Containers.Vectors is
       Count     : Count_Type := 1)
    is
    begin
-      if Count = 0 then
-         return;
+      if Index < Index_Type'First then
+         raise Constraint_Error with "Index is out of range (too small)";
       end if;
 
-      declare
-         subtype I_Subtype is Index_Type'Base range
-           Index_Type'First .. Container.Last;
+      if Index > Container.Last then
+         if Index > Container.Last + 1 then
+            raise Constraint_Error with "Index is out of range (too large)";
+         end if;
 
-         I : constant I_Subtype := Index;
-         --  TODO: not sure whether to relax this check ???
+         return;
+      end if;
 
-         I_As_Int : constant Int := Int (I);
+      if Count = 0 then
+         return;
+      end if;
 
+      if Container.Busy > 0 then
+         raise Program_Error with
+           "attempt to tamper with elements (vector is busy)";
+      end if;
+
+      declare
+         I_As_Int        : constant Int := Int (Index);
          Old_Last_As_Int : constant Int := Index_Type'Pos (Container.Last);
 
          Count1 : constant Int'Base := Count_Type'Pos (Count);
          Count2 : constant Int'Base := Old_Last_As_Int - I_As_Int + 1;
-
-         N : constant Int'Base := Int'Min (Count1, Count2);
+         N      : constant Int'Base := Int'Min (Count1, Count2);
 
          J_As_Int : constant Int'Base := I_As_Int + N;
-         J        : constant Index_Type'Base := Index_Type'Base (J_As_Int);
 
-         E : Elements_Type renames Container.Elements.all;
+      begin
+         if J_As_Int > Old_Last_As_Int then
+            Container.Last := Index - 1;
 
-         New_Last_As_Int : constant Int'Base := Old_Last_As_Int - N;
+         else
+            declare
+               J  : constant Index_Type := Index_Type (J_As_Int);
+               EA : Elements_Array renames Container.Elements.EA;
 
-         New_Last : constant Extended_Index :=
-                      Extended_Index (New_Last_As_Int);
+               New_Last_As_Int : constant Int'Base := Old_Last_As_Int - N;
+               New_Last        : constant Index_Type :=
+                                   Index_Type (New_Last_As_Int);
 
-      begin
-         E (I .. New_Last) := E (J .. Container.Last);
-         Container.Last := New_Last;
+            begin
+               EA (Index .. New_Last) := EA (J .. Container.Last);
+               Container.Last := New_Last;
+            end;
+         end if;
       end;
    end Delete;
 
@@ -388,29 +428,23 @@ package body Ada.Containers.Vectors is
       Position  : in out Cursor;
       Count     : Count_Type := 1)
    is
+      pragma Warnings (Off, Position);
+
    begin
+      if Position.Container = null then
+         raise Constraint_Error with "Position cursor has no element";
+      end if;
 
-      if Position.Container /= null
-        and then Position.Container /=
-                   Vector_Access'(Container'Unchecked_Access)
-      then
-         raise Program_Error;
+      if Position.Container /= Container'Unrestricted_Access then
+         raise Program_Error with "Position cursor denotes wrong container";
       end if;
 
-      if Position.Container = null
-        or else Position.Index > Container.Last
-      then
-         Position := No_Element;
-         return;
+      if Position.Index > Container.Last then
+         raise Program_Error with "Position index is out of range";
       end if;
 
       Delete (Container, Position.Index, Count);
-
-      if Position.Index <= Container.Last then
-         Position := (Container'Unchecked_Access, Position.Index);
-      else
-         Position := No_Element;
-      end if;
+      Position := No_Element;
    end Delete;
 
    ------------------
@@ -449,14 +483,17 @@ package body Ada.Containers.Vectors is
          return;
       end if;
 
-      if Count >= Length (Container) then
-         Clear (Container);
-         return;
+      if Container.Busy > 0 then
+         raise Program_Error with
+           "attempt to tamper with elements (vector is busy)";
       end if;
 
-      Index := Int'Base (Container.Last) - Int'Base (Count) + 1;
+      Index := Int'Base (Container.Last) - Int'Base (Count);
 
-      Delete (Container, Index_Type'Base (Index), Count);
+      Container.Last :=
+         (if Index < Index_Type'Pos (Index_Type'First)
+          then No_Index
+          else Index_Type (Index));
    end Delete_Last;
 
    -------------
@@ -467,15 +504,25 @@ package body Ada.Containers.Vectors is
      (Container : Vector;
       Index     : Index_Type) return Element_Type
    is
-      subtype T is Index_Type'Base range
-        Index_Type'First .. Container.Last;
    begin
-      return Container.Elements (T'(Index));
+      if Index > Container.Last then
+         raise Constraint_Error with "Index is out of range";
+      end if;
+
+      return Container.Elements.EA (Index);
    end Element;
 
    function Element (Position : Cursor) return Element_Type is
    begin
-      return Element (Position.Container.all, Position.Index);
+      if Position.Container = null then
+         raise Constraint_Error with "Position cursor has no element";
+      end if;
+
+      if Position.Index > Position.Container.Last then
+         raise Constraint_Error with "Position cursor is out of range";
+      end if;
+
+      return Position.Container.Elements.EA (Position.Index);
    end Element;
 
    --------------
@@ -484,9 +531,15 @@ package body Ada.Containers.Vectors is
 
    procedure Finalize (Container : in out Vector) is
       X : Elements_Access := Container.Elements;
+
    begin
+      if Container.Busy > 0 then
+         raise Program_Error with
+           "attempt to tamper with elements (vector is busy)";
+      end if;
+
       Container.Elements := null;
-      Container.Last := Index_Type'Pred (Index_Type'First);
+      Container.Last := No_Index;
       Free (X);
    end Finalize;
 
@@ -497,18 +550,21 @@ package body Ada.Containers.Vectors is
    function Find
      (Container : Vector;
       Item      : Element_Type;
-      Position  : Cursor := No_Element) return Cursor is
-
+      Position  : Cursor := No_Element) return Cursor
+   is
    begin
-      if Position.Container /= null
-        and then Position.Container /=
-                   Vector_Access'(Container'Unchecked_Access)
-      then
-         raise Program_Error;
+      if Position.Container /= null then
+         if Position.Container /= Container'Unrestricted_Access then
+            raise Program_Error with "Position cursor denotes wrong container";
+         end if;
+
+         if Position.Index > Container.Last then
+            raise Program_Error with "Position index is out of range";
+         end if;
       end if;
 
       for J in Position.Index .. Container.Last loop
-         if Container.Elements (J) = Item then
+         if Container.Elements.EA (J) = Item then
             return (Container'Unchecked_Access, J);
          end if;
       end loop;
@@ -523,10 +579,11 @@ package body Ada.Containers.Vectors is
    function Find_Index
      (Container : Vector;
       Item      : Element_Type;
-      Index     : Index_Type := Index_Type'First) return Extended_Index is
+      Index     : Index_Type := Index_Type'First) return Extended_Index
+   is
    begin
       for Indx in Index .. Container.Last loop
-         if Container.Elements (Indx) = Item then
+         if Container.Elements.EA (Indx) = Item then
             return Indx;
          end if;
       end loop;
@@ -553,7 +610,11 @@ package body Ada.Containers.Vectors is
 
    function First_Element (Container : Vector) return Element_Type is
    begin
-      return Element (Container, Index_Type'First);
+      if Container.Last = No_Index then
+         raise Constraint_Error with "Container is empty";
+      end if;
+
+      return Container.Elements.EA (Index_Type'First);
    end First_Element;
 
    -----------------
@@ -566,26 +627,127 @@ package body Ada.Containers.Vectors is
       return Index_Type'First;
    end First_Index;
 
-   ------------------
-   -- Generic_Sort --
-   ------------------
+   ---------------------
+   -- Generic_Sorting --
+   ---------------------
 
-   procedure Generic_Sort (Container : Vector)
-   is
-      procedure Sort is
-         new Generic_Array_Sort
-          (Index_Type   => Index_Type,
-           Element_Type => Element_Type,
-           Array_Type   => Elements_Type,
-           "<"          => "<");
+   package body Generic_Sorting is
 
-   begin
-      if Container.Elements = null then
-         return;
-      end if;
+      ---------------
+      -- Is_Sorted --
+      ---------------
+
+      function Is_Sorted (Container : Vector) return Boolean is
+      begin
+         if Container.Last <= Index_Type'First then
+            return True;
+         end if;
+
+         declare
+            EA : Elements_Array renames Container.Elements.EA;
+         begin
+            for I in Index_Type'First .. Container.Last - 1 loop
+               if EA (I + 1) < EA (I) then
+                  return False;
+               end if;
+            end loop;
+         end;
+
+         return True;
+      end Is_Sorted;
+
+      -----------
+      -- Merge --
+      -----------
+
+      procedure Merge (Target, Source : in out Vector) is
+         I : Index_Type'Base := Target.Last;
+         J : Index_Type'Base;
 
-      Sort (Container.Elements (Index_Type'First .. Container.Last));
-   end Generic_Sort;
+      begin
+         if Target.Last < Index_Type'First then
+            Move (Target => Target, Source => Source);
+            return;
+         end if;
+
+         if Target'Address = Source'Address then
+            return;
+         end if;
+
+         if Source.Last < Index_Type'First then
+            return;
+         end if;
+
+         if Source.Busy > 0 then
+            raise Program_Error with
+              "attempt to tamper with elements (vector is busy)";
+         end if;
+
+         Target.Set_Length (Length (Target) + Length (Source));
+
+         declare
+            TA : Elements_Array renames Target.Elements.EA;
+            SA : Elements_Array renames Source.Elements.EA;
+
+         begin
+            J := Target.Last;
+            while Source.Last >= Index_Type'First loop
+               pragma Assert (Source.Last <= Index_Type'First
+                                or else not (SA (Source.Last) <
+                                             SA (Source.Last - 1)));
+
+               if I < Index_Type'First then
+                  TA (Index_Type'First .. J) :=
+                    SA (Index_Type'First .. Source.Last);
+
+                  Source.Last := No_Index;
+                  return;
+               end if;
+
+               pragma Assert (I <= Index_Type'First
+                                or else not (TA (I) < TA (I - 1)));
+
+               if SA (Source.Last) < TA (I) then
+                  TA (J) := TA (I);
+                  I := I - 1;
+
+               else
+                  TA (J) := SA (Source.Last);
+                  Source.Last := Source.Last - 1;
+               end if;
+
+               J := J - 1;
+            end loop;
+         end;
+      end Merge;
+
+      ----------
+      -- Sort --
+      ----------
+
+      procedure Sort (Container : in out Vector)
+      is
+         procedure Sort is
+            new Generic_Array_Sort
+             (Index_Type   => Index_Type,
+              Element_Type => Element_Type,
+              Array_Type   => Elements_Array,
+              "<"          => "<");
+
+      begin
+         if Container.Last <= Index_Type'First then
+            return;
+         end if;
+
+         if Container.Lock > 0 then
+            raise Program_Error with
+              "attempt to tamper with cursors (vector is locked)";
+         end if;
+
+         Sort (Container.Elements.EA (Index_Type'First .. Container.Last));
+      end Sort;
+
+   end Generic_Sorting;
 
    -----------------
    -- Has_Element --
@@ -610,58 +772,91 @@ package body Ada.Containers.Vectors is
       New_Item  : Element_Type;
       Count     : Count_Type := 1)
    is
-      Old_Last : constant Extended_Index := Container.Last;
-
-      Old_Last_As_Int : constant Int := Index_Type'Pos (Old_Last);
-
       N : constant Int := Count_Type'Pos (Count);
 
-      New_Last_As_Int : constant Int'Base := Old_Last_As_Int + N;
+      First           : constant Int := Int (Index_Type'First);
+      New_Last_As_Int : Int'Base;
+      New_Last        : Index_Type;
+      New_Length      : UInt;
+      Max_Length      : constant UInt := UInt (Count_Type'Last);
 
-      New_Last : constant Extended_Index := Extended_Index (New_Last_As_Int);
+      Dst : Elements_Access;
 
-      Index : Index_Type;
+   begin
+      if Before < Index_Type'First then
+         raise Constraint_Error with
+           "Before index is out of range (too small)";
+      end if;
 
-      Dst_Last : Index_Type;
-      Dst      : Elements_Access;
+      if Before > Container.Last
+        and then Before > Container.Last + 1
+      then
+         raise Constraint_Error with
+           "Before index is out of range (too large)";
+      end if;
 
-   begin
       if Count = 0 then
          return;
       end if;
 
       declare
-         subtype Before_Subtype is Index_Type'Base range
-           Index_Type'First .. Index_Type'Succ (Container.Last);
+         Old_Last_As_Int : constant Int := Int (Container.Last);
 
-         Old_First : constant Before_Subtype := Before;
+      begin
+         if Old_Last_As_Int > Int'Last - N then
+            raise Constraint_Error with "new length is out of range";
+         end if;
 
-         Old_First_As_Int : constant Int := Index_Type'Pos (Old_First);
+         New_Last_As_Int := Old_Last_As_Int + N;
 
-         New_First_As_Int : constant Int'Base := Old_First_As_Int + N;
+         if New_Last_As_Int > Int (Index_Type'Last) then
+            raise Constraint_Error with "new length is out of range";
+         end if;
 
-      begin
-         Index := Index_Type (New_First_As_Int);
+         New_Length := UInt (New_Last_As_Int - First + Int'(1));
+
+         if New_Length > Max_Length then
+            raise Constraint_Error with "new length is out of range";
+         end if;
+
+         New_Last := Index_Type (New_Last_As_Int);
       end;
 
-      if Container.Elements = null then
-         declare
-            subtype Elements_Subtype is
-              Elements_Type (Index_Type'First .. New_Last);
-         begin
-            Container.Elements := new Elements_Subtype'(others => New_Item);
-         end;
+      if Container.Busy > 0 then
+         raise Program_Error with
+           "attempt to tamper with elements (vector is busy)";
+      end if;
 
+      if Container.Elements = null then
+         Container.Elements := new Elements_Type'
+                                     (Last => New_Last,
+                                      EA   => (others => New_Item));
          Container.Last := New_Last;
          return;
       end if;
 
-      if New_Last <= Container.Elements'Last then
+      if New_Last <= Container.Elements.Last then
          declare
-            E : Elements_Type renames Container.Elements.all;
+            EA : Elements_Array renames Container.Elements.EA;
+
          begin
-            E (Index .. New_Last) := E (Before .. Container.Last);
-            E (Before .. Index_Type'Pred (Index)) := (others => New_Item);
+            if Before <= Container.Last then
+               declare
+                  Index_As_Int : constant Int'Base :=
+                                   Index_Type'Pos (Before) + N;
+
+                  Index : constant Index_Type := Index_Type (Index_As_Int);
+
+               begin
+                  EA (Index .. New_Last) := EA (Before .. Container.Last);
+
+                  EA (Before .. Index_Type'Pred (Index)) :=
+                      (others => New_Item);
+               end;
+
+            else
+               EA (Before .. New_Last) := (others => New_Item);
+            end if;
          end;
 
          Container.Last := New_Last;
@@ -669,48 +864,67 @@ package body Ada.Containers.Vectors is
       end if;
 
       declare
-         First : constant Int := Int (Index_Type'First);
+         C, CC : UInt;
 
-         New_Size : constant Int'Base := New_Last_As_Int - First + 1;
-         Max_Size : constant Int'Base := Int (Index_Type'Last) - First + 1;
+      begin
+         C := UInt'Max (1, Container.Elements.EA'Length);  -- ???
+         while C < New_Length loop
+            if C > UInt'Last / 2 then
+               C := UInt'Last;
+               exit;
+            end if;
 
-         Size, Dst_Last_As_Int : Int'Base;
+            C := 2 * C;
+         end loop;
 
-      begin
-         if New_Size >= Max_Size / 2 then
-            Dst_Last := Index_Type'Last;
+         if C > Max_Length then
+            C := Max_Length;
+         end if;
 
+         if Index_Type'First <= 0
+           and then Index_Type'Last >= 0
+         then
+            CC := UInt (Index_Type'Last) + UInt (-Index_Type'First) + 1;
          else
-            Size := Container.Elements'Length;
+            CC := UInt (Int (Index_Type'Last) - First + 1);
+         end if;
 
-            if Size = 0 then
-               Size := 1;
-            end if;
+         if C > CC then
+            C := CC;
+         end if;
 
-            while Size < New_Size loop
-               Size := 2 * Size;
-            end loop;
+         declare
+            Dst_Last : constant Index_Type :=
+                         Index_Type (First + UInt'Pos (C) - 1);
 
-            Dst_Last_As_Int := First + Size - 1;
-            Dst_Last := Index_Type (Dst_Last_As_Int);
-         end if;
+         begin
+            Dst := new Elements_Type (Dst_Last);
+         end;
       end;
 
-      Dst := new Elements_Type (Index_Type'First .. Dst_Last);
-
       declare
-         Src : Elements_Type renames Container.Elements.all;
+         SA : Elements_Array renames Container.Elements.EA;
+         DA : Elements_Array renames Dst.EA;
 
       begin
-         Dst (Index_Type'First .. Index_Type'Pred (Before)) :=
-           Src (Index_Type'First .. Index_Type'Pred (Before));
+         DA (Index_Type'First .. Index_Type'Pred (Before)) :=
+           SA (Index_Type'First .. Index_Type'Pred (Before));
 
-         Dst (Before .. Index_Type'Pred (Index)) :=
-           (others => New_Item);
+         if Before <= Container.Last then
+            declare
+               Index_As_Int : constant Int'Base :=
+                                Index_Type'Pos (Before) + N;
+
+               Index : constant Index_Type := Index_Type (Index_As_Int);
 
-         Dst (Index .. New_Last) :=
-           Src (Before .. Container.Last);
+            begin
+               DA (Before .. Index_Type'Pred (Index)) := (others => New_Item);
+               DA (Index .. New_Last) := SA (Before .. Container.Last);
+            end;
 
+         else
+            DA (Before .. New_Last) := (others => New_Item);
+         end if;
       exception
          when others =>
             Free (Dst);
@@ -734,6 +948,18 @@ package body Ada.Containers.Vectors is
       N : constant Count_Type := Length (New_Item);
 
    begin
+      if Before < Index_Type'First then
+         raise Constraint_Error with
+           "Before index is out of range (too small)";
+      end if;
+
+      if Before > Container.Last
+        and then Before > Container.Last + 1
+      then
+         raise Constraint_Error with
+           "Before index is out of range (too large)";
+      end if;
+
       if N = 0 then
          return;
       end if;
@@ -747,51 +973,56 @@ package body Ada.Containers.Vectors is
          Dst_Last : constant Index_Type := Index_Type (Dst_Last_As_Int);
 
       begin
-         if Container'Address = New_Item'Address then
-            declare
-               subtype Src_Index_Subtype is Index_Type'Base range
-                 Index_Type'First .. Index_Type'Pred (Before);
+         if Container'Address /= New_Item'Address then
+            Container.Elements.EA (Before .. Dst_Last) :=
+              New_Item.Elements.EA (Index_Type'First .. New_Item.Last);
 
-               Src : Elements_Type renames
-                       Container.Elements (Src_Index_Subtype);
+            return;
+         end if;
 
-               Index_As_Int : constant Int'Base :=
-                                Int (Before) + Src'Length - 1;
+         declare
+            subtype Src_Index_Subtype is Index_Type'Base range
+              Index_Type'First .. Before - 1;
 
-               Index : constant Index_Type'Base :=
-                         Index_Type'Base (Index_As_Int);
+            Src : Elements_Array renames
+                    Container.Elements.EA (Src_Index_Subtype);
 
-               Dst : Elements_Type renames
-                       Container.Elements (Before .. Index);
+            Index_As_Int : constant Int'Base :=
+                             Int (Before) + Src'Length - 1;
 
-            begin
-               Dst := Src;
-            end;
+            Index : constant Index_Type'Base :=
+                      Index_Type'Base (Index_As_Int);
 
-            declare
-               subtype Src_Index_Subtype is Index_Type'Base range
-                 Index_Type'Succ (Dst_Last) .. Container.Last;
+            Dst : Elements_Array renames
+                    Container.Elements.EA (Before .. Index);
+
+         begin
+            Dst := Src;
+         end;
 
-               Src : Elements_Type renames
-                       Container.Elements (Src_Index_Subtype);
+         if Dst_Last = Container.Last then
+            return;
+         end if;
 
-               Index_As_Int : constant Int'Base :=
-                                Dst_Last_As_Int - Src'Length + 1;
+         declare
+            subtype Src_Index_Subtype is Index_Type'Base range
+              Dst_Last + 1 .. Container.Last;
 
-               Index : constant Index_Type'Base :=
-                         Index_Type'Base (Index_As_Int);
+            Src : Elements_Array renames
+                    Container.Elements.EA (Src_Index_Subtype);
 
-               Dst : Elements_Type renames
-                       Container.Elements (Index .. Dst_Last);
+            Index_As_Int : constant Int'Base :=
+                             Dst_Last_As_Int - Src'Length + 1;
 
-            begin
-               Dst := Src;
-            end;
+            Index : constant Index_Type :=
+                      Index_Type (Index_As_Int);
 
-         else
-            Container.Elements (Before .. Dst_Last) :=
-              New_Item.Elements (Index_Type'First .. New_Item.Last);
-         end if;
+            Dst : Elements_Array renames
+                    Container.Elements.EA (Index .. Dst_Last);
+
+         begin
+            Dst := Src;
+         end;
       end;
    end Insert;
 
@@ -804,9 +1035,9 @@ package body Ada.Containers.Vectors is
 
    begin
       if Before.Container /= null
-        and then Before.Container /= Vector_Access'(Container'Unchecked_Access)
+        and then Before.Container /= Container'Unchecked_Access
       then
-         raise Program_Error;
+         raise Program_Error with "Before cursor denotes wrong container";
       end if;
 
       if Is_Empty (New_Item) then
@@ -816,7 +1047,13 @@ package body Ada.Containers.Vectors is
       if Before.Container = null
         or else Before.Index > Container.Last
       then
-         Index := Index_Type'Succ (Container.Last);
+         if Container.Last = Index_Type'Last then
+            raise Constraint_Error with
+              "vector is already at its maximum length";
+         end if;
+
+         Index := Container.Last + 1;
+
       else
          Index := Before.Index;
       end if;
@@ -834,9 +1071,9 @@ package body Ada.Containers.Vectors is
 
    begin
       if Before.Container /= null
-        and then Before.Container /= Vector_Access'(Container'Unchecked_Access)
+        and then Before.Container /= Container'Unchecked_Access
       then
-         raise Program_Error;
+         raise Program_Error with "Before cursor denotes wrong container";
       end if;
 
       if Is_Empty (New_Item) then
@@ -854,7 +1091,13 @@ package body Ada.Containers.Vectors is
       if Before.Container = null
         or else Before.Index > Container.Last
       then
-         Index := Index_Type'Succ (Container.Last);
+         if Container.Last = Index_Type'Last then
+            raise Constraint_Error with
+              "vector is already at its maximum length";
+         end if;
+
+         Index := Container.Last + 1;
+
       else
          Index := Before.Index;
       end if;
@@ -874,9 +1117,9 @@ package body Ada.Containers.Vectors is
 
    begin
       if Before.Container /= null
-        and then Before.Container /= Vector_Access'(Container'Unchecked_Access)
+        and then Before.Container /= Container'Unchecked_Access
       then
-         raise Program_Error;
+         raise Program_Error with "Before cursor denotes wrong container";
       end if;
 
       if Count = 0 then
@@ -886,7 +1129,13 @@ package body Ada.Containers.Vectors is
       if Before.Container = null
         or else Before.Index > Container.Last
       then
-         Index := Index_Type'Succ (Container.Last);
+         if Container.Last = Index_Type'Last then
+            raise Constraint_Error with
+              "vector is already at its maximum length";
+         end if;
+
+         Index := Container.Last + 1;
+
       else
          Index := Before.Index;
       end if;
@@ -905,9 +1154,9 @@ package body Ada.Containers.Vectors is
 
    begin
       if Before.Container /= null
-        and then Before.Container /= Vector_Access'(Container'Unchecked_Access)
+        and then Before.Container /= Container'Unchecked_Access
       then
-         raise Program_Error;
+         raise Program_Error with "Before cursor denotes wrong container";
       end if;
 
       if Count = 0 then
@@ -925,14 +1174,45 @@ package body Ada.Containers.Vectors is
       if Before.Container = null
         or else Before.Index > Container.Last
       then
-         Index := Index_Type'Succ (Container.Last);
+         if Container.Last = Index_Type'Last then
+            raise Constraint_Error with
+              "vector is already at its maximum length";
+         end if;
+
+         Index := Container.Last + 1;
+
       else
          Index := Before.Index;
       end if;
 
       Insert (Container, Index, New_Item, Count);
 
-      Position := Cursor'(Container'Unchecked_Access, Index);
+      Position := Cursor'(Container'Unchecked_Access, Index);
+   end Insert;
+
+   procedure Insert
+     (Container : in out Vector;
+      Before    : Extended_Index;
+      Count     : Count_Type := 1)
+   is
+      New_Item : Element_Type;  -- Default-initialized value
+      pragma Warnings (Off, New_Item);
+
+   begin
+      Insert (Container, Before, New_Item, Count);
+   end Insert;
+
+   procedure Insert
+     (Container : in out Vector;
+      Before    : Cursor;
+      Position  : out Cursor;
+      Count     : Count_Type := 1)
+   is
+      New_Item : Element_Type;  -- Default-initialized value
+      pragma Warnings (Off, New_Item);
+
+   begin
+      Insert (Container, Before, New_Item, Position, Count);
    end Insert;
 
    ------------------
@@ -944,53 +1224,82 @@ package body Ada.Containers.Vectors is
       Before    : Extended_Index;
       Count     : Count_Type := 1)
    is
-      Old_Last : constant Extended_Index := Container.Last;
-
-      Old_Last_As_Int : constant Int := Index_Type'Pos (Old_Last);
-
       N : constant Int := Count_Type'Pos (Count);
 
-      New_Last_As_Int : constant Int'Base := Old_Last_As_Int + N;
+      First           : constant Int := Int (Index_Type'First);
+      New_Last_As_Int : Int'Base;
+      New_Last        : Index_Type;
+      New_Length      : UInt;
+      Max_Length      : constant UInt := UInt (Count_Type'Last);
 
-      New_Last : constant Extended_Index := Extended_Index (New_Last_As_Int);
+      Dst : Elements_Access;
 
-      Index : Index_Type;
+   begin
+      if Before < Index_Type'First then
+         raise Constraint_Error with
+           "Before index is out of range (too small)";
+      end if;
 
-      Dst_Last : Index_Type;
-      Dst      : Elements_Access;
+      if Before > Container.Last
+        and then Before > Container.Last + 1
+      then
+         raise Constraint_Error with
+           "Before index is out of range (too large)";
+      end if;
 
-   begin
       if Count = 0 then
          return;
       end if;
 
       declare
-         subtype Before_Subtype is Index_Type'Base range
-           Index_Type'First .. Index_Type'Succ (Container.Last);
+         Old_Last_As_Int : constant Int := Int (Container.Last);
+
+      begin
+         if Old_Last_As_Int > Int'Last - N then
+            raise Constraint_Error with "new length is out of range";
+         end if;
 
-         Old_First : constant Before_Subtype := Before;
+         New_Last_As_Int := Old_Last_As_Int + N;
 
-         Old_First_As_Int : constant Int := Index_Type'Pos (Old_First);
+         if New_Last_As_Int > Int (Index_Type'Last) then
+            raise Constraint_Error with "new length is out of range";
+         end if;
 
-         New_First_As_Int : constant Int'Base := Old_First_As_Int + N;
+         New_Length := UInt (New_Last_As_Int - First + Int'(1));
 
-      begin
-         Index := Index_Type (New_First_As_Int);
+         if New_Length > Max_Length then
+            raise Constraint_Error with "new length is out of range";
+         end if;
+
+         New_Last := Index_Type (New_Last_As_Int);
       end;
 
-      if Container.Elements = null then
-         Container.Elements :=
-           new Elements_Type (Index_Type'First .. New_Last);
+      if Container.Busy > 0 then
+         raise Program_Error with
+           "attempt to tamper with elements (vector is busy)";
+      end if;
 
+      if Container.Elements = null then
+         Container.Elements := new Elements_Type (New_Last);
          Container.Last := New_Last;
          return;
       end if;
 
-      if New_Last <= Container.Elements'Last then
+      if New_Last <= Container.Elements.Last then
          declare
-            E : Elements_Type renames Container.Elements.all;
+            EA : Elements_Array renames Container.Elements.EA;
          begin
-            E (Index .. New_Last) := E (Before .. Container.Last);
+            if Before <= Container.Last then
+               declare
+                  Index_As_Int : constant Int'Base :=
+                                   Index_Type'Pos (Before) + N;
+
+                  Index : constant Index_Type := Index_Type (Index_As_Int);
+
+               begin
+                  EA (Index .. New_Last) := EA (Before .. Container.Last);
+               end;
+            end if;
          end;
 
          Container.Last := New_Last;
@@ -998,45 +1307,63 @@ package body Ada.Containers.Vectors is
       end if;
 
       declare
-         First : constant Int := Int (Index_Type'First);
+         C, CC : UInt;
 
-         New_Size : constant Int'Base := New_Last_As_Int - First + 1;
-         Max_Size : constant Int'Base := Int (Index_Type'Last) - First + 1;
+      begin
+         C := UInt'Max (1, Container.Elements.EA'Length);  -- ???
+         while C < New_Length loop
+            if C > UInt'Last / 2 then
+               C := UInt'Last;
+               exit;
+            end if;
 
-         Size, Dst_Last_As_Int : Int'Base;
+            C := 2 * C;
+         end loop;
 
-      begin
-         if New_Size >= Max_Size / 2 then
-            Dst_Last := Index_Type'Last;
+         if C > Max_Length then
+            C := Max_Length;
+         end if;
 
+         if Index_Type'First <= 0
+           and then Index_Type'Last >= 0
+         then
+            CC := UInt (Index_Type'Last) + UInt (-Index_Type'First) + 1;
          else
-            Size := Container.Elements'Length;
+            CC := UInt (Int (Index_Type'Last) - First + 1);
+         end if;
 
-            if Size = 0 then
-               Size := 1;
-            end if;
+         if C > CC then
+            C := CC;
+         end if;
 
-            while Size < New_Size loop
-               Size := 2 * Size;
-            end loop;
+         declare
+            Dst_Last : constant Index_Type :=
+                         Index_Type (First + UInt'Pos (C) - 1);
 
-            Dst_Last_As_Int := First + Size - 1;
-            Dst_Last := Index_Type (Dst_Last_As_Int);
-         end if;
+         begin
+            Dst := new Elements_Type (Dst_Last);
+         end;
       end;
 
-      Dst := new Elements_Type (Index_Type'First .. Dst_Last);
-
       declare
-         Src : Elements_Type renames Container.Elements.all;
+         SA : Elements_Array renames Container.Elements.EA;
+         DA : Elements_Array renames Dst.EA;
 
       begin
-         Dst (Index_Type'First .. Index_Type'Pred (Before)) :=
-           Src (Index_Type'First .. Index_Type'Pred (Before));
+         DA (Index_Type'First .. Index_Type'Pred (Before)) :=
+           SA (Index_Type'First .. Index_Type'Pred (Before));
+
+         if Before <= Container.Last then
+            declare
+               Index_As_Int : constant Int'Base :=
+                                Index_Type'Pos (Before) + N;
 
-         Dst (Index .. New_Last) :=
-           Src (Before .. Container.Last);
+               Index : constant Index_Type := Index_Type (Index_As_Int);
 
+            begin
+               DA (Index .. New_Last) := SA (Before .. Container.Last);
+            end;
+         end if;
       exception
          when others =>
             Free (Dst);
@@ -1048,7 +1375,6 @@ package body Ada.Containers.Vectors is
       begin
          Container.Elements := Dst;
          Container.Last := New_Last;
-
          Free (X);
       end;
    end Insert_Space;
@@ -1063,9 +1389,9 @@ package body Ada.Containers.Vectors is
 
    begin
       if Before.Container /= null
-        and then Before.Container /= Vector_Access'(Container'Unchecked_Access)
+        and then Before.Container /= Container'Unchecked_Access
       then
-         raise Program_Error;
+         raise Program_Error with "Before cursor denotes wrong container";
       end if;
 
       if Count = 0 then
@@ -1083,12 +1409,18 @@ package body Ada.Containers.Vectors is
       if Before.Container = null
         or else Before.Index > Container.Last
       then
-         Index := Index_Type'Succ (Container.Last);
+         if Container.Last = Index_Type'Last then
+            raise Constraint_Error with
+              "vector is already at its maximum length";
+         end if;
+
+         Index := Container.Last + 1;
+
       else
          Index := Before.Index;
       end if;
 
-      Insert_Space (Container, Index, Count);
+      Insert_Space (Container, Index, Count => Count);
 
       Position := Cursor'(Container'Unchecked_Access, Index);
    end Insert_Space;
@@ -1110,10 +1442,23 @@ package body Ada.Containers.Vectors is
      (Container : Vector;
       Process   : not null access procedure (Position : Cursor))
    is
+      V : Vector renames Container'Unrestricted_Access.all;
+      B : Natural renames V.Busy;
+
    begin
-      for Indx in Index_Type'First .. Container.Last loop
-         Process (Cursor'(Container'Unchecked_Access, Indx));
-      end loop;
+      B := B + 1;
+
+      begin
+         for Indx in Index_Type'First .. Container.Last loop
+            Process (Cursor'(Container'Unchecked_Access, Indx));
+         end loop;
+      exception
+         when others =>
+            B := B - 1;
+            raise;
+      end;
+
+      B := B - 1;
    end Iterate;
 
    ----------
@@ -1135,7 +1480,11 @@ package body Ada.Containers.Vectors is
 
    function Last_Element (Container : Vector) return Element_Type is
    begin
-      return Element (Container, Container.Last);
+      if Container.Last = No_Index then
+         raise Constraint_Error with "Container is empty";
+      end if;
+
+      return Container.Elements.EA (Container.Last);
    end Last_Element;
 
    ----------------
@@ -1155,6 +1504,7 @@ package body Ada.Containers.Vectors is
       L : constant Int := Int (Container.Last);
       F : constant Int := Int (Index_Type'First);
       N : constant Int'Base := L - F + 1;
+
    begin
       return Count_Type (N);
    end Length;
@@ -1167,25 +1517,30 @@ package body Ada.Containers.Vectors is
      (Target : in out Vector;
       Source : in out Vector)
    is
-      X : Elements_Access := Target.Elements;
-
    begin
       if Target'Address = Source'Address then
          return;
       end if;
 
-      if Target.Last >= Index_Type'First then
-         raise Constraint_Error;
+      if Target.Busy > 0 then
+         raise Program_Error with
+           "attempt to tamper with elements (Target is busy)";
       end if;
 
-      Target.Elements := null;
-      Free (X);
+      if Source.Busy > 0 then
+         raise Program_Error with
+           "attempt to tamper with elements (Source is busy)";
+      end if;
 
-      Target.Elements := Source.Elements;
-      Target.Last := Source.Last;
+      declare
+         Target_Elements : constant Elements_Access := Target.Elements;
+      begin
+         Target.Elements := Source.Elements;
+         Source.Elements := Target_Elements;
+      end;
 
-      Source.Elements := null;
-      Source.Last := Index_Type'Pred (Index_Type'First);
+      Target.Last := Source.Last;
+      Source.Last := No_Index;
    end Move;
 
    ----------
@@ -1199,7 +1554,7 @@ package body Ada.Containers.Vectors is
       end if;
 
       if Position.Index < Position.Container.Last then
-         return (Position.Container, Index_Type'Succ (Position.Index));
+         return (Position.Container, Position.Index + 1);
       end if;
 
       return No_Element;
@@ -1216,7 +1571,7 @@ package body Ada.Containers.Vectors is
       end if;
 
       if Position.Index < Position.Container.Last then
-         Position.Index := Index_Type'Succ (Position.Index);
+         Position.Index := Position.Index + 1;
       else
          Position := No_Element;
       end if;
@@ -1254,7 +1609,7 @@ package body Ada.Containers.Vectors is
       end if;
 
       if Position.Index > Index_Type'First then
-         Position.Index := Index_Type'Pred (Position.Index);
+         Position.Index := Position.Index - 1;
       else
          Position := No_Element;
       end if;
@@ -1267,7 +1622,7 @@ package body Ada.Containers.Vectors is
       end if;
 
       if Position.Index > Index_Type'First then
-         return (Position.Container, Index_Type'Pred (Position.Index));
+         return (Position.Container, Position.Index - 1);
       end if;
 
       return No_Element;
@@ -1282,23 +1637,41 @@ package body Ada.Containers.Vectors is
       Index     : Index_Type;
       Process   : not null access procedure (Element : Element_Type))
    is
-      subtype T is Index_Type'Base range
-        Index_Type'First .. Container.Last;
+      V : Vector renames Container'Unrestricted_Access.all;
+      B : Natural renames V.Busy;
+      L : Natural renames V.Lock;
+
    begin
-      Process (Container.Elements (T'(Index)));
+      if Index > Container.Last then
+         raise Constraint_Error with "Index is out of range";
+      end if;
+
+      B := B + 1;
+      L := L + 1;
+
+      begin
+         Process (V.Elements.EA (Index));
+      exception
+         when others =>
+            L := L - 1;
+            B := B - 1;
+            raise;
+      end;
+
+      L := L - 1;
+      B := B - 1;
    end Query_Element;
 
    procedure Query_Element
      (Position : Cursor;
       Process  : not null access procedure (Element : Element_Type))
    is
-      Container : Vector renames Position.Container.all;
-
-      subtype T is Index_Type'Base range
-        Index_Type'First .. Container.Last;
-
    begin
-      Process (Container.Elements (T'(Position.Index)));
+      if Position.Container = null then
+         raise Constraint_Error with "Position cursor has no element";
+      end if;
+
+      Query_Element (Position.Container.all, Position.Index, Process);
    end Query_Element;
 
    ----------
@@ -1306,11 +1679,11 @@ package body Ada.Containers.Vectors is
    ----------
 
    procedure Read
-     (Stream    : access Root_Stream_Type'Class;
+     (Stream    : not null access Root_Stream_Type'Class;
       Container : out Vector)
    is
       Length : Count_Type'Base;
-      Last   : Index_Type'Base := Index_Type'Pred (Index_Type'First);
+      Last   : Index_Type'Base := No_Index;
 
    begin
       Clear (Container);
@@ -1322,32 +1695,66 @@ package body Ada.Containers.Vectors is
       end if;
 
       for J in Count_Type range 1 .. Length loop
-         Last := Index_Type'Succ (Last);
-         Element_Type'Read (Stream, Container.Elements (Last));
+         Last := Last + 1;
+         Element_Type'Read (Stream, Container.Elements.EA (Last));
          Container.Last := Last;
       end loop;
    end Read;
 
+   procedure Read
+     (Stream   : not null access Root_Stream_Type'Class;
+      Position : out Cursor)
+   is
+   begin
+      raise Program_Error with "attempt to stream vector cursor";
+   end Read;
+
    ---------------------
    -- Replace_Element --
    ---------------------
 
    procedure Replace_Element
-     (Container : Vector;
+     (Container : in out Vector;
       Index     : Index_Type;
-      By        : Element_Type)
+      New_Item  : Element_Type)
    is
-      subtype T is Index_Type'Base range
-        Index_Type'First .. Container.Last;
    begin
-      Container.Elements (T'(Index)) := By;
+      if Index > Container.Last then
+         raise Constraint_Error with "Index is out of range";
+      end if;
+
+      if Container.Lock > 0 then
+         raise Program_Error with
+           "attempt to tamper with cursors (vector is locked)";
+      end if;
+
+      Container.Elements.EA (Index) := New_Item;
    end Replace_Element;
 
-   procedure Replace_Element (Position : Cursor; By : Element_Type) is
-      subtype T is Index_Type'Base range
-        Index_Type'First .. Position.Container.Last;
+   procedure Replace_Element
+     (Container : in out Vector;
+      Position  : Cursor;
+      New_Item  : Element_Type)
+   is
    begin
-      Position.Container.Elements (T'(Position.Index)) := By;
+      if Position.Container = null then
+         raise Constraint_Error with "Position cursor has no element";
+      end if;
+
+      if Position.Container /= Container'Unrestricted_Access then
+         raise Program_Error with "Position cursor denotes wrong container";
+      end if;
+
+      if Position.Index > Container.Last then
+         raise Constraint_Error with "Position cursor is out of range";
+      end if;
+
+      if Container.Lock > 0 then
+         raise Program_Error with
+           "attempt to tamper with cursors (vector is locked)";
+      end if;
+
+      Container.Elements.EA (Position.Index) := New_Item;
    end Replace_Element;
 
    ----------------------
@@ -1370,21 +1777,23 @@ package body Ada.Containers.Vectors is
                Free (X);
             end;
 
-         elsif N < Container.Elements'Length then
+         elsif N < Container.Elements.EA'Length then
+            if Container.Busy > 0 then
+               raise Program_Error with
+                 "attempt to tamper with elements (vector is busy)";
+            end if;
+
             declare
-               subtype Array_Index_Subtype is Index_Type'Base range
+               subtype Src_Index_Subtype is Index_Type'Base range
                  Index_Type'First .. Container.Last;
 
-               Src : Elements_Type renames
-                       Container.Elements (Array_Index_Subtype);
-
-               subtype Array_Subtype is
-                 Elements_Type (Array_Index_Subtype);
+               Src : Elements_Array renames
+                       Container.Elements.EA (Src_Index_Subtype);
 
                X : Elements_Access := Container.Elements;
 
             begin
-               Container.Elements := new Array_Subtype'(Src);
+               Container.Elements := new Elements_Type'(Container.Last, Src);
                Free (X);
             end;
          end if;
@@ -1397,34 +1806,40 @@ package body Ada.Containers.Vectors is
             Last_As_Int : constant Int'Base :=
                             Int (Index_Type'First) + Int (Capacity) - 1;
 
-            Last : constant Index_Type := Index_Type (Last_As_Int);
+         begin
+            if Last_As_Int > Index_Type'Pos (Index_Type'Last) then
+               raise Constraint_Error with "new length is out of range";
+            end if;
 
-            subtype Array_Subtype is
-              Elements_Type (Index_Type'First .. Last);
+            declare
+               Last : constant Index_Type := Index_Type (Last_As_Int);
 
-         begin
-            Container.Elements := new Array_Subtype;
+            begin
+               Container.Elements := new Elements_Type (Last);
+            end;
          end;
 
          return;
       end if;
 
       if Capacity <= N then
-         if N < Container.Elements'Length then
+         if N < Container.Elements.EA'Length then
+            if Container.Busy > 0 then
+               raise Program_Error with
+                 "attempt to tamper with elements (vector is busy)";
+            end if;
+
             declare
-               subtype Array_Index_Subtype is Index_Type'Base range
+               subtype Src_Index_Subtype is Index_Type'Base range
                  Index_Type'First .. Container.Last;
 
-               Src : Elements_Type renames
-                       Container.Elements (Array_Index_Subtype);
-
-               subtype Array_Subtype is
-                 Elements_Type (Array_Index_Subtype);
+               Src : Elements_Array renames
+                       Container.Elements.EA (Src_Index_Subtype);
 
                X : Elements_Access := Container.Elements;
 
             begin
-               Container.Elements := new Array_Subtype'(Src);
+               Container.Elements := new Elements_Type'(Container.Last, Src);
                Free (X);
             end;
 
@@ -1433,47 +1848,95 @@ package body Ada.Containers.Vectors is
          return;
       end if;
 
-      if Capacity = Container.Elements'Length then
+      if Capacity = Container.Elements.EA'Length then
          return;
       end if;
 
+      if Container.Busy > 0 then
+         raise Program_Error with
+           "attempt to tamper with elements (vector is busy)";
+      end if;
+
       declare
          Last_As_Int : constant Int'Base :=
                          Int (Index_Type'First) + Int (Capacity) - 1;
 
-         Last : constant Index_Type := Index_Type (Last_As_Int);
-
-         subtype Array_Subtype is
-           Elements_Type (Index_Type'First .. Last);
-
-         E : Elements_Access := new Array_Subtype;
-
       begin
+         if Last_As_Int > Index_Type'Pos (Index_Type'Last) then
+            raise Constraint_Error with "new length is out of range";
+         end if;
+
          declare
-            Src : Elements_Type renames
-                    Container.Elements (Index_Type'First .. Container.Last);
+            Last : constant Index_Type := Index_Type (Last_As_Int);
 
-            Tgt : Elements_Type renames
-                    E (Index_Type'First .. Container.Last);
+            E : Elements_Access := new Elements_Type (Last);
 
          begin
-            Tgt := Src;
+            declare
+               subtype Index_Subtype is Index_Type'Base range
+                 Index_Type'First .. Container.Last;
 
-         exception
-            when others =>
-               Free (E);
-               raise;
-         end;
+               Src : Elements_Array renames
+                       Container.Elements.EA (Index_Subtype);
 
-         declare
-            X : Elements_Access := Container.Elements;
-         begin
-            Container.Elements := E;
-            Free (X);
+               Tgt : Elements_Array renames E.EA (Index_Subtype);
+
+            begin
+               Tgt := Src;
+
+            exception
+               when others =>
+                  Free (E);
+                  raise;
+            end;
+
+            declare
+               X : Elements_Access := Container.Elements;
+            begin
+               Container.Elements := E;
+               Free (X);
+            end;
          end;
       end;
    end Reserve_Capacity;
 
+   ----------------------
+   -- Reverse_Elements --
+   ----------------------
+
+   procedure Reverse_Elements (Container : in out Vector) is
+   begin
+      if Container.Length <= 1 then
+         return;
+      end if;
+
+      if Container.Lock > 0 then
+         raise Program_Error with
+           "attempt to tamper with cursors (vector is locked)";
+      end if;
+
+      declare
+         I, J : Index_Type;
+         E    : Elements_Type renames Container.Elements.all;
+
+      begin
+         I := Index_Type'First;
+         J := Container.Last;
+         while I < J loop
+            declare
+               EI : constant Element_Type := E.EA (I);
+
+            begin
+               E.EA (I) := E.EA (J);
+               E.EA (J) := EI;
+            end;
+
+            I := I + 1;
+            J := J - 1;
+         end loop;
+      end;
+   end Reverse_Elements;
+
    ------------------
    -- Reverse_Find --
    ------------------
@@ -1487,22 +1950,18 @@ package body Ada.Containers.Vectors is
 
    begin
       if Position.Container /= null
-        and then Position.Container /=
-                   Vector_Access'(Container'Unchecked_Access)
+        and then Position.Container /= Container'Unchecked_Access
       then
-         raise Program_Error;
+         raise Program_Error with "Position cursor denotes wrong container";
       end if;
 
-      if Position.Container = null
-        or else Position.Index > Container.Last
-      then
-         Last := Container.Last;
-      else
-         Last := Position.Index;
-      end if;
+      Last :=
+        (if Position.Container = null or else Position.Index > Container.Last
+         then Container.Last
+         else Position.Index);
 
       for Indx in reverse Index_Type'First .. Last loop
-         if Container.Elements (Indx) = Item then
+         if Container.Elements.EA (Indx) = Item then
             return (Container'Unchecked_Access, Indx);
          end if;
       end loop;
@@ -1519,17 +1978,12 @@ package body Ada.Containers.Vectors is
       Item      : Element_Type;
       Index     : Index_Type := Index_Type'Last) return Extended_Index
    is
-      Last : Index_Type'Base;
+      Last : constant Index_Type'Base :=
+               Index_Type'Min (Container.Last, Index);
 
    begin
-      if Index > Container.Last then
-         Last := Container.Last;
-      else
-         Last := Index;
-      end if;
-
       for Indx in reverse Index_Type'First .. Last loop
-         if Container.Elements (Indx) = Item then
+         if Container.Elements.EA (Indx) = Item then
             return Indx;
          end if;
       end loop;
@@ -1545,10 +1999,23 @@ package body Ada.Containers.Vectors is
      (Container : Vector;
       Process   : not null access procedure (Position : Cursor))
    is
+      V : Vector renames Container'Unrestricted_Access.all;
+      B : Natural renames V.Busy;
+
    begin
-      for Indx in reverse Index_Type'First .. Container.Last loop
-         Process (Cursor'(Container'Unchecked_Access, Indx));
-      end loop;
+      B := B + 1;
+
+      begin
+         for Indx in reverse Index_Type'First .. Container.Last loop
+            Process (Cursor'(Container'Unchecked_Access, Indx));
+         end loop;
+      exception
+         when others =>
+            B := B - 1;
+            raise;
+      end;
+
+      B := B - 1;
    end Reverse_Iterate;
 
    ----------------
@@ -1557,23 +2024,24 @@ package body Ada.Containers.Vectors is
 
    procedure Set_Length (Container : in out Vector; Length : Count_Type) is
    begin
-      if Length = 0 then
-         Clear (Container);
+      if Length = Vectors.Length (Container) then
          return;
       end if;
 
+      if Container.Busy > 0 then
+         raise Program_Error with
+           "attempt to tamper with elements (vector is busy)";
+      end if;
+
+      if Length > Capacity (Container) then
+         Reserve_Capacity (Container, Capacity => Length);
+      end if;
+
       declare
          Last_As_Int : constant Int'Base :=
                          Int (Index_Type'First) + Int (Length) - 1;
-
-         Last        : constant Index_Type := Index_Type (Last_As_Int);
-
       begin
-         if Length > Capacity (Container) then
-            Reserve_Capacity (Container, Capacity => Length);
-         end if;
-
-         Container.Last := Last;
+         Container.Last := Index_Type'Base (Last_As_Int);
       end;
    end Set_Length;
 
@@ -1581,44 +2049,52 @@ package body Ada.Containers.Vectors is
    -- Swap --
    ----------
 
-   procedure Swap
-     (Container : Vector;
-      I, J      : Index_Type)
-   is
-
-      subtype T is Index_Type'Base range
-        Index_Type'First .. Container.Last;
-
-      EI : constant Element_Type := Container.Elements (T'(I));
-
+   procedure Swap (Container : in out Vector; I, J : Index_Type) is
    begin
+      if I > Container.Last then
+         raise Constraint_Error with "I index is out of range";
+      end if;
 
-      Container.Elements (T'(I)) := Container.Elements (T'(J));
-      Container.Elements (T'(J)) := EI;
-
-   end Swap;
+      if J > Container.Last then
+         raise Constraint_Error with "J index is out of range";
+      end if;
 
-   procedure Swap (I, J : Cursor) is
+      if I = J then
+         return;
+      end if;
 
-      --  NOTE: The behavior has been liberalized here to
-      --  allow I and J to designate different containers.
-      --  TODO: Probably this is supposed to raise P_E ???
+      if Container.Lock > 0 then
+         raise Program_Error with
+           "attempt to tamper with cursors (vector is locked)";
+      end if;
 
-      subtype TI is Index_Type'Base range
-        Index_Type'First .. I.Container.Last;
+      declare
+         EI_Copy : constant Element_Type := Container.Elements.EA (I);
+      begin
+         Container.Elements.EA (I) := Container.Elements.EA (J);
+         Container.Elements.EA (J) := EI_Copy;
+      end;
+   end Swap;
 
-      EI : Element_Type renames I.Container.Elements (TI'(I.Index));
+   procedure Swap (Container : in out Vector; I, J : Cursor) is
+   begin
+      if I.Container = null then
+         raise Constraint_Error with "I cursor has no element";
+      end if;
 
-      EI_Copy : constant Element_Type := EI;
+      if J.Container = null then
+         raise Constraint_Error with "J cursor has no element";
+      end if;
 
-      subtype TJ is Index_Type'Base range
-        Index_Type'First .. J.Container.Last;
+      if I.Container /= Container'Unrestricted_Access then
+         raise Program_Error with "I cursor denotes wrong container";
+      end if;
 
-      EJ : Element_Type renames J.Container.Elements (TJ'(J.Index));
+      if J.Container /= Container'Unrestricted_Access then
+         raise Program_Error with "J cursor denotes wrong container";
+      end if;
 
-   begin
-      EI := EJ;
-      EJ := EI_Copy;
+      Swap (Container, I.Index, J.Index);
    end Swap;
 
    ---------------
@@ -1667,11 +2143,18 @@ package body Ada.Containers.Vectors is
       declare
          First       : constant Int := Int (Index_Type'First);
          Last_As_Int : constant Int'Base := First + Int (Length) - 1;
-         Last        : constant Index_Type := Index_Type (Last_As_Int);
-         Elements    : constant Elements_Access :=
-                         new Elements_Type (Index_Type'First .. Last);
+         Last        : Index_Type;
+         Elements    : Elements_Access;
+
       begin
-         return (Controlled with Elements, Last);
+         if Last_As_Int > Index_Type'Pos (Index_Type'Last) then
+            raise Constraint_Error with "Length is out of range";
+         end if;
+
+         Last := Index_Type (Last_As_Int);
+         Elements := new Elements_Type (Last);
+
+         return Vector'(Controlled with Elements, Last, 0, 0);
       end;
    end To_Vector;
 
@@ -1687,12 +2170,18 @@ package body Ada.Containers.Vectors is
       declare
          First       : constant Int := Int (Index_Type'First);
          Last_As_Int : constant Int'Base := First + Int (Length) - 1;
-         Last        : constant Index_Type := Index_Type (Last_As_Int);
-         Elements    : constant Elements_Access :=
-                         new Elements_Type'
-                                   (Index_Type'First .. Last => New_Item);
+         Last        : Index_Type;
+         Elements    : Elements_Access;
+
       begin
-         return (Controlled with Elements, Last);
+         if Last_As_Int > Index_Type'Pos (Index_Type'Last) then
+            raise Constraint_Error with "Length is out of range";
+         end if;
+
+         Last := Index_Type (Last_As_Int);
+         Elements := new Elements_Type'(Last, EA => (others => New_Item));
+
+         return Vector'(Controlled with Elements, Last, 0, 0);
       end;
    end To_Vector;
 
@@ -1701,24 +2190,49 @@ package body Ada.Containers.Vectors is
    --------------------
 
    procedure Update_Element
-     (Container : Vector;
+     (Container : in out Vector;
       Index     : Index_Type;
       Process   : not null access procedure (Element : in out Element_Type))
    is
-      subtype T is Index_Type'Base range
-        Index_Type'First .. Container.Last;
+      B : Natural renames Container.Busy;
+      L : Natural renames Container.Lock;
+
    begin
-      Process (Container.Elements (T'(Index)));
+      if Index > Container.Last then
+         raise Constraint_Error with "Index is out of range";
+      end if;
+
+      B := B + 1;
+      L := L + 1;
+
+      begin
+         Process (Container.Elements.EA (Index));
+      exception
+         when others =>
+            L := L - 1;
+            B := B - 1;
+            raise;
+      end;
+
+      L := L - 1;
+      B := B - 1;
    end Update_Element;
 
    procedure Update_Element
-     (Position : Cursor;
-      Process  : not null access procedure (Element : in out Element_Type))
+     (Container : in out Vector;
+      Position  : Cursor;
+      Process   : not null access procedure (Element : in out Element_Type))
    is
-      subtype T is Index_Type'Base range
-        Index_Type'First .. Position.Container.Last;
    begin
-      Process (Position.Container.Elements (T'(Position.Index)));
+      if Position.Container = null then
+         raise Constraint_Error with "Position cursor has no element";
+      end if;
+
+      if Position.Container /= Container'Unrestricted_Access then
+         raise Program_Error with "Position cursor denotes wrong container";
+      end if;
+
+      Update_Element (Container, Position.Index, Process);
    end Update_Element;
 
    -----------
@@ -1726,16 +2240,23 @@ package body Ada.Containers.Vectors is
    -----------
 
    procedure Write
-     (Stream    : access Root_Stream_Type'Class;
+     (Stream    : not null access Root_Stream_Type'Class;
       Container : Vector)
    is
    begin
       Count_Type'Base'Write (Stream, Length (Container));
 
       for J in Index_Type'First .. Container.Last loop
-         Element_Type'Write (Stream, Container.Elements (J));
+         Element_Type'Write (Stream, Container.Elements.EA (J));
       end loop;
    end Write;
 
-end Ada.Containers.Vectors;
+   procedure Write
+     (Stream   : not null access Root_Stream_Type'Class;
+      Position : Cursor)
+   is
+   begin
+      raise Program_Error with "attempt to stream vector cursor";
+   end Write;
 
+end Ada.Containers.Vectors;