* patch by Alexander (Rouse_) Bagel: TArrayHelper.BinarySearch, when searching

for an element that is obviously missing from the array, should return
    the position where the element should have been, but instead it reset AFoundIndex to -1, resolves #40867
This commit is contained in:
florian 2024-08-29 21:18:57 +01:00
parent 90cc6db5cb
commit 7d1bb89455
2 changed files with 85 additions and 10 deletions

View File

@ -1335,17 +1335,11 @@ begin
// deferred test for equality
AFoundIndex := imin;
LCompare := AComparer.Compare(AValues[imin], AItem);
if (imax = imin) and (LCompare = 0) then
begin
AFoundIndex := imin;
Exit(True);
end
else
begin
AFoundIndex := -1;
Exit(False);
end;
Result := (imax = imin) and (LCompare = 0);
if not Result and (LCompare < 0) then
Inc(AFoundIndex);
end;
{ TEnumerator<T> }

81
tests/tbs/tb0716.pp Normal file
View File

@ -0,0 +1,81 @@
program tbs9001;
{$mode Delphi}
uses
SysUtils,
Generics.Collections,
Generics.Defaults,
Math;
type
TStackParam = record
Base, Limit: QWord;
end;
var
List: TList<TStackParam>;
S: TStackParam;
Index: SizeInt;
begin
List := TList<TStackParam>.Create(TComparer<TStackParam>.Construct(
function (const A, B: TStackParam): Integer
begin
Result := IfThen(A.Limit < B.Limit, -1,
IfThen(A.Limit = B.Limit, 0, 1));
end)
);
try
S.Limit := 100;
S.Base := 200;
List.Add(S);
S.Limit := 210;
S.Base := 300;
List.Add(S);
S.Limit := 350;
S.Base := 400;
List.Add(S);
S.Limit := 50;
if List.BinarySearch(S, Index) or (Index <> 0) then
Halt(1);
S.Limit := 100;
if not List.BinarySearch(S, Index) or (Index <> 0) then
Halt(2);
S.Limit := 150;
if List.BinarySearch(S, Index) or (Index <> 1) then
Halt(3);
S.Limit := 210;
if not List.BinarySearch(S, Index) or (Index <> 1) then
Halt(4);
S.Limit := 290;
if List.BinarySearch(S, Index) or (Index <> 2) then
Halt(5);
S.Limit := 340;
if List.BinarySearch(S, Index) or (Index <> 2) then
Halt(6);
S.Limit := 350;
if not List.BinarySearch(S, Index) or (Index <> 2) then
Halt(7);
S.Limit := 360;
if List.BinarySearch(S, Index) or (Index <> 3) then
Halt(8);
S.Limit := 450;
if List.BinarySearch(S, Index) or (Index <> 3) then
Halt(9);
finally
List.Free;
end;
end.