📄 ezdslbar.pas
字号:
if not aAction(Self, Result, aExtraData) then
Exit;
end;
CurByte := CurByte shl 1;
end;
end;
end;
Result := -1;
end;
{--------}
procedure TezBooleanArray.baRecount;
{$I EZBitCnt.INC}
var
i : longint;
NewCount : longint;
begin
{if there are no booleans, there can't be any true ones}
if (Capacity = 0) then begin
baCount := 0;
Exit;
end;
{count in byte sized chunks; use local variable for speed} {!!.03}
NewCount := 0; {!!.03}
for i := 0 to pred(baArraySize) do {!!.03}
inc(NewCount, BitCount[baArray^[i]]); {!!.03}
baCount := NewCount; {!!.03}
end;
{--------}
procedure TezBooleanArray.baSetFlag(aInx : longint; aValue : boolean);
var
ByteNum : integer;
BitNum : integer;
begin
if (aInx < 0) or (aInx >= Capacity) then
RaiseError(escBadBooleanInx);
if (baArray <> nil) then begin
ByteNum := aInx div 8;
BitNum := aInx mod 8;
if aValue then begin
if ((baArray^[ByteNum] and Mask[BitNum]) = 0) then begin
inc(baCount);
baArray^[ByteNum] := baArray^[ByteNum] or Mask[BitNum];
end;
end
else begin
if ((baArray^[ByteNum] and Mask[BitNum]) <> 0) then begin
dec(baCount);
baArray^[ByteNum] := baArray^[ByteNum] and (not Mask[BitNum]);
end;
end;
end;
end;
{--------}
procedure TezBooleanArray.baSetCapacity(aCapacity : longint);
var
NewArray : PByteArray;
NewSize : longint;
begin
{$IFDEF DEBUG}
EZAssert(aCapacity >= 0, ascBadCapacity);
{$ENDIF}
if (aCapacity = baCapacity) then
Exit;
if (aCapacity = 0) then begin
NewSize := 0;
NewArray := nil;
end
else begin
NewSize := (aCapacity + 7) shr 3;
GetMem(NewArray, NewSize);
if (baArray = nil) then
FillChar(NewArray^, NewSize, 0)
else begin
if (NewSize <= baArraySize) then
Move(baArray^, NewArray^, NewSize)
else begin
FillChar(NewArray^[baArraySize], {!!.03}
NewSize - baArraySize, 0); {!!.03}
Move(baArray^, NewArray^, baArraySize);
end;
end;
end;
if baArrayOwner and (baArray <> nil) then
FreeMem(baArray, baArraySize);
baArray := NewArray;
baArraySize := NewSize;
baCapacity := aCapacity;
baArrayOwner := (aCapacity <> 0);
baCalcCleanMask; {!!.03}
end;
{--------}
function TezBooleanArray.Iterate(aAction : TezBooleanArrayIterator;
aValue : boolean;
aBackwards : boolean;
aExtraData : pointer) : longint;
begin
if (Capacity = 0) then
Result := -1
else begin
if aBackwards then
Result := baIterateBkwd(pred(Capacity), aValue, aAction, aExtraData)
else
Result := baIterateFwd(0, aValue, aAction, aExtraData)
end;
end;
{--------}
function TezBooleanArray.FirstFalse : longint;
begin
if (Capacity = 0) or (Count = Capacity) then
Result := -1
else
Result := baIterateFwd(0, false, AlwaysStop, nil);
end;
{--------}
function TezBooleanArray.FirstTrue : longint;
begin
if (Capacity = 0) or (Count = 0) then
Result := -1
else
Result := baIterateFwd(0, true, AlwaysStop, nil);
end;
{--------}
function TezBooleanArray.LastFalse : longint;
begin
if (Capacity = 0) or (Count = Capacity) then
Result := -1
else
Result := baIterateBkwd(pred(Capacity), false, AlwaysStop, nil);
end;
{--------}
function TezBooleanArray.LastTrue : longint;
begin
if (Capacity = 0) or (Count = 0) then
Result := -1
else
Result := baIterateBkwd(pred(Capacity), true, AlwaysStop, nil);
end;
{--------}
function TezBooleanArray.NextFalse(aFromInx : longint) : longint;
begin
inc(aFromInx);
if (aFromInx < 0) or (aFromInx >= Capacity) then
Result := -1
else
Result := baIterateFwd(aFromInx, false, AlwaysStop, nil);
end;
{--------}
function TezBooleanArray.NextTrue(aFromInx : longint) : longint;
begin
inc(aFromInx);
if (aFromInx < 0) or (aFromInx >= Capacity) then
Result := -1
else
Result := baIterateFwd(aFromInx, true, AlwaysStop, nil);
end;
{--------}
procedure TezBooleanArray.OrArray(aArray : TezBooleanArray);
var
i : integer;
begin
{$IFDEF DEBUG}
EZAssert(aArray <> nil, ascNilArray);
EZAssert(Capacity = aArray.Capacity, ascNotSameSize);
{$ENDIF}
for i := 0 to pred(baArraySize) do
baArray^[i] := baArray^[i] or aArray.baArray^[i];
baArray^[pred(baArraySize)] := {!!.03}
baArray^[pred(baArraySize)] and baCleanMask; {!!.03}
baRecount; {!!.03}
end;
{--------}
function TezBooleanArray.PrevFalse(aFromInx : longint) : longint;
begin
dec(aFromInx);
if (aFromInx < 0) or (aFromInx >= Capacity) then
Result := -1
else
Result := baIterateBkwd(aFromInx, false, AlwaysStop, nil);
end;
{--------}
function TezBooleanArray.PrevTrue(aFromInx : longint) : longint;
begin
dec(aFromInx);
if (aFromInx < 0) or (aFromInx >= Capacity) then
Result := -1
else
Result := baIterateBkwd(aFromInx, true, AlwaysStop, nil);
end;
{--------}
procedure TezBooleanArray.SetAllFalse;
begin
if (baArray <> nil) then begin
FillChar(baArray^, baArraySize, 0);
baCount := 0;
end;
end;
{--------}
procedure TezBooleanArray.SetAllTrue;
begin
if (baArray <> nil) then begin
FillChar(baArray^, baArraySize, $FF);
baArray^[pred(baArraySize)] := {!!.03}
baArray^[pred(baArraySize)] and baCleanMask; {!!.03}
baCount := baCapacity;
end;
end;
{--------}
procedure TezBooleanArray.SwitchArrays(aNewArray : PByteArray;
aCapacity : longint);
begin
if baArrayOwner and (baCapacity <> 0) then
baSetCapacity(0);
if (aNewArray = nil) then begin
baArray := nil;
baArraySize := 0;
baCapacity := 0;
baArrayOwner := false;
baCount := 0;
baCleanMask := 0;
end
else begin
baArray := aNewArray;
baArraySize := (aCapacity + 7) shr 3;
baCapacity := aCapacity;
baArrayOwner := false;
baCalcCleanMask; {!!.03}
baArray^[pred(baArraySize)] := {!!.03}
baArray^[pred(baArraySize)] and baCleanMask; {!!.03}
baRecount;
end;
end;
{--------}
function TezBooleanArray.Toggle(aInx : longint) : boolean;
{rewritten !!.03}
var
ByteNum : integer;
BitNum : integer;
begin
if (aInx < 0) or (aInx >= Capacity) then
RaiseError(escBadBooleanInx);
ByteNum := aInx div 8;
BitNum := aInx mod 8;
Result := (baArray^[ByteNum] and Mask[BitNum]) = 0;
if Result then begin
baArray^[ByteNum] := baArray^[ByteNum] or Mask[BitNum];
inc(baCount)
end
else begin
baArray^[ByteNum] := baArray^[ByteNum] and (not Mask[BitNum]);
dec(baCount);
end;
end;
{--------}
procedure TezBooleanArray.ToggleAll;
var
i : longint;
begin
if (baArray <> nil) then begin {!!.03}
for i := 0 to pred(baArraySize) do
baArray^[i] := not baArray^[i];
baArray^[pred(baArraySize)] := {!!.03}
baArray^[pred(baArraySize)] and baCleanMask; {!!.03}
baRecount; {!!.03}
end; {!!.03}
end;
{--------}
procedure TezBooleanArray.XorArray(aArray : TezBooleanArray);
var
i : integer;
begin
{$IFDEF DEBUG}
EZAssert(aArray <> nil, ascNilArray);
EZAssert(Capacity = aArray.Capacity, ascNotSameSize);
{$ENDIF}
for i := 0 to pred(baArraySize) do
baArray^[i] := baArray^[i] xor aArray.baArray^[i];
baArray^[pred(baArraySize)] := {!!.03}
baArray^[pred(baArraySize)] and baCleanMask; {!!.03}
baRecount; {!!.03}
end;
{====================================================================}
{$IFDEF ThreadsExist}
{===TezThreadsafeBooleanArray========================================}
constructor TezThreadsafeBooleanArray.Create(aCapacity : longint);
begin
inherited Create;
baResLock := TezResourceLock.Create;
baBooleanArray := TezBooleanArray.Create(aCapacity);
end;
{--------}
destructor TezThreadsafeBooleanArray.Destroy;
begin
baBooleanArray.Free;
baResLock.Free;
inherited Destroy;
end;
{--------}
function TezThreadsafeBooleanArray.AcquireAccess : TezBooleanArray;
begin
baResLock.Lock;
Result := baBooleanArray;
end;
{--------}
procedure TezThreadsafeBooleanArray.ReleaseAccess;
begin
baResLock.Unlock;
end;
{====================================================================}
{$ENDIF}
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -