diff --git a/rtl/objpas/fgl.pp b/rtl/objpas/fgl.pp index 78ec3b5020..430cf60284 100644 --- a/rtl/objpas/fgl.pp +++ b/rtl/objpas/fgl.pp @@ -41,6 +41,8 @@ type TFPSList = class; TFPSListCompareFunc = function(Key1, Key2: Pointer): Integer of object; + { TFPSList } + TFPSList = class(TObject) protected FList: PByte; @@ -48,6 +50,7 @@ type FCapacity: Integer; { list has room for capacity+1 items, contains room for a temporary item } FItemSize: Integer; procedure CopyItem(Src, Dest: Pointer); virtual; + procedure CopyItems(Src, Dest: Pointer; aCount : Integer); virtual; procedure Deref(Item: Pointer); virtual; overload; procedure Deref(FromIndex, ToIndex: Integer); overload; function Get(Index: Integer): Pointer; @@ -68,6 +71,7 @@ type public constructor Create(AItemSize: Integer = sizeof(Pointer)); destructor Destroy; override; + class Function ItemIsManaged : Boolean; virtual; function Add(Item: Pointer): Integer; procedure Clear; procedure Delete(Index: Integer); @@ -113,6 +117,8 @@ type property Current: T read GetCurrent; end; + { TFPGList } + generic TFPGList = class(TFPSList) private type @@ -132,6 +138,8 @@ type procedure SetLast(const Value: T); {$ifdef FGLINLINE} inline; {$endif} function GetFirst: T; {$ifdef FGLINLINE} inline; {$endif} procedure SetFirst(const Value: T); {$ifdef FGLINLINE} inline; {$endif} + Protected + class Function ItemIsManaged : Boolean; override; public Type TFPGListEnumeratorSpec = specialize TFPGListEnumerator; @@ -455,6 +463,11 @@ begin System.Move(Src^, Dest^, FItemSize); end; +procedure TFPSList.CopyItems(Src, Dest: Pointer; aCount: Integer); +begin + System.Move(Src^, Dest^, FItemSize*aCount); +end; + procedure TFPSList.RaiseIndexError(Index : Integer); begin Error(SListIndexError, Index); @@ -547,6 +560,11 @@ begin Error(SListIndexError, AIndex); end; +class function TFPSList.ItemIsManaged: Boolean; +begin + Result:=False; +end; + procedure TFPSList.Clear; begin @@ -838,8 +856,21 @@ var begin if Obj.ItemSize <> FItemSize then Error(SListItemSizeError, 0); - for I := 0 to Obj.Count - 1 do - Add(Obj[i]); + // Do this now. + Capacity:=Capacity+Obj.Count; + if ItemIsManaged then + begin + // nothing for it, need to do it manually to give deref a chance. + For I:=0 to Obj.Count-1 do + Add(Obj[i]) + end + else + begin + if Obj.Count=0 then + exit; + CopyItems(Obj.InternalItems[0],InternalItems[FCount],Obj.Count); + FCount:=FCount+Obj.Count; + end end; procedure TFPSList.Assign(Obj: TFPSList); @@ -890,7 +921,7 @@ end; procedure TFPGList.Deref(Item: Pointer); begin - Finalize(T(Item^)); + Finalize(T(Item^)); end; function TFPGList.Get(Index: Integer): T; @@ -936,6 +967,11 @@ begin inherited SetFirst(@Value); end; +class function TFPGList.ItemIsManaged: Boolean; +begin + Result:=IsManagedType(T); +end; + function TFPGList.GetEnumerator: TFPGListEnumeratorSpec; begin Result := TFPGListEnumeratorSpec.Create(Self); @@ -976,14 +1012,25 @@ var i: Integer; begin - for I := 0 to Source.Count - 1 do - Add(Source[i]); + if IsManagedType(T) then + begin + Capacity:=Capacity+Source.Count; + for I := 0 to Source.Count - 1 do + Add(Source[i]); + end + else + Inherited AddList(TFPSList(source)) end; procedure TFPGList.Assign(Source: TFPGList); begin - Clear; - AddList(Source); + if IsManagedType(T) then + begin + Clear; + AddList(Source); + end + else + Inherited Assign(TFPSList(source)) end; {$endif VER2_4}