summaryrefslogtreecommitdiff
path: root/gcc/ada/a-coinve.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/a-coinve.adb')
-rw-r--r--gcc/ada/a-coinve.adb137
1 files changed, 111 insertions, 26 deletions
diff --git a/gcc/ada/a-coinve.adb b/gcc/ada/a-coinve.adb
index dca166f495b..fed45faddda 100644
--- a/gcc/ada/a-coinve.adb
+++ b/gcc/ada/a-coinve.adb
@@ -44,7 +44,7 @@ package body Ada.Containers.Indefinite_Vectors is
Vector_Iterator_Interfaces.Reversible_Iterator with
record
Container : Vector_Access;
- Index : Index_Type;
+ Index : Index_Type'Base;
end record;
overriding procedure Finalize (Object : in out Iterator);
@@ -1109,14 +1109,9 @@ package body Ada.Containers.Indefinite_Vectors is
end Finalize;
procedure Finalize (Object : in out Iterator) is
+ B : Natural renames Object.Container.Busy;
begin
- if Object.Container /= null then
- declare
- B : Natural renames Object.Container.all.Busy;
- begin
- B := B - 1;
- end;
- end if;
+ B := B - 1;
end Finalize;
----------
@@ -1185,9 +1180,26 @@ package body Ada.Containers.Indefinite_Vectors is
end First;
function First (Object : Iterator) return Cursor is
- C : constant Cursor := (Object.Container, Index_Type'First);
begin
- return C;
+ -- The value of the iterator object's Index component influences the
+ -- behavior of the First (and Last) selector function.
+
+ -- When the Index component is No_Index, this means the iterator object
+ -- was constructed without a start expression, in which case the
+ -- (forward) iteration starts from the (logical) beginning of the entire
+ -- sequence of items (corresponding to Container.First, for a forward
+ -- iterator).
+
+ -- Otherwise, this is iteration over a partial sequence of items. When
+ -- the Index component isn't No_Index, the iterator object was
+ -- constructed with a start expression, that specifies the position from
+ -- which the (forward) partial iteration begins.
+
+ if Object.Index = No_Index then
+ return First (Object.Container.all);
+ else
+ return Cursor'(Object.Container, Object.Index);
+ end if;
end First;
-------------------
@@ -2552,15 +2564,26 @@ package body Ada.Containers.Indefinite_Vectors is
end Iterate;
function Iterate (Container : Vector)
- return Vector_Iterator_Interfaces.Reversible_Iterator'class
+ return Vector_Iterator_Interfaces.Reversible_Iterator'Class
is
- B : Natural renames Container'Unrestricted_Access.all.Busy;
+ V : constant Vector_Access := Container'Unrestricted_Access;
+ B : Natural renames V.Busy;
begin
+ -- The value of its Index component influences the behavior of the First
+ -- and Last selector functions of the iterator object. When the Index
+ -- component is No_Index (as is the case here), this means the iterator
+ -- object was constructed without a start expression. This is a complete
+ -- iterator, meaning that the iteration starts from the (logical)
+ -- beginning of the sequence of items.
+
+ -- Note: For a forward iterator, Container.First is the beginning, and
+ -- for a reverse iterator, Container.Last is the beginning.
+
return It : constant Iterator :=
(Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Index => Index_Type'First)
+ Container => V,
+ Index => No_Index)
do
B := B + 1;
end return;
@@ -2569,14 +2592,50 @@ package body Ada.Containers.Indefinite_Vectors is
function Iterate
(Container : Vector;
Start : Cursor)
- return Vector_Iterator_Interfaces.Reversible_Iterator'class
+ return Vector_Iterator_Interfaces.Reversible_Iterator'Class
is
- B : Natural renames Container'Unrestricted_Access.all.Busy;
+ V : constant Vector_Access := Container'Unrestricted_Access;
+ B : Natural renames V.Busy;
begin
+ -- It was formerly the case that when Start = No_Element, the partial
+ -- iterator was defined to behave the same as for a complete iterator,
+ -- and iterate over the entire sequence of items. However, those
+ -- semantics were unintuitive and arguably error-prone (it is too easy
+ -- to accidentally create an endless loop), and so they were changed,
+ -- per the ARG meeting in Denver on 2011/11. However, there was no
+ -- consensus about what positive meaning this corner case should have,
+ -- and so it was decided to simply raise an exception. This does imply,
+ -- however, that it is not possible to use a partial iterator to specify
+ -- an empty sequence of items.
+
+ if Start.Container = null then
+ raise Constraint_Error with
+ "Start position for iterator equals No_Element";
+ end if;
+
+ if Start.Container /= V then
+ raise Program_Error with
+ "Start cursor of Iterate designates wrong vector";
+ end if;
+
+ if Start.Index > V.Last then
+ raise Constraint_Error with
+ "Start position for iterator equals No_Element";
+ end if;
+
+ -- The value of its Index component influences the behavior of the First
+ -- and Last selector functions of the iterator object. When the Index
+ -- component is not No_Index (as is the case here), it means that this
+ -- is a partial iteration, over a subset of the complete sequence of
+ -- items. The iterator object was constructed with a start expression,
+ -- indicating the position from which the iteration begins. Note that
+ -- the start position has the same value irrespective of whether this is
+ -- a forward or reverse iteration.
+
return It : constant Iterator :=
(Limited_Controlled with
- Container => Container'Unrestricted_Access,
+ Container => V,
Index => Start.Index)
do
B := B + 1;
@@ -2597,9 +2656,25 @@ package body Ada.Containers.Indefinite_Vectors is
end Last;
function Last (Object : Iterator) return Cursor is
- C : constant Cursor := (Object.Container, Object.Container.Last);
begin
- return C;
+ -- The value of the iterator object's Index component influences the
+ -- behavior of the Last (and First) selector function.
+
+ -- When the Index component is No_Index, this means the iterator object
+ -- was constructed without a start expression, in which case the
+ -- (reverse) iteration starts from the (logical) beginning of the entire
+ -- sequence (corresponding to Container.Last, for a reverse iterator).
+
+ -- Otherwise, this is iteration over a partial sequence of items. When
+ -- the Index component is not No_Index, the iterator object was
+ -- constructed with a start expression, that specifies the position from
+ -- which the (reverse) partial iteration begins.
+
+ if Object.Index = No_Index then
+ return Last (Object.Container.all);
+ else
+ return Cursor'(Object.Container, Object.Index);
+ end if;
end Last;
-----------------
@@ -2718,11 +2793,16 @@ package body Ada.Containers.Indefinite_Vectors is
function Next (Object : Iterator; Position : Cursor) return Cursor is
begin
- if Position.Index = Object.Container.Last then
- return No_Element;
- else
- return (Object.Container, Position.Index + 1);
+ if Position.Container = null then
+ return No_Element;
end if;
+
+ if Position.Container /= Object.Container then
+ raise Program_Error with
+ "Position cursor of Next designates wrong vector";
+ end if;
+
+ return Next (Position);
end Next;
procedure Next (Position : in out Cursor) is
@@ -2791,11 +2871,16 @@ package body Ada.Containers.Indefinite_Vectors is
function Previous (Object : Iterator; Position : Cursor) return Cursor is
begin
- if Position.Index > Index_Type'First then
- return (Object.Container, Position.Index - 1);
- else
+ if Position.Container = null then
return No_Element;
end if;
+
+ if Position.Container /= Object.Container then
+ raise Program_Error with
+ "Position cursor of Previous designates wrong vector";
+ end if;
+
+ return Previous (Position);
end Previous;
-------------------