Browse Source

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

git-svn-id: trunk@42908 -
marco 6 years ago
parent
commit
fef4741eb8
2 changed files with 59 additions and 33 deletions
  1. 7 7
      packages/fcl-stl/doc/hashmapexample.pp
  2. 52 26
      packages/fcl-stl/src/ghashmap.pp

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

+ 52 - 26
packages/fcl-stl/src/ghashmap.pp

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