(Object : Iterator;
Position : Cursor) return Cursor;
+ procedure Append_Slow_Path
+ (Container : in out Vector;
+ New_Item : Element_Type;
+ Count : Count_Type);
+ -- This is the slow path for Append. This is split out to minimize the size
+ -- of Append, because we have Inline (Append).
+
---------
-- "&" --
---------
Elements : constant Elements_Access :=
new Elements_Type'(Right.Last, RE);
begin
- return (Controlled with Elements, Right.Last, 0, 0);
+ return (Controlled with Elements, Right.Last, others => <>);
end;
end if;
Elements : constant Elements_Access :=
new Elements_Type'(Left.Last, LE);
begin
- return (Controlled with Elements, Left.Last, 0, 0);
+ return (Controlled with Elements, Left.Last, others => <>);
end;
end if;
-- exceed Index_Type'Last. We use the wider of Index_Type'Base and
-- Count_Type'Base as the type for intermediate values.
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
-- We perform a two-part test. First we determine whether the
-- computed Last value lies in the base range of the type, and then
Elements : constant Elements_Access :=
new Elements_Type'(Last, LE & RE);
begin
- return (Controlled with Elements, Last, 0, 0);
+ return (Controlled with Elements, Last, others => <>);
end;
end "&";
EA => (others => Right));
begin
- return (Controlled with Elements, Index_Type'First, 0, 0);
+ return (Controlled with Elements, Index_Type'First, others => <>);
end;
end if;
Elements : constant Elements_Access :=
new Elements_Type'(Last => Last, EA => LE & Right);
begin
- return (Controlled with Elements, Last, 0, 0);
+ return (Controlled with Elements, Last, others => <>);
end;
end "&";
(Last => Index_Type'First,
EA => (others => Left));
begin
- return (Controlled with Elements, Index_Type'First, 0, 0);
+ return (Controlled with Elements, Index_Type'First, others => <>);
end;
end if;
EA => Left & RE);
begin
- return (Controlled with Elements, Last, 0, 0);
+ return (Controlled with Elements, Last, others => <>);
end;
end "&";
EA => (Left, Right));
begin
- return (Controlled with Elements, Last, 0, 0);
+ return (Controlled with Elements, Last, others => <>);
end;
end "&";
Count : Count_Type := 1)
is
begin
+ -- In the general case, we pass the buck to Insert, but for efficiency,
+ -- we check for the usual case where Count = 1 and the vector has enough
+ -- room for at least one more element.
+
+ if Count = 1
+ and then Container.Elements /= null
+ and then Container.Last /= Container.Elements.Last
+ then
+ if Container.Busy > 0 then
+ raise Program_Error with
+ "attempt to tamper with cursors (vector is busy)";
+ end if;
+
+ -- Increment Container.Last after assigning the New_Item, so we
+ -- leave the Container unmodified in case Finalize/Adjust raises
+ -- an exception.
+
+ declare
+ New_Last : constant Index_Type := Container.Last + 1;
+ begin
+ Container.Elements.EA (New_Last) := New_Item;
+ Container.Last := New_Last;
+ end;
+
+ else
+ Append_Slow_Path (Container, New_Item, Count);
+ end if;
+ end Append;
+
+ ----------------------
+ -- Append_Slow_Path --
+ ----------------------
+
+ procedure Append_Slow_Path
+ (Container : in out Vector;
+ New_Item : Element_Type;
+ Count : Count_Type)
+ is
+ begin
if Count = 0 then
return;
elsif Container.Last = Index_Type'Last then
else
Insert (Container, Container.Last + 1, New_Item, Count);
end if;
- end Append;
+ end Append_Slow_Path;
------------
-- Assign --
-- index value New_Last is the last index value of their new home, and
-- index value J is the first index of their old home.
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
New_Last := Old_Last - Index_Type'Base (Count);
J := Index + Index_Type'Base (Count);
else
if Count >= Container.Length then
Container.Last := No_Index;
- elsif Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ elsif Index_Type'Base'Last >= Count_Type_Last then
Container.Last := Container.Last - Index_Type'Base (Count);
else
X : Elements_Access := Container.Elements;
begin
+ Container.Elements := null;
+ Container.Last := No_Index;
+
+ Free (X);
+
if Container.Busy > 0 then
raise Program_Error with
"attempt to tamper with cursors (vector is busy)";
-
- else
- Container.Elements := null;
- Container.Last := No_Index;
- Free (X);
end if;
end Finalize;
-- deeper flaw in the caller's algorithm, so that case is treated as a
-- proper error.)
- if Before > Container.Last and then Before > Container.Last + 1 then
+ if Before > Container.Last + 1 then
raise Constraint_Error with
"Before index is out of range (too large)";
end if;
-- compare the new length to the maximum length. If the new length is
-- acceptable, then we compute the new last index from that.
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
-- We have to handle the case when there might be more values in the
-- range of Index_Type than in the range of Count_Type.
-- worry about if No_Index were less than 0, but that case is
-- handled above).
- if Index_Type'Last - No_Index >=
- Count_Type'Pos (Count_Type'Last)
- then
+ if Index_Type'Last - No_Index >= Count_Type_Last then
+
-- We have determined that range of Index_Type has at least as
-- many values as in Count_Type, so Count_Type'Last is the
-- maximum number of items that are allowed.
-- insertion. Use the wider of Index_Type'Base and Count_Type'Base to
-- compute its value from the New_Length.
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
New_Last := No_Index + Index_Type'Base (New_Length);
else
New_Last := Index_Type'Base (Count_Type'Base (No_Index) + New_Length);
-- new home. We use the wider of Index_Type'Base and
-- Count_Type'Base as the type for intermediate index values.
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
Index := Before + Index_Type'Base (Count);
else
Index := Index_Type'Base (Count_Type'Base (Before) + Count);
-- We have computed the length of the new internal array (and this is
-- what "vector capacity" means), so use that to compute its last index.
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
Dst_Last := No_Index + Index_Type'Base (New_Capacity);
else
Dst_Last :=
-- The new items are being inserted before some existing elements,
-- so we must slide the existing elements up to their new home.
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
Index := Before + Index_Type'Base (Count);
else
Index := Index_Type'Base (Count_Type'Base (Before) + Count);
-- We calculate the last index value of the destination slice using the
-- wider of Index_Type'Base and count_Type'Base.
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
J := (Before - 1) + Index_Type'Base (N);
else
J := Index_Type'Base (Count_Type'Base (Before - 1) + N);
-- equals Index_Type'First, then this first source slice will be
-- empty, which is harmless.)
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
K := L + Index_Type'Base (Src'Length);
else
K := Index_Type'Base (Count_Type'Base (L) + Src'Length);
-- destination that receives this slice of the source. (For the
-- reasons given above, this slice is guaranteed to be non-empty.)
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
K := F - Index_Type'Base (Src'Length);
else
K := Index_Type'Base (Count_Type'Base (F) - Src'Length);
-- deeper flaw in the caller's algorithm, so that case is treated as a
-- proper error.)
- if Before > Container.Last and then Before > Container.Last + 1 then
+ if Before > Container.Last + 1 then
raise Constraint_Error with
"Before index is out of range (too large)";
end if;
-- compare the new length to the maximum length. If the new length is
-- acceptable, then we compute the new last index from that.
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
-- We have to handle the case when there might be more values in the
-- range of Index_Type than in the range of Count_Type.
-- worry about if No_Index were less than 0, but that case is
-- handled above).
- if Index_Type'Last - No_Index >=
- Count_Type'Pos (Count_Type'Last)
- then
+ if Index_Type'Last - No_Index >= Count_Type_Last then
+
-- We have determined that range of Index_Type has at least as
-- many values as in Count_Type, so Count_Type'Last is the
-- maximum number of items that are allowed.
-- insertion. Use the wider of Index_Type'Base and Count_Type'Base to
-- compute its value from the New_Length.
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
New_Last := No_Index + Index_Type'Base (New_Length);
else
New_Last := Index_Type'Base (Count_Type'Base (No_Index) + New_Length);
-- home. We use the wider of Index_Type'Base and
-- Count_Type'Base as the type for intermediate index values.
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
Index := Before + Index_Type'Base (Count);
else
-- We have computed the length of the new internal array (and this is
-- what "vector capacity" means), so use that to compute its last index.
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
Dst_Last := No_Index + Index_Type'Base (New_Capacity);
else
Dst_Last :=
-- The space is being inserted before some existing elements, so
-- we must slide the existing elements up to their new home.
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
Index := Before + Index_Type'Base (Count);
else
Index := Index_Type'Base (Count_Type'Base (Before) + Count);
-- the Last index value of the new internal array, in a way that avoids
-- any possibility of overflow.
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
-- We perform a two-part test. First we determine whether the
-- computed Last value lies in the base range of the type, and then
-- index). We must therefore check whether the specified Length would
-- create a Last index value greater than Index_Type'Last.
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
-- We perform a two-part test. First we determine whether the
-- computed Last value lies in the base range of the type, and then
Elements := new Elements_Type (Last);
- return Vector'(Controlled with Elements, Last, 0, 0);
+ return Vector'(Controlled with Elements, Last, others => <>);
end To_Vector;
function To_Vector
-- index). We must therefore check whether the specified Length would
-- create a Last index value greater than Index_Type'Last.
- if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
+ if Index_Type'Base'Last >= Count_Type_Last then
-- We perform a two-part test. First we determine whether the
-- computed Last value lies in the base range of the type, and then
Elements := new Elements_Type'(Last, EA => (others => New_Item));
- return Vector'(Controlled with Elements, Last, 0, 0);
+ return Vector'(Controlled with Elements, Last, others => <>);
end To_Vector;
--------------------