From fef4741eb8132b707192b973e64c4130b52dc6b5 Mon Sep 17 00:00:00 2001 From: marco Date: Tue, 3 Sep 2019 09:57:22 +0000 Subject: [PATCH] * for..in std iterator support for ghashmap, mantis #35940 git-svn-id: trunk@42908 - --- packages/fcl-stl/doc/hashmapexample.pp | 14 ++--- packages/fcl-stl/src/ghashmap.pp | 78 +++++++++++++++++--------- 2 files changed, 59 insertions(+), 33 deletions(-) diff --git a/packages/fcl-stl/doc/hashmapexample.pp b/packages/fcl-stl/doc/hashmapexample.pp index 5c592a2f18..3ea6f9932e 100644 --- a/packages/fcl-stl/doc/hashmapexample.pp +++ b/packages/fcl-stl/doc/hashmapexample.pp @@ -1,5 +1,7 @@ {$mode objfpc} +{define oldstyleiterator} + uses ghashmap; type hashlli=class @@ -13,7 +15,8 @@ begin hash:= a mod b; end; -var data:maplli; i:longint; iterator:maplli.TIterator; +var data:maplli; i:longint; + pair : maplli.TPair; begin data:=maplli.Create; @@ -24,12 +27,9 @@ begin data.delete(5); {Iteration through elements} - iterator:=data.Iterator; - repeat - writeln(iterator.Key, ' ', iterator.Value); - until not iterator.Next; - {Don't forget to destroy iterator} - iterator.Destroy; + // destroying class iterators is afaik a FPC extension. + for pair in data do + writeln(pair.Key, ' ', pair.Value); data.Destroy; end. diff --git a/packages/fcl-stl/src/ghashmap.pp b/packages/fcl-stl/src/ghashmap.pp index dd53761f4f..87568d1574 100644 --- a/packages/fcl-stl/src/ghashmap.pp +++ b/packages/fcl-stl/src/ghashmap.pp @@ -38,25 +38,31 @@ } type - generic THashmapIterator=class - public - type PValue=^TValue; - var - Fh,Fp:SizeUInt; - FData:TTable; - function Next:boolean;inline; - function Prev:boolean;inline; - function GetData:T;inline; - function GetKey:TKey;inline; - function GetValue:TValue;inline; - function GetMutable:PValue;inline; - procedure SetValue(value:TValue);inline; - property Data:T read GetData; - property Key:TKey read GetKey; - property Value:TValue read GetValue write SetValue; - property MutableValue:PValue read GetMutable; - end; + { THashmapIterator } + + generic THashmapIterator=class + public + type PValue=^TValue; + var + Fh,Fp:SizeUInt; + FData:TTable; + function Next:boolean;inline; + function MoveNext:boolean;inline; + function Prev:boolean;inline; + function GetData:T;inline; + function GetKey:TKey;inline; + function GetValue:TValue;inline; + function GetMutable:PValue;inline; + procedure SetValue(value:TValue);inline; + property Data:T read GetData; + property Key:TKey read GetKey; + property Value:TValue read GetValue write SetValue; + property MutableValue:PValue read GetMutable; + property Current : T read GetData; + end; + + { THashmap } generic THashmap=class public type @@ -76,20 +82,19 @@ public type TIterator = specialize THashmapIterator; - constructor create; - destructor destroy;override; + constructor Create; + destructor Destroy;override; procedure insert(key:TKey;value:TValue);inline; function contains(key:TKey):boolean;inline; - function size:SizeUInt;inline; + function Size:SizeUInt;inline; procedure delete(key:TKey);inline; procedure erase(iter:TIterator);inline; function IsEmpty:boolean;inline; function GetData(key:TKey):TValue;inline; function GetValue(key:TKey;out value:TValue):boolean;inline; - - property Items[i : TKey]: TValue read GetData write Insert; default; - function Iterator:TIterator; + function getenumerator :TIterator; + property Items[i : TKey]: TValue read GetData write Insert; default; end; implementation @@ -111,7 +116,7 @@ begin FData.Destroy; end; -function THashmap.IsEmpty(): boolean; +function THashmap.IsEmpty: boolean; begin IsEmpty := Size()=0; end; @@ -145,7 +150,7 @@ begin end; end; -constructor THashmap.create; +constructor THashmap.Create; var i: SizeUInt; begin FDataSize:=0; @@ -290,6 +295,22 @@ begin exit(false); end; +function THashmapIterator.MoveNext: boolean; +begin + Assert(Fh < FData.size); // assumes FData.size>0 (i.e. buckets don't shrink) and cannot call Next again after reaching end + inc(Fp); + if (Fp < (FData[Fh]).size) then + exit(true); + Fp:=0; Inc(Fh); + while Fh < FData.size do begin + if ((FData[Fh]).size > 0) then + exit(true); + Inc(Fh); + end; + //Assert((Fp = 0) and (Fh = FData.size)); + exit(false); +end; + function THashmapIterator.Prev: boolean; var bs:SizeUInt; begin @@ -330,6 +351,11 @@ begin Iterator.FData := FData; end; +function THashmap.getenumerator: TIterator; +begin + result:=iterator; +end; + function THashmapIterator.GetKey: TKey; begin GetKey:=((FData[Fh])[Fp]).Key;