@@ -1253,22 +1253,28 @@ function TEnumerableBase<T>.Single: T;
12531253function TEnumerableBase <T>.Single(const predicate: Predicate<T>): T;
12541254var
12551255 enumerator: IEnumerator<T>;
1256+ item: T;
1257+ found: Boolean;
12561258begin
12571259 if not Assigned(predicate) then RaiseHelper.ArgumentNil(ExceptionArgument.predicate);
12581260
1261+ found := False;
12591262 enumerator := IEnumerable<T>(this).GetEnumerator;
1260- while enumerator.MoveNext do
1263+ while True do
12611264 begin
1262- Result := enumerator.Current;
1263- if predicate(Result) then
1265+ if not enumerator.MoveNext then Break;
1266+ item := enumerator.Current;
1267+ if predicate(item) then
12641268 begin
1265- while enumerator.MoveNext do
1266- if predicate(enumerator.Current) then
1267- RaiseHelper.MoreThanOneMatch;
1268- Exit;
1269+ found := not found;
1270+ if found then
1271+ Result := item
1272+ else
1273+ RaiseHelper.MoreThanOneMatch;
12691274 end ;
12701275 end ;
1271- RaiseHelper.NoMatch;
1276+ if not found then
1277+ RaiseHelper.NoMatch;
12721278end ;
12731279
12741280function TEnumerableBase <T>.SingleOrDefault: T;
@@ -1299,26 +1305,31 @@ function TEnumerableBase<T>.SingleOrDefault(const predicate: Predicate<T>): T;
12991305 Result := IEnumerable<T>(this).SingleOrDefault(predicate, defaultValue);
13001306end ;
13011307
1302- function TEnumerableBase <T>.SingleOrDefault(const predicate: Predicate<T>;
1303- const defaultValue: T): T;
1308+ function TEnumerableBase <T>.SingleOrDefault(const predicate: Predicate<T>; const defaultValue: T): T;
13041309var
13051310 enumerator: IEnumerator<T>;
1311+ item: T;
1312+ found: Boolean;
13061313begin
13071314 if not Assigned(predicate) then RaiseHelper.ArgumentNil(ExceptionArgument.predicate);
13081315
1316+ found := False;
13091317 enumerator := IEnumerable<T>(this).GetEnumerator;
1310- while enumerator.MoveNext do
1318+ while True do
13111319 begin
1312- Result := enumerator.Current;
1313- if predicate(Result) then
1320+ if not enumerator.MoveNext then Break;
1321+ item := enumerator.Current;
1322+ if predicate(item) then
13141323 begin
1315- while enumerator.MoveNext do
1316- if predicate(enumerator.Current) then
1317- RaiseHelper.MoreThanOneMatch;
1318- Exit;
1324+ found := not found;
1325+ if found then
1326+ Result := item
1327+ else
1328+ RaiseHelper.MoreThanOneMatch;
13191329 end ;
13201330 end ;
1321- Result := defaultValue;
1331+ if not found then
1332+ Result := defaultValue;
13221333end ;
13231334
13241335function TEnumerableBase <T>.Skip(count: Integer): IEnumerable<T>;
@@ -1393,52 +1404,46 @@ function TEnumerableBase<T>.TakeWhile(
13931404
13941405function TEnumerableBase <T>.ToArray: TArray<T>;
13951406var
1396- intf: IInterface ;
1397- count: Integer;
1407+ enumerator: IEnumerator<T> ;
1408+ count, capacity : Integer;
13981409begin
13991410 Result := nil ;
1400- if GetInterface(IReadOnlyCollectionOfTGuid, Pointer(intf)) then
1401- begin
1402- count := IReadOnlyCollection<T>(intf).Count;
1403- if count > 0 then
1404- begin
1405- SetLength(Result, count);
1406- IReadOnlyCollection<T>(intf).CopyTo(Result, 0 );
1407- end ;
1408- end
1409- else
1411+ count := 0 ;
1412+ capacity := 0 ;
1413+ enumerator := IEnumerable<T>(this).GetEnumerator;
1414+ while enumerator.MoveNext do
14101415 begin
1411- count := 0 ;
1412- intf := IEnumerable<T>(this).GetEnumerator;
1413- while IEnumerator<T>(intf).MoveNext do
1416+ if count >= capacity then
14141417 begin
1415- if Result = nil then
1416- SetLength(Result, 4 )
1417- else if DynArrayLength(Result) = count then
1418- SetLength(Result, count * 2 );
1419- Result[count] := IEnumerator<T>(intf).Current;
1420- Inc(count);
1418+ capacity := GrowCapacity(capacity);
1419+ SetLength(Result, capacity);
14211420 end ;
1422- SetLength(Result, count);
1421+ Result[count] := enumerator.Current;
1422+ Inc(count);
14231423 end ;
1424+ SetLength(Result, count);
14241425end ;
14251426
14261427function TEnumerableBase <T>.TryGetElementAt(var value : T; index: Integer): Boolean;
14271428var
14281429 enumerator: IEnumerator<T>;
14291430begin
1430- if index < 0 then
1431- Exit(False);
1432- enumerator := IEnumerable<T>(this).GetEnumerator;
1433- while enumerator.MoveNext do
1431+ if index >= 0 then
14341432 begin
1435- if index = 0 then
1433+ enumerator := IEnumerable<T>(this).GetEnumerator;
1434+ while True do
14361435 begin
1436+ if not enumerator.MoveNext then
1437+ Break;
1438+ Dec(index);
1439+ if index >= 0 then
1440+ Continue;
1441+
14371442 value := enumerator.Current;
14381443 Exit(True);
14391444 end ;
1440- Dec(index);
14411445 end ;
1446+ value := Default(T);
14421447 Result := False;
14431448end ;
14441449
0 commit comments