204 lines
4.0 KiB
ObjectPascal
204 lines
4.0 KiB
ObjectPascal
unit OObjects;
|
|
|
|
interface
|
|
|
|
uses Classes;
|
|
|
|
const
|
|
|
|
{ TOCollection interfaces between OWL TCollection and VCL TList }
|
|
MaxCollectionSize = Maxint div (SizeOf(Integer) * 2);
|
|
|
|
type
|
|
TOCollection = class(TList)
|
|
public
|
|
constructor Create(ACapacity: Integer);
|
|
procedure AtFree(Index: Integer);
|
|
procedure FreeAll;
|
|
procedure DoFree(Item: Pointer);
|
|
procedure FreeItem(Item: Pointer); virtual;
|
|
destructor Destroy; override;
|
|
end;
|
|
|
|
TNoOwnerCollection = class(TOCollection)
|
|
public
|
|
procedure FreeItem(Item: Pointer); override;
|
|
end;
|
|
|
|
{ TSortedCollection object }
|
|
|
|
TSortedCollection = class(TOCollection)
|
|
public
|
|
Duplicates: Boolean;
|
|
constructor Create(ACapacity: Integer);
|
|
function Compare(Key1, Key2: Pointer): Integer; virtual; abstract;
|
|
function IndexOf(Item: Pointer): Integer; virtual;
|
|
procedure Add(Item: Pointer); virtual;
|
|
procedure AddReplace(Item: Pointer); virtual;
|
|
{ if duplicate then replace the duplicate else add }
|
|
function KeyOf(Item: Pointer): Pointer; virtual;
|
|
function Search(Key: Pointer; var Index: Integer): Boolean; virtual;
|
|
end;
|
|
|
|
{ TStrCollection object }
|
|
|
|
TStrCollection = class(TSortedCollection)
|
|
public
|
|
function Compare(Key1, Key2: Pointer): Integer; override;
|
|
procedure FreeItem(Item: Pointer); override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses SysUtils, AnsiStrings;
|
|
|
|
constructor TOCollection.Create(ACapacity: Integer);
|
|
begin
|
|
inherited Create;
|
|
SetCapacity(ACapacity);
|
|
{ Delta is automatic in TList }
|
|
end;
|
|
|
|
destructor TOCollection.Destroy;
|
|
begin
|
|
FreeAll;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TOCollection.AtFree(Index: Integer);
|
|
var
|
|
Item: Pointer;
|
|
begin
|
|
Item := Items[Index];
|
|
Delete(Index);
|
|
FreeItem(Item);
|
|
end;
|
|
|
|
procedure TOCollection.FreeAll;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
try
|
|
for I := 0 to Count - 1 do
|
|
FreeItem(Items[I]);
|
|
finally
|
|
Count := 0;
|
|
end;
|
|
end;
|
|
|
|
procedure TOCollection.DoFree(Item: Pointer);
|
|
begin
|
|
AtFree(IndexOf(Item));
|
|
end;
|
|
|
|
procedure TOCollection.FreeItem(Item: Pointer);
|
|
begin
|
|
if (Item <> nil) then
|
|
with TObject(Item) as TObject do
|
|
Free;
|
|
end;
|
|
|
|
{ ----------------------------------------------------------------virtual;
|
|
Implementing TNoOwnerCollection
|
|
----------------------------------------------------------------- }
|
|
|
|
procedure TNoOwnerCollection.FreeItem(Item: Pointer);
|
|
begin
|
|
end;
|
|
|
|
{ TSortedCollection }
|
|
|
|
{$IFDEF maxComp}
|
|
|
|
constructor TSortedCollection.Create(ACapacity, ADelta: Integer);
|
|
begin
|
|
inherited Create(ACapacity, ADelta);
|
|
Duplicates := False;
|
|
end;
|
|
{$ELSE}
|
|
|
|
constructor TSortedCollection.Create(ACapacity: Integer);
|
|
begin
|
|
inherited Create(ACapacity);
|
|
Duplicates := False;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
function TSortedCollection.IndexOf(Item: Pointer): Integer;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
IndexOf := -1;
|
|
if Search(KeyOf(Item), I) then
|
|
begin
|
|
if Duplicates then
|
|
while (I < Count) and (Item <> Items[I]) do
|
|
Inc(I);
|
|
if I < Count then
|
|
IndexOf := I;
|
|
end;
|
|
end;
|
|
|
|
procedure TSortedCollection.AddReplace(Item: Pointer);
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
if Search(KeyOf(Item), Index) then
|
|
Delete(Index);
|
|
Add(Item);
|
|
end;
|
|
|
|
procedure TSortedCollection.Add(Item: Pointer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if not Search(KeyOf(Item), I) or Duplicates then
|
|
Insert(I, Item);
|
|
end;
|
|
|
|
function TSortedCollection.KeyOf(Item: Pointer): Pointer;
|
|
begin
|
|
KeyOf := Item;
|
|
end;
|
|
|
|
function TSortedCollection.Search(Key: Pointer; var Index: Integer): Boolean;
|
|
var
|
|
L, H, I, C: Integer;
|
|
begin
|
|
Search := False;
|
|
L := 0;
|
|
H := Count - 1;
|
|
while L <= H do
|
|
begin
|
|
I := (L + H) shr 1;
|
|
C := Compare(KeyOf(Items[I]), Key);
|
|
if C < 0 then
|
|
L := I + 1
|
|
else
|
|
begin
|
|
H := I - 1;
|
|
if C = 0 then
|
|
begin
|
|
Search := True;
|
|
if not Duplicates then
|
|
L := I;
|
|
end;
|
|
end;
|
|
end;
|
|
Index := L;
|
|
end;
|
|
|
|
{ TStrCollection }
|
|
|
|
function TStrCollection.Compare(Key1, Key2: Pointer): Integer;
|
|
begin
|
|
Compare := AnsiStrings.StrComp(PAnsiChar(Key1), PAnsiChar(Key2));
|
|
end;
|
|
|
|
procedure TStrCollection.FreeItem(Item: Pointer);
|
|
begin
|
|
AnsiStrings.StrDispose(PAnsiChar(Item));
|
|
end;
|
|
|
|
end.
|