diff options
Diffstat (limited to 'gcc/ada/a-coinve.adb')
-rw-r--r-- | gcc/ada/a-coinve.adb | 137 |
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; ------------------- |