瀏覽代碼

* fix TFPSMap.GetKeyData on non-sorted map (#9672)
+ add test for issue #9672

git-svn-id: trunk@8485 -

micha 18 年之前
父節點
當前提交
f48e51c380
共有 4 個文件被更改,包括 53 次插入8 次删除
  1. 1 0
      .gitattributes
  2. 9 8
      rtl/objpas/fgl.pp
  3. 1 0
      rtl/objpas/rtlconst.inc
  4. 42 0
      tests/webtbs/tw9672.pp

+ 1 - 0
.gitattributes

@@ -8425,6 +8425,7 @@ tests/webtbs/tw9347a.pp svneol=native#text/plain
 tests/webtbs/tw9347b.pp svneol=native#text/plain
 tests/webtbs/tw9347b.pp svneol=native#text/plain
 tests/webtbs/tw9384.pp svneol=native#text/plain
 tests/webtbs/tw9384.pp svneol=native#text/plain
 tests/webtbs/tw9385.pp svneol=native#text/plain
 tests/webtbs/tw9385.pp svneol=native#text/plain
+tests/webtbs/tw9672.pp svneol=native#text/plain
 tests/webtbs/ub1873.pp svneol=native#text/plain
 tests/webtbs/ub1873.pp svneol=native#text/plain
 tests/webtbs/ub1883.pp svneol=native#text/plain
 tests/webtbs/ub1883.pp svneol=native#text/plain
 tests/webtbs/uw0555.pp svneol=native#text/plain
 tests/webtbs/uw0555.pp svneol=native#text/plain

+ 9 - 8
rtl/objpas/fgl.pp

@@ -685,10 +685,11 @@ function TFPSMap.GetKeyData(AKey: Pointer): Pointer;
 var
 var
   I: Integer;
   I: Integer;
 begin
 begin
-  if Find(AKey, I) then
+  I := IndexOf(AKey);
+  if I >= 0 then
     Result := InternalItems[I]
     Result := InternalItems[I]
   else
   else
-    Result := nil;
+    Error(SMapKeyError, PtrInt(AKey));
 end;
 end;
 
 
 procedure TFPSMap.InitOnPtrCompare;
 procedure TFPSMap.InitOnPtrCompare;
@@ -712,7 +713,8 @@ procedure TFPSMap.PutKeyData(AKey: Pointer; NewData: Pointer);
 var
 var
   I: Integer;
   I: Integer;
 begin
 begin
-  if Find(AKey, I) then
+  I := IndexOf(AKey);
+  if I >= 0 then
     Data[I] := NewData
     Data[I] := NewData
   else
   else
     Add(AKey, NewData);
     Add(AKey, NewData);
@@ -736,7 +738,7 @@ begin
       end;
       end;
   end else
   end else
     Result := Count;
     Result := Count;
-  CopyKey(AKey, Insert(Result));
+  CopyKey(AKey, inherited Insert(Result));
 end;
 end;
 
 
 function TFPSMap.Add(AKey, AData: Pointer): Integer;
 function TFPSMap.Add(AKey, AData: Pointer): Integer;
@@ -841,10 +843,9 @@ end;
 
 
 function TFPSMap.Remove(AKey: Pointer): Integer;
 function TFPSMap.Remove(AKey: Pointer): Integer;
 begin
 begin
-  if Find(AKey, Result) then
-    Delete(Result)
-  else
-    Result := -1;
+  Result := IndexOf(AKey);
+  if Result >= 0 then
+    Delete(Result);
 end;
 end;
 
 
 procedure TFPSMap.Sort;
 procedure TFPSMap.Sort;

+ 1 - 0
rtl/objpas/rtlconst.inc

@@ -179,6 +179,7 @@ ResourceString
   SListCountError               = 'List count (%d) out of bounds.';
   SListCountError               = 'List count (%d) out of bounds.';
   SListIndexError               = 'List index (%d) out of bounds';
   SListIndexError               = 'List index (%d) out of bounds';
   SListItemSizeError            = 'Incompatible item size in source list';
   SListItemSizeError            = 'Incompatible item size in source list';
+  SMapKeyError                  = 'Map key (address $%x) does not exist';
   SMaskEditErr                  = 'Invalid mask input value.  Use escape key to abandon changes';
   SMaskEditErr                  = 'Invalid mask input value.  Use escape key to abandon changes';
   SMaskErr                      = 'Invalid mask input value';
   SMaskErr                      = 'Invalid mask input value';
   SMDIChildNotVisible           = 'A MDI-Child Window can not be hidden.';
   SMDIChildNotVisible           = 'A MDI-Child Window can not be hidden.';

+ 42 - 0
tests/webtbs/tw9672.pp

@@ -0,0 +1,42 @@
+{$mode objfpc} {$H+}
+uses fgl,sysutils;
+
+const strs : array[0..16] of integer = (1,2,2,7,0,12,3,4,5,3,6,7,8,9,0,3,4);
+    
+type
+  TInterestingData = integer;
+  TMySet = specialize TFPGmap<integer, TInterestingData>;
+
+function mycompare(const a,b : integer) : integer;
+begin
+  result := a-b;
+end;
+
+var
+  s : TMySet;
+  idx, i,j : Integer;
+  
+  b : TInterestingData;
+
+begin
+  s := TMySet.Create; 
+  s.sorted := false;
+  s.OnCompare := @mycompare;
+  
+  for i := low(strs) to high(strs) do begin
+    idx := s.IndexOf(strs[i]);
+    writeln('count ', s.count, ' used of ', s.capacity, ' available');
+    if (idx <> -1) then begin
+      b := s[strs[i]];
+    end else begin
+      b := i;
+      s[strs[i]] := b;
+    end;
+    
+    // do something with existing interesting data
+    writeln('data: ', b);
+  end;
+  
+  s.Free;
+end.
+