Skip to content

RTL: TArrayHelper<T>.BinarySearch resets AFoundIndex to -1

  • Lazarus/FPC Version: Lazarus 3.99 (rev main_3_99-2290-gf76614452c) FPC 3.3.1 x86_64-win64-win32/win64
  • Operating System: any
  • CPU / Bitness: both

What happens

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 resets AFoundIndex to -1

What did you expect

TArrayHelper.BinarySearch will return the correct item position even if the item is missing. https://docwiki.embarcadero.com/Libraries/Sydney/en/System.Generics.Collections.TArray.BinarySearch

FoundIndex contains the index of the first entry larger than Item.

Steps to reproduce

program Project1;

{$mode Delphi}

uses
  SysUtils,
  Generics.Collections,
  Generics.Defaults,
  Math;

type
  TStackParam = record
    Base, Limit: Word;
  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)
  );

  S.Limit := 100;
  S.Base := 200;
  List.Add(S);

  S.Limit := 50;
  List.BinarySearch(S, Index);
  if Index <> 0 then
    raise Exception.CreateFmt('Index should be equal to 0, but instead it is equal to %d', [Index]);

  List.Free;
end. 

Suggested patch

I propose to make small changes in the form of the following patch (includes test)

8.fpc_41043_binarysearch.patch

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information