xtool/contrib/fundamentals/Utils/Templates/flcDynArrays.inc

2209 lines
85 KiB
PHP

{*******************************************************************************}
{ }
{ Library: Fundamentals 5.00 }
{ File name: flcDynArrays.pas }
{ File version: 5.34 }
{ Description: Utility functions for dynamic arrays }
{ }
{ Copyright: Copyright (c) 2000-2020, David J Butler }
{ All rights reserved. }
{ Redistribution and use in source and binary forms, with }
{ or without modification, are permitted provided that }
{ the following conditions are met: }
{ Redistributions of source code must retain the above }
{ copyright notice, this list of conditions and the }
{ following disclaimer. }
{ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND }
{ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED }
{ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED }
{ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A }
{ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL }
{ THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, }
{ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR }
{ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, }
{ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF }
{ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) }
{ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER }
{ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING }
{ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE }
{ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE }
{ POSSIBILITY OF SUCH DAMAGE. }
{ }
{ Github: https://github.com/fundamentalslib }
{ E-mail: fundamentals.library at gmail.com }
{ }
{ Revision history: }
{ }
{ 2000/03/08 1.01 Initial verison: array functions. }
{ 2000/04/10 1.02 Added Append, Renamed Delete to Remove and added }
{ StringArrays. }
{ 2000/06/01 1.03 Added Range and Dup constructors for dynamic arrays. }
{ 2000/06/03 1.04 Added ArrayInsert functions. }
{ 2000/06/14 1.05 Unit now generated from a template using a source }
{ pre-processor. }
{ 2000/07/04 1.06 Revision for first Fundamentals release. }
{ 2000/07/24 1.07 Added TrimArray functions. }
{ 2000/07/26 1.08 Added Difference functions. }
{ 2000/09/02 1.09 Added RemoveDuplicates functions. }
{ Added Count functions. }
{ Fixed bug in Sort. }
{ 2000/09/27 1.10 Fixed bug in ArrayInsert. }
{ 2001/11/11 2.11 Revision. }
{ 2002/05/31 3.12 Refactored for Fundamentals 3. }
{ 2003/09/11 3.13 Added InterfaceArray functions. }
{ 2004/01/18 3.14 Added WideStringArray functions. }
{ 2004/07/24 3.15 Optimizations of Sort functions. }
{ 2004/08/22 3.16 Compilable with Delphi 8. }
{ 2005/06/10 4.17 Compilable with FreePascal 2 Win32 i386. }
{ 2005/08/19 4.18 Compilable with FreePascal 2 Linux i386. }
{ 2005/09/21 4.19 Revised for Fundamentals 4. }
{ 2006/03/04 4.20 Compilable with Delphi 2006 Win32/.NET. }
{ 2007/06/08 4.21 Compilable with FreePascal 2.04 Win32 i386 }
{ 2009/10/09 4.22 Compilable with Delphi 2009 Win32/.NET. }
{ 2010/06/27 4.23 Compilable with FreePascal 2.4.0 OSX x86-64. }
{ 2011/04/03 4.24 Support for Delphi XE string and integer types. }
{ 2011/04/04 4.25 Split dynamic array functions from Utils unit. }
{ 2012/08/26 4.26 UnicodeString functions. }
{ 2015/03/13 4.27 RawByteString functions. }
{ 2016/01/09 5.28 Revised for Fundamentals 5. }
{ 2016/04/16 5.29 Changes for FreePascal 3.0.0. }
{ 2018/07/17 5.30 Int32/Word32 functions. }
{ 2018/08/12 5.31 String type changes. }
{ 2019/03/22 5.32 FreePascal 3.04 Win64 changes. }
{ 2019/04/02 5.33 Integer/Cardinal functions. }
{ 2020/03/31 5.34 Word64 functions. }
{ }
{ Supported compilers: }
{ }
{ Delphi 2010-10.4 Win32/Win64 5.34 2020/06/02 }
{ Delphi 10.2-10.4 Linux64 5.34 2020/06/02 }
{ FreePascal 3.0.4 Win64 5.34 2020/06/02 }
{ }
{*******************************************************************************}
{$INCLUDE ..\flcInclude.inc}
{$IFDEF FREEPASCAL}
{$WARNINGS OFF}
{$HINTS OFF}
{$ENDIF}
{$IFDEF DEBUG}
{$IFDEF TEST}
{$DEFINE DYNARRAYS_TEST}
{$ENDIF}
{$ENDIF}
unit flcDynArrays;
interface
uses
{ System }
SysUtils,
{ Fundamentals }
flcStdTypes,
flcUtils;
{ }
{ Dynamic arrays }
{ }
{%DEFINE DynArrayAppend}
function DynArrayAppend%1%(var V: %2%Array; const R: %3%): Integer; overload; {$IFDEF UseInline}inline;{$ENDIF}{%ENDDEF}
{%TEMPLATE DynArrayAppend '' 'Byte' 'Byte'}
{%TEMPLATE DynArrayAppend '' 'Word16' 'Word16'}
{%TEMPLATE DynArrayAppend '' 'Word32' 'Word32'}
{%TEMPLATE DynArrayAppend '' 'Word64' 'Word64'}
{%TEMPLATE DynArrayAppend '' 'LongWord' 'LongWord'}
{%TEMPLATE DynArrayAppend '' 'Cardinal' 'Cardinal'}
{%TEMPLATE DynArrayAppend '' 'NativeUInt' 'NativeUInt'}
{%TEMPLATE DynArrayAppend '' 'ShortInt' 'ShortInt'}
{%TEMPLATE DynArrayAppend '' 'SmallInt' 'SmallInt'}
{%TEMPLATE DynArrayAppend '' 'LongInt' 'LongInt'}
{%TEMPLATE DynArrayAppend '' 'Integer' 'Integer'}
{%TEMPLATE DynArrayAppend '' 'Int32' 'Int32'}
{%TEMPLATE DynArrayAppend '' 'Int64' 'Int64'}
{%TEMPLATE DynArrayAppend '' 'NativeInt' 'NativeInt'}
{%TEMPLATE DynArrayAppend '' 'Single' 'Single'}
{%TEMPLATE DynArrayAppend '' 'Double' 'Double'}
{%TEMPLATE DynArrayAppend '' 'Extended' 'Extended'}
{%TEMPLATE DynArrayAppend '' 'Currency' 'Currency'}
{%TEMPLATE DynArrayAppend '' 'Boolean' 'Boolean'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayAppend 'A' 'AnsiString' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayAppend 'B' 'RawByteString' 'RawByteString'}
{%TEMPLATE DynArrayAppend 'U' 'UnicodeString' 'UnicodeString'}
{%TEMPLATE DynArrayAppend '' 'String' 'String'}
{%TEMPLATE DynArrayAppend '' 'Pointer' 'Pointer'}
{%TEMPLATE DynArrayAppend '' 'Object' 'TObject'}
{%TEMPLATE DynArrayAppend '' 'Interface' 'IInterface'}
{%TEMPLATE DynArrayAppend '' 'ByteSet' 'ByteSet'}
{%TEMPLATE DynArrayAppend '' 'ByteCharSet' 'ByteCharSet'}
{%DEFINE DynArrayAppendArray}
function DynArrayAppend%1%Array(var V: %1%Array; const R: %2%): Integer; overload;{%ENDDEF}
{%TEMPLATE DynArrayAppendArray 'Byte' 'array of Byte'}
{%TEMPLATE DynArrayAppendArray 'Word16' 'array of Word16'}
{%TEMPLATE DynArrayAppendArray 'Word32' 'array of Word32'}
{%TEMPLATE DynArrayAppendArray 'Word64' 'array of Word64'}
{%TEMPLATE DynArrayAppendArray 'Cardinal' 'array of Cardinal'}
{%TEMPLATE DynArrayAppendArray 'NativeUInt' 'array of NativeUInt'}
{%TEMPLATE DynArrayAppendArray 'ShortInt' 'array of ShortInt'}
{%TEMPLATE DynArrayAppendArray 'SmallInt' 'array of SmallInt'}
{%TEMPLATE DynArrayAppendArray 'LongInt' 'array of LongInt'}
{%TEMPLATE DynArrayAppendArray 'Integer' 'array of Integer'}
{%TEMPLATE DynArrayAppendArray 'Int32' 'array of Int32'}
{%TEMPLATE DynArrayAppendArray 'Int64' 'array of Int64'}
{%TEMPLATE DynArrayAppendArray 'NativeInt' 'array of NativeInt'}
{%TEMPLATE DynArrayAppendArray 'Single' 'array of Single'}
{%TEMPLATE DynArrayAppendArray 'Double' 'array of Double'}
{%TEMPLATE DynArrayAppendArray 'Extended' 'array of Extended'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayAppendArray 'AnsiString' 'array of AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayAppendArray 'RawByteString' 'array of RawByteString'}
{%TEMPLATE DynArrayAppendArray 'UnicodeString' 'array of UnicodeString'}
{%TEMPLATE DynArrayAppendArray 'String' 'array of String'}
{%TEMPLATE DynArrayAppendArray 'Currency' 'array of Currency'}
{%TEMPLATE DynArrayAppendArray 'Pointer' 'array of Pointer'}
{%TEMPLATE DynArrayAppendArray 'ByteCharSet' 'array of ByteCharSet'}
{%TEMPLATE DynArrayAppendArray 'ByteSet' 'array of ByteSet'}
{%TEMPLATE DynArrayAppendArray 'Object' 'ObjectArray'}
{%DEFINE DynArrayRemove}
function DynArrayRemove%1%(var V: %2%Array; const Idx: Integer; const Count: Integer = 1): Integer; overload;{%ENDDEF}
{%TEMPLATE DynArrayRemove '' 'Byte'}
{%TEMPLATE DynArrayRemove '' 'Word16'}
{%TEMPLATE DynArrayRemove '' 'Word32'}
{%TEMPLATE DynArrayRemove '' 'Word64'}
{%TEMPLATE DynArrayRemove '' 'LongWord'}
{%TEMPLATE DynArrayRemove '' 'Cardinal'}
{%TEMPLATE DynArrayRemove '' 'NativeUInt'}
{%TEMPLATE DynArrayRemove '' 'ShortInt'}
{%TEMPLATE DynArrayRemove '' 'SmallInt'}
{%TEMPLATE DynArrayRemove '' 'LongInt'}
{%TEMPLATE DynArrayRemove '' 'Integer'}
{%TEMPLATE DynArrayRemove '' 'Int32'}
{%TEMPLATE DynArrayRemove '' 'Int64'}
{%TEMPLATE DynArrayRemove '' 'NativeInt'}
{%TEMPLATE DynArrayRemove '' 'Single'}
{%TEMPLATE DynArrayRemove '' 'Double'}
{%TEMPLATE DynArrayRemove '' 'Extended'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayRemove 'A' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayRemove 'B' 'RawByteString'}
{%TEMPLATE DynArrayRemove 'U' 'UnicodeString'}
{%TEMPLATE DynArrayRemove '' 'String'}
{%TEMPLATE DynArrayRemove '' 'Pointer'}
{%TEMPLATE DynArrayRemove '' 'Currency'}
function DynArrayRemove(var V: ObjectArray; const Idx: Integer; const Count: Integer = 1;
const FreeObjects: Boolean = False): Integer; overload;
{%TEMPLATE DynArrayRemove '' 'Interface'}
{%DEFINE DynArrayRemoveDuplicates}
procedure DynArrayRemoveDuplicates%1%(var V: %2%Array; const IsSorted: Boolean); overload;{%ENDDEF}
{%TEMPLATE DynArrayRemoveDuplicates '' 'Byte'}
{%TEMPLATE DynArrayRemoveDuplicates '' 'Word16'}
{%TEMPLATE DynArrayRemoveDuplicates '' 'LongWord'}
{%TEMPLATE DynArrayRemoveDuplicates '' 'ShortInt'}
{%TEMPLATE DynArrayRemoveDuplicates '' 'SmallInt'}
{%TEMPLATE DynArrayRemoveDuplicates '' 'LongInt'}
{%TEMPLATE DynArrayRemoveDuplicates '' 'Int64'}
{%TEMPLATE DynArrayRemoveDuplicates '' 'Single'}
{%TEMPLATE DynArrayRemoveDuplicates '' 'Double'}
{%TEMPLATE DynArrayRemoveDuplicates '' 'Extended'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayRemoveDuplicates 'A' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayRemoveDuplicates 'U' 'UnicodeString'}
{%TEMPLATE DynArrayRemoveDuplicates '' 'String'}
{%TEMPLATE DynArrayRemoveDuplicates '' 'Pointer'}
{%DEFINE DynArrayTrimLeft}
procedure DynArrayTrimLeft%1%(var S: %2%Array; const TrimList: array of %3%); overload;{%ENDDEF}
{%TEMPLATE DynArrayTrimLeft '' 'Byte' 'Byte'}
{%TEMPLATE DynArrayTrimLeft '' 'Word16' 'Word16'}
{%TEMPLATE DynArrayTrimLeft '' 'LongWord' 'LongWord'}
{%TEMPLATE DynArrayTrimLeft '' 'ShortInt' 'ShortInt'}
{%TEMPLATE DynArrayTrimLeft '' 'SmallInt' 'SmallInt'}
{%TEMPLATE DynArrayTrimLeft '' 'LongInt' 'LongInt'}
{%TEMPLATE DynArrayTrimLeft '' 'Int64' 'Int64'}
{%TEMPLATE DynArrayTrimLeft '' 'Single' 'Single'}
{%TEMPLATE DynArrayTrimLeft '' 'Double' 'Double'}
{%TEMPLATE DynArrayTrimLeft '' 'Extended' 'Extended'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayTrimLeft 'A' 'AnsiString' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayTrimLeft 'U' 'UnicodeString' 'UnicodeString'}
{%TEMPLATE DynArrayTrimLeft '' 'Pointer' 'Pointer'}
{%DEFINE DynArrayTrimRight}
procedure DynArrayTrimRight%1%(var S: %2%Array; const TrimList: array of %3%); overload;{%ENDDEF}
{%TEMPLATE DynArrayTrimRight '' 'Byte' 'Byte'}
{%TEMPLATE DynArrayTrimRight '' 'Word16' 'Word16'}
{%TEMPLATE DynArrayTrimRight '' 'LongWord' 'LongWord'}
{%TEMPLATE DynArrayTrimRight '' 'ShortInt' 'ShortInt'}
{%TEMPLATE DynArrayTrimRight '' 'SmallInt' 'SmallInt'}
{%TEMPLATE DynArrayTrimRight '' 'LongInt' 'LongInt'}
{%TEMPLATE DynArrayTrimRight '' 'Int64' 'Int64'}
{%TEMPLATE DynArrayTrimRight '' 'Single' 'Single'}
{%TEMPLATE DynArrayTrimRight '' 'Double' 'Double'}
{%TEMPLATE DynArrayTrimRight '' 'Extended' 'Extended'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayTrimRight 'A' 'AnsiString' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayTrimRight 'U' 'UnicodeString' 'UnicodeString'}
{%TEMPLATE DynArrayTrimRight '' 'String' 'String'}
{%TEMPLATE DynArrayTrimRight '' 'Pointer' 'Pointer'}
{%DEFINE DynArrayInsert}
function DynArrayInsert%1%(var V: %2%Array; const Idx: Integer; const Count: Integer): Integer; overload;{%ENDDEF}
{%TEMPLATE DynArrayInsert '' 'Byte'}
{%TEMPLATE DynArrayInsert '' 'Word16'}
{%TEMPLATE DynArrayInsert '' 'Word32'}
{%TEMPLATE DynArrayInsert '' 'Word64'}
{%TEMPLATE DynArrayInsert '' 'LongWord'}
{%TEMPLATE DynArrayInsert '' 'NativeUInt'}
{%TEMPLATE DynArrayInsert '' 'ShortInt'}
{%TEMPLATE DynArrayInsert '' 'SmallInt'}
{%TEMPLATE DynArrayInsert '' 'LongInt'}
{%TEMPLATE DynArrayInsert '' 'Int32'}
{%TEMPLATE DynArrayInsert '' 'Int64'}
{%TEMPLATE DynArrayInsert '' 'NativeInt'}
{%TEMPLATE DynArrayInsert '' 'Single'}
{%TEMPLATE DynArrayInsert '' 'Double'}
{%TEMPLATE DynArrayInsert '' 'Extended'}
{%TEMPLATE DynArrayInsert '' 'Currency'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayInsert 'A' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayInsert 'B' 'RawByteString'}
{%TEMPLATE DynArrayInsert 'U' 'UnicodeString'}
{%TEMPLATE DynArrayInsert '' 'String'}
{%TEMPLATE DynArrayInsert '' 'Pointer'}
{%TEMPLATE DynArrayInsert '' 'Object'}
{%TEMPLATE DynArrayInsert '' 'Interface'}
{%DEFINE DynArrayPosNext}
function DynArrayPosNext%1%(const Find: %3%; const V: %2%Array; const PrevPos: Integer = -1;
const IsSortedAscending: Boolean = False): Integer; overload;{%ENDDEF}
{%TEMPLATE DynArrayPosNext '' 'Byte' 'Byte'}
{%TEMPLATE DynArrayPosNext '' 'Word16' 'Word16'}
{%TEMPLATE DynArrayPosNext '' 'Word32' 'Word32'}
{%TEMPLATE DynArrayPosNext '' 'Word64' 'Word64'}
{%TEMPLATE DynArrayPosNext '' 'LongWord' 'LongWord'}
{%TEMPLATE DynArrayPosNext '' 'Cardinal' 'Cardinal'}
{%TEMPLATE DynArrayPosNext '' 'NativeUInt' 'NativeUInt'}
{%TEMPLATE DynArrayPosNext '' 'ShortInt' 'ShortInt'}
{%TEMPLATE DynArrayPosNext '' 'SmallInt' 'SmallInt'}
{%TEMPLATE DynArrayPosNext '' 'LongInt' 'LongInt'}
{%TEMPLATE DynArrayPosNext '' 'Integer' 'Integer'}
{%TEMPLATE DynArrayPosNext '' 'Int32' 'Int32'}
{%TEMPLATE DynArrayPosNext '' 'Int64' 'Int64'}
{%TEMPLATE DynArrayPosNext '' 'NativeInt' 'NativeInt'}
{%TEMPLATE DynArrayPosNext '' 'Single' 'Single'}
{%TEMPLATE DynArrayPosNext '' 'Double' 'Double'}
{%TEMPLATE DynArrayPosNext '' 'Extended' 'Extended'}
{%TEMPLATE DynArrayPosNext '' 'Boolean' 'Boolean'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayPosNext 'A' 'AnsiString' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayPosNext 'B' 'RawByteString' 'RawByteString'}
{%TEMPLATE DynArrayPosNext 'U' 'UnicodeString' 'UnicodeString'}
{%TEMPLATE DynArrayPosNext '' 'String' 'String'}
function DynArrayPosNext(const Find: Pointer; const V: PointerArray;
const PrevPos: Integer = -1): Integer; overload;
function DynArrayPosNext(const Find: TObject; const V: ObjectArray;
const PrevPos: Integer = -1): Integer; overload;
function DynArrayPosNext(const ClassType: TClass; const V: ObjectArray;
const PrevPos: Integer = -1): Integer; overload;
function DynArrayPosNext(const ClassName: String; const V: ObjectArray;
const PrevPos: Integer = -1): Integer; overload;
{%DEFINE DynArrayCount}
function DynArrayCount%1%(const Find: %3%; const V: %2%Array;
const IsSortedAscending: Boolean = False): Integer; overload;{%ENDDEF}
{%TEMPLATE DynArrayCount '' 'Byte' 'Byte'}
{%TEMPLATE DynArrayCount '' 'Word16' 'Word16'}
{%TEMPLATE DynArrayCount '' 'LongWord' 'LongWord'}
{%TEMPLATE DynArrayCount '' 'ShortInt' 'ShortInt'}
{%TEMPLATE DynArrayCount '' 'SmallInt' 'SmallInt'}
{%TEMPLATE DynArrayCount '' 'LongInt' 'LongInt'}
{%TEMPLATE DynArrayCount '' 'Int64' 'Int64'}
{%TEMPLATE DynArrayCount '' 'Single' 'Single'}
{%TEMPLATE DynArrayCount '' 'Double' 'Double'}
{%TEMPLATE DynArrayCount '' 'Extended' 'Extended'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayCount 'A' 'AnsiString' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayCount 'B' 'RawByteString' 'RawByteString'}
{%TEMPLATE DynArrayCount 'U' 'UnicodeString' 'UnicodeString'}
{%TEMPLATE DynArrayCount '' 'String' 'String'}
{%TEMPLATE DynArrayCount '' 'Boolean' 'Boolean'}
{%DEFINE DynArrayRemoveAll}
procedure DynArrayRemoveAll%1%(const Find: %3%; var V: %2%Array;
const IsSortedAscending: Boolean = False); overload; {%ENDDEF}
{%TEMPLATE DynArrayRemoveAll '' 'Byte' 'Byte'}
{%TEMPLATE DynArrayRemoveAll '' 'Word16' 'Word16'}
{%TEMPLATE DynArrayRemoveAll '' 'LongWord' 'LongWord'}
{%TEMPLATE DynArrayRemoveAll '' 'ShortInt' 'ShortInt'}
{%TEMPLATE DynArrayRemoveAll '' 'SmallInt' 'SmallInt'}
{%TEMPLATE DynArrayRemoveAll '' 'LongInt' 'LongInt'}
{%TEMPLATE DynArrayRemoveAll '' 'Int64' 'Int64'}
{%TEMPLATE DynArrayRemoveAll '' 'Single' 'Single'}
{%TEMPLATE DynArrayRemoveAll '' 'Double' 'Double'}
{%TEMPLATE DynArrayRemoveAll '' 'Extended' 'Extended'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayRemoveAll 'A' 'AnsiString' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayRemoveAll 'U' 'UnicodeString' 'UnicodeString'}
{%TEMPLATE DynArrayRemoveAll '' 'String' 'String'}
{%DEFINE DynArrayIntersection}
function DynArrayIntersection%1%(const V1, V2: %2%Array;
const IsSortedAscending: Boolean = False): %2%Array; overload;{%ENDDEF}
{%TEMPLATE DynArrayIntersection '' 'Byte'}
{%TEMPLATE DynArrayIntersection '' 'Word16'}
{%TEMPLATE DynArrayIntersection '' 'LongWord'}
{%TEMPLATE DynArrayIntersection '' 'ShortInt'}
{%TEMPLATE DynArrayIntersection '' 'SmallInt'}
{%TEMPLATE DynArrayIntersection '' 'LongInt'}
{%TEMPLATE DynArrayIntersection '' 'Int64'}
{%TEMPLATE DynArrayIntersection '' 'Single'}
{%TEMPLATE DynArrayIntersection '' 'Double'}
{%TEMPLATE DynArrayIntersection '' 'Extended'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayIntersection 'A' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayIntersection 'U' 'UnicodeString'}
{%TEMPLATE DynArrayIntersection '' 'String'}
{%DEFINE DynArrayDifference}
function DynArrayDifference%1%(const V1, V2: %2%Array;
const IsSortedAscending: Boolean = False): %2%Array; overload;{%ENDDEF}
{%TEMPLATE DynArrayDifference '' 'Byte'}
{%TEMPLATE DynArrayDifference '' 'Word16'}
{%TEMPLATE DynArrayDifference '' 'LongWord'}
{%TEMPLATE DynArrayDifference '' 'ShortInt'}
{%TEMPLATE DynArrayDifference '' 'SmallInt'}
{%TEMPLATE DynArrayDifference '' 'LongInt'}
{%TEMPLATE DynArrayDifference '' 'Int64'}
{%TEMPLATE DynArrayDifference '' 'Single'}
{%TEMPLATE DynArrayDifference '' 'Double'}
{%TEMPLATE DynArrayDifference '' 'Extended'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayDifference 'A' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayDifference 'U' 'UnicodeString'}
{%TEMPLATE DynArrayDifference '' 'String'}
{%DEFINE DynArrayReverse}
procedure DynArrayReverse%1%(var V: %2%Array); overload;{%ENDDEF}
{%TEMPLATE DynArrayReverse '' 'Byte'}
{%TEMPLATE DynArrayReverse '' 'Word16'}
{%TEMPLATE DynArrayReverse '' 'LongWord'}
{%TEMPLATE DynArrayReverse '' 'ShortInt'}
{%TEMPLATE DynArrayReverse '' 'SmallInt'}
{%TEMPLATE DynArrayReverse '' 'LongInt'}
{%TEMPLATE DynArrayReverse '' 'Int64'}
{%TEMPLATE DynArrayReverse '' 'Single'}
{%TEMPLATE DynArrayReverse '' 'Double'}
{%TEMPLATE DynArrayReverse '' 'Extended'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayReverse 'A' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayReverse 'U' 'UnicodeString'}
{%TEMPLATE DynArrayReverse '' 'String'}
{%TEMPLATE DynArrayReverse '' 'Pointer'}
{%TEMPLATE DynArrayReverse '' 'Object'}
{%DEFINE OpenArrayAsDynArray}
function As%1%Array(const V: array of %2%): %1%Array; overload;{%ENDDEF}
{%TEMPLATE OpenArrayAsDynArray 'Boolean' 'Boolean'}
{%TEMPLATE OpenArrayAsDynArray 'Byte' 'Byte'}
{%TEMPLATE OpenArrayAsDynArray 'Word16' 'Word16'}
{%TEMPLATE OpenArrayAsDynArray 'Word32' 'Word32'}
{%TEMPLATE OpenArrayAsDynArray 'Word64' 'Word64'}
{%TEMPLATE OpenArrayAsDynArray 'LongWord' 'LongWord'}
{%TEMPLATE OpenArrayAsDynArray 'Cardinal' 'Cardinal'}
{%TEMPLATE OpenArrayAsDynArray 'NativeUInt' 'NativeUInt'}
{%TEMPLATE OpenArrayAsDynArray 'ShortInt' 'ShortInt'}
{%TEMPLATE OpenArrayAsDynArray 'SmallInt' 'SmallInt'}
{%TEMPLATE OpenArrayAsDynArray 'LongInt' 'LongInt'}
{%TEMPLATE OpenArrayAsDynArray 'Integer' 'Integer'}
{%TEMPLATE OpenArrayAsDynArray 'Int32' 'Int32'}
{%TEMPLATE OpenArrayAsDynArray 'Int64' 'Int64'}
{%TEMPLATE OpenArrayAsDynArray 'NativeInt' 'NativeInt'}
{%TEMPLATE OpenArrayAsDynArray 'Single' 'Single'}
{%TEMPLATE OpenArrayAsDynArray 'Double' 'Double'}
{%TEMPLATE OpenArrayAsDynArray 'Extended' 'Extended'}
{%TEMPLATE OpenArrayAsDynArray 'Currency' 'Currency'}
{$IFDEF SupportAnsiString}
{%TEMPLATE OpenArrayAsDynArray 'AnsiString' 'AnsiString'}
{$ENDIF}
{%TEMPLATE OpenArrayAsDynArray 'RawByteString' 'RawByteString'}
{%TEMPLATE OpenArrayAsDynArray 'UnicodeString' 'UnicodeString'}
{%TEMPLATE OpenArrayAsDynArray 'String' 'String'}
{%TEMPLATE OpenArrayAsDynArray 'Pointer' 'Pointer'}
{%TEMPLATE OpenArrayAsDynArray 'ByteCharSet' 'ByteCharSet'}
function AsObjectArray(const V: array of TObject): ObjectArray; overload;
function AsInterfaceArray(const V: array of IInterface): InterfaceArray; overload;
{%DEFINE DynArrayRange}
function DynArrayRange%1%(const First: %1%; const Count: Integer;
const Increment: %1% = 1): %1%Array;{%ENDDEF}
{%TEMPLATE DynArrayRange 'Byte'}
{%TEMPLATE DynArrayRange 'Word16'}
{%TEMPLATE DynArrayRange 'LongWord'}
{%TEMPLATE DynArrayRange 'Cardinal'}
{%TEMPLATE DynArrayRange 'ShortInt'}
{%TEMPLATE DynArrayRange 'SmallInt'}
{%TEMPLATE DynArrayRange 'LongInt'}
{%TEMPLATE DynArrayRange 'Integer'}
{%TEMPLATE DynArrayRange 'Int64'}
{%TEMPLATE DynArrayRange 'Single'}
{%TEMPLATE DynArrayRange 'Double'}
{%TEMPLATE DynArrayRange 'Extended'}
{%DEFINE DynArrayDup}
function DynArrayDup%1%(const V: %2%; const Count: Integer): %1%Array;{%ENDDEF}
{%TEMPLATE DynArrayDup 'Byte' 'Byte' }
{%TEMPLATE DynArrayDup 'Word16' 'Word16' }
{%TEMPLATE DynArrayDup 'LongWord' 'LongWord' }
{%TEMPLATE DynArrayDup 'Cardinal' 'Cardinal' }
{%TEMPLATE DynArrayDup 'NativeUInt' 'NativeUInt' }
{%TEMPLATE DynArrayDup 'ShortInt' 'ShortInt' }
{%TEMPLATE DynArrayDup 'SmallInt' 'SmallInt' }
{%TEMPLATE DynArrayDup 'LongInt' 'LongInt' }
{%TEMPLATE DynArrayDup 'Integer' 'Integer' }
{%TEMPLATE DynArrayDup 'Int64' 'Int64' }
{%TEMPLATE DynArrayDup 'NativeInt' 'NativeInt' }
{%TEMPLATE DynArrayDup 'Single' 'Single' }
{%TEMPLATE DynArrayDup 'Double' 'Double' }
{%TEMPLATE DynArrayDup 'Extended' 'Extended' }
{%TEMPLATE DynArrayDup 'Currency' 'Currency' }
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayDup 'AnsiString' 'AnsiString' }
{$ENDIF}
{%TEMPLATE DynArrayDup 'UnicodeString' 'UnicodeString' }
{%TEMPLATE DynArrayDup 'String' 'String' }
{%TEMPLATE DynArrayDup 'ByteCharSet' 'ByteCharSet' }
{%TEMPLATE DynArrayDup 'Object' 'TObject' }
{%DEFINE SetLengthAndZero}
procedure SetLengthAndZero(var V: %1%Array; const NewLength: Integer); overload;{%ENDDEF}
{%TEMPLATE SetLengthAndZero 'Byte' }
{%TEMPLATE SetLengthAndZero 'Word16' }
{%TEMPLATE SetLengthAndZero 'Word32' }
{%TEMPLATE SetLengthAndZero 'Word64' }
{%TEMPLATE SetLengthAndZero 'LongWord' }
{%TEMPLATE SetLengthAndZero 'Cardinal' }
{%TEMPLATE SetLengthAndZero 'NativeUInt' }
{%TEMPLATE SetLengthAndZero 'ShortInt' }
{%TEMPLATE SetLengthAndZero 'SmallInt' }
{%TEMPLATE SetLengthAndZero 'LongInt' }
{%TEMPLATE SetLengthAndZero 'Integer' }
{%TEMPLATE SetLengthAndZero 'Int32' }
{%TEMPLATE SetLengthAndZero 'Int64' }
{%TEMPLATE SetLengthAndZero 'NativeInt' }
{%TEMPLATE SetLengthAndZero 'Single' }
{%TEMPLATE SetLengthAndZero 'Double' }
{%TEMPLATE SetLengthAndZero 'Extended' }
{%TEMPLATE SetLengthAndZero 'Currency' }
{%TEMPLATE SetLengthAndZero 'ByteCharSet'}
{%TEMPLATE SetLengthAndZero 'Boolean' }
{%TEMPLATE SetLengthAndZero 'Pointer' }
procedure SetLengthAndZero(var V: ObjectArray; const NewLength: Integer;
const FreeObjects: Boolean = False); overload;
{%DEFINE DynArrayIsEqual}
function DynArrayIsEqual%1%(const V1, V2: %2%Array): Boolean; overload;{%ENDDEF}
{%TEMPLATE DynArrayIsEqual '' 'Byte'}
{%TEMPLATE DynArrayIsEqual '' 'Word16'}
{%TEMPLATE DynArrayIsEqual '' 'LongWord'}
{%TEMPLATE DynArrayIsEqual '' 'ShortInt'}
{%TEMPLATE DynArrayIsEqual '' 'SmallInt'}
{%TEMPLATE DynArrayIsEqual '' 'LongInt'}
{%TEMPLATE DynArrayIsEqual '' 'Int64'}
{%TEMPLATE DynArrayIsEqual '' 'Single'}
{%TEMPLATE DynArrayIsEqual '' 'Double'}
{%TEMPLATE DynArrayIsEqual '' 'Extended'}
{%TEMPLATE DynArrayIsEqual '' 'Currency'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayIsEqual 'A' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayIsEqual 'B' 'RawByteString'}
{%TEMPLATE DynArrayIsEqual 'U' 'UnicodeString'}
{%TEMPLATE DynArrayIsEqual '' 'String'}
{%TEMPLATE DynArrayIsEqual '' 'ByteCharSet'}
{%DEFINE DynArrayToDynArray}
function %1%ArrayTo%2%Array(const V: %1%Array): %2%Array;{%ENDDEF}
{%TEMPLATE DynArrayToDynArray 'Byte' 'LongInt'}
{%TEMPLATE DynArrayToDynArray 'Word16' 'LongInt'}
{%TEMPLATE DynArrayToDynArray 'ShortInt' 'LongInt'}
{%TEMPLATE DynArrayToDynArray 'SmallInt' 'LongInt'}
{%TEMPLATE DynArrayToDynArray 'LongInt' 'Int64'}
{%TEMPLATE DynArrayToDynArray 'LongInt' 'Single'}
{%TEMPLATE DynArrayToDynArray 'LongInt' 'Double'}
{%TEMPLATE DynArrayToDynArray 'LongInt' 'Extended'}
{%TEMPLATE DynArrayToDynArray 'Single' 'Double'}
{%TEMPLATE DynArrayToDynArray 'Single' 'Extended'}
{%TEMPLATE DynArrayToDynArray 'Single' 'Currency'}
{%TEMPLATE DynArrayToDynArray 'Single' 'LongInt'}
{%TEMPLATE DynArrayToDynArray 'Single' 'Int64'}
{%TEMPLATE DynArrayToDynArray 'Double' 'Extended'}
{%TEMPLATE DynArrayToDynArray 'Double' 'Currency'}
{%TEMPLATE DynArrayToDynArray 'Double' 'LongInt'}
{%TEMPLATE DynArrayToDynArray 'Double' 'Int64'}
{%TEMPLATE DynArrayToDynArray 'Extended' 'Currency'}
{%TEMPLATE DynArrayToDynArray 'Extended' 'LongInt'}
{%TEMPLATE DynArrayToDynArray 'Extended' 'Int64'}
{%DEFINE DynArrayFromIndexes}
function %1%ArrayFromIndexes(const V: %1%Array;
const Indexes: IntegerArray): %1%Array;{%ENDDEF}
{%TEMPLATE DynArrayFromIndexes 'Byte'}
{%TEMPLATE DynArrayFromIndexes 'Word16'}
{%TEMPLATE DynArrayFromIndexes 'LongWord'}
{%TEMPLATE DynArrayFromIndexes 'Cardinal'}
{%TEMPLATE DynArrayFromIndexes 'ShortInt'}
{%TEMPLATE DynArrayFromIndexes 'SmallInt'}
{%TEMPLATE DynArrayFromIndexes 'LongInt'}
{%TEMPLATE DynArrayFromIndexes 'Integer'}
{%TEMPLATE DynArrayFromIndexes 'Int64'}
{%TEMPLATE DynArrayFromIndexes 'Single'}
{%TEMPLATE DynArrayFromIndexes 'Double'}
{%TEMPLATE DynArrayFromIndexes 'Extended'}
{%TEMPLATE DynArrayFromIndexes 'String'}
{%DEFINE DynArraySort}
procedure DynArraySort%1%(const V: %2%Array); overload;{%ENDDEF}
{%TEMPLATE DynArraySort '' 'Byte'}
{%TEMPLATE DynArraySort '' 'Word16'}
{%TEMPLATE DynArraySort '' 'LongWord'}
{%TEMPLATE DynArraySort '' 'Cardinal'}
{%TEMPLATE DynArraySort '' 'NativeUInt'}
{%TEMPLATE DynArraySort '' 'ShortInt'}
{%TEMPLATE DynArraySort '' 'SmallInt'}
{%TEMPLATE DynArraySort '' 'LongInt'}
{%TEMPLATE DynArraySort '' 'Integer'}
{%TEMPLATE DynArraySort '' 'Int64'}
{%TEMPLATE DynArraySort '' 'NativeInt'}
{%TEMPLATE DynArraySort '' 'Single'}
{%TEMPLATE DynArraySort '' 'Double'}
{%TEMPLATE DynArraySort '' 'Extended'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArraySort 'A' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArraySort 'B' 'RawByteString'}
{%TEMPLATE DynArraySort 'U' 'UnicodeString'}
{%TEMPLATE DynArraySort '' 'String'}
{%DEFINE DynArrayPairSort}
procedure DynArraySort(const Key: %1%Array; const Data: %2%Array); overload;{%ENDDEF}
{%TEMPLATE DynArrayPairSort 'Integer' 'Integer'}
{%TEMPLATE DynArrayPairSort 'Integer' 'Int64'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayPairSort 'Integer' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayPairSort 'Integer' 'Extended'}
{%TEMPLATE DynArrayPairSort 'Integer' 'Pointer'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayPairSort 'AnsiString' 'Integer'}
{%TEMPLATE DynArrayPairSort 'AnsiString' 'Int64'}
{%TEMPLATE DynArrayPairSort 'AnsiString' 'AnsiString'}
{%TEMPLATE DynArrayPairSort 'AnsiString' 'Extended'}
{%TEMPLATE DynArrayPairSort 'AnsiString' 'Pointer'}
{$ENDIF}
{%TEMPLATE DynArrayPairSort 'Extended' 'Integer'}
{%TEMPLATE DynArrayPairSort 'Extended' 'Int64'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayPairSort 'Extended' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayPairSort 'Extended' 'Extended'}
{%TEMPLATE DynArrayPairSort 'Extended' 'Pointer'}
{ }
{ Test cases }
{ }
{$IFDEF DYNARRAYS_TEST}
procedure Test;
{$ENDIF}
implementation
{ }
{ DynArrayAppend }
{ }
{%DEFINE DynArrayAppendImpl}
function DynArrayAppend%1%(var V: %2%Array; const R: %3%): Integer;
begin
Result := Length(V);
SetLength(V, Result + 1);
V[Result] := R;
end;
{%ENDDEF}
{%TEMPLATE DynArrayAppendImpl '' 'Byte' 'Byte'}
{%TEMPLATE DynArrayAppendImpl '' 'Word16' 'Word16'}
{%TEMPLATE DynArrayAppendImpl '' 'Word32' 'Word32'}
{%TEMPLATE DynArrayAppendImpl '' 'Word64' 'Word64'}
{%TEMPLATE DynArrayAppendImpl '' 'LongWord' 'LongWord'}
{%TEMPLATE DynArrayAppendImpl '' 'Cardinal' 'Cardinal'}
{%TEMPLATE DynArrayAppendImpl '' 'NativeUInt' 'NativeUInt'}
{%TEMPLATE DynArrayAppendImpl '' 'ShortInt' 'ShortInt'}
{%TEMPLATE DynArrayAppendImpl '' 'SmallInt' 'SmallInt'}
{%TEMPLATE DynArrayAppendImpl '' 'Int32' 'Int32'}
{%TEMPLATE DynArrayAppendImpl '' 'LongInt' 'LongInt'}
{%TEMPLATE DynArrayAppendImpl '' 'Integer' 'Integer'}
{%TEMPLATE DynArrayAppendImpl '' 'Int64' 'Int64'}
{%TEMPLATE DynArrayAppendImpl '' 'NativeInt' 'NativeInt'}
{%TEMPLATE DynArrayAppendImpl '' 'Single' 'Single'}
{%TEMPLATE DynArrayAppendImpl '' 'Double' 'Double'}
{%TEMPLATE DynArrayAppendImpl '' 'Extended' 'Extended'}
{%TEMPLATE DynArrayAppendImpl '' 'Currency' 'Currency'}
{%TEMPLATE DynArrayAppendImpl '' 'Boolean' 'Boolean'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayAppendImpl 'A' 'AnsiString' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayAppendImpl 'B' 'RawByteString' 'RawByteString'}
{%TEMPLATE DynArrayAppendImpl 'U' 'UnicodeString' 'UnicodeString'}
{%TEMPLATE DynArrayAppendImpl '' 'String' 'String'}
{%TEMPLATE DynArrayAppendImpl '' 'Pointer' 'Pointer'}
{%TEMPLATE DynArrayAppendImpl '' 'Object' 'TObject'}
{%TEMPLATE DynArrayAppendImpl '' 'Interface' 'IInterface'}
{%TEMPLATE DynArrayAppendImpl '' 'ByteSet' 'ByteSet'}
{%TEMPLATE DynArrayAppendImpl '' 'ByteCharSet' 'ByteCharSet'}
{%DEFINE DynArrayAppendArrayImpl}
function DynArrayAppend%2%Array(var V: %2%Array; const R: array of %1%): Integer;
var L : Integer;
begin
Result := Length(V);
L := Length(R);
if L > 0 then
begin
SetLength(V, Result + L);
Move(R[0], V[Result], Sizeof(%1%) * L);
end;
end;
{%ENDDEF}
{%TEMPLATE DynArrayAppendArrayImpl 'Byte' 'Byte'}
{%TEMPLATE DynArrayAppendArrayImpl 'Word16' 'Word16'}
{%TEMPLATE DynArrayAppendArrayImpl 'Word32' 'Word32'}
{%TEMPLATE DynArrayAppendArrayImpl 'Word64' 'Word64'}
{%TEMPLATE DynArrayAppendArrayImpl 'Cardinal' 'Cardinal'}
{%TEMPLATE DynArrayAppendArrayImpl 'NativeUInt' 'NativeUInt'}
{%TEMPLATE DynArrayAppendArrayImpl 'ShortInt' 'ShortInt'}
{%TEMPLATE DynArrayAppendArrayImpl 'SmallInt' 'SmallInt'}
{%TEMPLATE DynArrayAppendArrayImpl 'LongInt' 'LongInt'}
{%TEMPLATE DynArrayAppendArrayImpl 'Int32' 'Int32'}
{%TEMPLATE DynArrayAppendArrayImpl 'Integer' 'Integer'}
{%TEMPLATE DynArrayAppendArrayImpl 'Int64' 'Int64'}
{%TEMPLATE DynArrayAppendArrayImpl 'NativeInt' 'NativeInt'}
{%TEMPLATE DynArrayAppendArrayImpl 'Single' 'Single'}
{%TEMPLATE DynArrayAppendArrayImpl 'Double' 'Double'}
{%TEMPLATE DynArrayAppendArrayImpl 'Extended' 'Extended'}
{%TEMPLATE DynArrayAppendArrayImpl 'Currency' 'Currency'}
{%TEMPLATE DynArrayAppendArrayImpl 'Pointer' 'Pointer'}
{%TEMPLATE DynArrayAppendArrayImpl 'ByteCharSet' 'ByteCharSet'}
{%TEMPLATE DynArrayAppendArrayImpl 'ByteSet' 'ByteSet'}
function DynArrayAppendObjectArray(var V: ObjectArray; const R: ObjectArray): Integer;
var I, LR : Integer;
begin
Result := Length(V);
LR := Length(R);
if LR > 0 then
begin
SetLength(V, Result + LR);
for I := 0 to LR - 1 do
V[Result + I] := R[I];
end;
end;
{$IFDEF SupportAnsiString}
function DynArrayAppendAnsiStringArray(var V: AnsiStringArray; const R: array of AnsiString): Integer;
var I, LR : Integer;
begin
Result := Length(V);
LR := Length(R);
if LR > 0 then
begin
SetLength(V, Result + LR);
for I := 0 to LR - 1 do
V[Result + I] := R[I];
end;
end;
{$ENDIF}
function DynArrayAppendRawByteStringArray(var V: RawByteStringArray; const R: array of RawByteString): Integer;
var I, LR : Integer;
begin
Result := Length(V);
LR := Length(R);
if LR > 0 then
begin
SetLength(V, Result + LR);
for I := 0 to LR - 1 do
V[Result + I] := R[I];
end;
end;
function DynArrayAppendUnicodeStringArray(var V: UnicodeStringArray; const R: array of UnicodeString): Integer;
var I, LR : Integer;
begin
Result := Length(V);
LR := Length(R);
if LR > 0 then
begin
SetLength(V, Result + LR);
for I := 0 to LR - 1 do
V[Result + I] := R[I];
end;
end;
function DynArrayAppendStringArray(var V: StringArray; const R: array of String): Integer;
var I, LR : Integer;
begin
Result := Length(V);
LR := Length(R);
if LR > 0 then
begin
SetLength(V, Result + LR);
for I := 0 to LR - 1 do
V[Result + I] := R[I];
end;
end;
{ }
{ DynArrayRemove }
{ }
{%DEFINE DynArrayRemoveMemImpl}
function DynArrayRemove(var V: %1%Array; const Idx: Integer; const Count: Integer): Integer;
var I, J, L, M: Integer;
begin
L := Length(V);
if (Idx >= L) or (Idx + Count <= 0) or (L = 0) or (Count = 0) then
begin
Result := 0;
exit;
end;
I := MaxInt(Idx, 0);
J := MinInt(Count, L - I);
M := L - J - I;
if M > 0 then
Move(V[I + J], V[I], M * SizeOf(%2%));
SetLength(V, L - J);
Result := J;
end;
{%ENDDEF}
{%TEMPLATE DynArrayRemoveMemImpl 'Byte' 'Byte'}
{%TEMPLATE DynArrayRemoveMemImpl 'Word16' 'Word16'}
{%TEMPLATE DynArrayRemoveMemImpl 'Word32' 'Word32'}
{%TEMPLATE DynArrayRemoveMemImpl 'Word64' 'Word64'}
{%TEMPLATE DynArrayRemoveMemImpl 'LongWord' 'LongWord'}
{%TEMPLATE DynArrayRemoveMemImpl 'Cardinal' 'Cardinal'}
{%TEMPLATE DynArrayRemoveMemImpl 'NativeUInt' 'NativeUInt'}
{%TEMPLATE DynArrayRemoveMemImpl 'ShortInt' 'ShortInt'}
{%TEMPLATE DynArrayRemoveMemImpl 'SmallInt' 'SmallInt'}
{%TEMPLATE DynArrayRemoveMemImpl 'LongInt' 'LongInt'}
{%TEMPLATE DynArrayRemoveMemImpl 'Integer' 'Integer'}
{%TEMPLATE DynArrayRemoveMemImpl 'Int32' 'Int32'}
{%TEMPLATE DynArrayRemoveMemImpl 'Int64' 'Int64'}
{%TEMPLATE DynArrayRemoveMemImpl 'NativeInt' 'NativeInt'}
{%TEMPLATE DynArrayRemoveMemImpl 'Single' 'Single'}
{%TEMPLATE DynArrayRemoveMemImpl 'Double' 'Double'}
{%TEMPLATE DynArrayRemoveMemImpl 'Extended' 'Extended'}
{%TEMPLATE DynArrayRemoveMemImpl 'Currency' 'Currency'}
{%TEMPLATE DynArrayRemoveMemImpl 'Pointer' 'Pointer'}
function DynArrayRemove(var V: ObjectArray; const Idx: Integer; const Count: Integer;
const FreeObjects: Boolean): Integer;
var I, J, K, L, M, F : Integer;
begin
L := Length(V);
if (Idx >= L) or (Idx + Count <= 0) or (L = 0) or (Count = 0) then
begin
Result := 0;
exit;
end;
I := MaxInt(Idx, 0);
J := MinInt(Count, L - I);
if FreeObjects then
for K := I to I + J - 1 do
FreeAndNil(V[K]);
M := L - J - I;
for F := I to I + M - 1 do
V[F] := V[F + J];
SetLength(V, L - J);
Result := J;
end;
{$IFDEF SupportAnsiString}
function DynArrayRemoveA(var V: AnsiStringArray; const Idx: Integer; const Count: Integer): Integer;
var I, J, K, L : Integer;
begin
L := Length(V);
if (Idx >= L) or (Idx + Count <= 0) or (L = 0) or (Count = 0) then
begin
Result := 0;
exit;
end;
I := MaxInt(Idx, 0);
J := MinInt(Count, L - I);
for K := I to L - J - 1 do
V[K] := V[K + J];
SetLength(V, L - J);
Result := J;
end;
{$ENDIF}
function DynArrayRemoveB(var V: RawByteStringArray; const Idx: Integer; const Count: Integer): Integer;
var I, J, K, L : Integer;
begin
L := Length(V);
if (Idx >= L) or (Idx + Count <= 0) or (L = 0) or (Count = 0) then
begin
Result := 0;
exit;
end;
I := MaxInt(Idx, 0);
J := MinInt(Count, L - I);
for K := I to L - J - 1 do
V[K] := V[K + J];
SetLength(V, L - J);
Result := J;
end;
function DynArrayRemoveU(var V: UnicodeStringArray; const Idx: Integer; const Count: Integer): Integer;
var I, J, K, L : Integer;
begin
L := Length(V);
if (Idx >= L) or (Idx + Count <= 0) or (L = 0) or (Count = 0) then
begin
Result := 0;
exit;
end;
I := MaxInt(Idx, 0);
J := MinInt(Count, L - I);
for K := I to L - J - 1 do
V[K] := V[K + J];
SetLength(V, L - J);
Result := J;
end;
function DynArrayRemove(var V: StringArray; const Idx: Integer; const Count: Integer): Integer;
var I, J, K, L : Integer;
begin
L := Length(V);
if (Idx >= L) or (Idx + Count <= 0) or (L = 0) or (Count = 0) then
begin
Result := 0;
exit;
end;
I := MaxInt(Idx, 0);
J := MinInt(Count, L - I);
for K := I to L - J - 1 do
V[K] := V[K + J];
SetLength(V, L - J);
Result := J;
end;
function DynArrayRemove(var V: InterfaceArray; const Idx: Integer; const Count: Integer): Integer;
var I, J, K, L, M : Integer;
begin
L := Length(V);
if (Idx >= L) or (Idx + Count <= 0) or (L = 0) or (Count = 0) then
begin
Result := 0;
exit;
end;
I := MaxInt(Idx, 0);
J := MinInt(Count, L - I);
for K := I to I + J - 1 do
V[K] := nil;
M := L - J - I;
if M > 0 then
Move(V[I + J], V[I], M * SizeOf(IInterface));
FillChar(V[L - J], J * SizeOf(IInterface), #0);
SetLength(V, L - J);
Result := J;
end;
{ }
{ DynArrayRemoveDuplicates }
{ }
{%DEFINE DynArrayRemoveDuplicatesImpl}
procedure DynArrayRemoveDuplicates%1%(var V: %2%Array; const IsSorted: Boolean);
var I, C, J, L : Integer;
F : %3%;
begin
L := Length(V);
if L = 0 then
exit;
if IsSorted then
begin
J := 0;
repeat
F := V[J];
I := J + 1;
while (I < L) and (V[I] = F) do
Inc(I);
C := I - J;
if C > 1 then
begin
DynArrayRemove%1%(V, J + 1, C - 1);
Dec(L, C - 1);
Inc(J);
end
else
J := I;
until J >= L;
end else
begin
J := 0;
repeat
repeat
I := DynArrayPosNext%1%(V[J], V, J);
if I >= 0 then
DynArrayRemove%1%(V, I, 1);
until I < 0;
Inc(J);
until J >= Length(V);
end;
end;
{%ENDDEF}
{%TEMPLATE DynArrayRemoveDuplicatesImpl '' 'Byte' 'Byte' }
{%TEMPLATE DynArrayRemoveDuplicatesImpl '' 'Word16' 'Word16' }
{%TEMPLATE DynArrayRemoveDuplicatesImpl '' 'LongWord' 'LongWord' }
{%TEMPLATE DynArrayRemoveDuplicatesImpl '' 'ShortInt' 'ShortInt' }
{%TEMPLATE DynArrayRemoveDuplicatesImpl '' 'SmallInt' 'SmallInt' }
{%TEMPLATE DynArrayRemoveDuplicatesImpl '' 'LongInt' 'LongInt' }
{%TEMPLATE DynArrayRemoveDuplicatesImpl '' 'Int64' 'Int64' }
{%TEMPLATE DynArrayRemoveDuplicatesImpl '' 'Single' 'Single' }
{%TEMPLATE DynArrayRemoveDuplicatesImpl '' 'Double' 'Double' }
{%TEMPLATE DynArrayRemoveDuplicatesImpl '' 'Extended' 'Extended' }
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayRemoveDuplicatesImpl 'A' 'AnsiString' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayRemoveDuplicatesImpl 'U' 'UnicodeString' 'UnicodeString'}
{%TEMPLATE DynArrayRemoveDuplicatesImpl '' 'String' 'String' }
{%TEMPLATE DynArrayRemoveDuplicatesImpl '' 'Pointer' 'Pointer' }
{%DEFINE DynArrayTrimLeftImpl}
procedure DynArrayTrimLeft%1%(var S: %2%Array; const TrimList: array of %3%); overload;
var I, J : Integer;
R : Boolean;
begin
I := 0;
R := True;
while R and (I < Length(S)) do
begin
R := False;
for J := 0 to High(TrimList) do
if S[I] = TrimList[J] then
begin
R := True;
Inc(I);
break;
end;
end;
if I > 0 then
DynArrayRemove%1%(S, 0, I - 1);
end;
{%ENDDEF}
{%TEMPLATE DynArrayTrimLeftImpl '' 'Byte' 'Byte'}
{%TEMPLATE DynArrayTrimLeftImpl '' 'Word16' 'Word16'}
{%TEMPLATE DynArrayTrimLeftImpl '' 'LongWord' 'LongWord'}
{%TEMPLATE DynArrayTrimLeftImpl '' 'ShortInt' 'ShortInt'}
{%TEMPLATE DynArrayTrimLeftImpl '' 'SmallInt' 'SmallInt'}
{%TEMPLATE DynArrayTrimLeftImpl '' 'LongInt' 'LongInt'}
{%TEMPLATE DynArrayTrimLeftImpl '' 'Int64' 'Int64'}
{%TEMPLATE DynArrayTrimLeftImpl '' 'Single' 'Single'}
{%TEMPLATE DynArrayTrimLeftImpl '' 'Double' 'Double'}
{%TEMPLATE DynArrayTrimLeftImpl '' 'Extended' 'Extended'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayTrimLeftImpl 'A' 'AnsiString' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayTrimLeftImpl 'U' 'UnicodeString' 'UnicodeString'}
{%TEMPLATE DynArrayTrimLeftImpl '' 'String' 'String'}
{%TEMPLATE DynArrayTrimLeftImpl '' 'Pointer' 'Pointer'}
{%DEFINE DynArrayTrimRightImpl}
procedure DynArrayTrimRight%1%(var S: %2%Array; const TrimList: array of %3%); overload;
var I, J : Integer;
R : Boolean;
begin
I := Length(S) - 1;
R := True;
while R and (I >= 0) do
begin
R := False;
for J := 0 to High(TrimList) do
if S[I] = TrimList[J] then
begin
R := True;
Dec(I);
break;
end;
end;
if I < Length(S) - 1 then
SetLength(S, I + 1);
end;
{%ENDDEF}
{%TEMPLATE DynArrayTrimRightImpl '' 'Byte' 'Byte'}
{%TEMPLATE DynArrayTrimRightImpl '' 'Word16' 'Word16'}
{%TEMPLATE DynArrayTrimRightImpl '' 'LongWord' 'LongWord'}
{%TEMPLATE DynArrayTrimRightImpl '' 'ShortInt' 'ShortInt'}
{%TEMPLATE DynArrayTrimRightImpl '' 'SmallInt' 'SmallInt'}
{%TEMPLATE DynArrayTrimRightImpl '' 'LongInt' 'LongInt'}
{%TEMPLATE DynArrayTrimRightImpl '' 'Int64' 'Int64'}
{%TEMPLATE DynArrayTrimRightImpl '' 'Single' 'Single'}
{%TEMPLATE DynArrayTrimRightImpl '' 'Double' 'Double'}
{%TEMPLATE DynArrayTrimRightImpl '' 'Extended' 'Extended'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayTrimRightImpl 'A' 'AnsiString' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayTrimRightImpl 'U' 'UnicodeString' 'UnicodeString'}
{%TEMPLATE DynArrayTrimRightImpl '' 'String' 'String'}
{%TEMPLATE DynArrayTrimRightImpl '' 'Pointer' 'Pointer'}
{ }
{ DynArrayInsert }
{ }
{%DEFINE DynArrayInsertImpl}
function DynArrayInsert%1%(var V: %2%Array; const Idx: Integer; const Count: Integer): Integer;
var I, L : Integer;
P : Pointer;
begin
L := Length(V);
if (Idx > L) or (Idx + Count <= 0) or (Count <= 0) then
begin
Result := -1;
exit;
end;
SetLength(V, L + Count);
I := Idx;
if I < 0 then
I := 0;
P := @V[I];
if I < L then
Move(P^, V[I + Count], (L - I) * Sizeof(%3%));
FillChar(P^, Count * Sizeof(%3%), #0);
Result := I;
end;
{%ENDDEF}
{%TEMPLATE DynArrayInsertImpl '' 'Byte' 'Byte' '0'}
{%TEMPLATE DynArrayInsertImpl '' 'Word16' 'Word16' '0'}
{%TEMPLATE DynArrayInsertImpl '' 'Word32' 'Word32' '0'}
{%TEMPLATE DynArrayInsertImpl '' 'Word64' 'Word64' '0'}
{%TEMPLATE DynArrayInsertImpl '' 'LongWord' 'LongWord' '0'}
{%TEMPLATE DynArrayInsertImpl '' 'NativeUInt' 'NativeUInt' '0'}
{%TEMPLATE DynArrayInsertImpl '' 'ShortInt' 'ShortInt' '0'}
{%TEMPLATE DynArrayInsertImpl '' 'SmallInt' 'SmallInt' '0'}
{%TEMPLATE DynArrayInsertImpl '' 'LongInt' 'LongInt' '0'}
{%TEMPLATE DynArrayInsertImpl '' 'Int32' 'Int32' '0'}
{%TEMPLATE DynArrayInsertImpl '' 'Int64' 'Int64' '0'}
{%TEMPLATE DynArrayInsertImpl '' 'NativeInt' 'NativeInt' '0'}
{%TEMPLATE DynArrayInsertImpl '' 'Single' 'Single' '0.0'}
{%TEMPLATE DynArrayInsertImpl '' 'Double' 'Double' '0.0'}
{%TEMPLATE DynArrayInsertImpl '' 'Extended' 'Extended' '0.0'}
{%TEMPLATE DynArrayInsertImpl '' 'Currency' 'Currency' '0.0'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayInsertImpl 'A' 'AnsiString' 'AnsiString' ''''''}
{$ENDIF}
{%TEMPLATE DynArrayInsertImpl 'B' 'RawByteString' 'RawByteString' ''''''}
{%TEMPLATE DynArrayInsertImpl 'U' 'UnicodeString' 'UnicodeString' ''''''}
{%TEMPLATE DynArrayInsertImpl '' 'String' 'String' ''''''}
{%TEMPLATE DynArrayInsertImpl '' 'Pointer' 'Pointer' 'nil'}
{%TEMPLATE DynArrayInsertImpl '' 'Object' 'Pointer' 'nil'}
{%TEMPLATE DynArrayInsertImpl '' 'Interface' 'IInterface' 'nil'}
{%DEFINE ArrayValue}%1%{%ENDDEF}
{ }
{ DynArrayPosNext }
{ PosNext finds the next occurance of Find in V, -1 if it was not found. }
{ Searches from Item[PrevPos + 1], ie PrevPos = -1 to find first }
{ occurance. }
{ }
{%DEFINE DynArrayPosNextImpl}
function DynArrayPosNext%5%(const %4%: %2%; const V: %1%Array; const PrevPos: Integer;
const IsSortedAscending: Boolean): Integer;
var I, L, H : Integer;
D : %2%;
begin
if IsSortedAscending then // binary search
begin
if MaxInt(PrevPos + 1, 0) = 0 then // find first
begin
L := 0;
H := Length(V) - 1;
while L <= H do
begin
I := (L + H) div 2;
D := {%TEMPLATE %3% 'V[I]'};
if %4% = D then
begin
while (I > 0) and ({%TEMPLATE %3% 'V[I - 1]'} = %4%) do
Dec(I);
Result := I;
exit;
end else
if D > %4% then
H := I - 1
else
L := I + 1;
end;
Result := -1;
end
else // find next
if PrevPos >= Length(V) - 1 then
Result := -1
else
if {%TEMPLATE %3% 'V[PrevPos + 1]'} = %4% then
Result := PrevPos + 1
else
Result := -1;
end
else
begin // linear search
for I := MaxInt(PrevPos + 1, 0) to Length(V) - 1 do
if {%TEMPLATE %3% 'V[I]'} = %4% then
begin
Result := I;
exit;
end;
Result := -1;
end;
end;
{%ENDDEF}
{%DEFINE DynArrayPosNextArrayImpl}{%TEMPLATE DynArrayPosNextImpl '%2%' '%3%' 'ArrayValue' 'Find' '%1%'}{%ENDDEF}
{%TEMPLATE DynArrayPosNextArrayImpl '' 'Byte' 'Byte' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'Word16' 'Word16' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'Word32' 'Word32' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'Word64' 'Word64' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'LongWord' 'LongWord' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'Cardinal' 'Cardinal' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'NativeUInt' 'NativeUInt' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'ShortInt' 'ShortInt' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'SmallInt' 'SmallInt' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'LongInt' 'LongInt' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'Integer' 'Integer' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'Int32' 'Int32' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'Int64' 'Int64' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'NativeInt' 'NativeInt' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'Single' 'Single' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'Double' 'Double' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'Extended' 'Extended' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'Boolean' 'Boolean' }
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayPosNextArrayImpl 'A' 'AnsiString' 'AnsiString' }
{$ENDIF}
{%TEMPLATE DynArrayPosNextArrayImpl 'B' 'RawByteString' 'RawByteString' }
{%TEMPLATE DynArrayPosNextArrayImpl 'U' 'UnicodeString' 'UnicodeString' }
{%TEMPLATE DynArrayPosNextArrayImpl '' 'String' 'String' }
function DynArrayPosNext(const Find: TObject; const V: ObjectArray; const PrevPos: Integer): Integer;
var I : Integer;
begin
for I := MaxInt(PrevPos + 1, 0) to Length(V) - 1 do
if V[I] = Find then
begin
Result := I;
exit;
end;
Result := -1;
end;
function DynArrayPosNext(const ClassType: TClass; const V: ObjectArray; const PrevPos: Integer): Integer;
var I : Integer;
begin
for I := MaxInt(PrevPos + 1, 0) to Length(V) - 1 do
if V[I] is ClassType then
begin
Result := I;
exit;
end;
Result := -1;
end;
function DynArrayPosNext(const ClassName: String; const V: ObjectArray; const PrevPos: Integer): Integer;
var I : Integer;
T : TObject;
begin
for I := MaxInt(PrevPos + 1, 0) to Length(V) - 1 do
begin
T := V[I];
if Assigned(T) and (T.ClassName = ClassName) then
begin
Result := I;
exit;
end;
end;
Result := -1;
end;
function DynArrayPosNext(const Find: Pointer; const V: PointerArray; const PrevPos: Integer): Integer;
var I : Integer;
begin
for I := MaxInt(PrevPos + 1, 0) to Length(V) - 1 do
if V[I] = Find then
begin
Result := I;
exit;
end;
Result := -1;
end;
{ }
{ DynArrayCount }
{ }
{%DEFINE DynArrayCountImpl}
function DynArrayCount%1%(const Find: %3%; const V: %2%Array; const IsSortedAscending: Boolean = False): Integer;
var I, J : Integer;
begin
if IsSortedAscending then
begin
I := DynArrayPosNext%1%(Find, V, -1, True);
if I = -1 then
Result := 0 else
begin
Result := 1;
J := Length(V);
while (I + Result < J) and (V[I + Result] = Find) do
Inc(Result);
end;
end
else
begin
J := -1;
Result := 0;
repeat
I := DynArrayPosNext%1%(Find, V, J, False);
if I >= 0 then
begin
Inc(Result);
J := I;
end;
until I < 0;
end;
end;
{%ENDDEF}
{%TEMPLATE DynArrayCountImpl '' 'Byte' 'Byte'}
{%TEMPLATE DynArrayCountImpl '' 'Word16' 'Word16'}
{%TEMPLATE DynArrayCountImpl '' 'LongWord' 'LongWord'}
{%TEMPLATE DynArrayCountImpl '' 'ShortInt' 'ShortInt'}
{%TEMPLATE DynArrayCountImpl '' 'SmallInt' 'SmallInt'}
{%TEMPLATE DynArrayCountImpl '' 'LongInt' 'LongInt'}
{%TEMPLATE DynArrayCountImpl '' 'Int64' 'Int64'}
{%TEMPLATE DynArrayCountImpl '' 'Single' 'Single'}
{%TEMPLATE DynArrayCountImpl '' 'Double' 'Double'}
{%TEMPLATE DynArrayCountImpl '' 'Extended' 'Extended'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayCountImpl 'A' 'AnsiString' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayCountImpl 'B' 'RawByteString' 'RawByteString'}
{%TEMPLATE DynArrayCountImpl 'U' 'UnicodeString' 'UnicodeString'}
{%TEMPLATE DynArrayCountImpl '' 'String' 'String'}
{%TEMPLATE DynArrayCountImpl '' 'Boolean' 'Boolean'}
{ }
{ DynArrayRemoveAll }
{ }
{%DEFINE DynArrayRemoveAllImpl}
procedure DynArrayRemoveAll%1%(const Find: %3%; var V: %2%Array; const IsSortedAscending: Boolean = False);
var I, J : Integer;
begin
I := DynArrayPosNext%1%(Find, V, -1, IsSortedAscending);
while I >= 0 do
begin
J := 1;
while (I + J < Length(V)) and (V[I + J] = Find) do
Inc(J);
DynArrayRemove%1%(V, I, J);
I := DynArrayPosNext%1%(Find, V, I, IsSortedAscending);
end;
end;
{%ENDDEF}
{%TEMPLATE DynArrayRemoveAllImpl '' 'Byte' 'Byte'}
{%TEMPLATE DynArrayRemoveAllImpl '' 'Word16' 'Word16'}
{%TEMPLATE DynArrayRemoveAllImpl '' 'LongWord' 'LongWord'}
{%TEMPLATE DynArrayRemoveAllImpl '' 'ShortInt' 'ShortInt'}
{%TEMPLATE DynArrayRemoveAllImpl '' 'SmallInt' 'SmallInt'}
{%TEMPLATE DynArrayRemoveAllImpl '' 'LongInt' 'LongInt'}
{%TEMPLATE DynArrayRemoveAllImpl '' 'Int64' 'Int64'}
{%TEMPLATE DynArrayRemoveAllImpl '' 'Single' 'Single'}
{%TEMPLATE DynArrayRemoveAllImpl '' 'Double' 'Double'}
{%TEMPLATE DynArrayRemoveAllImpl '' 'Extended' 'Extended'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayRemoveAllImpl 'A' 'AnsiString' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayRemoveAllImpl 'U' 'UnicodeString' 'UnicodeString'}
{%TEMPLATE DynArrayRemoveAllImpl '' 'String' 'String'}
{ }
{ DynArrayIntersection }
{ If both arrays are sorted ascending then time is o(n) instead of o(n^2). }
{ }
{%DEFINE DynArrayIntersectionFloatImpl}
function DynArrayIntersection(const V1, V2: %1%Array; const IsSortedAscending: Boolean): %1%Array;
var I, J, L, LV : Integer;
begin
SetLength(Result, 0);
if IsSortedAscending then
begin
I := 0;
J := 0;
L := Length(V1);
LV := Length(V2);
while (I < L) and (J < LV) do
begin
while (I < L) and (V1[I] < V2[J]) do
Inc(I);
if I < L then
begin
if V1[I] = V2[J] then
DynArrayAppend(Result, V1[I]);
while (J < LV) and (V2[J] <= V1[I]) do
Inc(J);
end;
end;
end
else
for I := 0 to Length(V1) - 1 do
if (DynArrayPosNext(V1[I], V2) >= 0) and (DynArrayPosNext(V1[I], Result) = -1) then
DynArrayAppend(Result, V1[I]);
end;
{%ENDDEF}
{%TEMPLATE DynArrayIntersectionFloatImpl 'Single'}
{%TEMPLATE DynArrayIntersectionFloatImpl 'Double'}
{%TEMPLATE DynArrayIntersectionFloatImpl 'Extended'}
{%DEFINE DynArrayIntersectionImpl}
function DynArrayIntersection%1%(const V1, V2: %2%Array; const IsSortedAscending: Boolean): %2%Array;
var I, J, L, LV : Integer;
begin
SetLength(Result, 0);
if IsSortedAscending then
begin
I := 0;
J := 0;
L := Length(V1);
LV := Length(V2);
while (I < L) and (J < LV) do
begin
while (I < L) and (V1[I] < V2[J]) do
Inc(I);
if I < L then
begin
if V1[I] = V2[J] then
DynArrayAppend%1%(Result, V1[I]);
while (J < LV) and (V2[J] <= V1[I]) do
Inc(J);
end;
end;
end
else
for I := 0 to Length(V1) - 1 do
if (DynArrayPosNext%1%(V1[I], V2) >= 0) and (DynArrayPosNext%1%(V1[I], Result) = -1) then
DynArrayAppend%1%(Result, V1[I]);
end;
{%ENDDEF}
{%TEMPLATE DynArrayIntersectionImpl '' 'Byte'}
{%TEMPLATE DynArrayIntersectionImpl '' 'Word16'}
{%TEMPLATE DynArrayIntersectionImpl '' 'LongWord'}
{%TEMPLATE DynArrayIntersectionImpl '' 'ShortInt'}
{%TEMPLATE DynArrayIntersectionImpl '' 'SmallInt'}
{%TEMPLATE DynArrayIntersectionImpl '' 'LongInt'}
{%TEMPLATE DynArrayIntersectionImpl '' 'Int64'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayIntersectionImpl 'A' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayIntersectionImpl 'U' 'UnicodeString'}
{%TEMPLATE DynArrayIntersectionImpl '' 'String'}
{ }
{ DynArrayDifference }
{ Returns elements in V1 but not in V2. }
{ If both arrays are sorted ascending then time is o(n) instead of o(n^2). }
{ }
{%DEFINE DynArrayDifferenceFloatImpl}
function DynArrayDifference(const V1, V2: %1%Array; const IsSortedAscending: Boolean): %1%Array;
var I, J, L, LV : Integer;
begin
SetLength(Result, 0);
if IsSortedAscending then
begin
I := 0;
J := 0;
L := Length(V1);
LV := Length(V2);
while (I < L) and (J < LV) do
begin
while (I < L) and (V1[I] < V2[J]) do
Inc(I);
if I < L then
begin
if V1[I] <> V2[J] then
DynArrayAppend(Result, V1[I]);
while (J < LV) and (V2[J] <= V1[I]) do
Inc(J);
end;
end;
end
else
for I := 0 to Length(V1) - 1 do
if (DynArrayPosNext(V1[I], V2) = -1) and (DynArrayPosNext(V1[I], Result) = -1) then
DynArrayAppend(Result, V1[I]);
end;
{%ENDDEF}
{%TEMPLATE DynArrayDifferenceFloatImpl 'Single'}
{%TEMPLATE DynArrayDifferenceFloatImpl 'Double'}
{%TEMPLATE DynArrayDifferenceFloatImpl 'Extended'}
{%DEFINE DynArrayDifferenceImpl}
function DynArrayDifference%1%(const V1, V2: %2%Array; const IsSortedAscending: Boolean): %2%Array;
var I, J, L, LV : Integer;
begin
SetLength(Result, 0);
if IsSortedAscending then
begin
I := 0;
J := 0;
L := Length(V1);
LV := Length(V2);
while (I < L) and (J < LV) do
begin
while (I < L) and (V1[I] < V2[J]) do
Inc(I);
if I < L then
begin
if V1[I] <> V2[J] then
DynArrayAppend%1%(Result, V1[I]);
while (J < LV) and (V2[J] <= V1[I]) do
Inc(J);
end;
end;
end
else
for I := 0 to Length(V1) - 1 do
if (DynArrayPosNext%1%(V1[I], V2) = -1) and (DynArrayPosNext%1%(V1[I], Result) = -1) then
DynArrayAppend%1%(Result, V1[I]);
end;
{%ENDDEF}
{%TEMPLATE DynArrayDifferenceImpl '' 'Byte'}
{%TEMPLATE DynArrayDifferenceImpl '' 'Word16'}
{%TEMPLATE DynArrayDifferenceImpl '' 'LongWord'}
{%TEMPLATE DynArrayDifferenceImpl '' 'ShortInt'}
{%TEMPLATE DynArrayDifferenceImpl '' 'SmallInt'}
{%TEMPLATE DynArrayDifferenceImpl '' 'LongInt'}
{%TEMPLATE DynArrayDifferenceImpl '' 'Int64'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayDifferenceImpl 'A' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayDifferenceImpl 'U' 'UnicodeString'}
{%TEMPLATE DynArrayDifferenceImpl '' 'String'}
{ }
{ DynArrayReverse }
{ }
{%DEFINE DynArrayReverseImpl}
procedure DynArrayReverse%1%(var V: %2%Array);
var I, L : Integer;
begin
L := Length(V);
for I := 1 to L div 2 do
Swap%3%(V[I - 1], V[L - I]);
end;
{%ENDDEF}
{%TEMPLATE DynArrayReverseImpl '' 'Byte' ''}
{%TEMPLATE DynArrayReverseImpl '' 'Word16' ''}
{%TEMPLATE DynArrayReverseImpl '' 'LongWord' 'LW'}
{%TEMPLATE DynArrayReverseImpl '' 'ShortInt' ''}
{%TEMPLATE DynArrayReverseImpl '' 'SmallInt' ''}
{%TEMPLATE DynArrayReverseImpl '' 'LongInt' 'LI'}
{%TEMPLATE DynArrayReverseImpl '' 'Int64' ''}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayReverseImpl 'A' 'AnsiString' 'A'}
{$ENDIF}
{%TEMPLATE DynArrayReverseImpl 'U' 'UnicodeString' 'U'}
{%TEMPLATE DynArrayReverseImpl '' 'String' ''}
{%TEMPLATE DynArrayReverseImpl '' 'Pointer' ''}
{%TEMPLATE DynArrayReverseImpl '' 'Object' ''}
{%TEMPLATE DynArrayReverseImpl '' 'Single' ''}
{%TEMPLATE DynArrayReverseImpl '' 'Double' ''}
{%TEMPLATE DynArrayReverseImpl '' 'Extended' 'Ext'}
{ }
{ Returns an open array (V) as a dynamic array. }
{ }
{%DEFINE OpenArrayAsDynArrayImpl}
function As%1%Array(const V: array of %2%): %1%Array;
var I : Integer;
begin
SetLength(Result, High(V) + 1);
for I := 0 to High(V) do
Result[I] := V[I];
end;
{%ENDDEF}
{%TEMPLATE OpenArrayAsDynArrayImpl 'Boolean' 'Boolean'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'Byte' 'Byte'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'Word16' 'Word16'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'Word32' 'Word32'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'Word64' 'Word64'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'LongWord' 'LongWord'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'Cardinal' 'Cardinal'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'NativeUInt' 'NativeUInt'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'ShortInt' 'ShortInt'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'SmallInt' 'SmallInt'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'LongInt' 'LongInt'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'Integer' 'Integer'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'Int32' 'Int32'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'Int64' 'Int64'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'NativeInt' 'NativeInt'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'Single' 'Single'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'Double' 'Double'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'Extended' 'Extended'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'Currency' 'Currency'}
{$IFDEF SupportAnsiString}
{%TEMPLATE OpenArrayAsDynArrayImpl 'AnsiString' 'AnsiString'}
{$ENDIF}
{%TEMPLATE OpenArrayAsDynArrayImpl 'RawByteString' 'RawByteString'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'UnicodeString' 'UnicodeString'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'String' 'String'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'Pointer' 'Pointer'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'ByteCharSet' 'ByteCharSet'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'Object' 'TObject'}
{%TEMPLATE OpenArrayAsDynArrayImpl 'Interface' 'IInterface'}
{%DEFINE DynArrayRangeImpl}
function DynArrayRange%1%(const First: %1%; const Count: Integer; const Increment: %1%): %1%Array;
var I : Integer;
J : %1%;
begin
SetLength(Result, Count);
J := First;
for I := 0 to Count - 1 do
begin
Result[I] := J;
J := J + Increment;
end;
end;
{%ENDDEF}
{%TEMPLATE DynArrayRangeImpl 'Byte'}
{%TEMPLATE DynArrayRangeImpl 'Word16'}
{%TEMPLATE DynArrayRangeImpl 'LongWord'}
{%TEMPLATE DynArrayRangeImpl 'Cardinal'}
{%TEMPLATE DynArrayRangeImpl 'ShortInt'}
{%TEMPLATE DynArrayRangeImpl 'SmallInt'}
{%TEMPLATE DynArrayRangeImpl 'LongInt'}
{%TEMPLATE DynArrayRangeImpl 'Integer'}
{%TEMPLATE DynArrayRangeImpl 'Int64'}
{%TEMPLATE DynArrayRangeImpl 'Single'}
{%TEMPLATE DynArrayRangeImpl 'Double'}
{%TEMPLATE DynArrayRangeImpl 'Extended'}
{ }
{ DynArrayDup }
{ }
function DynArrayDupByte(const V: Byte; const Count: Integer): ByteArray;
begin
if Count <= 0 then
begin
SetLength(Result, 0);
exit;
end;
SetLength(Result, Count);
FillChar(Result[0], Count, V);
end;
{%DEFINE DynArrayDupImpl}
function DynArrayDup%1%(const V: %2%; const Count: Integer): %1%Array;
var I : Integer;
begin
if Count <= 0 then
begin
SetLength(Result, 0);
exit;
end;
SetLength(Result, Count);
for I := 0 to Count - 1 do
Result[I] := V;
end;
{%ENDDEF}
{%TEMPLATE DynArrayDupImpl 'Word16' 'Word16'}
{%TEMPLATE DynArrayDupImpl 'LongWord' 'LongWord'}
{%TEMPLATE DynArrayDupImpl 'Cardinal' 'Cardinal'}
{%TEMPLATE DynArrayDupImpl 'NativeUInt' 'NativeUInt'}
{%TEMPLATE DynArrayDupImpl 'ShortInt' 'ShortInt'}
{%TEMPLATE DynArrayDupImpl 'SmallInt' 'SmallInt'}
{%TEMPLATE DynArrayDupImpl 'LongInt' 'LongInt'}
{%TEMPLATE DynArrayDupImpl 'Integer' 'Integer'}
{%TEMPLATE DynArrayDupImpl 'Int64' 'Int64'}
{%TEMPLATE DynArrayDupImpl 'NativeInt' 'NativeInt'}
{%TEMPLATE DynArrayDupImpl 'Single' 'Single'}
{%TEMPLATE DynArrayDupImpl 'Double' 'Double'}
{%TEMPLATE DynArrayDupImpl 'Extended' 'Extended'}
{%TEMPLATE DynArrayDupImpl 'Currency' 'Currency'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayDupImpl 'AnsiString' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayDupImpl 'UnicodeString' 'UnicodeString'}
{%TEMPLATE DynArrayDupImpl 'String' 'String'}
{%TEMPLATE DynArrayDupImpl 'ByteCharSet' 'ByteCharSet'}
{%TEMPLATE DynArrayDupImpl 'Object' 'TObject'}
{ }
{ SetLengthAndZero }
{ }
{%DEFINE SetLengthAndZeroImpl}
procedure SetLengthAndZero(var V: %1%Array; const NewLength: Integer);
var OldLen, NewLen : Integer;
begin
NewLen := NewLength;
if NewLen < 0 then
NewLen := 0;
OldLen := Length(V);
if OldLen = NewLen then
exit;
SetLength(V, NewLen);
if OldLen > NewLen then
exit;
FillChar(Pointer(@V[OldLen])^, Sizeof(%2%) * (NewLen - OldLen), #0);
end;
{%ENDDEF}
{%TEMPLATE SetLengthAndZeroImpl 'Byte' 'Byte' '0'}
{%TEMPLATE SetLengthAndZeroImpl 'Word16' 'Word16' '0'}
{%TEMPLATE SetLengthAndZeroImpl 'Word32' 'Word32' '0'}
{%TEMPLATE SetLengthAndZeroImpl 'Word64' 'Word64' '0'}
{%TEMPLATE SetLengthAndZeroImpl 'LongWord' 'LongWord' '0'}
{%TEMPLATE SetLengthAndZeroImpl 'Cardinal' 'Cardinal' '0'}
{%TEMPLATE SetLengthAndZeroImpl 'NativeUInt' 'NativeUInt' '0'}
{%TEMPLATE SetLengthAndZeroImpl 'ShortInt' 'ShortInt' '0'}
{%TEMPLATE SetLengthAndZeroImpl 'SmallInt' 'SmallInt' '0'}
{%TEMPLATE SetLengthAndZeroImpl 'LongInt' 'LongInt' '0'}
{%TEMPLATE SetLengthAndZeroImpl 'Integer' 'Integer' '0'}
{%TEMPLATE SetLengthAndZeroImpl 'Int32' 'Int32' '0'}
{%TEMPLATE SetLengthAndZeroImpl 'Int64' 'Int64' '0'}
{%TEMPLATE SetLengthAndZeroImpl 'NativeInt' 'NativeInt' '0'}
{%TEMPLATE SetLengthAndZeroImpl 'Single' 'Single' '0.0'}
{%TEMPLATE SetLengthAndZeroImpl 'Double' 'Double' '0.0'}
{%TEMPLATE SetLengthAndZeroImpl 'Extended' 'Extended' '0.0'}
{%TEMPLATE SetLengthAndZeroImpl 'Currency' 'Currency' '0.0'}
{%TEMPLATE SetLengthAndZeroImpl 'ByteCharSet' 'ByteCharSet' '[]'}
{%TEMPLATE SetLengthAndZeroImpl 'Boolean' 'Boolean' 'False'}
{%TEMPLATE SetLengthAndZeroImpl 'Pointer' 'Pointer' 'nil'}
procedure SetLengthAndZero(var V: ObjectArray; const NewLength: Integer;
const FreeObjects: Boolean);
var I, L : Integer;
begin
L := Length(V);
if L = NewLength then
exit;
if (L > NewLength) and FreeObjects then
for I := NewLength to L - 1 do
FreeAndNil(V[I]);
SetLength(V, NewLength);
if L > NewLength then
exit;
FillChar(V[L], Sizeof(Pointer) * (NewLength - L), #0);
end;
{ }
{ DynArrayIsEqual }
{ }
{%DEFINE DynArrayIsEqualMemImpl}
function DynArrayIsEqual(const V1, V2: %1%Array): Boolean;
var L : Integer;
begin
L := Length(V1);
if L <> Length(V2) then
begin
Result := False;
exit;
end;
Result := EqualMem(Pointer(V1)^, Pointer(V2)^, Sizeof(%1%) * L);
end;
{%ENDDEF}
{%DEFINE DynArrayIsEqualBruteImpl}
function DynArrayIsEqual%1%(const V1, V2: %2%Array): Boolean;
var I, L : Integer;
begin
L := Length(V1);
if L <> Length(V2) then
begin
Result := False;
exit;
end;
for I := 0 to L - 1 do
if V1[I] <> V2[I] then
begin
Result := False;
exit;
end;
Result := True;
end;
{%ENDDEF}
{%TEMPLATE DynArrayIsEqualMemImpl 'Byte'}
{%TEMPLATE DynArrayIsEqualMemImpl 'Word16'}
{%TEMPLATE DynArrayIsEqualMemImpl 'LongWord'}
{%TEMPLATE DynArrayIsEqualMemImpl 'ShortInt'}
{%TEMPLATE DynArrayIsEqualMemImpl 'SmallInt'}
{%TEMPLATE DynArrayIsEqualMemImpl 'LongInt'}
{%TEMPLATE DynArrayIsEqualMemImpl 'Int64'}
{%TEMPLATE DynArrayIsEqualMemImpl 'Single'}
{%TEMPLATE DynArrayIsEqualMemImpl 'Double'}
{%TEMPLATE DynArrayIsEqualMemImpl 'Extended'}
{%TEMPLATE DynArrayIsEqualMemImpl 'Currency'}
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayIsEqualBruteImpl 'A' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayIsEqualBruteImpl 'B' 'RawByteString'}
{%TEMPLATE DynArrayIsEqualBruteImpl 'U' 'UnicodeString'}
{%TEMPLATE DynArrayIsEqualBruteImpl '' 'String'}
{%TEMPLATE DynArrayIsEqualBruteImpl '' 'ByteCharSet'}
{ }
{ Dynamic array to Dynamic array }
{ }
{%DEFINE DynArrayToDynArrayImpl}
function %1%ArrayTo%2%Array(const V: %1%Array): %2%Array;
var I, L : Integer;
begin
L := Length(V);
SetLength(Result, L);
for I := 0 to L - 1 do
Result[I] := %3%V[I]%4%;
end;
{%ENDDEF}
{%TEMPLATE DynArrayToDynArrayImpl 'Byte' 'LongInt' '' ''}
{%TEMPLATE DynArrayToDynArrayImpl 'Word16' 'LongInt' '' ''}
{%TEMPLATE DynArrayToDynArrayImpl 'ShortInt' 'LongInt' '' ''}
{%TEMPLATE DynArrayToDynArrayImpl 'SmallInt' 'LongInt' '' ''}
{%TEMPLATE DynArrayToDynArrayImpl 'LongInt' 'Int64' '' ''}
{%TEMPLATE DynArrayToDynArrayImpl 'LongInt' 'Single' '' ''}
{%TEMPLATE DynArrayToDynArrayImpl 'LongInt' 'Double' '' ''}
{%TEMPLATE DynArrayToDynArrayImpl 'LongInt' 'Extended' '' ''}
{%TEMPLATE DynArrayToDynArrayImpl 'Single' 'Double' '' ''}
{%TEMPLATE DynArrayToDynArrayImpl 'Single' 'Extended' '' ''}
{%TEMPLATE DynArrayToDynArrayImpl 'Single' 'Currency' '' ''}
{%TEMPLATE DynArrayToDynArrayImpl 'Single' 'LongInt' 'LongInt(Trunc(' '))'}
{%TEMPLATE DynArrayToDynArrayImpl 'Single' 'Int64' 'Trunc(' ')'}
{%TEMPLATE DynArrayToDynArrayImpl 'Double' 'Extended' '' ''}
{%TEMPLATE DynArrayToDynArrayImpl 'Double' 'Currency' '' ''}
{%TEMPLATE DynArrayToDynArrayImpl 'Double' 'LongInt' 'LongInt(Trunc(' '))'}
{%TEMPLATE DynArrayToDynArrayImpl 'Double' 'Int64' 'Trunc(' ')'}
{%TEMPLATE DynArrayToDynArrayImpl 'Extended' 'Currency' '' ''}
{%TEMPLATE DynArrayToDynArrayImpl 'Extended' 'LongInt' 'LongInt(Trunc(' '))'}
{%TEMPLATE DynArrayToDynArrayImpl 'Extended' 'Int64' 'Trunc(' ')'}
{ }
{ Array from indexes }
{ }
{%DEFINE DynArrayFromIndexesImpl}
function %1%ArrayFromIndexes(const V: %1%Array; const Indexes: IntegerArray): %1%Array;
var I, L : Integer;
begin
L := Length(Indexes);
SetLength(Result, L);
for I := 0 to L - 1 do
Result[I] := V[Indexes[I]];
end;
{%ENDDEF}
{%TEMPLATE DynArrayFromIndexesImpl 'Byte'}
{%TEMPLATE DynArrayFromIndexesImpl 'Word16'}
{%TEMPLATE DynArrayFromIndexesImpl 'LongWord'}
{%TEMPLATE DynArrayFromIndexesImpl 'Cardinal'}
{%TEMPLATE DynArrayFromIndexesImpl 'ShortInt'}
{%TEMPLATE DynArrayFromIndexesImpl 'SmallInt'}
{%TEMPLATE DynArrayFromIndexesImpl 'LongInt'}
{%TEMPLATE DynArrayFromIndexesImpl 'Integer'}
{%TEMPLATE DynArrayFromIndexesImpl 'Int64'}
{%TEMPLATE DynArrayFromIndexesImpl 'Single'}
{%TEMPLATE DynArrayFromIndexesImpl 'Double'}
{%TEMPLATE DynArrayFromIndexesImpl 'Extended'}
{%TEMPLATE DynArrayFromIndexesImpl 'String'}
{ }
{ Dynamic array sort }
{ }
{%DEFINE DynArraySortImpl}
procedure DynArraySort%1%(const V: %2%Array);
procedure QuickSort(L, R: Integer);
var I, J, M : Integer;
W, T : %3%;
begin
repeat
I := L;
J := R;
M := (L + R) shr 1;
W := V[M];
repeat
while V[I] < W do
Inc(I);
while V[J] > W do
Dec(J);
if I <= J then
begin
T := V[I];
V[I] := V[J];
V[J] := T;
if M = I then
begin
M := J;
W := V[J];
end else
if M = J then
begin
M := I;
W := V[I];
end;
Inc(I);
Dec(J);
end;
until I > J;
if L < J then
QuickSort(L, J);
L := I;
until I >= R;
end;
var I : Integer;
begin
I := Length(V);
if I > 0 then
QuickSort(0, I - 1);
end;
{%ENDDEF}
{%TEMPLATE DynArraySortImpl '' 'Byte' 'Byte' }
{%TEMPLATE DynArraySortImpl '' 'Word16' 'Word16' }
{%TEMPLATE DynArraySortImpl '' 'LongWord' 'LongWord' }
{%TEMPLATE DynArraySortImpl '' 'Cardinal' 'Cardinal' }
{%TEMPLATE DynArraySortImpl '' 'NativeUInt' 'NativeUInt' }
{%TEMPLATE DynArraySortImpl '' 'ShortInt' 'ShortInt' }
{%TEMPLATE DynArraySortImpl '' 'SmallInt' 'SmallInt' }
{%TEMPLATE DynArraySortImpl '' 'LongInt' 'LongInt' }
{%TEMPLATE DynArraySortImpl '' 'Integer' 'Integer' }
{%TEMPLATE DynArraySortImpl '' 'Int64' 'Int64' }
{%TEMPLATE DynArraySortImpl '' 'NativeInt' 'NativeInt' }
{%TEMPLATE DynArraySortImpl '' 'Single' 'Single' }
{%TEMPLATE DynArraySortImpl '' 'Double' 'Double' }
{%TEMPLATE DynArraySortImpl '' 'Extended' 'Extended' }
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArraySortImpl 'A' 'AnsiString' 'AnsiString' }
{$ENDIF}
{%TEMPLATE DynArraySortImpl 'B' 'RawByteString' 'RawByteString' }
{%TEMPLATE DynArraySortImpl 'U' 'UnicodeString' 'UnicodeString' }
{%TEMPLATE DynArraySortImpl '' 'String' 'String' }
{%DEFINE DynArrayPairSortImpl}
procedure DynArraySort(const Key: %1%Array; const Data: %2%Array);
procedure QuickSort(L, R: Integer);
var I, J, M : Integer;
W, T : %3%;
P, Q : P%3%;
A : %4%;
begin
repeat
I := L;
P := @Key[I];
J := R;
Q := @Key[J];
M := (L + R) shr 1;
W := Key[M];
repeat
while P^ < W do
begin
Inc(P);
Inc(I);
end;
while Q^ > W do
begin
Dec(Q);
Dec(J);
end;
if I <= J then
begin
T := P^;
P^ := Q^;
Q^ := T;
A := Data[I];
Data[I] := Data[J];
Data[J] := A;
if M = I then
begin
M := J;
W := Q^;
end else
if M = J then
begin
M := I;
W := P^;
end;
Inc(P);
Inc(I);
Dec(Q);
Dec(J);
end;
until I > J;
if L < J then
QuickSort(L, J);
L := I;
until I >= R;
end;
var I : Integer;
begin
Assert(Length(Key) = Length(Data));
I := Length(Key);
if I > 0 then
QuickSort(0, I - 1);
end;
{%ENDDEF}
{%TEMPLATE DynArrayPairSortImpl 'Integer' 'Integer' 'Integer' 'Integer' }
{%TEMPLATE DynArrayPairSortImpl 'Integer' 'Int64' 'Integer' 'Int64' }
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayPairSortImpl 'Integer' 'AnsiString' 'Integer' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayPairSortImpl 'Integer' 'Extended' 'Integer' 'Extended' }
{%TEMPLATE DynArrayPairSortImpl 'Integer' 'Pointer' 'Integer' 'Pointer' }
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayPairSortImpl 'AnsiString' 'Integer' 'AnsiString' 'Integer' }
{%TEMPLATE DynArrayPairSortImpl 'AnsiString' 'Int64' 'AnsiString' 'Int64' }
{%TEMPLATE DynArrayPairSortImpl 'AnsiString' 'AnsiString' 'AnsiString' 'AnsiString'}
{%TEMPLATE DynArrayPairSortImpl 'AnsiString' 'Extended' 'AnsiString' 'Extended' }
{%TEMPLATE DynArrayPairSortImpl 'AnsiString' 'Pointer' 'AnsiString' 'Pointer' }
{$ENDIF}
{%TEMPLATE DynArrayPairSortImpl 'Extended' 'Integer' 'Extended' 'Integer' }
{%TEMPLATE DynArrayPairSortImpl 'Extended' 'Int64' 'Extended' 'Int64' }
{$IFDEF SupportAnsiString}
{%TEMPLATE DynArrayPairSortImpl 'Extended' 'AnsiString' 'Extended' 'AnsiString'}
{$ENDIF}
{%TEMPLATE DynArrayPairSortImpl 'Extended' 'Extended' 'Extended' 'Extended' }
{%TEMPLATE DynArrayPairSortImpl 'Extended' 'Pointer' 'Extended' 'Pointer' }
{ }
{ Test cases }
{ }
{$IFDEF DYNARRAYS_TEST}
{$ASSERTIONS ON}
procedure Test_IntegerArray;
var S, T : IntegerArray;
F : Integer;
begin
S := nil;
for F := 1 to 100 do
begin
DynArrayAppend(S, F);
Assert(Length(S) = F, 'Append');
Assert(S[F - 1] = F, 'Append');
end;
T := Copy(S);
DynArrayAppendIntegerArray(S, T);
for F := 1 to 100 do
Assert(S[F + 99] = F, 'Append');
Assert(DynArrayPosNext(60, S) = 59, 'PosNext');
Assert(DynArrayPosNext(60, T) = 59, 'PosNext');
Assert(DynArrayPosNext(60, S, 59) = 159, 'PosNext');
Assert(DynArrayPosNext(60, T, 59) = -1, 'PosNext');
Assert(DynArrayPosNext(60, T, -1, True) = 59, 'PosNext');
Assert(DynArrayPosNext(60, T, 59, True) = -1, 'PosNext');
for F := 1 to 100 do
begin
DynArrayRemove(S, DynArrayPosNext(F, S), 1);
Assert(Length(S) = 200 - F, 'Remove');
end;
for F := 99 downto 0 do
begin
DynArrayRemove(S, DynArrayPosNext(F xor 3 + 1, S), 1);
Assert(Length(S) = F, 'Remove');
end;
S := AsIntegerArray([3, 1, 2, 5, 4]);
DynArraySort(S);
Assert(S[0] = 1, 'Sort');
Assert(S[1] = 2, 'Sort');
Assert(S[2] = 3, 'Sort');
Assert(S[3] = 4, 'Sort');
Assert(S[4] = 5, 'Sort');
S := AsIntegerArray([3, 5, 5, 2, 5, 5, 1]);
DynArraySort(S);
Assert(S[0] = 1, 'Sort');
Assert(S[1] = 2, 'Sort');
Assert(S[2] = 3, 'Sort');
Assert(S[3] = 5, 'Sort');
Assert(S[4] = 5, 'Sort');
Assert(S[5] = 5, 'Sort');
Assert(S[6] = 5, 'Sort');
SetLength(S, 1000);
for F := 0 to 999 do
S[F] := F mod 5;
DynArraySort(S);
for F := 0 to 999 do
Assert(S[F] = F div 200, 'Sort');
S := AsIntegerArray([6, 3, 5, 1]);
T := AsIntegerArray([1, 2, 3, 4]);
DynArraySort(S, T);
Assert(S[0] = 1, 'Sort');
Assert(S[1] = 3, 'Sort');
Assert(S[2] = 5, 'Sort');
Assert(S[3] = 6, 'Sort');
Assert(T[0] = 4, 'Sort');
Assert(T[1] = 2, 'Sort');
Assert(T[2] = 3, 'Sort');
Assert(T[3] = 1, 'Sort');
end;
procedure Test_ObjectArray;
var S, T : ObjectArray;
F : Integer;
V : TObject;
begin
S := nil;
V := TObject.Create;
try
for F := 1 to 100 do
begin
DynArrayAppend(S, V);
Assert(Length(S) = F, 'Append');
Assert(S[F - 1] = V, 'Append');
end;
T := Copy(S);
for F := 1 to 10 do
begin
DynArrayRemove(S, F - 1, 1, False);
Assert(Length(S) = 100 - F, 'Remove');
end;
DynArrayRemove(S, 89, 1, False);
Assert(Length(S) = 89, 'Remove');
DynArrayRemove(S, 87, 1, False);
Assert(Length(S) = 88, 'Remove');
DynArrayAppendObjectArray(S, T);
Assert(Length(S) = 188, 'AppendObjectArray');
DynArrayRemove(S, 10, 88, False);
Assert(Length(S) = 100, 'Remove');
DynArrayRemove(S, 0, 100, False);
Assert(Length(S) = 0, 'Remove');
finally
V.Free;
end;
end;
procedure Test_StringArray;
var S, T : StringArray;
U : String;
F : Integer;
begin
S := nil;
for F := 1 to 100 do
begin
U := IntToStr(F);
DynArrayAppend(S, U);
Assert(Length(S) = F, 'Append');
Assert(S[F - 1] = U, 'Append');
end;
T := Copy(S);
DynArrayAppendStringArray(S, T);
for F := 1 to 100 do
Assert(S[F + 99] = IntToStr(F), 'Append');
Assert(DynArrayPosNext('60', S) = 59, 'PosNext');
Assert(DynArrayPosNext('60', T) = 59, 'PosNext');
Assert(DynArrayPosNext('60', S, 59) = 159, 'PosNext');
Assert(DynArrayPosNext('60', T, 59) = -1, 'PosNext');
Assert(DynArrayPosNext('60', T, -1, True) = 59, 'PosNext');
Assert(DynArrayPosNext('60', T, 59, True) = -1, 'PosNext');
for F := 1 to 100 do
begin
DynArrayRemove(S, DynArrayPosNext(IntToStr(F), S), 1);
Assert(Length(S) = 200 - F, 'Remove');
end;
for F := 99 downto 0 do
begin
DynArrayRemove(S, DynArrayPosNext(IntToStr(F xor 3 + 1), S), 1);
Assert(Length(S) = F, 'Remove');
end;
S := AsStringArray(['3', '1', '2', '5', '4']);
DynArraySort(S);
Assert(S[0] = '1', 'Sort');
Assert(S[1] = '2', 'Sort');
Assert(S[2] = '3', 'Sort');
Assert(S[3] = '4', 'Sort');
Assert(S[4] = '5', 'Sort');
S := AsStringArray(['3', '5', '5', '2', '5', '5', '1']);
DynArraySort(S);
Assert(S[0] = '1', 'Sort');
Assert(S[1] = '2', 'Sort');
Assert(S[2] = '3', 'Sort');
Assert(S[3] = '5', 'Sort');
Assert(S[4] = '5', 'Sort');
Assert(S[5] = '5', 'Sort');
Assert(S[6] = '5', 'Sort');
SetLength(S, 1000);
for F := 0 to 999 do
S[F] := IntToStr(F mod 5);
DynArraySort(S);
for F := 0 to 999 do
Assert(S[F] = IntToStr(F div 200), 'Sort');
end;
procedure Test;
begin
Test_IntegerArray;
Test_ObjectArray;
Test_StringArray;
end;
{$ENDIF}
end.