Commit d43d5ef7 by Matthew Heaney Committed by Arnaud Charlet

a-convec.ads, [...]: Declaration of subtype Extended_Index was changed.

2005-07-04  Matthew Heaney  <heaney@adacore.com>

	* a-convec.ads, a-coinve.ads: Declaration of subtype Extended_Index
	was changed.
	* a-coinve.adb: Perform constraint checks explicitly.

From-SVN: r101597
parent c8effb4f
...@@ -76,7 +76,7 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -76,7 +76,7 @@ package body Ada.Containers.Indefinite_Vectors is
end if; end if;
exception exception
when others => when others =>
for J in Index_Type'First .. Index_Type'Pred (I) loop for J in Index_Type'First .. I - 1 loop
Free (Elements (J)); Free (Elements (J));
end loop; end loop;
...@@ -106,7 +106,7 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -106,7 +106,7 @@ package body Ada.Containers.Indefinite_Vectors is
end if; end if;
exception exception
when others => when others =>
for J in Index_Type'First .. Index_Type'Pred (I) loop for J in Index_Type'First .. I - 1 loop
Free (Elements (J)); Free (Elements (J));
end loop; end loop;
...@@ -120,60 +120,67 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -120,60 +120,67 @@ package body Ada.Containers.Indefinite_Vectors is
end if; end if;
declare declare
Last_As_Int : constant Int'Base := Last_As_Int : constant Int'Base := -- TODO: handle overflow
Int (Index_Type'First) + Int (LN) + Int (RN) - 1; Int (Index_Type'First) + Int (LN) + Int (RN) - 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;
end if;
LE : Elements_Type renames declare
Left.Elements (Index_Type'First .. Left.Last); Last : constant Index_Type := Index_Type (Last_As_Int);
RE : Elements_Type renames LE : Elements_Type renames
Right.Elements (Index_Type'First .. Right.Last); Left.Elements (Index_Type'First .. Left.Last);
Elements : Elements_Access := RE : Elements_Type renames
new Elements_Type (Index_Type'First .. Last); Right.Elements (Index_Type'First .. Right.Last);
I : Index_Type'Base := Index_Type'Pred (Index_Type'First); Elements : Elements_Access :=
new Elements_Type (Index_Type'First .. Last);
begin I : Index_Type'Base := No_Index;
for LI in LE'Range loop
I := Index_Type'Succ (I);
begin begin
if LE (LI) /= null then for LI in LE'Range loop
Elements (I) := new Element_Type'(LE (LI).all); I := I + 1;
end if;
exception
when others =>
for J in Index_Type'First .. Index_Type'Pred (I) loop
Free (Elements (J));
end loop;
Free (Elements); begin
raise; if LE (LI) /= null then
end; Elements (I) := new Element_Type'(LE (LI).all);
end loop; end if;
exception
when others =>
for J in Index_Type'First .. I - 1 loop
Free (Elements (J));
end loop;
for RI in RE'Range loop Free (Elements);
I := Index_Type'Succ (I); raise;
end;
end loop;
begin for RI in RE'Range loop
if RE (RI) /= null then I := I + 1;
Elements (I) := new Element_Type'(RE (RI).all);
end if;
exception
when others =>
for J in Index_Type'First .. Index_Type'Pred (I) loop
Free (Elements (J));
end loop;
Free (Elements); begin
raise; if RE (RI) /= null then
end; Elements (I) := new Element_Type'(RE (RI).all);
end loop; end if;
exception
when others =>
for J in Index_Type'First .. I - 1 loop
Free (Elements (J));
end loop;
return (Controlled with Elements, Last, 0, 0); Free (Elements);
raise;
end;
end loop;
return (Controlled with Elements, Last, 0, 0);
end;
end; end;
end "&"; end "&";
...@@ -205,49 +212,51 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -205,49 +212,51 @@ package body Ada.Containers.Indefinite_Vectors is
Last_As_Int : constant Int'Base := Last_As_Int : constant Int'Base :=
Int (Index_Type'First) + Int (LN); Int (Index_Type'First) + Int (LN);
Last : constant Index_Type := Index_Type (Last_As_Int); begin
if Last_As_Int > Index_Type'Pos (Index_Type'Last) then
raise Constraint_Error;
end if;
LE : Elements_Type renames declare
Left.Elements (Index_Type'First .. Left.Last); Last : constant Index_Type := Index_Type (Last_As_Int);
Elements : Elements_Access := LE : Elements_Type renames
new Elements_Type (Index_Type'First .. Last); Left.Elements (Index_Type'First .. Left.Last);
Elements : Elements_Access :=
new Elements_Type (Index_Type'First .. Last);
begin
for I in LE'Range loop
begin
if LE (I) /= null then
Elements (I) := new Element_Type'(LE (I).all);
end if;
exception
when others =>
for J in Index_Type'First .. I - 1 loop
Free (Elements (J));
end loop;
Free (Elements);
raise;
end;
end loop;
begin
for I in LE'Range loop
begin begin
if LE (I) /= null then Elements (Elements'Last) := new Element_Type'(Right);
Elements (I) := new Element_Type'(LE (I).all);
end if;
exception exception
when others => when others =>
for J in Index_Type'First .. Index_Type'Pred (I) loop for J in Index_Type'First .. Elements'Last - 1 loop
Free (Elements (J)); Free (Elements (J));
end loop; end loop;
Free (Elements); Free (Elements);
raise; raise;
end; end;
end loop;
begin
Elements (Elements'Last) := new Element_Type'(Right);
exception
when others =>
declare
subtype J_Subtype is Index_Type'Base range
Index_Type'First .. Index_Type'Pred (Elements'Last);
begin
for J in J_Subtype loop
Free (Elements (J));
end loop;
end;
Free (Elements); return (Controlled with Elements, Last, 0, 0);
raise;
end; end;
return (Controlled with Elements, Last, 0, 0);
end; end;
end "&"; end "&";
...@@ -279,72 +288,86 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -279,72 +288,86 @@ package body Ada.Containers.Indefinite_Vectors is
Last_As_Int : constant Int'Base := Last_As_Int : constant Int'Base :=
Int (Index_Type'First) + Int (RN); Int (Index_Type'First) + Int (RN);
Last : constant Index_Type := Index_Type (Last_As_Int); begin
if Last_As_Int > Index_Type'Pos (Index_Type'Last) then
RE : Elements_Type renames raise Constraint_Error;
Right.Elements (Index_Type'First .. Right.Last); end if;
Elements : Elements_Access := declare
new Elements_Type (Index_Type'First .. Last); Last : constant Index_Type := Index_Type (Last_As_Int);
I : Index_Type'Base := Index_Type'First; RE : Elements_Type renames
Right.Elements (Index_Type'First .. Right.Last);
begin Elements : Elements_Access :=
begin new Elements_Type (Index_Type'First .. Last);
Elements (I) := new Element_Type'(Left);
exception
when others =>
Free (Elements);
raise;
end;
for RI in RE'Range loop I : Index_Type'Base := Index_Type'First;
I := Index_Type'Succ (I);
begin
begin begin
if RE (RI) /= null then Elements (I) := new Element_Type'(Left);
Elements (I) := new Element_Type'(RE (RI).all);
end if;
exception exception
when others => when others =>
for J in Index_Type'First .. Index_Type'Pred (I) loop
Free (Elements (J));
end loop;
Free (Elements); Free (Elements);
raise; raise;
end; end;
end loop;
return (Controlled with Elements, Last, 0, 0); for RI in RE'Range loop
I := I + 1;
begin
if RE (RI) /= null then
Elements (I) := new Element_Type'(RE (RI).all);
end if;
exception
when others =>
for J in Index_Type'First .. I - 1 loop
Free (Elements (J));
end loop;
Free (Elements);
raise;
end;
end loop;
return (Controlled with Elements, Last, 0, 0);
end;
end; end;
end "&"; end "&";
function "&" (Left, Right : Element_Type) return Vector is function "&" (Left, Right : Element_Type) return Vector is
subtype IT is Index_Type'Base range begin
Index_Type'First .. Index_Type'Succ (Index_Type'First); if Index_Type'First >= Index_Type'Last then
raise Constraint_Error;
end if;
Elements : Elements_Access := new Elements_Type (IT); declare
Last : constant Index_Type := Index_Type'First + 1;
begin subtype ET is Elements_Type (Index_Type'First .. Last);
begin
Elements (Elements'First) := new Element_Type'(Left);
exception
when others =>
Free (Elements);
raise;
end;
Elements : Elements_Access := new ET;
begin begin
Elements (Elements'Last) := new Element_Type'(Right); begin
exception Elements (Elements'First) := new Element_Type'(Left);
when others => exception
Free (Elements (Elements'First)); when others =>
Free (Elements); Free (Elements);
raise; raise;
end; end;
return (Controlled with Elements, Elements'Last, 0, 0); begin
Elements (Elements'Last) := new Element_Type'(Right);
exception
when others =>
Free (Elements (Elements'First));
Free (Elements);
raise;
end;
return (Controlled with Elements, Elements'Last, 0, 0);
end;
end "&"; end "&";
--------- ---------
...@@ -362,17 +385,6 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -362,17 +385,6 @@ package body Ada.Containers.Indefinite_Vectors is
end if; end if;
for J in Index_Type'First .. Left.Last loop for J in Index_Type'First .. Left.Last loop
-- NOTE:
-- I think it's a bounded error to read or otherwise manipulate
-- an "empty" element, which here means that it has the value
-- null. If it's a bounded error then an exception might
-- propagate, or it might not. We take advantage of that
-- permission here to allow empty elements to be compared.
--
-- Whether this is the right decision I'm not really sure. If
-- you have a contrary argument then let me know.
-- END NOTE.
if Left.Elements (J) = null then if Left.Elements (J) = null then
if Right.Elements (J) /= null then if Right.Elements (J) /= null then
return False; return False;
...@@ -383,7 +395,6 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -383,7 +395,6 @@ package body Ada.Containers.Indefinite_Vectors is
elsif Left.Elements (J).all /= Right.Elements (J).all then elsif Left.Elements (J).all /= Right.Elements (J).all then
return False; return False;
end if; end if;
end loop; end loop;
...@@ -396,13 +407,7 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -396,13 +407,7 @@ package body Ada.Containers.Indefinite_Vectors is
procedure Adjust (Container : in out Vector) is procedure Adjust (Container : in out Vector) is
begin begin
if Container.Elements = null then if Container.Last = No_Index then
return;
end if;
if Container.Elements'Length = 0
or else Container.Last < Index_Type'First
then
Container.Elements := null; Container.Elements := null;
return; return;
end if; end if;
...@@ -410,6 +415,7 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -410,6 +415,7 @@ package body Ada.Containers.Indefinite_Vectors is
declare declare
E : Elements_Type renames Container.Elements.all; E : Elements_Type renames Container.Elements.all;
L : constant Index_Type := Container.Last; L : constant Index_Type := Container.Last;
begin begin
Container.Elements := null; Container.Elements := null;
Container.Last := No_Index; Container.Last := No_Index;
...@@ -438,9 +444,13 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -438,9 +444,13 @@ package body Ada.Containers.Indefinite_Vectors is
return; return;
end if; end if;
if Container.Last = Index_Type'Last then
raise Constraint_Error;
end if;
Insert Insert
(Container, (Container,
Index_Type'Succ (Container.Last), Container.Last + 1,
New_Item); New_Item);
end Append; end Append;
...@@ -454,9 +464,13 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -454,9 +464,13 @@ package body Ada.Containers.Indefinite_Vectors is
return; return;
end if; end if;
if Container.Last = Index_Type'Last then
raise Constraint_Error;
end if;
Insert Insert
(Container, (Container,
Index_Type'Succ (Container.Last), Container.Last + 1,
New_Item, New_Item,
Count); Count);
end Append; end Append;
...@@ -522,12 +536,12 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -522,12 +536,12 @@ package body Ada.Containers.Indefinite_Vectors is
raise Program_Error; raise Program_Error;
end if; end if;
for J in reverse Index_Type'First .. Container.Last loop while Container.Last >= Index_Type'First loop
declare declare
X : Element_Access := Container.Elements (J); X : Element_Access := Container.Elements (Container.Last);
begin begin
Container.Elements (J) := null; Container.Elements (Container.Last) := null;
Container.Last := Index_Type'Pred (J); Container.Last := Container.Last - 1;
Free (X); Free (X);
end; end;
end loop; end loop;
...@@ -575,37 +589,53 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -575,37 +589,53 @@ package body Ada.Containers.Indefinite_Vectors is
end if; end if;
declare declare
I_As_Int : constant Int := Int (Index); Index_As_Int : constant Int := Int (Index);
Old_Last_As_Int : constant Int := Int (Container.Last); Old_Last_As_Int : constant Int := Int (Container.Last);
-- TODO: somewhat vestigial...fix.
Count1 : constant Int'Base := Int (Count); Count1 : constant Int'Base := Int (Count);
Count2 : constant Int'Base := Old_Last_As_Int - I_As_Int + 1; Count2 : constant Int'Base := Old_Last_As_Int - Index_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 := Index_As_Int + N;
E : Elements_Type renames Container.Elements.all;
J_As_Int : constant Int'Base := I_As_Int + N; begin
J : constant Index_Type'Base := Index_Type'Base (J_As_Int); if J_As_Int > Old_Last_As_Int then
while Container.Last >= Index loop
declare
K : constant Index_Type := Container.Last;
X : Element_Access := E (K);
E : Elements_Type renames Container.Elements.all; begin
E (K) := null;
Container.Last := K - 1;
Free (X);
end;
end loop;
New_Last_As_Int : constant Int'Base := Old_Last_As_Int - N; else
declare
J : constant Index_Type := Index_Type (J_As_Int);
New_Last : constant Extended_Index := New_Last_As_Int : constant Int'Base := Old_Last_As_Int - N;
Extended_Index (New_Last_As_Int); New_Last : constant Index_Type :=
Index_Type (New_Last_As_Int);
begin
for K in Index .. Index_Type'Pred (J) loop
declare
X : Element_Access := E (K);
begin begin
E (K) := null; for K in Index .. J - 1 loop
Free (X); declare
end; X : Element_Access := E (K);
end loop; begin
E (K) := null;
Free (X);
end;
end loop;
E (Index .. New_Last) := E (J .. Container.Last); E (Index .. New_Last) := E (J .. Container.Last);
Container.Last := New_Last; Container.Last := New_Last;
end;
end if;
end; end;
end Delete; end Delete;
...@@ -664,21 +694,35 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -664,21 +694,35 @@ package body Ada.Containers.Indefinite_Vectors is
(Container : in out Vector; (Container : in out Vector;
Count : Count_Type := 1) Count : Count_Type := 1)
is is
Index : Int'Base; N : constant Count_Type := Length (Container);
begin begin
if Count = 0 then if Count = 0
or else N = 0
then
return; return;
end if; end if;
if Count >= Length (Container) then if Container.Busy > 0 then
Clear (Container); raise Program_Error;
return;
end if; end if;
Index := Int'Base (Container.Last) - Int'Base (Count) + 1; declare
E : Elements_Type renames Container.Elements.all;
Delete (Container, Index_Type'Base (Index), Count); begin
for Indx in 1 .. Count_Type'Min (Count, N) loop
declare
J : constant Index_Type := Container.Last;
X : Element_Access := E (J);
begin
E (J) := null;
Container.Last := J - 1;
Free (X);
end;
end loop;
end;
end Delete_Last; end Delete_Last;
------------- -------------
...@@ -689,14 +733,20 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -689,14 +733,20 @@ package body Ada.Containers.Indefinite_Vectors is
(Container : Vector; (Container : Vector;
Index : Index_Type) return Element_Type Index : Index_Type) return Element_Type
is is
subtype T is Index_Type'Base range
Index_Type'First .. Container.Last;
begin begin
return Container.Elements (T'(Index)).all; if Index > Container.Last then
raise Constraint_Error;
end if;
return Container.Elements (Index).all;
end Element; end Element;
function Element (Position : Cursor) return Element_Type is function Element (Position : Cursor) return Element_Type is
begin begin
if Position.Container = null then
raise Constraint_Error;
end if;
return Element (Position.Container.all, Position.Index); return Element (Position.Container.all, Position.Index);
end Element; end Element;
...@@ -970,10 +1020,7 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -970,10 +1020,7 @@ package body Ada.Containers.Indefinite_Vectors is
New_Last_As_Int : Int'Base; New_Last_As_Int : Int'Base;
New_Last : Index_Type; New_Last : Index_Type;
Index : Extended_Index; -- TODO: see note in a-convec.adb. Dst : Elements_Access;
Dst_Last : Index_Type;
Dst : Elements_Access;
begin begin
if Before < Index_Type'First then if Before < Index_Type'First then
...@@ -995,6 +1042,11 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -995,6 +1042,11 @@ package body Ada.Containers.Indefinite_Vectors is
begin begin
New_Last_As_Int := Old_Last_As_Int + N; New_Last_As_Int := Old_Last_As_Int + N;
if New_Last_As_Int > Index_Type'Pos (Index_Type'Last) then
raise Constraint_Error;
end if;
New_Last := Index_Type (New_Last_As_Int); New_Last := Index_Type (New_Last_As_Int);
end; end;
...@@ -1002,28 +1054,16 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1002,28 +1054,16 @@ package body Ada.Containers.Indefinite_Vectors is
raise Program_Error; raise Program_Error;
end if; end if;
declare
Old_First_As_Int : constant Int := Int (Before);
New_First_As_Int : constant Int'Base := Old_First_As_Int + N;
begin
Index := Extended_Index (New_First_As_Int); -- TODO
end;
if Container.Elements = null then if Container.Elements = null then
declare Container.Elements :=
subtype Elements_Subtype is new Elements_Type (Index_Type'First .. New_Last);
Elements_Type (Index_Type'First .. New_Last);
begin
Container.Elements := new Elements_Subtype;
Container.Last := Index_Type'Pred (Index_Type'First);
for J in Container.Elements'Range loop Container.Last := No_Index;
Container.Elements (J) := new Element_Type'(New_Item);
Container.Last := J; for J in Container.Elements'Range loop
end loop; Container.Elements (J) := new Element_Type'(New_Item);
end; Container.Last := J;
end loop;
return; return;
end if; end if;
...@@ -1032,105 +1072,116 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1032,105 +1072,116 @@ package body Ada.Containers.Indefinite_Vectors is
declare declare
E : Elements_Type renames Container.Elements.all; E : Elements_Type renames Container.Elements.all;
begin begin
E (Index .. New_Last) := E (Before .. Container.Last); if Before <= Container.Last then
Container.Last := New_Last; declare
Index_As_Int : constant Int'Base :=
Index_Type'Pos (Before) + N;
Index : constant Index_Type := Index_Type (Index_As_Int);
J : Index_Type'Base := Before;
-- NOTE:
-- Now we do the allocation. If it fails, we can propagate the
-- exception and invariants are more or less satisfied. The
-- issue is that we have some slots still null, and the client
-- has no way of detecting whether the slot is null (unless we
-- give him a way).
--
-- Another way is to allocate a subarray on the stack, do the
-- allocation into that array, and if that success then do
-- the insertion proper. The issue there is that you have to
-- allocate the subarray on the stack, and that may fail if the
-- subarray is long.
--
-- Or we could try to roll-back the changes: deallocate the
-- elements we have successfully deallocated, and then copy
-- the elements ptrs back to their original posns.
-- END NOTE.
-- NOTE: I have written the loop manually here. I could
-- have done it this way too:
-- E (Before .. Index_Type'Pred (Index)) :=
-- (others => new Element_Type'New_Item);
-- END NOTE.
for J in Before .. Index_Type'Pred (Index) loop
begin begin
E (J) := new Element_Type'(New_Item); E (Index .. New_Last) := E (Before .. Container.Last);
Container.Last := New_Last;
while J < Index loop
E (J) := new Element_Type'(New_Item);
J := J + 1;
end loop;
exception exception
when others => when others =>
E (J .. Index_Type'Pred (Index)) := (others => null); E (J .. Index - 1) := (others => null);
raise; raise;
end; end;
end loop;
else
for J in Before .. New_Last loop
E (J) := new Element_Type'(New_Item);
Container.Last := J;
end loop;
end if;
end; end;
return; return;
end if; end if;
declare declare
First : constant Int := Int (Index_Type'First); First : constant Int := Int (Index_Type'First);
New_Size : constant Int'Base := New_Last_As_Int - First + 1; New_Size : constant Int'Base := New_Last_As_Int - First + 1;
Max_Size : constant Int'Base := Int (Index_Type'Last) - First + 1; Size : Int'Base := Int'Max (1, Container.Elements'Length);
Size, Dst_Last_As_Int : Int'Base;
begin begin
if New_Size >= Max_Size / 2 then while Size < New_Size loop
Dst_Last := Index_Type'Last; if Size > Int'Last / 2 then
Size := Int'Last;
exit;
end if;
else Size := 2 * Size;
Size := Container.Elements'Length; end loop;
if Size = 0 then -- TODO: The following calculations aren't quite right, since
Size := 1; -- there will be overflow if Index_Type'Range is very large
end if; -- (e.g. this package is instantiated with a 64-bit integer).
-- END TODO.
while Size < New_Size loop declare
Size := 2 * Size; Max_Size : constant Int'Base := Int (Index_Type'Last) - First + 1;
end loop; begin
if Size > Max_Size then
Size := Max_Size;
end if;
end;
Dst_Last_As_Int := First + Size - 1; declare
Dst_Last := Index_Type (Dst_Last_As_Int); Dst_Last : constant Index_Type := Index_Type (First + Size - 1);
end if; begin
Dst := new Elements_Type (Index_Type'First .. Dst_Last);
end;
end; end;
Dst := new Elements_Type (Index_Type'First .. Dst_Last); if Before <= Container.Last then
declare
Index_As_Int : constant Int'Base :=
Index_Type'Pos (Before) + N;
declare Index : constant Index_Type := Index_Type (Index_As_Int);
Src : Elements_Type renames Container.Elements.all;
begin Src : Elements_Access := Container.Elements;
Dst (Index_Type'First .. Index_Type'Pred (Before)) :=
Src (Index_Type'First .. Index_Type'Pred (Before));
Dst (Index .. New_Last) := Src (Before .. Container.Last); begin
end; Dst (Index_Type'First .. Before - 1) :=
Src (Index_Type'First .. Before - 1);
declare Dst (Index .. New_Last) := Src (Before .. Container.Last);
X : Elements_Access := Container.Elements;
begin
Container.Elements := Dst;
Container.Last := New_Last;
Free (X); Container.Elements := Dst;
end; Container.Last := New_Last;
Free (Src);
for J in Before .. Index - 1 loop
Dst (J) := new Element_Type'(New_Item);
end loop;
end;
-- NOTE: else
-- Now do the allocation. If the allocation fails, declare
-- then the worst thing is that we have a few null slots. Src : Elements_Access := Container.Elements;
-- Our invariants are otherwise satisfied.
-- END NOTE.
for J in Before .. Index_Type'Pred (Index) loop begin
Dst (J) := new Element_Type'(New_Item); Dst (Index_Type'First .. Container.Last) :=
end loop; Src (Index_Type'First .. Container.Last);
Container.Elements := Dst;
Free (Src);
for J in Before .. New_Last loop
Dst (J) := new Element_Type'(New_Item);
Container.Last := J;
end loop;
end;
end if;
end Insert; end Insert;
procedure Insert procedure Insert
...@@ -1157,29 +1208,26 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1157,29 +1208,26 @@ package body Ada.Containers.Indefinite_Vectors is
Insert_Space (Container, Before, Count => N); Insert_Space (Container, Before, Count => N);
if Container'Address = New_Item'Address then declare
declare Dst_Last_As_Int : constant Int'Base :=
Dst_Last_As_Int : constant Int'Base := Int'Base (Before) + Int'Base (N) - 1;
Int'Base (Before) + Int'Base (N) - 1;
Dst_Last : constant Index_Type := Index_Type (Dst_Last_As_Int); Dst_Last : constant Index_Type := Index_Type (Dst_Last_As_Int);
Dst_Index : Index_Type'Base := Index_Type'Pred (Before); Dst : Elements_Type renames
Container.Elements (Before .. Dst_Last);
Dst : Elements_Type renames Dst_Index : Index_Type'Base := Before - 1;
Container.Elements (Before .. Dst_Last);
begin begin
if Container'Address /= New_Item'Address then
declare declare
subtype Src_Index_Subtype is Index_Type'Base range
Index_Type'First .. Index_Type'Pred (Before);
Src : Elements_Type renames Src : Elements_Type renames
Container.Elements (Src_Index_Subtype); New_Item.Elements (Index_Type'First .. New_Item.Last);
begin begin
for Src_Index in Src'Range loop for Src_Index in Src'Range loop
Dst_Index := Index_Type'Succ (Dst_Index); Dst_Index := Dst_Index + 1;
if Src (Src_Index) /= null then if Src (Src_Index) /= null then
Dst (Dst_Index) := new Element_Type'(Src (Src_Index).all); Dst (Dst_Index) := new Element_Type'(Src (Src_Index).all);
...@@ -1187,49 +1235,47 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1187,49 +1235,47 @@ package body Ada.Containers.Indefinite_Vectors is
end loop; end loop;
end; end;
declare return;
subtype Src_Index_Subtype is Index_Type'Base range end if;
Index_Type'Succ (Dst_Last) .. Container.Last;
Src : Elements_Type renames declare
Container.Elements (Src_Index_Subtype); subtype Src_Index_Subtype is Index_Type'Base range
Index_Type'First .. Before - 1;
begin Src : Elements_Type renames
for Src_Index in Src'Range loop Container.Elements (Src_Index_Subtype);
Dst_Index := Index_Type'Succ (Dst_Index);
if Src (Src_Index) /= null then begin
Dst (Dst_Index) := new Element_Type'(Src (Src_Index).all); for Src_Index in Src'Range loop
end if; Dst_Index := Dst_Index + 1;
end loop;
end;
end;
else if Src (Src_Index) /= null then
declare Dst (Dst_Index) := new Element_Type'(Src (Src_Index).all);
Dst_Last_As_Int : constant Int'Base := end if;
Int'Base (Before) + Int'Base (N) - 1; end loop;
end;
Dst_Last : constant Index_Type := Index_Type (Dst_Last_As_Int); if Dst_Last = Container.Last then
return;
end if;
Dst_Index : Index_Type'Base := Index_Type'Pred (Before); declare
subtype Src_Index_Subtype is Index_Type'Base range
Dst_Last + 1 .. Container.Last;
Src : Elements_Type renames Src : Elements_Type renames
New_Item.Elements (Index_Type'First .. New_Item.Last); Container.Elements (Src_Index_Subtype);
Dst : Elements_Type renames
Container.Elements (Before .. Dst_Last);
begin begin
for Src_Index in Src'Range loop for Src_Index in Src'Range loop
Dst_Index := Index_Type'Succ (Dst_Index); Dst_Index := Dst_Index + 1;
if Src (Src_Index) /= null then if Src (Src_Index) /= null then
Dst (Dst_Index) := new Element_Type'(Src (Src_Index).all); Dst (Dst_Index) := new Element_Type'(Src (Src_Index).all);
end if; end if;
end loop; end loop;
end; end;
end;
end if;
end Insert; end Insert;
procedure Insert procedure Insert
...@@ -1253,7 +1299,12 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1253,7 +1299,12 @@ package body Ada.Containers.Indefinite_Vectors is
if Before.Container = null if Before.Container = null
or else Before.Index > Container.Last or else Before.Index > Container.Last
then then
Index := Index_Type'Succ (Container.Last); if Container.Last = Index_Type'Last then
raise Constraint_Error;
end if;
Index := Container.Last + 1;
else else
Index := Before.Index; Index := Before.Index;
end if; end if;
...@@ -1291,7 +1342,12 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1291,7 +1342,12 @@ package body Ada.Containers.Indefinite_Vectors is
if Before.Container = null if Before.Container = null
or else Before.Index > Container.Last or else Before.Index > Container.Last
then then
Index := Index_Type'Succ (Container.Last); if Container.Last = Index_Type'Last then
raise Constraint_Error;
end if;
Index := Container.Last + 1;
else else
Index := Before.Index; Index := Before.Index;
end if; end if;
...@@ -1323,7 +1379,12 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1323,7 +1379,12 @@ package body Ada.Containers.Indefinite_Vectors is
if Before.Container = null if Before.Container = null
or else Before.Index > Container.Last or else Before.Index > Container.Last
then then
Index := Index_Type'Succ (Container.Last); if Container.Last = Index_Type'Last then
raise Constraint_Error;
end if;
Index := Container.Last + 1;
else else
Index := Before.Index; Index := Before.Index;
end if; end if;
...@@ -1362,7 +1423,12 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1362,7 +1423,12 @@ package body Ada.Containers.Indefinite_Vectors is
if Before.Container = null if Before.Container = null
or else Before.Index > Container.Last or else Before.Index > Container.Last
then then
Index := Index_Type'Succ (Container.Last); if Container.Last = Index_Type'Last then
raise Constraint_Error;
end if;
Index := Container.Last + 1;
else else
Index := Before.Index; Index := Before.Index;
end if; end if;
...@@ -1386,10 +1452,7 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1386,10 +1452,7 @@ package body Ada.Containers.Indefinite_Vectors is
New_Last_As_Int : Int'Base; New_Last_As_Int : Int'Base;
New_Last : Index_Type; New_Last : Index_Type;
Index : Extended_Index; -- TODO: see a-convec.adb. Dst : Elements_Access;
Dst_Last : Index_Type;
Dst : Elements_Access;
begin begin
if Before < Index_Type'First then if Before < Index_Type'First then
...@@ -1411,6 +1474,11 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1411,6 +1474,11 @@ package body Ada.Containers.Indefinite_Vectors is
begin begin
New_Last_As_Int := Old_Last_As_Int + N; New_Last_As_Int := Old_Last_As_Int + N;
if New_Last_As_Int > Index_Type'Pos (Index_Type'Last) then
raise Constraint_Error;
end if;
New_Last := Index_Type (New_Last_As_Int); New_Last := Index_Type (New_Last_As_Int);
end; end;
...@@ -1418,90 +1486,98 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1418,90 +1486,98 @@ package body Ada.Containers.Indefinite_Vectors is
raise Program_Error; raise Program_Error;
end if; end if;
declare
Old_First_As_Int : constant Int := Int (Before);
New_First_As_Int : constant Int'Base := Old_First_As_Int + N;
begin
Index := Extended_Index (New_First_As_Int); -- TODO
end;
if Container.Elements = null then if Container.Elements = null then
declare Container.Elements :=
subtype Elements_Subtype is new Elements_Type (Index_Type'First .. New_Last);
Elements_Type (Index_Type'First .. New_Last);
begin
Container.Elements := new Elements_Subtype;
Container.Last := New_Last;
end;
Container.Last := New_Last;
return; return;
end if; end if;
if New_Last <= Container.Elements'Last then if New_Last <= Container.Elements'Last then
declare declare
E : Elements_Type renames Container.Elements.all; E : Elements_Type renames Container.Elements.all;
begin begin
E (Index .. New_Last) := E (Before .. Container.Last); if Before <= Container.Last then
E (Before .. Index_Type'Pred (Index)) := (others => null); declare
Index_As_Int : constant Int'Base :=
Index_Type'Pos (Before) + N;
Container.Last := New_Last; Index : constant Index_Type := Index_Type (Index_As_Int);
begin
E (Index .. New_Last) := E (Before .. Container.Last);
E (Before .. Index - 1) := (others => null);
end;
end if;
end; end;
Container.Last := New_Last;
return; return;
end if; end if;
declare declare
First : constant Int := Int (Index_Type'First); First : constant Int := Int (Index_Type'First);
New_Size : constant Int'Base := New_Last_As_Int - First + 1;
New_Size : constant Int'Base := Size : Int'Base := Int'Max (1, Container.Elements'Length);
Int (New_Last_As_Int) - First + 1;
Max_Size : constant Int'Base :=
Int (Index_Type'Last) - First + 1;
Size, Dst_Last_As_Int : Int'Base;
begin begin
if New_Size >= Max_Size / 2 then while Size < New_Size loop
Dst_Last := Index_Type'Last; if Size > Int'Last / 2 then
Size := Int'Last;
exit;
end if;
else Size := 2 * Size;
Size := Container.Elements'Length; end loop;
if Size = 0 then -- TODO: The following calculations aren't quite right, since
Size := 1; -- there will be overflow if Index_Type'Range is very large
end if; -- (e.g. this package is instantiated with a 64-bit integer).
-- END TODO.
while Size < New_Size loop declare
Size := 2 * Size; Max_Size : constant Int'Base := Int (Index_Type'Last) - First + 1;
end loop; begin
if Size > Max_Size then
Size := Max_Size;
end if;
end;
Dst_Last_As_Int := First + Size - 1; declare
Dst_Last := Index_Type (Dst_Last_As_Int); Dst_Last : constant Index_Type := Index_Type (First + Size - 1);
end if; begin
Dst := new Elements_Type (Index_Type'First .. Dst_Last);
end;
end; end;
Dst := new Elements_Type (Index_Type'First .. Dst_Last);
declare declare
Src : Elements_Type renames Container.Elements.all; Src : Elements_Access := Container.Elements;
begin begin
Dst (Index_Type'First .. Index_Type'Pred (Before)) := if Before <= Container.Last then
Src (Index_Type'First .. Index_Type'Pred (Before)); 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);
end;
begin
Dst (Index_Type'First .. Before - 1) :=
Src (Index_Type'First .. Before - 1);
Dst (Index .. New_Last) := Src (Before .. Container.Last);
end;
else
Dst (Index_Type'First .. Container.Last) :=
Src (Index_Type'First .. Container.Last);
end if;
declare
X : Elements_Access := Container.Elements;
begin
Container.Elements := Dst; Container.Elements := Dst;
Container.Last := New_Last; Container.Last := New_Last;
Free (Src);
Free (X);
end; end;
end Insert_Space; end Insert_Space;
...@@ -1535,7 +1611,12 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1535,7 +1611,12 @@ package body Ada.Containers.Indefinite_Vectors is
if Before.Container = null if Before.Container = null
or else Before.Index > Container.Last or else Before.Index > Container.Last
then then
Index := Index_Type'Succ (Container.Last); if Container.Last = Index_Type'Last then
raise Constraint_Error;
end if;
Index := Container.Last + 1;
else else
Index := Before.Index; Index := Before.Index;
end if; end if;
...@@ -1620,7 +1701,12 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1620,7 +1701,12 @@ package body Ada.Containers.Indefinite_Vectors is
L : constant Int := Int (Container.Last); L : constant Int := Int (Container.Last);
F : constant Int := Int (Index_Type'First); F : constant Int := Int (Index_Type'First);
N : constant Int'Base := L - F + 1; N : constant Int'Base := L - F + 1;
begin begin
if N > Count_Type'Pos (Count_Type'Last) then
raise Constraint_Error;
end if;
return Count_Type (N); return Count_Type (N);
end Length; end Length;
...@@ -1644,16 +1730,13 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1644,16 +1730,13 @@ package body Ada.Containers.Indefinite_Vectors is
Clear (Target); Clear (Target);
declare declare
X : Elements_Access := Target.Elements; Target_Elements : constant Elements_Access := Target.Elements;
begin begin
Target.Elements := null; Target.Elements := Source.Elements;
Free (X); Source.Elements := Target_Elements;
end; end;
Target.Elements := Source.Elements;
Target.Last := Source.Last; Target.Last := Source.Last;
Source.Elements := null;
Source.Last := No_Index; Source.Last := No_Index;
end Move; end Move;
...@@ -1668,7 +1751,7 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1668,7 +1751,7 @@ package body Ada.Containers.Indefinite_Vectors is
end if; end if;
if Position.Index < Position.Container.Last then if Position.Index < Position.Container.Last then
return (Position.Container, Index_Type'Succ (Position.Index)); return (Position.Container, Position.Index + 1);
end if; end if;
return No_Element; return No_Element;
...@@ -1685,7 +1768,7 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1685,7 +1768,7 @@ package body Ada.Containers.Indefinite_Vectors is
end if; end if;
if Position.Index < Position.Container.Last then if Position.Index < Position.Container.Last then
Position.Index := Index_Type'Succ (Position.Index); Position.Index := Position.Index + 1;
else else
Position := No_Element; Position := No_Element;
end if; end if;
...@@ -1723,7 +1806,7 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1723,7 +1806,7 @@ package body Ada.Containers.Indefinite_Vectors is
end if; end if;
if Position.Index > Index_Type'First then if Position.Index > Index_Type'First then
Position.Index := Index_Type'Pred (Position.Index); Position.Index := Position.Index - 1;
else else
Position := No_Element; Position := No_Element;
end if; end if;
...@@ -1736,7 +1819,7 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1736,7 +1819,7 @@ package body Ada.Containers.Indefinite_Vectors is
end if; end if;
if Position.Index > Index_Type'First then if Position.Index > Index_Type'First then
return (Position.Container, Index_Type'Pred (Position.Index)); return (Position.Container, Position.Index - 1);
end if; end if;
return No_Element; return No_Element;
...@@ -1751,21 +1834,20 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1751,21 +1834,20 @@ package body Ada.Containers.Indefinite_Vectors is
Index : Index_Type; Index : Index_Type;
Process : not null access procedure (Element : in Element_Type)) Process : not null access procedure (Element : in Element_Type))
is is
subtype T is Index_Type'Base range
Index_Type'First .. Container.Last;
E : Element_Type renames Container.Elements (T'(Index)).all;
V : Vector renames Container'Unrestricted_Access.all; V : Vector renames Container'Unrestricted_Access.all;
B : Natural renames V.Busy; B : Natural renames V.Busy;
L : Natural renames V.Lock; L : Natural renames V.Lock;
begin begin
if Index > Container.Last then
raise Constraint_Error;
end if;
B := B + 1; B := B + 1;
L := L + 1; L := L + 1;
begin begin
Process (E); Process (V.Elements (Index).all);
exception exception
when others => when others =>
L := L - 1; L := L - 1;
...@@ -1782,6 +1864,10 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1782,6 +1864,10 @@ package body Ada.Containers.Indefinite_Vectors is
Process : not null access procedure (Element : in Element_Type)) Process : not null access procedure (Element : in Element_Type))
is is
begin begin
if Position.Container = null then
raise Constraint_Error;
end if;
Query_Element (Position.Container.all, Position.Index, Process); Query_Element (Position.Container.all, Position.Index, Process);
end Query_Element; end Query_Element;
...@@ -1808,7 +1894,7 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1808,7 +1894,7 @@ package body Ada.Containers.Indefinite_Vectors is
end if; end if;
for J in Count_Type range 1 .. Length loop for J in Count_Type range 1 .. Length loop
Last := Index_Type'Succ (Last); Last := Last + 1;
Boolean'Read (Stream, B); Boolean'Read (Stream, B);
...@@ -1830,22 +1916,29 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1830,22 +1916,29 @@ package body Ada.Containers.Indefinite_Vectors is
Index : Index_Type; Index : Index_Type;
By : Element_Type) By : Element_Type)
is is
subtype T is Index_Type'Base range
Index_Type'First .. Container.Last;
X : Element_Access := Container.Elements (T'(Index));
begin begin
if Index > Container.Last then
raise Constraint_Error;
end if;
if Container.Lock > 0 then if Container.Lock > 0 then
raise Program_Error; raise Program_Error;
end if; end if;
Container.Elements (T'(Index)) := new Element_Type'(By); declare
Free (X); X : Element_Access := Container.Elements (Index);
begin
Container.Elements (Index) := new Element_Type'(By);
Free (X);
end;
end Replace_Element; end Replace_Element;
procedure Replace_Element (Position : Cursor; By : Element_Type) is procedure Replace_Element (Position : Cursor; By : Element_Type) is
begin begin
if Position.Container = null then
raise Constraint_Error;
end if;
Replace_Element (Position.Container.all, Position.Index, By); Replace_Element (Position.Container.all, Position.Index, By);
end Replace_Element; end Replace_Element;
...@@ -1885,11 +1978,11 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1885,11 +1978,11 @@ package body Ada.Containers.Indefinite_Vectors is
Elements_Type (Array_Index_Subtype); Elements_Type (Array_Index_Subtype);
X : Elements_Access := Container.Elements; X : Elements_Access := Container.Elements;
begin begin
Container.Elements := new Array_Subtype'(Src); Container.Elements := new Array_Subtype'(Src);
Free (X); Free (X);
end; end;
end if; end if;
return; return;
...@@ -1900,14 +1993,20 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1900,14 +1993,20 @@ package body Ada.Containers.Indefinite_Vectors is
Last_As_Int : constant Int'Base := Last_As_Int : constant Int'Base :=
Int (Index_Type'First) + Int (Capacity) - 1; Int (Index_Type'First) + Int (Capacity) - 1;
Last : constant Index_Type := begin
Index_Type (Last_As_Int); if Last_As_Int > Index_Type'Pos (Index_Type'Last) then
raise Constraint_Error;
end if;
subtype Array_Subtype is declare
Elements_Type (Index_Type'First .. Last); Last : constant Index_Type := Index_Type (Last_As_Int);
begin subtype Array_Subtype is
Container.Elements := new Array_Subtype; Elements_Type (Index_Type'First .. Last);
begin
Container.Elements := new Array_Subtype;
end;
end; end;
return; return;
...@@ -1935,7 +2034,6 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1935,7 +2034,6 @@ package body Ada.Containers.Indefinite_Vectors is
Container.Elements := new Array_Subtype'(Src); Container.Elements := new Array_Subtype'(Src);
Free (X); Free (X);
end; end;
end if; end if;
return; return;
...@@ -1953,28 +2051,35 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -1953,28 +2051,35 @@ package body Ada.Containers.Indefinite_Vectors is
Last_As_Int : constant Int'Base := Last_As_Int : constant Int'Base :=
Int (Index_Type'First) + Int (Capacity) - 1; 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);
X : Elements_Access := Container.Elements;
begin begin
Container.Elements := new Array_Subtype; if Last_As_Int > Index_Type'Pos (Index_Type'Last) then
raise Constraint_Error;
end if;
declare declare
Src : Elements_Type renames Last : constant Index_Type := Index_Type (Last_As_Int);
X (Index_Type'First .. Container.Last);
Tgt : Elements_Type renames subtype Array_Subtype is
Container.Elements (Index_Type'First .. Container.Last); Elements_Type (Index_Type'First .. Last);
X : Elements_Access := Container.Elements;
begin begin
Tgt := Src; Container.Elements := new Array_Subtype;
end;
Free (X); declare
Src : Elements_Type renames
X (Index_Type'First .. Container.Last);
Tgt : Elements_Type renames
Container.Elements (Index_Type'First .. Container.Last);
begin
Tgt := Src;
end;
Free (X);
end;
end; end;
end Reserve_Capacity; end Reserve_Capacity;
...@@ -2087,42 +2192,36 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -2087,42 +2192,36 @@ package body Ada.Containers.Indefinite_Vectors is
return; return;
end if; end if;
if Length = 0 then
Clear (Container);
return;
end if;
if Container.Busy > 0 then if Container.Busy > 0 then
raise Program_Error; raise Program_Error;
end if; end if;
declare if Length < N then
Last_As_Int : constant Int'Base := for Index in 1 .. N - Length loop
Int (Index_Type'First) + Int (Length) - 1;
Last : constant Index_Type :=
Index_Type (Last_As_Int);
begin
if Length > N then
if Length > Capacity (Container) then
Reserve_Capacity (Container, Capacity => Length);
end if;
Container.Last := Last;
return;
end if;
for Indx in reverse Index_Type'Succ (Last) .. Container.Last loop
declare declare
X : Element_Access := Container.Elements (Indx); J : constant Index_Type := Container.Last;
X : Element_Access := Container.Elements (J);
begin begin
Container.Elements (Indx) := null; Container.Elements (J) := null;
Container.Last := Index_Type'Pred (Container.Last); Container.Last := J - 1;
Free (X); Free (X);
end; end;
end loop; end loop;
return;
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;
begin
Container.Last := Index_Type (Last_As_Int);
end; end;
end Set_Length; end Set_Length;
...@@ -2134,19 +2233,27 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -2134,19 +2233,27 @@ package body Ada.Containers.Indefinite_Vectors is
(Container : Vector; (Container : Vector;
I, J : Index_Type) I, J : Index_Type)
is is
subtype T is Index_Type'Base range begin
Index_Type'First .. Container.Last; if I > Container.Last
or else J > Container.Last
then
raise Constraint_Error;
end if;
EI : Element_Type renames Container.Elements (T'(I)).all; if I = J then
EJ : Element_Type renames Container.Elements (T'(J)).all; return;
end if;
begin
if Container.Lock > 0 then if Container.Lock > 0 then
raise Program_Error; raise Program_Error;
end if; end if;
declare declare
EI_Copy : constant Element_Type := EI; EI : Element_Access renames Container.Elements (I);
EJ : Element_Access renames Container.Elements (J);
EI_Copy : constant Element_Access := EI;
begin begin
EI := EJ; EI := EJ;
EJ := EI_Copy; EJ := EI_Copy;
...@@ -2215,10 +2322,17 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -2215,10 +2322,17 @@ package body Ada.Containers.Indefinite_Vectors is
declare declare
First : constant Int := Int (Index_Type'First); First : constant Int := Int (Index_Type'First);
Last_As_Int : constant Int'Base := First + Int (Length) - 1; Last_As_Int : constant Int'Base := First + Int (Length) - 1;
Last : constant Index_Type := Index_Type (Last_As_Int); Last : Index_Type;
Elements : constant Elements_Access := Elements : Elements_Access;
new Elements_Type (Index_Type'First .. Last);
begin begin
if Last_As_Int > Index_Type'Pos (Index_Type'Last) then
raise Constraint_Error;
end if;
Last := Index_Type (Last_As_Int);
Elements := new Elements_Type (Index_Type'First .. Last);
return (Controlled with Elements, Last, 0, 0); return (Controlled with Elements, Last, 0, 0);
end; end;
end To_Vector; end To_Vector;
...@@ -2235,24 +2349,34 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -2235,24 +2349,34 @@ package body Ada.Containers.Indefinite_Vectors is
declare declare
First : constant Int := Int (Index_Type'First); First : constant Int := Int (Index_Type'First);
Last_As_Int : constant Int'Base := First + Int (Length) - 1; Last_As_Int : constant Int'Base := First + Int (Length) - 1;
Last : constant Index_Type := Index_Type (Last_As_Int); Last : Index_Type'Base;
Elements : Elements_Access := Elements : Elements_Access;
new Elements_Type (Index_Type'First .. Last);
begin begin
for Indx in Elements'Range loop if Last_As_Int > Index_Type'Pos (Index_Type'Last) then
begin raise Constraint_Error;
Elements (Indx) := new Element_Type'(New_Item); end if;
exception
when others =>
for J in Index_Type'First .. Index_Type'Pred (Indx) loop
Free (Elements (J));
end loop;
Free (Elements); Last := Index_Type (Last_As_Int);
raise; Elements := new Elements_Type (Index_Type'First .. Last);
end;
end loop; Last := Index_Type'First;
begin
loop
Elements (Last) := new Element_Type'(New_Item);
exit when Last = Elements'Last;
Last := Last + 1;
end loop;
exception
when others =>
for J in Index_Type'First .. Last - 1 loop
Free (Elements (J));
end loop;
Free (Elements);
raise;
end;
return (Controlled with Elements, Last, 0, 0); return (Controlled with Elements, Last, 0, 0);
end; end;
...@@ -2267,21 +2391,20 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -2267,21 +2391,20 @@ package body Ada.Containers.Indefinite_Vectors is
Index : Index_Type; Index : Index_Type;
Process : not null access procedure (Element : in out Element_Type)) Process : not null access procedure (Element : in out Element_Type))
is is
subtype T is Index_Type'Base range
Index_Type'First .. Container.Last;
E : Element_Type renames Container.Elements (T'(Index)).all;
V : Vector renames Container'Unrestricted_Access.all; V : Vector renames Container'Unrestricted_Access.all;
B : Natural renames V.Busy; B : Natural renames V.Busy;
L : Natural renames V.Lock; L : Natural renames V.Lock;
begin begin
if Index > Container.Last then
raise Constraint_Error;
end if;
B := B + 1; B := B + 1;
L := L + 1; L := L + 1;
begin begin
Process (E); Process (V.Elements (Index).all);
exception exception
when others => when others =>
L := L - 1; L := L - 1;
...@@ -2298,6 +2421,10 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -2298,6 +2421,10 @@ package body Ada.Containers.Indefinite_Vectors is
Process : not null access procedure (Element : in out Element_Type)) Process : not null access procedure (Element : in out Element_Type))
is is
begin begin
if Position.Container = null then
raise Constraint_Error;
end if;
Update_Element (Position.Container.all, Position.Index, Process); Update_Element (Position.Container.all, Position.Index, Process);
end Update_Element; end Update_Element;
...@@ -2327,9 +2454,7 @@ package body Ada.Containers.Indefinite_Vectors is ...@@ -2327,9 +2454,7 @@ package body Ada.Containers.Indefinite_Vectors is
-- There's another way to do this. Instead a separate -- There's another way to do this. Instead a separate
-- Boolean for each element, you could write a Boolean -- Boolean for each element, you could write a Boolean
-- followed by a count of how many nulls or non-nulls -- followed by a count of how many nulls or non-nulls
-- follow in the array. Alternately you could use a -- follow in the array.
-- signed integer, and use the sign as the indicator
-- of null-ness.
if E (Indx) = null then if E (Indx) = null then
Boolean'Write (Stream, False); Boolean'Write (Stream, False);
......
...@@ -48,8 +48,7 @@ pragma Preelaborate (Indefinite_Vectors); ...@@ -48,8 +48,7 @@ pragma Preelaborate (Indefinite_Vectors);
subtype Extended_Index is Index_Type'Base subtype Extended_Index is Index_Type'Base
range Index_Type'First - 1 .. range Index_Type'First - 1 ..
Index_Type'Last + Index_Type'Min (Index_Type'Base'Last - 1, Index_Type'Last) + 1;
Boolean'Pos (Index_Type'Base'Last > Index_Type'Last);
No_Index : constant Extended_Index := Extended_Index'First; No_Index : constant Extended_Index := Extended_Index'First;
......
...@@ -46,8 +46,7 @@ pragma Preelaborate (Vectors); ...@@ -46,8 +46,7 @@ pragma Preelaborate (Vectors);
subtype Extended_Index is Index_Type'Base subtype Extended_Index is Index_Type'Base
range Index_Type'First - 1 .. range Index_Type'First - 1 ..
Index_Type'Last + Index_Type'Min (Index_Type'Base'Last - 1, Index_Type'Last) + 1;
Boolean'Pos (Index_Type'Base'Last > Index_Type'Last);
No_Index : constant Extended_Index := Extended_Index'First; No_Index : constant Extended_Index := Extended_Index'First;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment