diff --git a/packages/fcl-stl/src/gmap.pp b/packages/fcl-stl/src/gmap.pp index 2d6e1a9510..ca14cbc05f 100644 --- a/packages/fcl-stl/src/gmap.pp +++ b/packages/fcl-stl/src/gmap.pp @@ -29,7 +29,7 @@ type public type PNode=^TNode; TLMapIterator = specialize TMapIterator; - var FNode:PNode; + var FNode, FNext:PNode; // FNext is for MoveNext only, which has different semantics than Next in that it starts in the state 'before first'. type PValue=^TValue; function GetData:TPair;inline; function GetKey:TKey;inline; @@ -235,8 +235,13 @@ begin end; function TMap.GetEnumerator: TIterator; +var + setn: TMSet.PNode; begin result:=titerator.create; + setn := FSet.NMin; + result.FNode := setn; // for Next/Prev + result.FNext := setn; // for MoveNext end; function TMapIterator.GetData:TPair;inline; @@ -265,24 +270,28 @@ begin end; function TMapIterator.MoveNext: boolean; -var temp:PNode; +var + n, child: PNode; begin - if(FNode=nil) then exit(false); - if(FNode^.Right<>nil) then begin - temp:=FNode^.Right; - while(temp^.Left<>nil) do temp:=temp^.Left; + n := FNext; + result := n <> nil; + if not result then exit; + + FNode := n; + child := n^.Right; + if child <> nil then begin + repeat + n := child; + child := n^.Left; + until child = nil; end else begin - temp:=FNode; - while(true) do begin - if(temp^.Parent=nil) then begin temp:=temp^.Parent; break; end; - if(temp^.Parent^.Left=temp) then begin temp:=temp^.Parent; break; end; - temp:=temp^.Parent; - end; + repeat + child := n; + n := n^.Parent; + until (n = nil) or (child = n^.Left); end; - if (temp = nil) then exit(false); - FNode:=temp; - MoveNext:=true; + FNext := n; end; function TMapIterator.Next:boolean;inline; diff --git a/tests/webtbs/tw39354.pp b/tests/webtbs/tw39354.pp new file mode 100644 index 0000000000..f703947f01 --- /dev/null +++ b/tests/webtbs/tw39354.pp @@ -0,0 +1,21 @@ +program Project1; +uses gmap,gutil; +type + TMyMap=specialize TMap>; +var + Map:TMyMap; + Pair:TMyMap.TPair; + Count:Integer; +begin + Map:=TMyMap.Create; + Map.insert('test1',1); + Map.insert('test2',2); + count:=0; + For Pair in Map do begin + writeln(Pair.Key); + inc(count); + end; + if count=0 then + halt(1); + Map.Free; +end.