mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-06 17:03:04 +01:00
Apply patch from lks (with a few adjustments). Fixes Mantis #23938.
gvector.pp: * more consistent formatting - remove "inline" directives in implementation section * use "Move" instead of a for-loop in Erase and Insert (while also respecting managed types) for performance improvement * set the removed entry in PopBack to Default(T) (also for managed types) * fix a bug in Erase which checked for "<= Size" instead of "< Size" git-svn-id: trunk@23647 -
This commit is contained in:
parent
f229d601de
commit
d76ebd0748
@ -65,8 +65,8 @@ type
|
||||
procedure Clear; inline;
|
||||
function Front: T; inline;
|
||||
function Back: T; inline;
|
||||
procedure Reserve(Num: SizeUInt); inline;
|
||||
procedure Resize(Num: SizeUInt); inline;
|
||||
procedure Reserve(Num: SizeUInt);
|
||||
procedure Resize(Num: SizeUInt);
|
||||
|
||||
function GetEnumerator: TVectorEnumerator; inline;
|
||||
|
||||
@ -114,41 +114,38 @@ begin
|
||||
FData[Position]:=Value;
|
||||
end;
|
||||
|
||||
function TVector.GetValue(Position:SizeUInt):T;inline;
|
||||
function TVector.GetValue(Position: SizeUInt): T;
|
||||
begin
|
||||
Assert(position < size, SVectorPositionOutOfRange);
|
||||
GetValue:=FData[Position];
|
||||
end;
|
||||
|
||||
function TVector.GetMutable(Position:SizeUInt):PT;inline;
|
||||
function TVector.GetMutable(Position: SizeUInt): PT;
|
||||
begin
|
||||
Assert(position < size, SVectorPositionOutOfRange);
|
||||
GetMutable:=@FData[Position];
|
||||
end;
|
||||
|
||||
function TVector.Front():T;inline;
|
||||
function TVector.Front(): T;
|
||||
begin
|
||||
Assert(size > 0, SAccessingElementOfEmptyVector);
|
||||
Front:=FData[0];
|
||||
end;
|
||||
|
||||
function TVector.Back():T;inline;
|
||||
function TVector.Back(): T;
|
||||
begin
|
||||
Assert(size > 0, SAccessingElementOfEmptyVector);
|
||||
Back:=FData[FDataSize-1];
|
||||
end;
|
||||
|
||||
function TVector.Size():SizeUInt;inline;
|
||||
function TVector.Size(): SizeUInt;
|
||||
begin
|
||||
Size:=FDataSize;
|
||||
end;
|
||||
|
||||
function TVector.IsEmpty():boolean;inline;
|
||||
function TVector.IsEmpty(): boolean;
|
||||
begin
|
||||
if Size()=0 then
|
||||
IsEmpty:=true
|
||||
else
|
||||
IsEmpty:=false;
|
||||
IsEmpty := (Size() = 0);
|
||||
end;
|
||||
|
||||
procedure TVector.PushBack(const Value: T);
|
||||
@ -159,7 +156,7 @@ begin
|
||||
inc(FDataSize);
|
||||
end;
|
||||
|
||||
procedure TVector.IncreaseCapacity();inline;
|
||||
procedure TVector.IncreaseCapacity();
|
||||
begin
|
||||
if FCapacity=0 then
|
||||
FCapacity:=1
|
||||
@ -173,42 +170,51 @@ begin
|
||||
Result := TVectorEnumerator.Create(self);
|
||||
end;
|
||||
|
||||
procedure TVector.PopBack();inline;
|
||||
procedure TVector.PopBack();
|
||||
begin
|
||||
if FDataSize > 0 then
|
||||
FDataSize:=FDataSize-1;
|
||||
begin
|
||||
dec(FDataSize);
|
||||
// if a managed type, decrease the popped element's reference count (see http://bugs.freepascal.org/view.php?id=23938#)
|
||||
FData[FDataSize] := Default(T);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TVector.Insert(Position: SizeUInt; const Value: T);
|
||||
var i:SizeUInt;
|
||||
var
|
||||
def: T;
|
||||
begin
|
||||
pushBack(Value);
|
||||
for i:=Size-1 downto Position+1 do
|
||||
if Position <= Size then // allow appending a new element at end of vector (but not beyond)
|
||||
begin
|
||||
FData[i]:=FData[i-1];
|
||||
end;
|
||||
if FDataSize = FCapacity then
|
||||
IncreaseCapacity;
|
||||
if Position < FDataSize then
|
||||
System.Move (FData[Position], FData[Position+1], (FDataSize - Position) * SizeOf(T));
|
||||
// update inserted item
|
||||
def := Default(T);
|
||||
Move(def, FData[Position], SizeOf(T)); // this will clear FData[Position] without changing the reference count
|
||||
FData[Position] := Value;
|
||||
end;
|
||||
|
||||
procedure TVector.Erase(Position:SizeUInt);inline;
|
||||
var i:SizeUInt;
|
||||
begin
|
||||
if Position <= Size then
|
||||
begin
|
||||
for i:=Position to Size-2 do
|
||||
begin
|
||||
FData[i]:=FData[i+1];
|
||||
end;
|
||||
popBack();
|
||||
inc(FDataSize);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TVector.Clear;inline;
|
||||
procedure TVector.Erase(Position: SizeUInt);
|
||||
begin
|
||||
if Position < Size then
|
||||
begin
|
||||
dec(FDataSize);
|
||||
// ensure that the data we want to erase is released
|
||||
FData[Position] := Default(T);
|
||||
Move(FData[Position+1], FData[Position], (FDataSize - Position) * SizeOf(T));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TVector.Clear;
|
||||
begin
|
||||
FDataSize:=0;
|
||||
end;
|
||||
|
||||
procedure TVector.Reserve(Num:SizeUInt);inline;
|
||||
procedure TVector.Reserve(Num: SizeUInt);
|
||||
begin
|
||||
if(Num < FCapacity) then
|
||||
exit
|
||||
@ -220,7 +226,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TVector.Resize(Num:SizeUInt);inline;
|
||||
procedure TVector.Resize(Num: SizeUInt);
|
||||
begin
|
||||
Reserve(Num);
|
||||
FDataSize:=Num;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user