* patch by Rika: fix for ... in iterator for TMap and TSet, resolves #39354

This commit is contained in:
florian 2022-04-23 21:50:42 +02:00
parent 616538c251
commit 876ae56158
2 changed files with 45 additions and 15 deletions

View File

@ -29,7 +29,7 @@ type
public
type PNode=^TNode;
TLMapIterator = specialize TMapIterator<TKey, TValue, TPair, TNode>;
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;

21
tests/webtbs/tw39354.pp Normal file
View File

@ -0,0 +1,21 @@
program Project1;
uses gmap,gutil;
type
TMyMap=specialize TMap<String,Integer,specialize TLess<string>>;
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.