Het lijkt erop dat de internal error door de 'kruisverwijzing' in de TEnumeratorForFastList komt.
Code:
unit Base.Utils;
interface
uses
System.Types, System.Classes, System.SysUtils, System.TypInfo, System.IniFiles, System.Math, System.Contnrs,
TFastObjectList<T: class> = class;
// fastest possible 'for in' loop support
TEnumeratorForFastList<T: class> = record
private
fIndex: Integer;
fList: TFastObjectList<T>;
public
function MoveNext: Boolean; inline;
function GetCurrent: T; inline;
property Current: T read GetCurrent;
end;
// fast typed object list
TFastObjectList<T: class> = class(TObjectList)
public
function GetEnumerator: TEnumeratorForFastList<T>; inline;
function ValidIndex(ix: Integer): Boolean; inline;
procedure CheckIndex(aIndex: Integer);
function GetItem(aIndex: Integer): T; inline;
function First: T; inline;
function Last: T; inline;
function FirstOrDefault: T; inline;
function LastOrDefault: T; inline;
function HasItems: Boolean; inline;
function IsEmpty: Boolean; inline;
function ToArray: TArray<T>;
property Items[aIndex: Integer]: T read GetItem; default;
end;
implementation
{ TEnumeratorForFastList<T> }
function TEnumeratorForFastList<T>.GetCurrent: T;
begin
Result := fList.List[fIndex];
end;
function TEnumeratorForFastList<T>.MoveNext: Boolean;
begin
Inc(fIndex);
Result := fIndex < fList.Count;
end;
{ TFastObjectList<T> }
function TFastObjectList<T>.ValidIndex(ix: Integer): Boolean;
begin
Result := (ix >= 0) and (ix < Count);
end;
function TFastObjectList<T>.GetItem(aIndex: Integer): T;
begin
Result := List[aIndex];
end;
function TFastObjectList<T>.First: T;
begin
Result := GetItem(0);
end;
function TFastObjectList<T>.Last: T;
begin
Result := GetItem(Count - 1);
end;
function TFastObjectList<T>.FirstOrDefault: T;
begin
if Count > 0
then Result := GetItem(0)
else Result := nil;
end;
function TFastObjectList<T>.LastOrDefault: T;
begin
if Count > 0
then Result := GetItem(Count - 1)
else Result := nil;
end;
function TFastObjectList<T>.HasItems: Boolean;
begin
Result := Count > 0;
end;
function TFastObjectList<T>.IsEmpty: Boolean;
begin
Result := Count = 0;
end;
function TFastObjectList<T>.GetEnumerator: TEnumeratorForFastList<T>;
begin
// we do not use a record constructor. this is faster
Result.fIndex := -1;
Result.fList := Self;
end;
function TFastObjectList<T>.ToArray: TArray<T>;
begin
SetLength(Result, Count);
if Count > 0 then
System.Move(List[0], Result[0], Count * SizeOf(T));
end;
end.
Bookmarks