diff --git a/packages/rtl-generics/src/generics.collections.pas b/packages/rtl-generics/src/generics.collections.pas index b1789d539c..73157d6d59 100644 --- a/packages/rtl-generics/src/generics.collections.pas +++ b/packages/rtl-generics/src/generics.collections.pas @@ -121,6 +121,9 @@ type class function BinarySearch(const AValues: array of T; const AItem: T; out AFoundIndex: SizeInt; const AComparer: IComparer; AIndex, ACount: SizeInt): Boolean; override; overload; + class function Concat(const Args: array of TArray): TArray; static; + class procedure Copy(const aSource: array of T; var aDestination: array of T; aCount: NativeInt); overload; + class procedure Copy(const aSource: array of T; var aDestination: array of T; aSourceIndex, aDestIndex, aCount: SizeInt); overload; end {$ifdef EXTRA_WARNINGS}experimental{$endif}; // will be renamed to TArray (bug #24254) TCollectionNotification = (cnAdding, cnAdded, cnDeleting, cnRemoved, cnExtracting, cnExtracted); @@ -961,12 +964,34 @@ type end; function InCircularRange(ABottom, AItem, ATop: SizeInt): Boolean; +procedure ErrorArgumentOutOfRange; overload; +procedure ErrorArgumentOutOfRange(aIndex, aMaxIndex: SizeInt; aListObj: TObject); overload; +procedure ErrorArgumentOutOfRange(aIndex, aMaxIndex: SizeInt); overload; var EmptyRecord: TEmptyRecord; implementation + +procedure ErrorArgumentOutOfRange; + +begin + raise EArgumentOutOfRangeException.Create(SArgumentOutOfRange); +end; + +procedure ErrorArgumentOutOfRange(aIndex, aMaxIndex: SizeInt; aListObj: TObject); overload; + +begin + raise EArgumentOutOfRangeException.Create(ListIndexErrorMsg(aIndex,aMaxIndex,aListObj)); +end; + +procedure ErrorArgumentOutOfRange(aIndex, aMaxIndex: SizeInt); overload; + +begin + raise EArgumentOutOfRangeException.Create(ListIndexErrorMsg(aIndex,aMaxIndex,'')); +end; + function InCircularRange(ABottom, AItem, ATop: SizeInt): Boolean; begin Result := @@ -1211,6 +1236,58 @@ begin end; end; + +class procedure TArrayHelper.Copy(const aSource: array of T; var aDestination: array of T; aCount: NativeInt); +begin + Copy(aSource,aDestination,0,0,aCount); +end; + +class procedure TArrayHelper.Copy(const aSource: array of T; var aDestination: array of T; aSourceIndex, aDestIndex, aCount: SizeInt); + +var + I : Integer; + +begin + if (Length(aSource)>0) and (Length(aDestination)>0) and ((@aSource[0]) = (@aDestination[0])) then + raise EArgumentException.Create(SErrSameArrays); + if (aCount<0) or + (aCount>(Length(aSource)-aSourceIndex)) or + (aCount>(Length(aDestination)-aDestIndex)) then + ErrorArgumentOutOfRange; + + if IsManagedType(T) then + begin + // maybe this can be optimized too ? + For I:=0 to aCount-1 do + aDestination[aDestIndex+i]:=aSource[aSourceIndex+i]; + end + else + Move(Pointer(@aSource[aSourceIndex])^, Pointer(@aDestination[aDestIndex])^, SizeOf(T)*aCount); +end; + +class function TArrayHelper.Concat(const Args: array of TArray): TArray; + +var + TotalLen: SizeInt; + CurLen,Dest,i: SizeInt; + +begin + TotalLen:=0; + for i:=0 to Length(Args)-1 do + Inc(TotalLen,Length(Args[i])); + SetLength(Result,TotalLen); + Dest:=0; + for i:=0 to Length(Args)-1 do + begin + CurLen:=Length(Args[i]); + if CurLen>0 then + begin + Copy(Args[i],Result,0,Dest,CurLen); + Inc(Dest,CurLen); + end; + end; +end; + class function TArrayHelper.BinarySearch(const AValues: array of T; const AItem: T; out AFoundIndex: SizeInt; const AComparer: IComparer; AIndex, ACount: SizeInt): Boolean; diff --git a/packages/rtl-generics/src/generics.strings.pas b/packages/rtl-generics/src/generics.strings.pas index 117a6febfd..12da780091 100644 --- a/packages/rtl-generics/src/generics.strings.pas +++ b/packages/rtl-generics/src/generics.strings.pas @@ -33,6 +33,7 @@ resourcestring SDictionaryKeyDoesNotExist = 'Dictionary key does not exist'; SDictionaryKeyNNNDoesNotExist = 'Dictionary key "%s" does not exist'; SItemNotFound = 'Item not found'; + SErrSameArrays = 'Cannot copy between same arrays'; implementation