* for..in std iterator support for ghashmap, mantis #35940

git-svn-id: trunk@42908 -
This commit is contained in:
marco 2019-09-03 09:57:22 +00:00
parent 02a3b6bec7
commit fef4741eb8
2 changed files with 59 additions and 33 deletions

View File

@ -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.

View File

@ -38,25 +38,31 @@
}
type
generic THashmapIterator<TKey, TValue, T, TTable>=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<TKey, TValue, T, TTable>=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<TKey, TValue, Thash>=class
public
type
@ -76,20 +82,19 @@
public
type
TIterator = specialize THashmapIterator<TKey, TValue, TPair, TTable>;
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;