CentrED/ULinkedList.pas

168 lines
3.9 KiB
Plaintext

(*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at
* http://www.opensource.org/licenses/cddl1.php.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at
* http://www.opensource.org/licenses/cddl1.php. If applicable,
* add the following below this CDDL HEADER, with the fields enclosed
* by brackets "[]" replaced with your own identifying * information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Portions Copyright 2007 Andreas Schneider
*)
unit ULinkedList;
interface
uses
SysUtils;
type
PLinkedItem = ^TLinkedItem;
TLinkedItem = record
ID: Integer;
Data: Pointer;
Next: PLinkedItem;
end;
TLinkedList = class(TObject)
constructor Create; virtual;
destructor Destroy; override;
protected
FFirst: PLinkedItem;
FLast: PLinkedItem;
public
procedure Clear; virtual;
function Iterate(var ALinkedItem: PLinkedItem): Boolean; virtual;
function Add(AID: Integer; AData: Pointer): PLinkedItem; virtual;
procedure Delete(AData: Pointer); overload; virtual;
procedure Delete(AID: Integer); overload; virtual;
function Get(AID: Integer): Pointer; virtual;
property Last: PLinkedItem read FLast;
end;
implementation
{ TBlockList }
function TLinkedList.Add(AID: Integer; AData: Pointer): PLinkedItem;
var
current: PLinkedItem;
begin
New(current);
current^.ID := AID;
current^.Data := AData;
current^.Next := nil;
if FFirst = nil then FFirst := current;
if FLast <> nil then FLast^.Next := current;
FLast := current;
Result := current;
end;
procedure TLinkedList.Clear;
var
current, next: PLinkedItem;
begin
current := FFirst;
while current <> nil do
begin
next := current^.Next;
Dispose(current);
current := next;
end;
FFirst := nil;
FLast := nil;
end;
constructor TLinkedList.Create;
begin
inherited Create;
FFirst := nil;
FLast := nil;
end;
procedure TLinkedList.Delete(AData: Pointer);
var
currentItem, lastItem, nextItem: PLinkedItem;
begin
lastItem := nil;
currentItem := FFirst;
while currentItem <> nil do
begin
if currentItem^.Data = AData then
begin
if FFirst = currentItem then FFirst := currentItem^.Next;
if FLast = currentItem then FLast := lastItem;
if lastItem <> nil then lastItem^.Next := currentItem^.Next;
Dispose(currentItem);
nextItem := nil;
end else
nextItem := currentItem^.Next;
lastItem := currentItem;
currentItem := nextItem;
end;
end;
procedure TLinkedList.Delete(AID: Integer);
var
currentItem, lastItem, nextItem: PLinkedItem;
begin
lastItem := nil;
currentItem := FFirst;
while currentItem <> nil do
begin
if currentItem^.ID = AID then
begin
if FFirst = currentItem then FFirst := currentItem^.Next;
if FLast = currentItem then FLast := lastItem;
if lastItem <> nil then lastItem^.Next := currentItem^.Next;
Dispose(currentItem);
nextItem := nil;
end else
nextItem := currentItem^.Next;
lastItem := currentItem;
currentItem := nextItem;
end;
end;
destructor TLinkedList.Destroy;
begin
Clear;
inherited Destroy;
end;
function TLinkedList.Get(AID: Integer): Pointer;
var
item: PLinkedItem;
begin
Result := nil;
item := nil;
while Iterate(item) and (Result = nil) do
if item^.ID = AID then
Result := item^.Data;
end;
function TLinkedList.Iterate(var ALinkedItem: PLinkedItem): Boolean;
begin
if ALinkedItem = nil then
ALinkedItem := FFirst
else
ALinkedItem := ALinkedItem^.Next;
Result := ALinkedItem <> nil;
end;
end.