📄 jclarraylists.pas
字号:
{**************************************************************************************************}
{ }
{ Project JEDI Code Library (JCL) }
{ }
{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); }
{ you may not use this file except in compliance with the License. You may obtain a copy of the }
{ License at http://www.mozilla.org/MPL/ }
{ }
{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF }
{ ANY KIND, either express or implied. See the License for the specific language governing rights }
{ and limitations under the License. }
{ }
{ The Original Code is ArrayList.pas. }
{ }
{ The Initial Developer of the Original Code is Jean-Philippe BEMPEL aka RDM. Portions created by }
{ Jean-Philippe BEMPEL are Copyright (C) Jean-Philippe BEMPEL (rdm_30 att yahoo dott com) }
{ All rights reserved. }
{ }
{**************************************************************************************************}
{ }
{ The Delphi Container Library }
{ }
{**************************************************************************************************}
// Last modified: $Date: 2005/03/08 15:14:00 $
// For history see end of file
unit JclArrayLists;
{$I jcl.inc}
interface
uses
Classes,
JclBase, JclAbstractContainers, JclContainerIntf;
type
TJclIntfArrayList = class(TJclAbstractContainer, IJclIntfCollection,
IJclIntfList, IJclIntfArray, IJclIntfCloneable)
private
FElementData: TDynIInterfaceArray;
FSize: Integer;
FCapacity: Integer;
procedure SetCapacity(ACapacity: Integer);
protected
procedure Grow; virtual;
{ IJclIntfCollection }
function Add(AInterface: IInterface): Boolean; overload;
function AddAll(ACollection: IJclIntfCollection): Boolean; overload;
procedure Clear;
function Contains(AInterface: IInterface): Boolean;
function ContainsAll(ACollection: IJclIntfCollection): Boolean;
function Equals(ACollection: IJclIntfCollection): Boolean;
function First: IJclIntfIterator;
function IsEmpty: Boolean;
function Last: IJclIntfIterator;
function Remove(AInterface: IInterface): Boolean; overload;
function RemoveAll(ACollection: IJclIntfCollection): Boolean;
function RetainAll(ACollection: IJclIntfCollection): Boolean;
function Size: Integer;
{ IJclIntfList }
procedure Insert(Index: Integer; AInterface: IInterface); overload;
function InsertAll(Index: Integer; ACollection: IJclIntfCollection): Boolean; overload;
function GetObject(Index: Integer): IInterface;
function IndexOf(AInterface: IInterface): Integer;
function LastIndexOf(AInterface: IInterface): Integer;
function Remove(Index: Integer): IInterface; overload;
procedure SetObject(Index: Integer; AInterface: IInterface);
function SubList(First, Count: Integer): IJclIntfList;
{ IJclIntfCloneable }
function Clone: IInterface;
public
constructor Create(ACapacity: Integer = DefaultContainerCapacity); overload;
constructor Create(ACollection: IJclIntfCollection); overload;
destructor Destroy; override;
property Capacity: Integer read FCapacity write SetCapacity;
end;
//Daniele Teti 02/03/2005
TJclStrArrayList = class(TJclStrCollection, IJclStrList, IJclStrArray, IJclCloneable)
private
FCapacity: Integer;
FElementData: TDynStringArray;
FSize: Integer;
procedure SetCapacity(ACapacity: Integer);
protected
procedure Grow; virtual;
{ IJclStrCollection }
function Add(const AString: string): Boolean; overload; override;
function AddAll(ACollection: IJclStrCollection): Boolean; overload; override;
procedure Clear; override;
function Contains(const AString: string): Boolean; override;
function ContainsAll(ACollection: IJclStrCollection): Boolean; override;
function Equals(ACollection: IJclStrCollection): Boolean; override;
function First: IJclStrIterator; override;
function IsEmpty: Boolean; override;
function Last: IJclStrIterator; override;
function Remove(const AString: string): Boolean; overload; override;
function RemoveAll(ACollection: IJclStrCollection): Boolean; override;
function RetainAll(ACollection: IJclStrCollection): Boolean; override;
function Size: Integer; override;
{ IJclStrList }
procedure Insert(Index: Integer; const AString: string); overload;
function InsertAll(Index: Integer; ACollection: IJclStrCollection): Boolean; overload;
function GetString(Index: Integer): string;
function IndexOf(const AString: string): Integer;
function LastIndexOf(const AString: string): Integer;
function Remove(Index: Integer): string; overload;
procedure SetString(Index: Integer; const AString: string);
function SubList(First, Count: Integer): IJclStrList;
public
constructor Create(ACapacity: Integer = DefaultContainerCapacity); overload;
constructor Create(ACollection: IJclStrCollection); overload;
destructor Destroy; override;
{ IJclCloneable }
function Clone: TObject;
property Capacity: Integer read FCapacity write SetCapacity;
end;
TJclArrayList = class(TJclAbstractContainer, IJclCollection, IJclList,
IJclArray, IJclCloneable)
private
FCapacity: Integer;
FElementData: TDynObjectArray;
FOwnsObjects: Boolean;
FSize: Integer;
procedure SetCapacity(ACapacity: Integer);
protected
procedure Grow; virtual;
procedure FreeObject(var AObject: TObject);
{ IJclCollection }
function Add(AObject: TObject): Boolean; overload;
function AddAll(ACollection: IJclCollection): Boolean; overload;
procedure Clear;
function Contains(AObject: TObject): Boolean;
function ContainsAll(ACollection: IJclCollection): Boolean;
function Equals(ACollection: IJclCollection): Boolean;
function First: IJclIterator;
function IsEmpty: Boolean;
function Last: IJclIterator;
function Remove(AObject: TObject): Boolean; overload;
function RemoveAll(ACollection: IJclCollection): Boolean;
function RetainAll(ACollection: IJclCollection): Boolean;
function Size: Integer;
{ IJclList }
procedure Insert(Index: Integer; AObject: TObject); overload;
function InsertAll(Index: Integer; ACollection: IJclCollection): Boolean; overload;
function GetObject(Index: Integer): TObject;
function IndexOf(AObject: TObject): Integer;
function LastIndexOf(AObject: TObject): Integer;
function Remove(Index: Integer): TObject; overload;
procedure SetObject(Index: Integer; AObject: TObject);
function SubList(First, Count: Integer): IJclList;
{ IJclCloneable }
function Clone: TObject;
public
constructor Create(ACapacity: Integer = DefaultContainerCapacity; AOwnsObjects: Boolean = True); overload;
constructor Create(ACollection: IJclCollection; AOwnsObjects: Boolean = True); overload;
destructor Destroy; override;
property Capacity: Integer read FCapacity write SetCapacity;
property OwnsObjects: Boolean read FOwnsObjects;
end;
implementation
uses
SysUtils,
JclResources;
//=== { TIntfItr } ===========================================================
type
TIntfItr = class(TJclAbstractContainer, IJclIntfIterator)
private
FCursor: Integer;
FOwnList: TJclIntfArrayList;
//FLastRet: Integer;
FSize: Integer;
protected
{ IJclIntfIterator}
procedure Add(AInterface: IInterface);
function GetObject: IInterface;
function HasNext: Boolean;
function HasPrevious: Boolean;
function Next: IInterface;
function NextIndex: Integer;
function Previous: IInterface;
function PreviousIndex: Integer;
procedure Remove;
procedure SetObject(AInterface: IInterface);
public
constructor Create(AOwnList: TJclIntfArrayList);
destructor Destroy; override;
end;
constructor TIntfItr.Create(AOwnList: TJclIntfArrayList);
begin
inherited Create;
FCursor := 0;
FOwnList := AOwnList;
FOwnList._AddRef; // Add a ref because FOwnList is not an interface !
//FLastRet := -1;
FSize := FOwnList.Size;
end;
destructor TIntfItr.Destroy;
begin
FOwnList._Release;
inherited Destroy;
end;
procedure TIntfItr.Add(AInterface: IInterface);
{$IFDEF THREADSAFE}
var
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
// inlined FOwnList.Add
if FOwnList.FSize = FOwnList.Capacity then
FOwnList.Grow;
if FOwnList.FSize <> FCursor then
System.Move(FOwnList.FElementData[FCursor], FOwnList.FElementData[FCursor + 1],
(FOwnList.FSize - FCursor) * SizeOf(IInterface));
// (rom) otherwise interface reference counting may crash
FillChar(FOwnList.FElementData[FCursor], SizeOf(IInterface), 0);
FOwnList.FElementData[FCursor] := AInterface;
Inc(FOwnList.FSize);
Inc(FSize);
Inc(FCursor);
//FLastRet := -1;
end;
function TIntfItr.GetObject: IInterface;
{$IFDEF THREADSAFE}
var
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Result := FOwnList.FElementData[FCursor];
end;
function TIntfItr.HasNext: Boolean;
begin
Result := FCursor < FSize;
end;
function TIntfItr.HasPrevious: Boolean;
begin
Result := FCursor > 0;
end;
function TIntfItr.Next: IInterface;
{$IFDEF THREADSAFE}
var
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Result := FOwnList.FElementData[FCursor];
//FLastRet := FCursor;
Inc(FCursor);
end;
function TIntfItr.NextIndex: Integer;
begin
Result := FCursor;
end;
function TIntfItr.Previous: IInterface;
{$IFDEF THREADSAFE}
var
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Dec(FCursor);
//FLastRet := FCursor;
Result := FOwnList.FElementData[FCursor];
end;
function TIntfItr.PreviousIndex: Integer;
begin
Result := FCursor - 1;
end;
procedure TIntfItr.Remove;
{$IFDEF THREADSAFE}
var
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
with FOwnList do
begin
FElementData[FCursor] := nil; // Force Release
if FSize <> FCursor then
System.Move(FElementData[FCursor + 1], FElementData[FCursor],
(FSize - FCursor) * SizeOf(IInterface));
end;
Dec(FOwnList.FSize);
Dec(FSize);
end;
procedure TIntfItr.SetObject(AInterface: IInterface);
{$IFDEF THREADSAFE}
var
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{
if FLastRet = -1 then
raise EJclIllegalState.Create(SIllegalState);
}
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
FOwnList.FElementData[FCursor] := AInterface;
end;
//=== { TStrItr } ============================================================
type
TStrItr = class(TJclAbstractContainer, IJclStrIterator)
private
FCursor: Integer;
FOwnList: TJclStrArrayList;
//FLastRet: Integer;
FSize: Integer;
protected
{ IJclStrIterator}
procedure Add(const AString: string);
function GetString: string;
function HasNext: Boolean;
function HasPrevious: Boolean;
function Next: string;
function NextIndex: Integer;
function Previous: string;
function PreviousIndex: Integer;
procedure Remove;
procedure SetString(const AString: string);
public
constructor Create(AOwnList: TJclStrArrayList);
destructor Destroy; override;
end;
constructor TStrItr.Create(AOwnList: TJclStrArrayList);
begin
inherited Create;
FCursor := 0;
FOwnList := AOwnList;
FOwnList._AddRef; // Add a ref because FOwnList is not an interface !
//FLastRet := -1;
FSize := FOwnList.Size;
end;
destructor TStrItr.Destroy;
begin
FOwnList._Release;
inherited Destroy;
end;
procedure TStrItr.Add(const AString: string);
{$IFDEF THREADSAFE}
var
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
// inlined FOwnList.Add
if FOwnList.FSize = FOwnList.Capacity then
FOwnList.Grow;
if FOwnList.FSize <> FCursor then
System.Move(FOwnList.FElementData[FCursor], FOwnList.FElementData[FCursor + 1],
(FOwnList.FSize - FCursor) * SizeOf(string));
// (rom) otherwise string reference counting may crash
FillChar(FOwnList.FElementData[FCursor], SizeOf(string), 0);
FOwnList.FElementData[FCursor] := AString;
Inc(FOwnList.FSize);
Inc(FSize);
Inc(FCursor);
//FLastRet := -1;
end;
function TStrItr.GetString: string;
{$IFDEF THREADSAFE}
var
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Result := FOwnList.FElementData[FCursor];
end;
function TStrItr.HasNext: Boolean;
begin
Result := FCursor < FSize;
end;
function TStrItr.HasPrevious: Boolean;
begin
Result := FCursor > 0;
end;
function TStrItr.Next: string;
{$IFDEF THREADSAFE}
var
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Result := FOwnList.FElementData[FCursor];
//FLastRet := FCursor;
Inc(FCursor);
end;
function TStrItr.NextIndex: Integer;
begin
Result := FCursor;
end;
function TStrItr.Previous: string;
{$IFDEF THREADSAFE}
var
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Dec(FCursor);
//FLastRet := FCursor;
Result := FOwnList.FElementData[FCursor];
end;
function TStrItr.PreviousIndex: Integer;
begin
Result := FCursor - 1;
end;
procedure TStrItr.Remove;
{$IFDEF THREADSAFE}
var
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
with FOwnList do
begin
FElementData[FCursor] := ''; // Force Release
if FSize <> FCursor then
System.Move(FElementData[FCursor + 1], FElementData[FCursor],
(FSize - FCursor) * SizeOf(string));
end;
Dec(FOwnList.FSize);
Dec(FSize);
end;
procedure TStrItr.SetString(const AString: string);
{$IFDEF THREADSAFE}
var
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{
if FLastRet = -1 then
raise EJclIllegalState.Create(SIllegalState);
}
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
FOwnList.FElementData[FCursor] := AString;
end;
//=== { TItr } ===============================================================
type
TItr = class(TJclAbstractContainer, IJclIterator)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -