The concrete type Iterator is declared as limited, because there is no need for assignment for iterator objects. Hashed maps also do not support partial iteration, so the unnecessary node component is also removed from that type.
The Next operation vets the cursor parameter to ensure that it designates a node in the same container as the iterator. The function then forwards to the call to the corresponding cursor-based operation. Tested on x86_64-pc-linux-gnu, committed on trunk 2011-11-23 Matthew Heaney <hea...@adacore.com> * a-cohama.adb, a-cihama.adb, a-cbhama.adb (Iterator): Declare type as limited, and remove node component. (First, Next): Forward call to corresponding cursor-based operation. (Iterate): Representation of iterator no longer has node component.
Index: a-cihama.adb =================================================================== --- a-cihama.adb (revision 181654) +++ a-cihama.adb (working copy) @@ -45,10 +45,9 @@ procedure Free_Element is new Ada.Unchecked_Deallocation (Element_Type, Element_Access); - type Iterator is new + type Iterator is limited new Map_Iterator_Interfaces.Forward_Iterator with record Container : Map_Access; - Node : Node_Access; end record; overriding function First (Object : Iterator) return Cursor; @@ -476,14 +475,8 @@ end First; function First (Object : Iterator) return Cursor is - M : constant Map_Access := Object.Container; - N : constant Node_Access := HT_Ops.First (M.HT); begin - if N = null then - return No_Element; - else - return Cursor'(Object.Container.all'Unchecked_Access, N); - end if; + return Object.Container.First; end First; ---------- @@ -715,13 +708,11 @@ B := B - 1; end Iterate; - function Iterate (Container : Map) - return Map_Iterator_Interfaces.Forward_Iterator'class + function Iterate + (Container : Map) return Map_Iterator_Interfaces.Forward_Iterator'Class is - Node : constant Node_Access := HT_Ops.First (Container.HT); - It : constant Iterator := (Container'Unrestricted_Access, Node); begin - return It; + return Iterator'(Container => Container'Unrestricted_Access); end Iterate; --------- @@ -809,11 +800,16 @@ function Next (Object : Iterator; Position : Cursor) return Cursor is begin - if Position.Node = null then + if Position.Container = null then return No_Element; - else - return (Object.Container, Next (Position).Node); 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; ------------------- Index: a-cohama.adb =================================================================== --- a-cohama.adb (revision 181654) +++ a-cohama.adb (working copy) @@ -39,10 +39,9 @@ package body Ada.Containers.Hashed_Maps is - type Iterator is new + type Iterator is limited new Map_Iterator_Interfaces.Forward_Iterator with record Container : Map_Access; - Node : Node_Access; end record; overriding function First (Object : Iterator) return Cursor; @@ -440,14 +439,8 @@ end First; function First (Object : Iterator) return Cursor is - M : constant Map_Access := Object.Container; - N : constant Node_Access := HT_Ops.First (M.HT); begin - if N = null then - return No_Element; - end if; - - return Cursor'(Object.Container.all'Unchecked_Access, N); + return Object.Container.First; end First; ---------- @@ -667,12 +660,10 @@ end Iterate; function Iterate - (Container : Map) return Map_Iterator_Interfaces.Forward_Iterator'class + (Container : Map) return Map_Iterator_Interfaces.Forward_Iterator'Class is - Node : constant Node_Access := HT_Ops.First (Container.HT); - It : constant Iterator := (Container'Unrestricted_Access, Node); begin - return It; + return Iterator'(Container => Container'Unrestricted_Access); end Iterate; --------- @@ -752,11 +743,16 @@ Position : Cursor) return Cursor is begin - if Position.Node = null then + if Position.Container = null then return No_Element; - else - return (Object.Container, Next (Position).Node); 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; ------------------- Index: a-cbhama.adb =================================================================== --- a-cbhama.adb (revision 181654) +++ a-cbhama.adb (working copy) @@ -41,7 +41,6 @@ type Iterator is new Map_Iterator_Interfaces.Forward_Iterator with record Container : Map_Access; - Node : Count_Type; end record; overriding function First (Object : Iterator) return Cursor; @@ -424,14 +423,8 @@ end First; function First (Object : Iterator) return Cursor is - M : constant Map_Access := Object.Container; - N : constant Count_Type := HT_Ops.First (M.all); begin - if N = 0 then - return No_Element; - else - return Cursor'(Object.Container.all'Unchecked_Access, N); - end if; + return Object.Container.First; end First; ----------------- @@ -675,12 +668,10 @@ end Iterate; function Iterate - (Container : Map) return Map_Iterator_Interfaces.Forward_Iterator'class + (Container : Map) return Map_Iterator_Interfaces.Forward_Iterator'Class is - Node : constant Count_Type := HT_Ops.First (Container); - It : constant Iterator := (Container'Unrestricted_Access, Node); begin - return It; + return Iterator'(Container => Container'Unrestricted_Access); end Iterate; --------- @@ -770,11 +761,16 @@ Position : Cursor) return Cursor is begin - if Position.Node = 0 then + if Position.Container = null then return No_Element; - else - return (Object.Container, Next (Position).Node); 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; -------------------