summaryrefslogtreecommitdiff
path: root/packages/fcl-stl
diff options
context:
space:
mode:
authormichael <michael@3ad0048d-3df7-0310-abae-a5850022a9f2>2021-01-24 17:40:32 +0000
committermichael <michael@3ad0048d-3df7-0310-abae-a5850022a9f2>2021-01-24 17:40:32 +0000
commit8424f270648b6d1418fc6581ac7c386bb3c53025 (patch)
tree9eaafe4045da9fb90ff484505e4099dedab6442f /packages/fcl-stl
parentbad0d7e5b6ec306b2034e164fd2bf4e39abe8b08 (diff)
downloadfpc-8424f270648b6d1418fc6581ac7c386bb3c53025.tar.gz
* Patch from Bart Broersma to fix issue ID 38306
git-svn-id: https://svn.freepascal.org/svn/fpc/trunk@48405 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'packages/fcl-stl')
-rw-r--r--packages/fcl-stl/src/gdeque.pp54
1 files changed, 44 insertions, 10 deletions
diff --git a/packages/fcl-stl/src/gdeque.pp b/packages/fcl-stl/src/gdeque.pp
index a2ad0db57b..2fa9d2d443 100644
--- a/packages/fcl-stl/src/gdeque.pp
+++ b/packages/fcl-stl/src/gdeque.pp
@@ -31,6 +31,10 @@ type
function GetValue(position:SizeUInt):T;inline;
function GetMutable(position:SizeUInt):PT;inline;
procedure IncreaseCapacity();
+ protected
+ procedure MoveSimpleData(StartIndex: SizeUInt; Offset: SizeInt; NrElems: SizeUInt);
+ procedure MoveManagedData(StartIndex: SizeUInt; Offset: SizeInt; NrElems: SizeUInt);
+ procedure MoveData(StartIndex: SizeUInt; Offset: SizeInt; NrElems: SizeUInt);
public
function Size():SizeUInt;inline;
constructor Create();
@@ -127,6 +131,8 @@ end;
procedure TDeque.SetValue(position:SizeUInt; value:T);inline;
begin
Assert(position < size, 'Deque access out of range');
+ if IsManagedType(T) then
+ Finalize(FData[(FStart+position)mod FCapacity]);
FData[(FStart+position)mod FCapacity]:=value;
end;
@@ -142,6 +148,40 @@ begin
GetMutable:=@FData[(FStart+position) mod FCapacity];
end;
+
+
+procedure TDeque.MoveSimpleData(StartIndex: SizeUInt; Offset: SizeInt; NrElems: SizeUInt);
+begin
+ Move(FData[StartIndex], FData[StartIndex+Offset], NrElems*SizeOf(T));
+ if Offset>0 then
+ FillChar(FData[StartIndex], NrElems*SizeOf(T), 0)
+ else
+ FillChar(FData[StartIndex+NrElems+Offset], -Offset*SizeOf(T), 0);
+end;
+
+procedure TDeque.MoveManagedData(StartIndex: SizeUInt; Offset: SizeInt; NrElems: SizeUInt);
+var
+ i: SizeUInt;
+begin
+ //since we always move blocks where Abs(Offset)>=NrElems, there is no need for
+ //2 seperate loops (1 for ngeative and 1 for positive Offsett)
+ for i := 0 to NrElems-1 do
+ begin
+ Finalize(FData[StartIndex+i+Offset]);
+ FData[StartIndex+i+Offset] := FData[StartIndex+i];
+ Finalize(FData[StartIndex+i]);
+ FillChar(FData[StartIndex+i], SizeOf(T), 0);
+ end;
+end;
+
+procedure TDeque.MoveData(StartIndex: SizeUInt; Offset: SizeInt; NrElems: SizeUInt);
+begin
+ if IsManagedType(T) then
+ MoveManagedData(StartIndex, Offset, NrElems)
+ else
+ MoveSimpleData(StartIndex, Offset, NrElems);
+end;
+
procedure TDeque.IncreaseCapacity;
function Min(const A,B: SizeUInt): SizeUInt; inline; //no need to drag in the entire Math unit ;-)
begin
@@ -177,11 +217,7 @@ begin
begin
if (FCapacity-OldEnd>=FStart) then //we have room to move all items in one go
begin
- if IsManagedType(T) then
- for i:=0 to FStart-1 do
- FData[OldEnd+i]:=FData[i]
- else
- Move(FData[0], FData[OldEnd], FStart*SizeOf(T));
+ MoveData(0, OldEnd ,FStart)
end
else
begin //we have to move things around in chunks: we have more data in front of FStart than we have newly created unused elements
@@ -189,11 +225,9 @@ begin
EmptyElems:=FCapacity-1-CurLast;
while (FStart>0) do
begin
- Elems:=Min(EmptyElems, FStart);
- for i:=0 to Elems-1 do
- FData[CurLast+1+i]:=FData[i];
- for i := 0 to FCapacity-Elems-1 do
- FData[i]:=FData[Elems+i];
+ Elems := Min(EmptyElems, FStart);
+ MoveData(0, CurLast+1, Elems);
+ MoveData(Elems, -Elems, FCapacity-Elems);
Dec(FStart, Elems);
end;
end;