📄 gr32_containers.pas
字号:
Move(Items[ItemIndex + 1], Items[ItemIndex], (Count - ItemIndex) * SizeOf(TPointerBucketItem));
Dec(Count);
end;
Dec(FCount);
end;
function TPointerMap.Remove(Item: PItem): PData;
var
BucketIndex, ItemIndex: Integer;
begin
if Exists(Item, BucketIndex, ItemIndex) then
Result := Delete(BucketIndex, ItemIndex)
else
Result := nil;
end;
function TPointerMap.Contains(Item: PItem): Boolean;
var
Dummy: Integer;
begin
Result := Exists(Item, Dummy, Dummy);
end;
function TPointerMap.Find(Item: PItem; out Data: PPData): Boolean;
var
BucketIndex, ItemIndex: Integer;
begin
Result := Exists(Item, BucketIndex, ItemIndex);
if Result then
Data := @FBuckets[BucketIndex].Items[ItemIndex].Data;
end;
function TPointerMap.Exists(Item: PItem; out BucketIndex, ItemIndex: Integer): Boolean;
var
I: Integer;
begin
BucketIndex := Integer(Item) shr 8 and BUCKET_MASK; // KISS pointer hash(TM)
// due to their randomness, pointers most commonly differ at byte 1, we use
// this characteristic for our hash and just apply the mask to it.
// Worst case scenario happens when most changes are at byte 0, which causes
// one bucket to be saturated whereas the other buckets are almost empty...
Result := False;
with FBuckets[BucketIndex] do
for I := 0 to Count - 1 do
if Items[I].Item = Item then
begin
ItemIndex := I;
Result := True;
Exit;
end;
end;
function TPointerMap.GetData(Item: PItem): PData;
var
BucketIndex, ItemIndex: Integer;
begin
if not Exists(Item, BucketIndex, ItemIndex) then
raise EListError.CreateFmt(SItemNotFound, [Integer(Item)])
else
Result := FBuckets[BucketIndex].Items[ItemIndex].Data;
end;
procedure TPointerMap.SetData(Item: PItem; const Data: PData);
var
BucketIndex, ItemIndex: Integer;
begin
if not Exists(Item, BucketIndex, ItemIndex) then
raise EListError.CreateFmt(SItemNotFound, [Integer(Item)])
else
FBuckets[BucketIndex].Items[ItemIndex].Data := Data;
end;
{ TPointerMapIterator }
constructor TPointerMapIterator.Create(SrcPointerMap: TPointerMap);
begin
inherited Create;
FSrcPointerMap := SrcPointerMap;
FCurBucketIndex := -1;
FCurItemIndex := -1;
end;
function TPointerMapIterator.Next: Boolean;
begin
if FCurItemIndex > 0 then
Dec(FCurItemIndex)
else
begin
FCurItemIndex := -1;
while (FCurBucketIndex < BUCKET_MASK) and (FCurItemIndex = -1) do
begin
Inc(FCurBucketIndex);
FCurItemIndex := FSrcPointerMap.FBuckets[FCurBucketIndex].Count - 1;
end;
if FCurBucketIndex = BUCKET_MASK then
begin
Result := False;
Exit;
end
end;
Result := True;
with FSrcPointerMap.FBuckets[FCurBucketIndex].Items[FCurItemIndex] do
begin
FItem := Item;
FData := Data;
end;
end;
{ TRectList }
destructor TRectList.Destroy;
begin
SetCount(0);
SetCapacity(0);
end;
function TRectList.Add(const Rect: TRect): Integer;
begin
Result := FCount;
if Result = FCapacity then
Grow;
FList^[Result] := Rect;
Inc(FCount);
end;
procedure TRectList.Clear;
begin
SetCount(0);
SetCapacity(10);
end;
procedure TRectList.Delete(Index: Integer);
begin
Dec(FCount);
if Index < FCount then
System.Move(FList^[Index + 1], FList^[Index],
(FCount - Index) * SizeOf(TRect));
end;
procedure TRectList.Exchange(Index1, Index2: Integer);
var
Item: TRect;
begin
Item := FList^[Index1];
FList^[Index1] := FList^[Index2];
FList^[Index2] := Item;
end;
function TRectList.Get(Index: Integer): PRect;
begin
if (Index < 0) or (Index >= FCount) then
Result := nil
else
Result := @FList^[Index];
end;
procedure TRectList.Grow;
var
Delta: Integer;
begin
if FCapacity > 128 then
Delta := FCapacity div 4
else
if FCapacity > 8 then
Delta := 32
else
Delta := 8;
SetCapacity(FCapacity + Delta);
end;
function TRectList.IndexOf(const Rect: TRect): Integer;
begin
Result := 0;
while (Result < FCount) and not EqualRect(FList^[Result], Rect) do
Inc(Result);
if Result = FCount then
Result := -1;
end;
procedure TRectList.Insert(Index: Integer; const Rect: TRect);
begin
if FCount = FCapacity then
Grow;
if Index < FCount then
System.Move(FList^[Index], FList^[Index + 1],
(FCount - Index) * SizeOf(TRect));
FList^[Index] := Rect;
Inc(FCount);
end;
procedure TRectList.Move(CurIndex, NewIndex: Integer);
var
Item: TRect;
begin
if CurIndex <> NewIndex then
begin
Item := Get(CurIndex)^;
Delete(CurIndex);
Insert(NewIndex, Item);
end;
end;
function TRectList.Remove(const Rect: TRect): Integer;
begin
Result := IndexOf(Rect);
if Result >= 0 then
Delete(Result);
end;
procedure TRectList.Pack;
var
I: Integer;
begin
for I := FCount - 1 downto 0 do
if Items[I] = nil then
Delete(I);
end;
procedure TRectList.SetCapacity(NewCapacity: Integer);
begin
if NewCapacity <> FCapacity then
begin
ReallocMem(FList, NewCapacity * SizeOf(TRect));
FCapacity := NewCapacity;
end;
end;
procedure TRectList.SetCount(NewCount: Integer);
var
I: Integer;
begin
if NewCount > FCapacity then
SetCapacity(NewCount);
if NewCount > FCount then
FillChar(FList^[FCount], (NewCount - FCount) * SizeOf(TRect), 0)
else
for I := FCount - 1 downto NewCount do
Delete(I);
FCount := NewCount;
end;
{ TClassList }
function TClassList.Add(AClass: TClass): Integer;
begin
Result := inherited Add(AClass);
end;
function TClassList.Extract(Item: TClass): TClass;
begin
Result := TClass(inherited Extract(Item));
end;
function TClassList.Find(AClassName: string): TClass;
var
I: Integer;
begin
Result := nil;
for I := 0 to Count - 1 do
if TClass(List[I]).ClassName = AClassName then
begin
Result := TClass(List[I]);
Break;
end;
end;
function TClassList.First: TClass;
begin
Result := TClass(inherited First);
end;
procedure TClassList.GetClassNames(Strings: TStrings);
var
I: Integer;
begin
for I := 0 to Count - 1 do
Strings.Add(TClass(List[I]).ClassName);
end;
function TClassList.GetItems(Index: Integer): TClass;
begin
Result := TClass(inherited Items[Index]);
end;
function TClassList.IndexOf(AClass: TClass): Integer;
begin
Result := inherited IndexOf(AClass);
end;
procedure TClassList.Insert(Index: Integer; AClass: TClass);
begin
inherited Insert(Index, AClass);
end;
function TClassList.Last: TClass;
begin
Result := TClass(inherited Last);
end;
function TClassList.Remove(AClass: TClass): Integer;
begin
Result := inherited Remove(AClass);
end;
procedure TClassList.SetItems(Index: Integer; AClass: TClass);
begin
inherited Items[Index] := AClass;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -