📄 jcllinkedlists.pas
字号:
Inc(FSize);
end
else
begin
Current := FStart;
for I := 0 to Index - 2 do
Current := Current.Next;
NewItem.Next := Current.Next;
Current.Next := NewItem;
Inc(FSize);
end;
end;
function TJclLinkedList.Add(AObject: TObject): Boolean;
var
NewItem: PJclLinkedListItem;
{$IFDEF THREADSAFE}
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Result := False;
if AObject = nil then
Exit;
Result := True;
if FStart = nil then
begin
AddFirst(AObject);
Exit;
end;
New(NewItem);
NewItem.Obj := AObject;
NewItem.Next := nil;
FEnd.Next := NewItem;
FEnd := NewItem;
Inc(FSize);
end;
function TJclLinkedList.AddAll(ACollection: IJclCollection): Boolean;
var
It: IJclIterator;
{$IFDEF THREADSAFE}
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Result := False;
if ACollection = nil then
Exit;
It := ACollection.First;
while It.HasNext do
Result := Add(It.Next) or Result;
Result := True;
end;
function TJclLinkedList.InsertAll(Index: Integer; ACollection: IJclCollection): Boolean;
var
I: Integer;
It: IJclIterator;
Current: PJclLinkedListItem;
NewItem: PJclLinkedListItem;
{$IFDEF THREADSAFE}
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Result := False;
if (Index < 0) or (Index > FSize) then
raise EJclOutOfBoundsError.CreateRes(@RsEOutOfBounds);
if ACollection = nil then
Exit;
It := ACollection.First;
// (rom) is this a bug? Only one element added.
if (FStart = nil) and It.HasNext then
begin
AddFirst(It.Next);
Exit;
end;
Current := FStart;
I := 0;
while (Current <> nil) and (I <> Index) do
Current := Current.Next;
while It.HasNext do
begin
New(NewItem);
NewItem.Obj := It.Next;
if Index = 0 then
begin
NewItem.Next := FStart;
FStart := NewItem;
Inc(FSize);
end
else
begin
NewItem.Next := Current.Next;
Current.Next := NewItem;
Inc(FSize);
end;
Inc(Index);
end;
Result := True;
end;
procedure TJclLinkedList.AddFirst(AObject: TObject);
begin
New(FStart);
FStart.Obj := AObject;
FStart.Next := nil;
FEnd := FStart;
Inc(FSize);
end;
procedure TJclLinkedList.Clear;
var
I: Integer;
Old, Current: PJclLinkedListItem;
{$IFDEF THREADSAFE}
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Current := FStart;
for I := 0 to FSize - 1 do
begin
Current.Obj := nil;
Old := Current;
Current := Current.Next;
Dispose(Old);
end;
FSize := 0;
//Daniele Teti 27/12/2004
FStart := nil;
FEnd := nil;
end;
function TJclLinkedList.Clone: TObject;
var
NewList: TJclLinkedList;
begin
NewList := TJclLinkedList.Create;
NewList.AddAll(Self);
Result := NewList;
end;
function TJclLinkedList.Contains(AObject: TObject): Boolean;
var
I: Integer;
Current: PJclLinkedListItem;
{$IFDEF THREADSAFE}
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Result := False;
if AObject = nil then
Exit;
Current := FStart;
for I := 0 to FSize - 1 do
begin
if Current.Obj = AObject then
begin
Result := True;
Break;
end;
Current := Current.Next;
end;
end;
function TJclLinkedList.ContainsAll(ACollection: IJclCollection): Boolean;
var
It: IJclIterator;
{$IFDEF THREADSAFE}
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Result := True;
if ACollection = nil then
Exit;
It := ACollection.First;
while Result and It.HasNext do
Result := contains(It.Next);
end;
function TJclLinkedList.Equals(ACollection: IJclCollection): Boolean;
var
It, ItSelf: IJclIterator;
{$IFDEF THREADSAFE}
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Result := False;
if ACollection = nil then
Exit;
if FSize <> ACollection.Size then
Exit;
It := ACollection.First;
ItSelf := First;
while ItSelf.HasNext do
if ItSelf.Next <> It.Next then
Exit;
Result := True;
end;
procedure TJclLinkedList.FreeObject(var AObject: TObject);
begin
if FOwnsObjects then
begin
AObject.Free;
AObject := nil;
end;
end;
function TJclLinkedList.GetObject(Index: Integer): TObject;
var
I: Integer;
Current: PJclLinkedListItem;
{$IFDEF THREADSAFE}
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Result := nil;
if FStart = nil then
Exit;
Current := FStart;
for I := 0 to Index - 1 do
Current := Current.Next;
Result := Current.Obj;
end;
function TJclLinkedList.IndexOf(AObject: TObject): Integer;
var
I: Integer;
Current: PJclLinkedListItem;
{$IFDEF THREADSAFE}
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Result := -1;
if AObject = nil then
Exit;
if FStart = nil then
Exit;
Current := FStart;
for I := 0 to FSize - 1 do
begin
if Current.Obj = AObject then
begin
Result := I;
Break;
end;
Current := Current.Next;
end;
end;
function TJclLinkedList.First: IJclIterator;
begin
Result := TItr.Create(Self, FStart);
end;
function TJclLinkedList.IsEmpty: Boolean;
begin
Result := FSize = 0;
end;
function TJclLinkedList.Last: IJclIterator;
begin
Result := TItr.Create(Self, FStart);
end;
function TJclLinkedList.LastIndexOf(AObject: TObject): Integer;
var
I: Integer;
Current: PJclLinkedListItem;
{$IFDEF THREADSAFE}
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Result := -1;
if AObject = nil then
Exit;
if FStart = nil then
Exit;
Current := FStart;
for I := 0 to FSize - 1 do
begin
if Current.Obj = AObject then
Result := I;
Current := Current.Next;
end;
end;
function TJclLinkedList.Remove(AObject: TObject): Boolean;
var
I: Integer;
Old, Current: PJclLinkedListItem;
{$IFDEF THREADSAFE}
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Result := False;
if AObject = nil then
Exit;
if FStart = nil then
Exit;
Old := nil;
Current := FStart;
for I := 0 to FSize - 1 do
begin
if Current.Obj = AObject then
begin
FreeObject(Current.Obj);
if Old <> nil then
begin
Old.Next := Current.Next;
if Old.Next = nil then
FEnd := Old;
end
else
FStart := Current.Next;
Dispose(Current);
Dec(FSize);
Result := True;
Exit;
end;
Old := Current;
Current := Current.Next;
end;
end;
function TJclLinkedList.Remove(Index: Integer): TObject;
var
I: Integer;
Old, Current: PJclLinkedListItem;
{$IFDEF THREADSAFE}
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Result := nil;
if FStart = nil then
Exit;
Old := nil;
Current := FStart;
for I := 0 to Index - 1 do
begin
Old := Current;
Current := Current.Next;
end;
FreeObject(Current.Obj);
if Old <> nil then
begin
Old.Next := Current.Next;
if Old.Next = nil then
FEnd := Old;
end
else
FStart := Current.Next;
Dispose(Current);
Dec(FSize);
end;
function TJclLinkedList.RemoveAll(ACollection: IJclCollection): Boolean;
var
It: IJclIterator;
{$IFDEF THREADSAFE}
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Result := True;
if ACollection = nil then
Exit;
It := ACollection.First;
while It.HasNext do
Result := Remove(It.Next) and Result;
end;
function TJclLinkedList.RetainAll(ACollection: IJclCollection): Boolean;
var
It: IJclIterator;
{$IFDEF THREADSAFE}
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Result := False;
if ACollection = nil then
Exit;
It := First;
while It.HasNext do
if not ACollection.Contains(It.Next) then
It.Remove;
end;
procedure TJclLinkedList.SetObject(Index: Integer; AObject: TObject);
var
I: Integer;
Current: PJclLinkedListItem;
{$IFDEF THREADSAFE}
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
if FStart = nil then
Exit;
Current := FStart;
for I := 0 to Index - 1 do
Current := Current.Next;
Current.Obj := AObject;
end;
function TJclLinkedList.Size: Integer;
begin
Result := FSize;
end;
function TJclLinkedList.SubList(First, Count: Integer): IJclList;
var
I: Integer;
It: IJclIterator;
Last: Integer;
{$IFDEF THREADSAFE}
CS: IInterface;
{$ENDIF THREADSAFE}
begin
{$IFDEF THREADSAFE}
CS := EnterCriticalSection;
{$ENDIF THREADSAFE}
Last := First + Count - 1;
if Last > FSize then
Last := FSize - 1;
Result := TJclLinkedList.Create;
I := 0;
It := Self.First;
while (I < First) and It.HasNext do
begin
It.Next;
Inc(I);
end;
while (I <= Last) and It.HasNext do
begin
Result.Add(It.Next);
Inc(I);
end;
end;
{
function TJclStrLinkedList.GetAsStrings: TStrings;
begin
Result := TStringList.Create;
try
AppendToStrings(Result);
except
Result.Free;
raise;
end;
end;
procedure TJclStrLinkedList.LoadFromStrings(Strings: TStrings);
begin
Clear;
AppendFromStrings(Strings);
end;
procedure TJclStrLinkedList.AppendToStrings(Strings: TStrings);
var
It: IJclStrIterator;
begin
It := First;
Strings.BeginUpdate;
try
while It.HasNext do
Strings.Add(It.Next);
finally
Strings.EndUpdate;
end;
end;
procedure TJclStrLinkedList.SaveToStrings(Strings: TStrings);
begin
Strings.Clear;
AppendToStrings(Strings);
end;
procedure TJclStrLinkedList.AppendFromStrings(Strings: TStrings);
var
I: Integer;
begin
for I := 0 to Strings.Count - 1 do
Add(Strings[I]);
end;
function TJclStrLinkedList.GetAsDelimited(Separator: string): string;
var
It: IJclStrIterator;
begin
It := First;
Result := '';
if It.HasNext then
Result := It.Next;
while It.HasNext do
Result := Result + Separator + It.Next;
end;
procedure TJclStrLinkedList.AppendDelimited(AString, Separator: string);
begin
DCLAppendDelimited(Self, AString, Separator);
end;
procedure TJclStrLinkedList.LoadDelimited(AString, Separator: string);
begin
Clear;
AppendDelimited(AString, Separator);
end;
}
// History:
// $Log: JclLinkedLists.pas,v $
// Revision 1.8 2005/03/08 15:14:00 dade2004
// Fixed some bug on
// IJclStrList.InsertAll implementation
//
// Revision 1.7 2005/03/08 08:33:16 marquardt
// overhaul of exceptions and resourcestrings, minor style cleaning
//
// Revision 1.6 2005/03/03 08:02:57 marquardt
// various style cleanings, bugfixes and improvements
//
// Revision 1.5 2005/03/02 17:51:24 rrossmair
// - removed DCLAppendDelimited from JclAlgorithms, changed uses clauses accordingly
//
// Revision 1.4 2005/03/02 09:59:30 dade2004
// Added
// -TJclStrCollection in JclContainerIntf
// Every common methods for IJclStrCollection are implemented here
//
// -Every class that implement IJclStrCollection now derive from TJclStrCollection instead of TJclAbstractContainer
// -Every abstract method in TJclStrCollection has been marked as "override" in descendent classes
//
// DCLAppendDelimited has been removed from JclAlgorothms, his body has been fixed for a bug and put into
// relative method in TJclStrCollection
//
// Revision 1.3 2005/02/27 07:27:47 marquardt
// changed interface names from I to IJcl, moved resourcestrings to JclResource.pas
//
// Revision 1.2 2005/02/24 07:36:24 marquardt
// resolved the compiler warnings, style cleanup, removed code from JclContainerIntf.pas
//
// Revision 1.1 2005/02/24 03:57:10 rrossmair
// - donated DCL code, initial check-in
//
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -