diff options
author | Arnaud Charlet <charlet@gcc.gnu.org> | 2011-11-23 12:04:39 +0100 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2011-11-23 12:04:39 +0100 |
commit | f947ee3467dee8ca1b681c459804b02657113e9d (patch) | |
tree | 5fb6c077b0e3f24d74204d0e539e282bdb998d66 /gcc/ada/a-cborma.adb | |
parent | fb2bd3a70d29393806e9c21c9568de1170fee9f9 (diff) | |
download | gcc-f947ee3467dee8ca1b681c459804b02657113e9d.tar.gz |
[multiple changes]
2011-11-23 Ed Schonberg <schonberg@adacore.com>
* exp_ch5.adb (Expand_Iterator_Loop): Wrap the expanded loop
and the cursor declarations in a block, so that the loop variable
is local to the construct.
2011-11-23 Matthew Heaney <heaney@adacore.com>
* a-coorma.ads, a-ciorma.ads, a-cborma.ads (Iterate): Returns
type Reversible_Iterator'Class.
* a-coorma.adb, a-ciorma.adb, a-cborma.adb (Iterator):
Declare type as limited.
(First, Last): Return value depends on iterator's start node value.
(Next, Previous): Call corresponding Cursor-based operation.
(Iterate): Indicate whether complete or partial iteration
From-SVN: r181659
Diffstat (limited to 'gcc/ada/a-cborma.adb')
-rw-r--r-- | gcc/ada/a-cborma.adb | 116 |
1 files changed, 98 insertions, 18 deletions
diff --git a/gcc/ada/a-cborma.adb b/gcc/ada/a-cborma.adb index 4cc2686bb22..940d6efa9cb 100644 --- a/gcc/ada/a-cborma.adb +++ b/gcc/ada/a-cborma.adb @@ -39,7 +39,7 @@ with System; use type System.Address; package body Ada.Containers.Bounded_Ordered_Maps is - type Iterator is new + type Iterator is limited new Map_Iterator_Interfaces.Reversible_Iterator with record Container : Map_Access; Node : Count_Type; @@ -579,12 +579,24 @@ package body Ada.Containers.Bounded_Ordered_Maps is end First; function First (Object : Iterator) return Cursor is - F : constant Count_Type := Object.Container.First; begin - if F = 0 then - return No_Element; + -- The value of the iterator object's Node component influences the + -- behavior of the First (and Last) selector function. + + -- When the Node component is 0, 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 Node component is positive, the iterator object was constructed + -- with a start expression, that specifies the position from which the + -- (forward) partial iteration begins. + + if Object.Node = 0 then + return Bounded_Ordered_Maps.First (Object.Container.all); else - return Cursor'(Object.Container.all'Unchecked_Access, F); + return Cursor'(Object.Container, Object.Node); end if; end First; @@ -886,22 +898,62 @@ package body Ada.Containers.Bounded_Ordered_Maps is end Iterate; function Iterate - (Container : Map) return Map_Iterator_Interfaces.Forward_Iterator'class + (Container : Map) return Map_Iterator_Interfaces.Reversible_Iterator'Class is - It : constant Iterator := - (Container'Unrestricted_Access, Container.First); begin - return It; + -- The value of the Node component influences the behavior of the First + -- and Last selector functions of the iterator object. When the Node + -- component is 0 (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 Iterator'(Container'Unrestricted_Access, Node => 0); end Iterate; function Iterate (Container : Map; Start : Cursor) - return Map_Iterator_Interfaces.Reversible_Iterator'class + return Map_Iterator_Interfaces.Reversible_Iterator'Class is - It : constant Iterator := (Container'Unrestricted_Access, Start.Node); begin - return It; + + -- 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 = No_Element then + raise Constraint_Error with + "Start position for iterator equals No_Element"; + end if; + + if Start.Container /= Container'Unrestricted_Access then + raise Program_Error with + "Start cursor of Iterate designates wrong map"; + end if; + + pragma Assert (Vet (Container, Start.Node), + "Start cursor of Iterate is bad"); + + -- The value of the Node component influences the behavior of the First + -- and Last selector functions of the iterator object. When the Node + -- component is positive (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 Iterator'(Container'Unrestricted_Access, Node => Start.Node); end Iterate; --------- @@ -935,12 +987,24 @@ package body Ada.Containers.Bounded_Ordered_Maps is end Last; function Last (Object : Iterator) return Cursor is - F : constant Count_Type := Object.Container.Last; begin - if F = 0 then - return No_Element; + -- The value of the iterator object's Node component influences the + -- behavior of the Last (and First) selector function. + + -- When the Node component is 0, 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 Node component is positive, the iterator object was constructed + -- with a start expression, that specifies the position from which the + -- (reverse) partial iteration begins. + + if Object.Node = 0 then + return Bounded_Ordered_Maps.Last (Object.Container.all); else - return Cursor'(Object.Container.all'Unchecked_Access, F); + return Cursor'(Object.Container, Object.Node); end if; end Last; @@ -1044,8 +1108,16 @@ package body Ada.Containers.Bounded_Ordered_Maps is (Object : Iterator; Position : Cursor) return Cursor is - pragma Unreferenced (Object); begin + 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 map"; + end if; + return Next (Position); end Next; @@ -1095,8 +1167,16 @@ package body Ada.Containers.Bounded_Ordered_Maps is (Object : Iterator; Position : Cursor) return Cursor is - pragma Unreferenced (Object); begin + 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 map"; + end if; + return Previous (Position); end Previous; |