lazarus-ccr/components/orpheus/o32intdeq.pas
2007-01-16 02:17:08 +00:00

147 lines
4.6 KiB
ObjectPascal

{*********************************************************}
{* O32INTDEQ.PAS 4.06 *}
{*********************************************************}
{* ***** BEGIN LICENSE BLOCK ***** *}
{* Version: MPL 1.1 *}
{* *}
{* 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 TurboPower Orpheus *}
{* *}
{* The Initial Developer of the Original Code is TurboPower Software *}
{* *}
{* Portions created by TurboPower Software Inc. are Copyright (C)1995-2002 *}
{* TurboPower Software Inc. All Rights Reserved. *}
{* *}
{* Contributor(s): *}
{* *}
{* ***** END LICENSE BLOCK ***** *}
{The following is a modified version of deque code, which was originally written
for Algorithms Alfresco. It is copyright(c)2001 by Julian M. Bucknall and is
used here with permission.}
{$I OVC.INC}
{$B-} {Complete Boolean Evaluation}
{$I+} {Input/Output-Checking}
{$P+} {Open Parameters}
{$T-} {Typed @ Operator}
{.W-} {Windows Stack Frame}
{$X+} {Extended Syntax}
unit o32intdeq;
{A simple deque class for Orpheus}
interface
uses
Classes;
type
TO32IntDeque = class
protected {private}
FList : TList;
FHead : integer;
FTail : integer;
procedure idGrow;
public
constructor Create(aCapacity : integer);
destructor Destroy; override;
function IsEmpty : boolean;
procedure Enqueue(aValue: integer);
procedure Push(aValue: integer);
function Pop: integer;
end;
implementation
uses
SysUtils;
{=== TO32IntDeque ====================================================}
constructor TO32IntDeque.Create(aCapacity : integer);
begin
inherited Create;
FList := TList.Create;
FList.Count := aCapacity;
{let's help out the user of the deque by putting the head and tail
pointers in the middle: it's probably more efficient}
FHead := aCapacity div 2;
FTail := FHead;
end;
{--------}
destructor TO32IntDeque.Destroy;
begin
FList.Free;
inherited Destroy;
end;
{--------}
procedure TO32IntDeque.Enqueue(aValue : integer);
begin
FList.List^[FTail] := pointer(aValue);
inc(FTail);
if (FTail = FList.Count) then
FTail := 0;
if (FTail = FHead) then
idGrow;
end;
{--------}
procedure TO32IntDeque.idGrow;
var
OldCount : integer;
i, j : integer;
begin
{grow the list by 50%}
OldCount := FList.Count;
FList.Count := (OldCount * 3) div 2;
{expand the data into the increased space, maintaining the deque}
if (FHead = 0) then
FTail := OldCount
else begin
j := FList.Count;
for i := pred(OldCount) downto FHead do begin
dec(j);
FList.List^[j] := FList.List^[i]
end;
FHead := j;
end;
end;
{--------}
function TO32IntDeque.IsEmpty : boolean;
begin
Result := FHead = FTail;
end;
{--------}
procedure TO32IntDeque.Push(aValue : integer);
begin
if (FHead = 0) then
FHead := FList.Count;
dec(FHead);
FList.List^[FHead] := pointer(aValue);
if (FTail = FHead) then
idGrow;
end;
{--------}
function TO32IntDeque.Pop : integer;
begin
if FHead = FTail then
raise Exception.Create('Integer deque is empty: cannot pop');
Result := integer(FList.List^[FHead]);
inc(FHead);
if (FHead = FList.Count) then
FHead := 0;
end;
{=== TO32IntDeque - end ==============================================}
end.