home *** CD-ROM | disk | FTP | other *** search
/ Chip 2003 January / Chip_2003-01_cd1.bin / zkuste / delphi / unity / d56 / FNDUTL.ZIP / Datastructs / cArrays.pas next >
Encoding:
Pascal/Delphi Source File  |  2002-10-29  |  146.8 KB  |  4,745 lines

  1. {$INCLUDE ..\cDefines.inc}
  2. unit cArrays;
  3.  
  4. {                                                                              }
  5. {                        Data structures: Arrays v3.13                         }
  6. {                                                                              }
  7. {      This unit is copyright ⌐ 1999-2002 by David Butler (david@e.co.za)      }
  8. {                                                                              }
  9. {                  This unit is part of Delphi Fundamentals.                   }
  10. {                    Its original file name is cArrays.pas                     }
  11. {                     It was generated 29 Oct 2002 02:22.                      }
  12. {       The latest version is available from the Fundamentals home page        }
  13. {                     http://fundementals.sourceforge.net/                     }
  14. {                                                                              }
  15. {                I invite you to use this unit, free of charge.                }
  16. {        I invite you to distibute this unit, but it must be for free.         }
  17. {             I also invite you to contribute to its development,              }
  18. {             but do not distribute a modified copy of this file.              }
  19. {                                                                              }
  20. {          A forum is available on SourceForge for general discussion          }
  21. {             http://sourceforge.net/forum/forum.php?forum_id=2117             }
  22. {                                                                              }
  23. {                                                                              }
  24. { Revision history:                                                            }
  25. {   [ cDataStructs ]                                                           }
  26. {   1999/11/12  0.01  Split cTypes from cDataStruct and cHolder.               }
  27. {   1999/11/14  0.02  Added AListType.                                         }
  28. {   2000/02/08  1.03  Initial version. AArray, TArray and TStreamArray.        }
  29. {   2000/06/07  1.04  Base classes (AIntegerArray, ASet).                      }
  30. {   2000/06/08  1.05  Added AObjectArray.                                      }
  31. {   2000/06/03  1.06  Added AArray, AIntegerArray, AExtendedArray,             }
  32. {                     AStringArray and ABitArray (formerly ASet) with some     }
  33. {                     implementations.                                         }
  34. {   2000/06/06  1.07  TFlatBitArray implementation.                            }
  35. {                     Added AInt64Array.                                       }
  36. {   2000/06/08  1.08  Added TObjectArray.                                      }
  37. {   2000/06/14  1.09  Converted cDataStructs to template.                      }
  38. {   2001/07/15  1.10  Changed memory arrays to pre-allocate when growing.      }
  39. {   2001/08/20  2.11  Merged cTypes and cDataStructs to allow object           }
  40. {                     interface implementation in base classes.                }
  41. {   [ cArrays ]                                                                }
  42. {   2002/05/15  3.12  Created cArrays unit from cDataStructs.                  }
  43. {                     Refactored for Fundamentals 3.                           }
  44. {   2002/09/30  3.13  Moved stream array classes to unit cStreamArrays.        }
  45. {                                                                              }
  46.  
  47. interface
  48.  
  49. uses
  50.   // Delphi
  51.   SysUtils,
  52.  
  53.   // Fundamentals
  54.   cUtils,
  55.   cTypes;
  56.  
  57. const
  58.   UnitName      = 'cArrays';
  59.   UnitVersion   = '3.13';
  60.   UnitDesc      = 'Data structures: Arrays';
  61.   UnitCopyright = '(c) 1999-2002 David Butler';
  62.  
  63.  
  64.  
  65. {                                                                              }
  66. { ARRAY BASE CLASSES                                                           }
  67. {   Classes with the A-prefix are abstract base classes. They define the       }
  68. {   interface for the type and must never be instanciated.                     }
  69. {   Instead, create one of the implementation classes (T-prefix).              }
  70. {                                                                              }
  71.  
  72.  
  73.  
  74. {                                                                              }
  75. { AArray                                                                       }
  76. {                                                                              }
  77. type
  78.   AArray = class (AType)
  79.     protected
  80.     Procedure IndexError (const Idx : Integer); virtual;
  81.  
  82.     Function  GetCount : Integer; virtual; abstract;
  83.     Procedure SetCount (const NewCount : Integer); virtual; abstract;
  84.  
  85.     public
  86.     Procedure Clear; override;
  87.     Property  Count : Integer read GetCount write SetCount;
  88.  
  89.     Function  CompareItems (const Idx1, Idx2 : Integer) : TCompareResult; virtual; abstract;
  90.     Procedure ExchangeItems (const Idx1, Idx2 : Integer); virtual; abstract;
  91.     Procedure Sort; virtual;
  92.     Procedure ReverseOrder; virtual;
  93.  
  94.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; virtual; abstract;
  95.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); virtual; abstract;
  96.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); virtual; abstract;
  97.     Function  AddArray (const V : AArray) : Integer; virtual; abstract;
  98.   end;
  99.   EArray = class (Exception);
  100.   ArrayClass = class of AArray;
  101.  
  102.  
  103.  
  104. {                                                                              }
  105. { ALongIntArray                                                                }
  106. {   Base class for an array of LongInt's.                                      }
  107. {                                                                              }
  108. type
  109.   ALongIntArray = class (AArray)
  110.     protected
  111.     Procedure SetItem (const Idx : Integer; const Value : LongInt); virtual; abstract;
  112.     Function  GetItem (const Idx : Integer) : LongInt; virtual; abstract;
  113.  
  114.     Function  GetRange (const LoIdx, HiIdx : Integer) : LongIntArray; virtual;
  115.     Procedure SetRange (const LoIdx, HiIdx : Integer; const V : LongIntArray); virtual;
  116.  
  117.     Function  GetAsString : String; override;
  118.     Procedure SetAsString (const S : String); override;
  119.  
  120.     public
  121.     { AType implementations                                                    }
  122.     Procedure Assign (const Source : TObject); override;
  123.     Function  IsEqual (const V : TObject) : Boolean; override;
  124.  
  125.     { AArray implementations                                                   }
  126.     Procedure ExchangeItems (const Idx1, Idx2 : Integer); override;
  127.     Function  CompareItems (const Idx1, Idx2 : Integer) : TCompareResult; override;
  128.     Function  AddArray (const V : AArray) : Integer; reintroduce; overload; override;
  129.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; override;
  130.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  131.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); override;
  132.  
  133.     { ALongIntArray interface                                                      }
  134.     Property  Item [const Idx : Integer] : LongInt read GetItem write SetItem; default;
  135.     Property  Range [const LoIdx, HiIdx : Integer] : LongIntArray read GetRange write SetRange;
  136.     Procedure Fill (const Idx, Count : Integer; const Value : LongInt); virtual;
  137.     Function  AddItem (const Value : LongInt) : Integer; reintroduce; overload; virtual;
  138.     Function  AddArray (const V : LongIntArray) : Integer; reintroduce; overload; virtual;
  139.     Function  PosNext (const Find : LongInt; const PrevPos : Integer = -1;
  140.               const IsSortedAscending : Boolean = False) : Integer; virtual;
  141.   end;
  142.   ELongIntArray = class (EArray);
  143.  
  144.  
  145.  
  146. {                                                                              }
  147. { AIntegerArray                                                                }
  148. {                                                                              }
  149. type
  150.   AIntegerArray = ALongIntArray;
  151.   EIntegerArray = ELongIntArray;
  152.  
  153.  
  154.  
  155. {                                                                              }
  156. { ALongWordArray                                                               }
  157. {   Base class for an array of LongWord's.                                     }
  158. {                                                                              }
  159. type
  160.   ALongWordArray = class (AArray)
  161.     protected
  162.     Procedure SetItem (const Idx : Integer; const Value : LongWord); virtual; abstract;
  163.     Function  GetItem (const Idx : Integer) : LongWord; virtual; abstract;
  164.  
  165.     Function  GetRange (const LoIdx, HiIdx : Integer) : LongWordArray; virtual;
  166.     Procedure SetRange (const LoIdx, HiIdx : Integer; const V : LongWordArray); virtual;
  167.  
  168.     Function  GetAsString : String; override;
  169.     Procedure SetAsString (const S : String); override;
  170.  
  171.     public
  172.     { AType implementations                                                    }
  173.     Procedure Assign (const Source : TObject); override;
  174.     Function  IsEqual (const V : TObject) : Boolean; override;
  175.  
  176.     { AArray implementations                                                   }
  177.     Procedure ExchangeItems (const Idx1, Idx2 : Integer); override;
  178.     Function  CompareItems (const Idx1, Idx2 : Integer) : TCompareResult; override;
  179.     Function  AddArray (const V : AArray) : Integer; reintroduce; overload; override;
  180.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; override;
  181.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  182.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); override;
  183.  
  184.     { ALongWordArray interface                                                     }
  185.     Property  Item [const Idx : Integer] : LongWord read GetItem write SetItem; default;
  186.     Property  Range [const LoIdx, HiIdx : Integer] : LongWordArray read GetRange write SetRange;
  187.     Procedure Fill (const Idx, Count : Integer; const Value : LongWord); virtual;
  188.     Function  AddItem (const Value : LongWord) : Integer; reintroduce; overload; virtual;
  189.     Function  AddArray (const V : LongWordArray) : Integer; reintroduce; overload; virtual;
  190.     Function  PosNext (const Find : LongWord; const PrevPos : Integer = -1;
  191.               const IsSortedAscending : Boolean = False) : Integer; virtual;
  192.   end;
  193.   ELongWordArray = class (EArray);
  194.  
  195.  
  196.  
  197. {                                                                              }
  198. { ACardinalArray                                                               }
  199. {                                                                              }
  200. type
  201.   ACardinalArray = ALongWordArray;
  202.   ECardinalArray = ELongWordArray;
  203.  
  204.  
  205.  
  206. {                                                                              }
  207. { AInt64Array                                                                  }
  208. {   Base class for an array of Int64's.                                        }
  209. {                                                                              }
  210. type
  211.   AInt64Array = class (AArray)
  212.     protected
  213.     Procedure SetItem (const Idx : Integer; const Value : Int64); virtual; abstract;
  214.     Function  GetItem (const Idx : Integer) : Int64; virtual; abstract;
  215.  
  216.     Function  GetRange (const LoIdx, HiIdx : Integer) : Int64Array; virtual;
  217.     Procedure SetRange (const LoIdx, HiIdx : Integer; const V : Int64Array); virtual;
  218.  
  219.     Function  GetAsString : String; override;
  220.     Procedure SetAsString (const S : String); override;
  221.  
  222.     public
  223.     { AType implementations                                                    }
  224.     Procedure Assign (const Source : TObject); override;
  225.     Function  IsEqual (const V : TObject) : Boolean; override;
  226.  
  227.     { AArray implementations                                                   }
  228.     Procedure ExchangeItems (const Idx1, Idx2 : Integer); override;
  229.     Function  CompareItems (const Idx1, Idx2 : Integer) : TCompareResult; override;
  230.     Function  AddArray (const V : AArray) : Integer; reintroduce; overload; override;
  231.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; override;
  232.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  233.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); override;
  234.  
  235.     { AInt64Array interface                                                        }
  236.     Property  Item [const Idx : Integer] : Int64 read GetItem write SetItem; default;
  237.     Property  Range [const LoIdx, HiIdx : Integer] : Int64Array read GetRange write SetRange;
  238.     Procedure Fill (const Idx, Count : Integer; const Value : Int64); virtual;
  239.     Function  AddItem (const Value : Int64) : Integer; reintroduce; overload; virtual;
  240.     Function  AddArray (const V : Int64Array) : Integer; reintroduce; overload; virtual;
  241.     Function  PosNext (const Find : Int64; const PrevPos : Integer = -1;
  242.               const IsSortedAscending : Boolean = False) : Integer; virtual;
  243.   end;
  244.   EInt64Array = class (EArray);
  245.  
  246.  
  247.  
  248. {                                                                              }
  249. { ASingleArray                                                                 }
  250. {   Base class for an array of Single's.                                       }
  251. {                                                                              }
  252. type
  253.   ASingleArray = class (AArray)
  254.     protected
  255.     Procedure SetItem (const Idx : Integer; const Value : Single); virtual; abstract;
  256.     Function  GetItem (const Idx : Integer) : Single; virtual; abstract;
  257.  
  258.     Function  GetRange (const LoIdx, HiIdx : Integer) : SingleArray; virtual;
  259.     Procedure SetRange (const LoIdx, HiIdx : Integer; const V : SingleArray); virtual;
  260.  
  261.     Function  GetAsString : String; override;
  262.     Procedure SetAsString (const S : String); override;
  263.  
  264.     public
  265.     { AType implementations                                                    }
  266.     Procedure Assign (const Source : TObject); override;
  267.     Function  IsEqual (const V : TObject) : Boolean; override;
  268.  
  269.     { AArray implementations                                                   }
  270.     Procedure ExchangeItems (const Idx1, Idx2 : Integer); override;
  271.     Function  CompareItems (const Idx1, Idx2 : Integer) : TCompareResult; override;
  272.     Function  AddArray (const V : AArray) : Integer; reintroduce; overload; override;
  273.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; override;
  274.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  275.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); override;
  276.  
  277.     { ASingleArray interface                                                       }
  278.     Property  Item [const Idx : Integer] : Single read GetItem write SetItem; default;
  279.     Property  Range [const LoIdx, HiIdx : Integer] : SingleArray read GetRange write SetRange;
  280.     Procedure Fill (const Idx, Count : Integer; const Value : Single); virtual;
  281.     Function  AddItem (const Value : Single) : Integer; reintroduce; overload; virtual;
  282.     Function  AddArray (const V : SingleArray) : Integer; reintroduce; overload; virtual;
  283.     Function  PosNext (const Find : Single; const PrevPos : Integer = -1;
  284.               const IsSortedAscending : Boolean = False) : Integer; virtual;
  285.   end;
  286.   ESingleArray = class (EArray);
  287.  
  288.  
  289.  
  290. {                                                                              }
  291. { ADoubleArray                                                                 }
  292. {   Base class for an array of Double's.                                       }
  293. {                                                                              }
  294. type
  295.   ADoubleArray = class (AArray)
  296.     protected
  297.     Procedure SetItem (const Idx : Integer; const Value : Double); virtual; abstract;
  298.     Function  GetItem (const Idx : Integer) : Double; virtual; abstract;
  299.  
  300.     Function  GetRange (const LoIdx, HiIdx : Integer) : DoubleArray; virtual;
  301.     Procedure SetRange (const LoIdx, HiIdx : Integer; const V : DoubleArray); virtual;
  302.  
  303.     Function  GetAsString : String; override;
  304.     Procedure SetAsString (const S : String); override;
  305.  
  306.     public
  307.     { AType implementations                                                    }
  308.     Procedure Assign (const Source : TObject); override;
  309.     Function  IsEqual (const V : TObject) : Boolean; override;
  310.  
  311.     { AArray implementations                                                   }
  312.     Procedure ExchangeItems (const Idx1, Idx2 : Integer); override;
  313.     Function  CompareItems (const Idx1, Idx2 : Integer) : TCompareResult; override;
  314.     Function  AddArray (const V : AArray) : Integer; reintroduce; overload; override;
  315.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; override;
  316.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  317.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); override;
  318.  
  319.     { ADoubleArray interface                                                       }
  320.     Property  Item [const Idx : Integer] : Double read GetItem write SetItem; default;
  321.     Property  Range [const LoIdx, HiIdx : Integer] : DoubleArray read GetRange write SetRange;
  322.     Procedure Fill (const Idx, Count : Integer; const Value : Double); virtual;
  323.     Function  AddItem (const Value : Double) : Integer; reintroduce; overload; virtual;
  324.     Function  AddArray (const V : DoubleArray) : Integer; reintroduce; overload; virtual;
  325.     Function  PosNext (const Find : Double; const PrevPos : Integer = -1;
  326.               const IsSortedAscending : Boolean = False) : Integer; virtual;
  327.   end;
  328.   EDoubleArray = class (EArray);
  329.  
  330.  
  331.  
  332. {                                                                              }
  333. { AExtendedArray                                                               }
  334. {   Base class for an array of Extended's.                                     }
  335. {                                                                              }
  336. type
  337.   AExtendedArray = class (AArray)
  338.     protected
  339.     Procedure SetItem (const Idx : Integer; const Value : Extended); virtual; abstract;
  340.     Function  GetItem (const Idx : Integer) : Extended; virtual; abstract;
  341.  
  342.     Function  GetRange (const LoIdx, HiIdx : Integer) : ExtendedArray; virtual;
  343.     Procedure SetRange (const LoIdx, HiIdx : Integer; const V : ExtendedArray); virtual;
  344.  
  345.     Function  GetAsString : String; override;
  346.     Procedure SetAsString (const S : String); override;
  347.  
  348.     public
  349.     { AType implementations                                                    }
  350.     Procedure Assign (const Source : TObject); override;
  351.     Function  IsEqual (const V : TObject) : Boolean; override;
  352.  
  353.     { AArray implementations                                                   }
  354.     Procedure ExchangeItems (const Idx1, Idx2 : Integer); override;
  355.     Function  CompareItems (const Idx1, Idx2 : Integer) : TCompareResult; override;
  356.     Function  AddArray (const V : AArray) : Integer; reintroduce; overload; override;
  357.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; override;
  358.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  359.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); override;
  360.  
  361.     { AExtendedArray interface                                                     }
  362.     Property  Item [const Idx : Integer] : Extended read GetItem write SetItem; default;
  363.     Property  Range [const LoIdx, HiIdx : Integer] : ExtendedArray read GetRange write SetRange;
  364.     Procedure Fill (const Idx, Count : Integer; const Value : Extended); virtual;
  365.     Function  AddItem (const Value : Extended) : Integer; reintroduce; overload; virtual;
  366.     Function  AddArray (const V : ExtendedArray) : Integer; reintroduce; overload; virtual;
  367.     Function  PosNext (const Find : Extended; const PrevPos : Integer = -1;
  368.               const IsSortedAscending : Boolean = False) : Integer; virtual;
  369.   end;
  370.   EExtendedArray = class (EArray);
  371.  
  372.  
  373.  
  374. {                                                                              }
  375. { APointerArray                                                                }
  376. {   Base class for an array of Pointer's.                                      }
  377. {                                                                              }
  378. type
  379.   APointerArray = class (AArray)
  380.     protected
  381.     Procedure SetItem (const Idx : Integer; const Value : Pointer); virtual; abstract;
  382.     Function  GetItem (const Idx : Integer) : Pointer; virtual; abstract;
  383.  
  384.     Function  GetRange (const LoIdx, HiIdx : Integer) : PointerArray; virtual;
  385.     Procedure SetRange (const LoIdx, HiIdx : Integer; const V : PointerArray); virtual;
  386.  
  387.     Function  GetAsString : String; override;
  388.     Procedure SetAsString (const S : String); override;
  389.  
  390.     public
  391.     { AType implementations                                                    }
  392.     Procedure Assign (const Source : TObject); override;
  393.     Function  IsEqual (const V : TObject) : Boolean; override;
  394.  
  395.     { AArray implementations                                                   }
  396.     Procedure ExchangeItems (const Idx1, Idx2 : Integer); override;
  397.     Function  AddArray (const V : AArray) : Integer; reintroduce; overload; override;
  398.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; override;
  399.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  400.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); override;
  401.  
  402.     { APointerArray interface                                                      }
  403.     Property  Item [const Idx : Integer] : Pointer read GetItem write SetItem; default;
  404.     Property  Range [const LoIdx, HiIdx : Integer] : PointerArray read GetRange write SetRange;
  405.     Procedure Fill (const Idx, Count : Integer; const Value : Pointer); virtual;
  406.     Function  AddItem (const Value : Pointer) : Integer; reintroduce; overload; virtual;
  407.     Function  AddArray (const V : PointerArray) : Integer; reintroduce; overload; virtual;
  408.     Function  PosNext (const Find : Pointer; const PrevPos : Integer = -1) : Integer; virtual;
  409.   end;
  410.   EPointerArray = class (EArray);
  411.  
  412.  
  413.  
  414. {                                                                              }
  415. { AStringArray                                                                 }
  416. {   Base class for an array of Strings.                                        }
  417. {                                                                              }
  418. type
  419.   EStringArray = class (EArray);
  420.   AStringArray = class (AArray)
  421.     protected
  422.     Procedure SetItem (const Idx : Integer; const Value : String); virtual; abstract;
  423.     Function  GetItem (const Idx : Integer) : String; virtual; abstract;
  424.     Function  GetRange (const LoIdx, HiIdx : Integer) : StringArray; virtual;
  425.     Procedure SetRange (const LoIdx, HiIdx : Integer; const V : StringArray); virtual;
  426.     Function  GetAsString : String; override;
  427.     Procedure SetAsString (const S : String); override;
  428.  
  429.     public
  430.     { AType implementations                                                    }
  431.     Procedure Assign (const Source : TObject); override;
  432.     Function  IsEqual (const V : TObject) : Boolean; override;
  433.  
  434.     { AArray implementations                                                   }
  435.     Procedure ExchangeItems (const Idx1, Idx2 : Integer); override;
  436.     Function  CompareItems (const Idx1, Idx2 : Integer) : TCompareResult; override;
  437.     Function  AddArray (const V : AArray) : Integer; reintroduce; overload; override;
  438.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; override;
  439.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  440.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); override;
  441.  
  442.     { AStringArray interface                                                   }
  443.     Property  Item [const Idx : Integer] : String read GetItem write SetItem; default;
  444.     Property  Range [const LoIdx, HiIdx : Integer] : StringArray read GetRange write SetRange;
  445.     Procedure Fill (const Idx, Count : Integer; const Value : String = ''); virtual;
  446.     Function  AddItem (const Value : String) : Integer; reintroduce; overload; virtual;
  447.     Function  AddArray (const V : StringArray) : Integer; reintroduce; overload; virtual;
  448.     Function  PosNext (const Find : String; const PrevPos : Integer = -1;
  449.               const IsSortedAscending : Boolean = False) : Integer; virtual;
  450.   end;
  451.  
  452.  
  453.  
  454. {                                                                              }
  455. { AObjectArray                                                                 }
  456. {   Base class for an array of objects.                                        }
  457. {                                                                              }
  458. type
  459.   EObjectArray = class (EArray);
  460.   AObjectArray = class (AArray)
  461.     protected
  462.     Procedure SetItem (const Idx : Integer; const Value : TObject); virtual; abstract;
  463.     Function  GetItem (const Idx : Integer) : TObject; virtual; abstract;
  464.     Function  GetRange (const LoIdx, HiIdx : Integer) : ObjectArray; virtual;
  465.     Procedure SetRange (const LoIdx, HiIdx : Integer; const V : ObjectArray); virtual;
  466.     Function  GetAsString : String; override;
  467.     Function  GetIsItemOwner : Boolean; virtual; abstract;
  468.     Procedure SetIsItemOwner (const IsItemOwner : Boolean); virtual; abstract;
  469.  
  470.     public
  471.     { AType implementations                                                    }
  472.     Procedure Clear; override;
  473.     Procedure Assign (const Source : TObject); override;
  474.     Function  IsEqual (const V : TObject) : Boolean; override;
  475.     Function  Compare (const V : TObject) : TCompareResult; override;
  476.  
  477.     { AArray implementations                                                   }
  478.     Procedure ExchangeItems (const Idx1, Idx2 : Integer); override;
  479.     Function  CompareItems (const Idx1, Idx2 : Integer) : TCompareResult; override;
  480.     Function  AddArray (const V : AArray) : Integer; reintroduce; overload; override;
  481.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  482.  
  483.     { AObjectArray interface                                                   }
  484.     Property  Item [const Idx : Integer] : TObject read GetItem write SetItem; default;
  485.     Property  Range [const LoIdx, HiIdx : Integer] : ObjectArray read GetRange write SetRange;
  486.     Function  AddItem (const Value : TObject) : Integer; virtual;
  487.     Function  AddArray (const V : ObjectArray) : Integer; reintroduce; overload; virtual;
  488.  
  489.     Function  PosNext (const Find : TObject; const PrevPos : Integer) : Integer; overload; virtual;
  490.     Function  PosNext (var Item : TObject; const ClassType : TClass; const PrevPos : Integer = -1) : Integer; overload; virtual;
  491.     Function  PosNext (var Item : TObject; const ClassName : String; const PrevPos : Integer = -1) : Integer; overload; virtual;
  492.     Function  Find (const ClassType : TClass; const Count : Integer = 1) : TObject; overload; virtual;
  493.     Function  Find (const ClassName : String; const Count : Integer = 1) : TObject; overload; virtual;
  494.     Function  FindAll (const ClassType : TClass) : ObjectArray; overload;
  495.     Function  FindAll (const ClassName : String) : ObjectArray; overload;
  496.     Function  CountItems (const ClassType : TClass) : Integer; overload; virtual;
  497.     Function  CountItems (const ClassName : String) : Integer; overload; virtual;
  498.  
  499.     Property  IsItemOwner : Boolean read GetIsItemOwner write SetIsItemOwner;
  500.     Procedure ReleaseItems; virtual; abstract;
  501.     Procedure FreeItems; virtual; abstract;
  502.     Function  ReleaseItem (const Idx : Integer) : TObject; virtual; abstract;
  503.   end;
  504.  
  505.  
  506.  
  507. {                                                                              }
  508. { ABitArray                                                                    }
  509. {   Base class for a bit array (a set) implementations.                        }
  510. {   Bits are defined as False at initialization.                               }
  511. {   FindRange finds Count consequetive bits set to Value, starting at Start.   }
  512. {     It returns the index of the leftmost bit or -1 if not found.             }
  513. {                                                                              }
  514. type
  515.   EBitArray = class (EArray);
  516.   ABitArray = class (AArray)
  517.     protected
  518.     Function  GetBit (const Idx : Integer) : Boolean; virtual; abstract;
  519.     Procedure SetBit (const Idx : Integer; const Value : Boolean); virtual; abstract;
  520.     Function  GetRange (const Idx : Integer) : LongWord; virtual;
  521.     Procedure SetRange (const Idx : Integer; const Value : LongWord); virtual;
  522.  
  523.     public
  524.     { AType implementations                                                    }
  525.     Procedure Assign (const Source : TObject); override;
  526.  
  527.     { AArray implementations                                                   }
  528.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  529.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); override;
  530.     Function  AddArray (const V : AArray) : Integer; override;
  531.     Procedure ExchangeItems (const Idx1, Idx2 : Integer); override;
  532.     Function  CompareItems (const Idx1, Idx2 : Integer) : TCompareResult; override;
  533.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; override;
  534.  
  535.     { ABitArray interface                                                      }
  536.     Property  Bit [const Idx : Integer] : Boolean read GetBit write SetBit; default;
  537.     Property  Range [const Idx : Integer] : LongWord read GetRange write SetRange;
  538.     Function  CompareRange (const LoIdx, HiIdx : Integer; const Value : Boolean) : Boolean; virtual;
  539.     Procedure Fill (const Idx, Count : Integer; const Value : Boolean); virtual;
  540.     Function  IsEqual (const V : TObject) : Boolean; override;
  541.     Function  AddItem (const Value : Boolean) : Integer; reintroduce; overload; virtual;
  542.     Procedure Invert; virtual;
  543.     Function  Find (const Value : Boolean = False; const Start : Integer = 0;
  544.               const FindForward : Boolean = True) : Integer; virtual;
  545.     Function  FindRange (const Value : Boolean = False; const Start : Integer = 0;
  546.               const Count : Integer = 1; const FindForward : Boolean = True) : Integer; virtual;
  547.   end;
  548.  
  549.  
  550.  
  551. {                                                                              }
  552. { ARRAY IMPLEMENTATIONS                                                        }
  553. {                                                                              }
  554.  
  555.  
  556.  
  557. {                                                                              }
  558. { TLongIntArray                                                                }
  559. {   ALongIntArray implemented using a dynamic array.                           }
  560. {                                                                              }
  561. type
  562.   TLongIntArray = class (ALongIntArray)
  563.     protected
  564.     FData  : LongIntArray;
  565.     FCount : Integer;
  566.  
  567.     { ACollection implementations                                              }
  568.     Function  GetCount : Integer; override;
  569.     Procedure SetCount (const NewCount : Integer); override;
  570.  
  571.     { ALongIntArray implementations                                            }
  572.     Procedure SetItem (const Idx : Integer; const Value : LongInt); override;
  573.     Function  GetItem (const Idx : Integer) : LongInt; override;
  574.     Function  GetRange (const LoIdx, HiIdx : Integer) : LongIntArray; override;
  575.     Procedure SetRange (const LoIdx, HiIdx : Integer; const V : LongIntArray); override;
  576.     Procedure SetData (const Data : LongIntArray);
  577.  
  578.     public
  579.     Constructor Create (const V : LongIntArray = nil);
  580.  
  581.     { AType implementations                                                    }
  582.     class Function CreateInstance : AType; override;
  583.     Procedure Assign (const Source : TObject); reintroduce; overload; override;
  584.  
  585.     { AArray implementations                                                   }
  586.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; override;
  587.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  588.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); override;
  589.  
  590.     { ALongIntArray implementations                                            }
  591.     Procedure Assign (const V : LongIntArray); reintroduce; overload;
  592.     Procedure Assign (const V : array of LongInt); reintroduce; overload;
  593.     Property  Data : LongIntArray read FData write SetData;
  594.   end;
  595.  
  596.  
  597.  
  598. {                                                                              }
  599. { TIntegerArray                                                                }
  600. {                                                                              }
  601. type
  602.   TIntegerArray = TLongIntArray;
  603.  
  604.  
  605.  
  606. {                                                                              }
  607. { TLongWordArray                                                               }
  608. {   ALongWordArray implemented using a dynamic array.                          }
  609. {                                                                              }
  610. type
  611.   TLongWordArray = class (ALongWordArray)
  612.     protected
  613.     FData  : LongWordArray;
  614.     FCount : Integer;
  615.  
  616.     { ACollection implementations                                              }
  617.     Function  GetCount : Integer; override;
  618.     Procedure SetCount (const NewCount : Integer); override;
  619.  
  620.     { ALongWordArray implementations                                            }
  621.     Procedure SetItem (const Idx : Integer; const Value : LongWord); override;
  622.     Function  GetItem (const Idx : Integer) : LongWord; override;
  623.     Function  GetRange (const LoIdx, HiIdx : Integer) : LongWordArray; override;
  624.     Procedure SetRange (const LoIdx, HiIdx : Integer; const V : LongWordArray); override;
  625.     Procedure SetData (const Data : LongWordArray);
  626.  
  627.     public
  628.     Constructor Create (const V : LongWordArray = nil);
  629.  
  630.     { AType implementations                                                    }
  631.     class Function CreateInstance : AType; override;
  632.     Procedure Assign (const Source : TObject); reintroduce; overload; override;
  633.  
  634.     { AArray implementations                                                   }
  635.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; override;
  636.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  637.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); override;
  638.  
  639.     { ALongWordArray implementations                                            }
  640.     Procedure Assign (const V : LongWordArray); reintroduce; overload;
  641.     Procedure Assign (const V : array of LongWord); reintroduce; overload;
  642.     Property  Data : LongWordArray read FData write SetData;
  643.   end;
  644.  
  645.  
  646.  
  647. {                                                                              }
  648. { TCardinalArray                                                               }
  649. {                                                                              }
  650. type
  651.   TCardinalArray = TLongWordArray;
  652.  
  653.  
  654.  
  655. {                                                                              }
  656. { TInt64Array                                                                  }
  657. {   AInt64Array implemented using a dynamic array.                             }
  658. {                                                                              }
  659. type
  660.   TInt64Array = class (AInt64Array)
  661.     protected
  662.     FData  : Int64Array;
  663.     FCount : Integer;
  664.  
  665.     { ACollection implementations                                              }
  666.     Function  GetCount : Integer; override;
  667.     Procedure SetCount (const NewCount : Integer); override;
  668.  
  669.     { AInt64Array implementations                                            }
  670.     Procedure SetItem (const Idx : Integer; const Value : Int64); override;
  671.     Function  GetItem (const Idx : Integer) : Int64; override;
  672.     Function  GetRange (const LoIdx, HiIdx : Integer) : Int64Array; override;
  673.     Procedure SetRange (const LoIdx, HiIdx : Integer; const V : Int64Array); override;
  674.     Procedure SetData (const Data : Int64Array);
  675.  
  676.     public
  677.     Constructor Create (const V : Int64Array = nil);
  678.  
  679.     { AType implementations                                                    }
  680.     class Function CreateInstance : AType; override;
  681.     Procedure Assign (const Source : TObject); reintroduce; overload; override;
  682.  
  683.     { AArray implementations                                                   }
  684.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; override;
  685.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  686.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); override;
  687.  
  688.     { AInt64Array implementations                                            }
  689.     Procedure Assign (const V : Int64Array); reintroduce; overload;
  690.     Procedure Assign (const V : array of Int64); reintroduce; overload;
  691.     Property  Data : Int64Array read FData write SetData;
  692.   end;
  693.  
  694.  
  695.  
  696. {                                                                              }
  697. { TSingleArray                                                                 }
  698. {   ASingleArray implemented using a dynamic array.                            }
  699. {                                                                              }
  700. type
  701.   TSingleArray = class (ASingleArray)
  702.     protected
  703.     FData  : SingleArray;
  704.     FCount : Integer;
  705.  
  706.     { ACollection implementations                                              }
  707.     Function  GetCount : Integer; override;
  708.     Procedure SetCount (const NewCount : Integer); override;
  709.  
  710.     { ASingleArray implementations                                            }
  711.     Procedure SetItem (const Idx : Integer; const Value : Single); override;
  712.     Function  GetItem (const Idx : Integer) : Single; override;
  713.     Function  GetRange (const LoIdx, HiIdx : Integer) : SingleArray; override;
  714.     Procedure SetRange (const LoIdx, HiIdx : Integer; const V : SingleArray); override;
  715.     Procedure SetData (const Data : SingleArray);
  716.  
  717.     public
  718.     Constructor Create (const V : SingleArray = nil);
  719.  
  720.     { AType implementations                                                    }
  721.     class Function CreateInstance : AType; override;
  722.     Procedure Assign (const Source : TObject); reintroduce; overload; override;
  723.  
  724.     { AArray implementations                                                   }
  725.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; override;
  726.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  727.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); override;
  728.  
  729.     { ASingleArray implementations                                            }
  730.     Procedure Assign (const V : SingleArray); reintroduce; overload;
  731.     Procedure Assign (const V : array of Single); reintroduce; overload;
  732.     Property  Data : SingleArray read FData write SetData;
  733.   end;
  734.  
  735.  
  736.  
  737. {                                                                              }
  738. { TDoubleArray                                                                 }
  739. {   ADoubleArray implemented using a dynamic array.                            }
  740. {                                                                              }
  741. type
  742.   TDoubleArray = class (ADoubleArray)
  743.     protected
  744.     FData  : DoubleArray;
  745.     FCount : Integer;
  746.  
  747.     { ACollection implementations                                              }
  748.     Function  GetCount : Integer; override;
  749.     Procedure SetCount (const NewCount : Integer); override;
  750.  
  751.     { ADoubleArray implementations                                            }
  752.     Procedure SetItem (const Idx : Integer; const Value : Double); override;
  753.     Function  GetItem (const Idx : Integer) : Double; override;
  754.     Function  GetRange (const LoIdx, HiIdx : Integer) : DoubleArray; override;
  755.     Procedure SetRange (const LoIdx, HiIdx : Integer; const V : DoubleArray); override;
  756.     Procedure SetData (const Data : DoubleArray);
  757.  
  758.     public
  759.     Constructor Create (const V : DoubleArray = nil);
  760.  
  761.     { AType implementations                                                    }
  762.     class Function CreateInstance : AType; override;
  763.     Procedure Assign (const Source : TObject); reintroduce; overload; override;
  764.  
  765.     { AArray implementations                                                   }
  766.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; override;
  767.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  768.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); override;
  769.  
  770.     { ADoubleArray implementations                                            }
  771.     Procedure Assign (const V : DoubleArray); reintroduce; overload;
  772.     Procedure Assign (const V : array of Double); reintroduce; overload;
  773.     Property  Data : DoubleArray read FData write SetData;
  774.   end;
  775.  
  776.  
  777.  
  778. {                                                                              }
  779. { TExtendedArray                                                               }
  780. {   AExtendedArray implemented using a dynamic array.                          }
  781. {                                                                              }
  782. type
  783.   TExtendedArray = class (AExtendedArray)
  784.     protected
  785.     FData  : ExtendedArray;
  786.     FCount : Integer;
  787.  
  788.     { ACollection implementations                                              }
  789.     Function  GetCount : Integer; override;
  790.     Procedure SetCount (const NewCount : Integer); override;
  791.  
  792.     { AExtendedArray implementations                                            }
  793.     Procedure SetItem (const Idx : Integer; const Value : Extended); override;
  794.     Function  GetItem (const Idx : Integer) : Extended; override;
  795.     Function  GetRange (const LoIdx, HiIdx : Integer) : ExtendedArray; override;
  796.     Procedure SetRange (const LoIdx, HiIdx : Integer; const V : ExtendedArray); override;
  797.     Procedure SetData (const Data : ExtendedArray);
  798.  
  799.     public
  800.     Constructor Create (const V : ExtendedArray = nil);
  801.  
  802.     { AType implementations                                                    }
  803.     class Function CreateInstance : AType; override;
  804.     Procedure Assign (const Source : TObject); reintroduce; overload; override;
  805.  
  806.     { AArray implementations                                                   }
  807.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; override;
  808.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  809.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); override;
  810.  
  811.     { AExtendedArray implementations                                            }
  812.     Procedure Assign (const V : ExtendedArray); reintroduce; overload;
  813.     Procedure Assign (const V : array of Extended); reintroduce; overload;
  814.     Property  Data : ExtendedArray read FData write SetData;
  815.   end;
  816.  
  817.  
  818.  
  819. {                                                                              }
  820. { TStringArray                                                                 }
  821. {   AStringArray implemented using a dynamic array.                            }
  822. {                                                                              }
  823. type
  824.   TStringArray = class (AStringArray)
  825.     protected
  826.     FData  : StringArray;
  827.     FCount : Integer;
  828.  
  829.     { ACollection implementations                                              }
  830.     Function  GetCount : Integer; override;
  831.     Procedure SetCount (const NewCount : Integer); override;
  832.  
  833.     { AStringArray implementations                                            }
  834.     Procedure SetItem (const Idx : Integer; const Value : String); override;
  835.     Function  GetItem (const Idx : Integer) : String; override;
  836.     Function  GetRange (const LoIdx, HiIdx : Integer) : StringArray; override;
  837.     Procedure SetRange (const LoIdx, HiIdx : Integer; const V : StringArray); override;
  838.     Procedure SetData (const Data : StringArray);
  839.  
  840.     public
  841.     Constructor Create (const V : StringArray = nil);
  842.  
  843.     { AType implementations                                                    }
  844.     class Function CreateInstance : AType; override;
  845.     Procedure Assign (const Source : TObject); reintroduce; overload; override;
  846.  
  847.     { AArray implementations                                                   }
  848.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; override;
  849.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  850.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); override;
  851.  
  852.     { AStringArray implementations                                            }
  853.     Procedure Assign (const V : StringArray); reintroduce; overload;
  854.     Procedure Assign (const V : array of String); reintroduce; overload;
  855.     Property  Data : StringArray read FData write SetData;
  856.   end;
  857.  
  858.  
  859.  
  860. {                                                                              }
  861. { TObjectArray                                                                 }
  862. {   AObjectArray implemented using a dynamic array.                            }
  863. {                                                                              }
  864. type
  865.   TObjectArray = class (AObjectArray)
  866.     protected
  867.     FData        : ObjectArray;
  868.     FCount       : Integer;
  869.     FIsItemOwner : Boolean;
  870.  
  871.     Procedure SetData (const Data : ObjectArray); virtual;
  872.     Function  GetIsItemOwner : Boolean; override;
  873.     Procedure SetIsItemOwner (const IsItemOwner : Boolean); override;
  874.  
  875.     { AArray implementations                                                   }
  876.     Function  GetCount : Integer; override;
  877.     Procedure SetCount (const NewCount : Integer); override;
  878.  
  879.     { AObjectArray implementations                                             }
  880.     Procedure SetItem (const Idx : Integer; const Value : TObject); override;
  881.     Function  GetItem (const Idx : Integer) : TObject; override;
  882.     Function  GetRange (const LoIdx, HiIdx : Integer) : ObjectArray; override;
  883.  
  884.     public
  885.     { TObjectArray interface                                                   }
  886.     Constructor Create (const V : ObjectArray = nil; const IsItemOwner : Boolean = False);
  887.     Destructor Destroy; override;
  888.  
  889.     Property  Data : ObjectArray read FData write SetData;
  890.     Property  IsItemOwner : Boolean read FIsItemOwner write FIsItemOwner;
  891.     Procedure FreeItems; override;
  892.     Procedure ReleaseItems; override;
  893.     Function  ReleaseItem (const Idx : Integer) : TObject; override;
  894.  
  895.     { AType implementations                                                    }
  896.     class Function CreateInstance : AType; override;
  897.  
  898.     { AArray implementations                                                   }
  899.     Function  DuplicateRange (const LoIdx, HiIdx : Integer) : AArray; override;
  900.     Procedure Delete (const Idx : Integer; const Count : Integer = 1); override;
  901.     Procedure Insert (const Idx : Integer; const Count : Integer = 1); override;
  902.   end;
  903.  
  904.  
  905.  
  906. {                                                                              }
  907. { TFlatBitArray                                                                }
  908. {   ABitArray stored as an array of LongWords.                                 }
  909. {   GetBit and SetBit is very fast.                                            }
  910. {                                                                              }
  911. type
  912.   TFlatBitArray = class (ABitArray)
  913.     protected
  914.     FData  : LongWordArray;
  915.     FCount : Integer;
  916.  
  917.     { AArray implementations                                                   }
  918.     Function  GetCount : Integer; override;
  919.     Procedure SetCount (const NewCount : Integer); override;
  920.  
  921.     { ABitArray implementations                                                }
  922.     Function  GetBit (const Idx : Integer) : Boolean; override;
  923.     Procedure SetBit (const Idx : Integer; const Value : Boolean); override;
  924.     Function  GetRange (const Idx : Integer) : LongWord; override;
  925.     Procedure SetRange (const Idx : Integer; const Value : LongWord); override;
  926.  
  927.     public
  928.     { AType implementations                                                    }
  929.     class Function CreateInstance : AType; override;
  930.  
  931.     { ABitArray implementations                                                }
  932.     Procedure Fill (const LoIdx, HiIdx : Integer; const Value : Boolean); override;
  933.     Function  CompareRange (const LoIdx, HiIdx : Integer; const Value : Boolean) : Boolean; override;
  934.   end;
  935.   TBitArray = TFlatBitArray;
  936.  
  937.  
  938.  
  939. {                                                                              }
  940. { Self testing code                                                            }
  941. {                                                                              }
  942. Procedure SelfTest;
  943.  
  944.  
  945.  
  946. implementation
  947.  
  948. uses
  949.   // Fundamentals
  950.   cStrings;
  951.  
  952.  
  953.  
  954. {                                                                              }
  955. {                                                                              }
  956. { TYPE BASE CLASSES                                                            }
  957. {                                                                              }
  958. {                                                                              }
  959.  
  960.  
  961.  
  962. {                                                                              }
  963. { AArray                                                                       }
  964. {                                                                              }
  965. Procedure AArray.IndexError (const Idx : Integer);
  966.   Begin
  967.     raise EArray.Create ({$IFDEF DEBUG}ObjectClassName (self) + ': ' + {$ENDIF}
  968.           'Array index out of bounds'
  969.           {$IFDEF DEBUG} + ': ' + IntToStr (Idx) + '/' + IntToStr (GetCount){$ENDIF});
  970.   End;
  971.  
  972. Procedure AArray.Clear;
  973.   Begin
  974.     Count := 0;
  975.   End;
  976.  
  977. Procedure AArray.Sort;
  978.  
  979.   Procedure QuickSort (L, R : Integer);
  980.   var I, J : Integer;
  981.       M    : Integer;
  982.     Begin
  983.       Repeat
  984.         I := L;
  985.         J := R;
  986.         M := (L + R) shr 1;
  987.         Repeat
  988.           While CompareItems (I, M) = crLess do
  989.             Inc (I);
  990.           While CompareItems (J, M) = crGreater do
  991.             Dec (J);
  992.           if I <= J then
  993.             begin
  994.               ExchangeItems (I, J);
  995.               Inc (I);
  996.               Dec (J);
  997.             end;
  998.         Until I > J;
  999.         if L < J then
  1000.           QuickSort (L, J);
  1001.         L := I;
  1002.       Until I >= R;
  1003.     End;
  1004.  
  1005. var I : Integer;
  1006.   Begin
  1007.     I := Count;
  1008.     if I > 0 then
  1009.       QuickSort (0, I - 1);
  1010.   End;
  1011.  
  1012. Procedure AArray.ReverseOrder;
  1013. var I, L : Integer;
  1014.   Begin
  1015.     L := Count;
  1016.     For I := 1 to L div 2 do
  1017.       ExchangeItems (I - 1, L - I);
  1018.   End;
  1019.  
  1020.  
  1021.  
  1022. {                                                                              }
  1023. { ALongIntArray                                                                }
  1024. {                                                                              }
  1025. Procedure ALongIntArray.ExchangeItems (const Idx1, Idx2 : Integer);
  1026. var I : LongInt;
  1027.   Begin
  1028.     I := Item [Idx1];
  1029.     Item [Idx1] := Item [Idx2];
  1030.     Item [Idx2] := I;
  1031.   End;
  1032.  
  1033. Function ALongIntArray.AddItem (const Value : LongInt) : Integer;
  1034.   Begin
  1035.     Result := Count;
  1036.     Count := Result + 1;
  1037.     Item [Result] := Value;
  1038.   End;
  1039.  
  1040. Function ALongIntArray.GetRange (const LoIdx, HiIdx : Integer) : LongIntArray;
  1041. var I, L, H, C : Integer;
  1042.   Begin
  1043.     L := MaxI (0, LoIdx);
  1044.     H := MinI (Count - 1, HiIdx);
  1045.     C := H - L + 1;
  1046.     SetLength (Result, C);
  1047.     For I := 0 to C - 1 do
  1048.       Result [I] := Item [L + I];
  1049.   End;
  1050.  
  1051. Function ALongIntArray.DuplicateRange (const LoIdx, HiIdx : Integer) : AArray;
  1052. var I, L, H, C : Integer;
  1053.   Begin
  1054.     Result := ALongIntArray (CreateInstance);
  1055.     L := MaxI (0, LoIdx);
  1056.     H := MinI (Count - 1, HiIdx);
  1057.     C := H - L + 1;
  1058.     ALongIntArray (Result).Count := C;
  1059.     For I := 0 to C - 1 do
  1060.       ALongIntArray (Result) [I] := Item [L + I];
  1061.   End;
  1062.  
  1063. Procedure ALongIntArray.SetRange (const LoIdx, HiIdx : Integer; const V : LongIntArray);
  1064. var I, L, H, C : Integer;
  1065.   Begin
  1066.     L := MaxI (0, LoIdx);
  1067.     H := MinI (Count - 1, HiIdx);
  1068.     C := MinI (Length (V), H - L + 1);
  1069.     For I := 0 to C - 1 do
  1070.       Item [L + I] := V [I];
  1071.   End;
  1072.  
  1073. Procedure ALongIntArray.Fill (const Idx, Count : Integer; const Value : LongInt);
  1074. var I : Integer;
  1075.   Begin
  1076.     For I := Idx to Idx + Count - 1 do
  1077.       Item [I] := Value;
  1078.   End;
  1079.  
  1080. Function ALongIntArray.AddArray (const V : LongIntArray) : Integer;
  1081.   Begin
  1082.     Result := Count;
  1083.     Count := Result + Length (V);
  1084.     Range [Result, Count - 1] := V;
  1085.   End;
  1086.  
  1087. Function ALongIntArray.CompareItems (const Idx1, Idx2 : Integer) : TCompareResult;
  1088. var I, J : LongInt;
  1089.   Begin
  1090.     I := Item [Idx1];
  1091.     J := Item [Idx2];
  1092.     if I < J then
  1093.       Result := crLess else
  1094.     if I > J then
  1095.       Result := crGreater else
  1096.       Result := crEqual;
  1097.   End;
  1098.  
  1099. Function ALongIntArray.PosNext (const Find : LongInt; const PrevPos : Integer; const IsSortedAscending : Boolean) : Integer;
  1100. var I, L, H : Integer;
  1101.     D       : LongInt;
  1102.   Begin
  1103.     if IsSortedAscending then // binary search
  1104.       begin
  1105.         if MaxI (PrevPos + 1, 0) = 0 then // find first
  1106.           begin
  1107.             L := 0;
  1108.             H := Count - 1;
  1109.             Repeat
  1110.               I := (L + H) div 2;
  1111.               D := Item [I];
  1112.               if D = Find then
  1113.                 begin
  1114.                   While (I > 0) and (Item [I - 1] = Find) do
  1115.                     Dec (I);
  1116.                   Result := I;
  1117.                   exit;
  1118.                 end else
  1119.               if D > Find then
  1120.                 H := I - 1 else
  1121.                 L := I + 1;
  1122.             Until L > H;
  1123.             Result := -1;
  1124.           end else // find next
  1125.           if PrevPos >= Count - 1 then
  1126.             Result := -1 else
  1127.             if Item [PrevPos + 1] = Find then
  1128.               Result := PrevPos + 1 else
  1129.               Result := -1;
  1130.       end else // linear search
  1131.       begin
  1132.   
  1133.         For I := MaxI (PrevPos + 1, 0) to Count - 1 do
  1134.           if Item [I] = Find then
  1135.             begin
  1136.               Result := I;
  1137.               exit;
  1138.             end;
  1139.         Result := -1;
  1140.       end;
  1141.   End;
  1142.  
  1143. Function ALongIntArray.GetAsString : String;
  1144. var I, L : Integer;
  1145.   Begin
  1146.     L := Count;
  1147.     if L = 0 then
  1148.       begin
  1149.         Result := '';
  1150.         exit;
  1151.       end;
  1152.     Result := IntToStr (Item [0]);
  1153.     For I := 1 to L - 1 do
  1154.       Result := Result + ',' + IntToStr (Item [I]);
  1155.     Result := Result;
  1156.   End;
  1157.  
  1158. Procedure ALongIntArray.SetAsString (const S : String);
  1159. var F, G, L, C : Integer;
  1160.   Begin
  1161.     L := Length (S);
  1162.     if L = 0 then
  1163.       begin
  1164.         Count := 0;
  1165.         exit;
  1166.       end;
  1167.     L := 0;
  1168.     F := 2;
  1169.     C := Length (S);
  1170.     While F < C do
  1171.       begin
  1172.         G := 0;
  1173.         While (F + G < C) and (S [F + G] <> ',') do
  1174.           Inc (G);
  1175.         Inc (L);
  1176.         Count := L;
  1177.         if G = 0 then
  1178.           Item [L - 1] := 0 else
  1179.           Item [L - 1] := StrToInt (Copy (S, F, G));
  1180.         Inc (F, G + 1);
  1181.       end;
  1182.   End;
  1183.  
  1184. Procedure ALongIntArray.Assign (const Source : TObject);
  1185. var I, L : Integer;
  1186.   Begin
  1187.     if Source is ALongIntArray then
  1188.       begin
  1189.         L := ALongIntArray (Source).Count;
  1190.         Count := L;
  1191.         For I := 0 to L - 1 do
  1192.           Item [I] := ALongIntArray (Source).Item [I];
  1193.       end else
  1194.       inherited Assign (Source);
  1195.   End;
  1196.   
  1197. Function ALongIntArray.IsEqual (const V : TObject) : Boolean;
  1198. var I, L : Integer;
  1199.   Begin
  1200.     if V is ALongIntArray then
  1201.       begin
  1202.         L := ALongIntArray (V).Count;
  1203.         Result := L = Count;
  1204.         if not Result then
  1205.           exit;
  1206.         For I := 0 to L - 1 do
  1207.           if Item [I] <> ALongIntArray (V).Item [I] then
  1208.             begin
  1209.               Result := False;
  1210.               exit;
  1211.             end;
  1212.       end else
  1213.       Result := inherited IsEqual (V);
  1214.   End;
  1215.  
  1216. Function ALongIntArray.AddArray (const V : AArray) : Integer;
  1217. var I, L : Integer;
  1218.   Begin
  1219.     if V is ALongIntArray then
  1220.       begin
  1221.         Result := Count;
  1222.         L := V.Count;
  1223.         Count := Result + L;
  1224.         For I := 0 to L - 1 do
  1225.           Item [Result + I] := ALongIntArray (V) [I];
  1226.       end else
  1227.       begin
  1228.         TypeError (ObjectClassName (self) + ' can not add array ' + ObjectClassName (V));
  1229.         Result := -1;
  1230.       end;
  1231.   End;
  1232.  
  1233. Procedure ALongIntArray.Delete (const Idx : Integer; const Count : Integer);
  1234. var I, C, J, L : Integer;
  1235.   Begin
  1236.     J := MaxI (Idx, 0);
  1237.     C := GetCount;
  1238.     L := MinI (Count, C - J);
  1239.     if L > 0 then
  1240.       begin
  1241.         For I := J to J + C - 1 do
  1242.           SetItem (I, GetItem (I + Count));
  1243.         SetCount (C - L);
  1244.       end;
  1245.   End;
  1246.  
  1247. Procedure ALongIntArray.Insert (const Idx : Integer; const Count : Integer);
  1248. var I, C, J, L : Integer;
  1249.   Begin
  1250.     if Count <= 0 then
  1251.       exit;
  1252.     C := GetCount;
  1253.     SetCount (C + Count);
  1254.     J := MinI (MaxI (Idx, 0), C);
  1255.     L := C - J;
  1256.     For I := C - 1 downto C - L do
  1257.       SetItem (I + Count, GetItem (I));
  1258.   End;
  1259.  
  1260.  
  1261.  
  1262. {                                                                              }
  1263. { ALongWordArray                                                               }
  1264. {                                                                              }
  1265. Procedure ALongWordArray.ExchangeItems (const Idx1, Idx2 : Integer);
  1266. var I : LongWord;
  1267.   Begin
  1268.     I := Item [Idx1];
  1269.     Item [Idx1] := Item [Idx2];
  1270.     Item [Idx2] := I;
  1271.   End;
  1272.  
  1273. Function ALongWordArray.AddItem (const Value : LongWord) : Integer;
  1274.   Begin
  1275.     Result := Count;
  1276.     Count := Result + 1;
  1277.     Item [Result] := Value;
  1278.   End;
  1279.  
  1280. Function ALongWordArray.GetRange (const LoIdx, HiIdx : Integer) : LongWordArray;
  1281. var I, L, H, C : Integer;
  1282.   Begin
  1283.     L := MaxI (0, LoIdx);
  1284.     H := MinI (Count - 1, HiIdx);
  1285.     C := H - L + 1;
  1286.     SetLength (Result, C);
  1287.     For I := 0 to C - 1 do
  1288.       Result [I] := Item [L + I];
  1289.   End;
  1290.  
  1291. Function ALongWordArray.DuplicateRange (const LoIdx, HiIdx : Integer) : AArray;
  1292. var I, L, H, C : Integer;
  1293.   Begin
  1294.     Result := ALongWordArray (CreateInstance);
  1295.     L := MaxI (0, LoIdx);
  1296.     H := MinI (Count - 1, HiIdx);
  1297.     C := H - L + 1;
  1298.     ALongWordArray (Result).Count := C;
  1299.     For I := 0 to C - 1 do
  1300.       ALongWordArray (Result) [I] := Item [L + I];
  1301.   End;
  1302.  
  1303. Procedure ALongWordArray.SetRange (const LoIdx, HiIdx : Integer; const V : LongWordArray);
  1304. var I, L, H, C : Integer;
  1305.   Begin
  1306.     L := MaxI (0, LoIdx);
  1307.     H := MinI (Count - 1, HiIdx);
  1308.     C := MinI (Length (V), H - L + 1);
  1309.     For I := 0 to C - 1 do
  1310.       Item [L + I] := V [I];
  1311.   End;
  1312.  
  1313. Procedure ALongWordArray.Fill (const Idx, Count : Integer; const Value : LongWord);
  1314. var I : Integer;
  1315.   Begin
  1316.     For I := Idx to Idx + Count - 1 do
  1317.       Item [I] := Value;
  1318.   End;
  1319.  
  1320. Function ALongWordArray.AddArray (const V : LongWordArray) : Integer;
  1321.   Begin
  1322.     Result := Count;
  1323.     Count := Result + Length (V);
  1324.     Range [Result, Count - 1] := V;
  1325.   End;
  1326.  
  1327. Function ALongWordArray.CompareItems (const Idx1, Idx2 : Integer) : TCompareResult;
  1328. var I, J : LongWord;
  1329.   Begin
  1330.     I := Item [Idx1];
  1331.     J := Item [Idx2];
  1332.     if I < J then
  1333.       Result := crLess else
  1334.     if I > J then
  1335.       Result := crGreater else
  1336.       Result := crEqual;
  1337.   End;
  1338.  
  1339. Function ALongWordArray.PosNext (const Find : LongWord; const PrevPos : Integer; const IsSortedAscending : Boolean) : Integer;
  1340. var I, L, H : Integer;
  1341.     D       : LongWord;
  1342.   Begin
  1343.     if IsSortedAscending then // binary search
  1344.       begin
  1345.         if MaxI (PrevPos + 1, 0) = 0 then // find first
  1346.           begin
  1347.             L := 0;
  1348.             H := Count - 1;
  1349.             Repeat
  1350.               I := (L + H) div 2;
  1351.               D := Item [I];
  1352.               if D = Find then
  1353.                 begin
  1354.                   While (I > 0) and (Item [I - 1] = Find) do
  1355.                     Dec (I);
  1356.                   Result := I;
  1357.                   exit;
  1358.                 end else
  1359.               if D > Find then
  1360.                 H := I - 1 else
  1361.                 L := I + 1;
  1362.             Until L > H;
  1363.             Result := -1;
  1364.           end else // find next
  1365.           if PrevPos >= Count - 1 then
  1366.             Result := -1 else
  1367.             if Item [PrevPos + 1] = Find then
  1368.               Result := PrevPos + 1 else
  1369.               Result := -1;
  1370.       end else // linear search
  1371.       begin
  1372.   
  1373.         For I := MaxI (PrevPos + 1, 0) to Count - 1 do
  1374.           if Item [I] = Find then
  1375.             begin
  1376.               Result := I;
  1377.               exit;
  1378.             end;
  1379.         Result := -1;
  1380.       end;
  1381.   End;
  1382.  
  1383. Function ALongWordArray.GetAsString : String;
  1384. var I, L : Integer;
  1385.   Begin
  1386.     L := Count;
  1387.     if L = 0 then
  1388.       begin
  1389.         Result := '';
  1390.         exit;
  1391.       end;
  1392.     Result := IntToStr (Item [0]);
  1393.     For I := 1 to L - 1 do
  1394.       Result := Result + ',' + IntToStr (Item [I]);
  1395.     Result := Result;
  1396.   End;
  1397.  
  1398. Procedure ALongWordArray.SetAsString (const S : String);
  1399. var F, G, L, C : Integer;
  1400.   Begin
  1401.     L := Length (S);
  1402.     if L = 0 then
  1403.       begin
  1404.         Count := 0;
  1405.         exit;
  1406.       end;
  1407.     L := 0;
  1408.     F := 2;
  1409.     C := Length (S);
  1410.     While F < C do
  1411.       begin
  1412.         G := 0;
  1413.         While (F + G < C) and (S [F + G] <> ',') do
  1414.           Inc (G);
  1415.         Inc (L);
  1416.         Count := L;
  1417.         if G = 0 then
  1418.           Item [L - 1] := 0 else
  1419.           Item [L - 1] := StrToInt (Copy (S, F, G));
  1420.         Inc (F, G + 1);
  1421.       end;
  1422.   End;
  1423.  
  1424. Procedure ALongWordArray.Assign (const Source : TObject);
  1425. var I, L : Integer;
  1426.   Begin
  1427.     if Source is ALongWordArray then
  1428.       begin
  1429.         L := ALongWordArray (Source).Count;
  1430.         Count := L;
  1431.         For I := 0 to L - 1 do
  1432.           Item [I] := ALongWordArray (Source).Item [I];
  1433.       end else
  1434.       inherited Assign (Source);
  1435.   End;
  1436.   
  1437. Function ALongWordArray.IsEqual (const V : TObject) : Boolean;
  1438. var I, L : Integer;
  1439.   Begin
  1440.     if V is ALongWordArray then
  1441.       begin
  1442.         L := ALongWordArray (V).Count;
  1443.         Result := L = Count;
  1444.         if not Result then
  1445.           exit;
  1446.         For I := 0 to L - 1 do
  1447.           if Item [I] <> ALongWordArray (V).Item [I] then
  1448.             begin
  1449.               Result := False;
  1450.               exit;
  1451.             end;
  1452.       end else
  1453.       Result := inherited IsEqual (V);
  1454.   End;
  1455.  
  1456. Function ALongWordArray.AddArray (const V : AArray) : Integer;
  1457. var I, L : Integer;
  1458.   Begin
  1459.     if V is ALongWordArray then
  1460.       begin
  1461.         Result := Count;
  1462.         L := V.Count;
  1463.         Count := Result + L;
  1464.         For I := 0 to L - 1 do
  1465.           Item [Result + I] := ALongWordArray (V) [I];
  1466.       end else
  1467.       begin
  1468.         TypeError (ObjectClassName (self) + ' can not add array ' + ObjectClassName (V));
  1469.         Result := -1;
  1470.       end;
  1471.   End;
  1472.  
  1473. Procedure ALongWordArray.Delete (const Idx : Integer; const Count : Integer);
  1474. var I, C, J, L : Integer;
  1475.   Begin
  1476.     J := MaxI (Idx, 0);
  1477.     C := GetCount;
  1478.     L := MinI (Count, C - J);
  1479.     if L > 0 then
  1480.       begin
  1481.         For I := J to J + C - 1 do
  1482.           SetItem (I, GetItem (I + Count));
  1483.         SetCount (C - L);
  1484.       end;
  1485.   End;
  1486.  
  1487. Procedure ALongWordArray.Insert (const Idx : Integer; const Count : Integer);
  1488. var I, C, J, L : Integer;
  1489.   Begin
  1490.     if Count <= 0 then
  1491.       exit;
  1492.     C := GetCount;
  1493.     SetCount (C + Count);
  1494.     J := MinI (MaxI (Idx, 0), C);
  1495.     L := C - J;
  1496.     For I := C - 1 downto C - L do
  1497.       SetItem (I + Count, GetItem (I));
  1498.   End;
  1499.  
  1500.  
  1501.  
  1502. {                                                                              }
  1503. { AInt64Array                                                                  }
  1504. {                                                                              }
  1505. Procedure AInt64Array.ExchangeItems (const Idx1, Idx2 : Integer);
  1506. var I : Int64;
  1507.   Begin
  1508.     I := Item [Idx1];
  1509.     Item [Idx1] := Item [Idx2];
  1510.     Item [Idx2] := I;
  1511.   End;
  1512.  
  1513. Function AInt64Array.AddItem (const Value : Int64) : Integer;
  1514.   Begin
  1515.     Result := Count;
  1516.     Count := Result + 1;
  1517.     Item [Result] := Value;
  1518.   End;
  1519.  
  1520. Function AInt64Array.GetRange (const LoIdx, HiIdx : Integer) : Int64Array;
  1521. var I, L, H, C : Integer;
  1522.   Begin
  1523.     L := MaxI (0, LoIdx);
  1524.     H := MinI (Count - 1, HiIdx);
  1525.     C := H - L + 1;
  1526.     SetLength (Result, C);
  1527.     For I := 0 to C - 1 do
  1528.       Result [I] := Item [L + I];
  1529.   End;
  1530.  
  1531. Function AInt64Array.DuplicateRange (const LoIdx, HiIdx : Integer) : AArray;
  1532. var I, L, H, C : Integer;
  1533.   Begin
  1534.     Result := AInt64Array (CreateInstance);
  1535.     L := MaxI (0, LoIdx);
  1536.     H := MinI (Count - 1, HiIdx);
  1537.     C := H - L + 1;
  1538.     AInt64Array (Result).Count := C;
  1539.     For I := 0 to C - 1 do
  1540.       AInt64Array (Result) [I] := Item [L + I];
  1541.   End;
  1542.  
  1543. Procedure AInt64Array.SetRange (const LoIdx, HiIdx : Integer; const V : Int64Array);
  1544. var I, L, H, C : Integer;
  1545.   Begin
  1546.     L := MaxI (0, LoIdx);
  1547.     H := MinI (Count - 1, HiIdx);
  1548.     C := MinI (Length (V), H - L + 1);
  1549.     For I := 0 to C - 1 do
  1550.       Item [L + I] := V [I];
  1551.   End;
  1552.  
  1553. Procedure AInt64Array.Fill (const Idx, Count : Integer; const Value : Int64);
  1554. var I : Integer;
  1555.   Begin
  1556.     For I := Idx to Idx + Count - 1 do
  1557.       Item [I] := Value;
  1558.   End;
  1559.  
  1560. Function AInt64Array.AddArray (const V : Int64Array) : Integer;
  1561.   Begin
  1562.     Result := Count;
  1563.     Count := Result + Length (V);
  1564.     Range [Result, Count - 1] := V;
  1565.   End;
  1566.  
  1567. Function AInt64Array.CompareItems (const Idx1, Idx2 : Integer) : TCompareResult;
  1568. var I, J : Int64;
  1569.   Begin
  1570.     I := Item [Idx1];
  1571.     J := Item [Idx2];
  1572.     if I < J then
  1573.       Result := crLess else
  1574.     if I > J then
  1575.       Result := crGreater else
  1576.       Result := crEqual;
  1577.   End;
  1578.  
  1579. Function AInt64Array.PosNext (const Find : Int64; const PrevPos : Integer; const IsSortedAscending : Boolean) : Integer;
  1580. var I, L, H : Integer;
  1581.     D       : Int64;
  1582.   Begin
  1583.     if IsSortedAscending then // binary search
  1584.       begin
  1585.         if MaxI (PrevPos + 1, 0) = 0 then // find first
  1586.           begin
  1587.             L := 0;
  1588.             H := Count - 1;
  1589.             Repeat
  1590.               I := (L + H) div 2;
  1591.               D := Item [I];
  1592.               if D = Find then
  1593.                 begin
  1594.                   While (I > 0) and (Item [I - 1] = Find) do
  1595.                     Dec (I);
  1596.                   Result := I;
  1597.                   exit;
  1598.                 end else
  1599.               if D > Find then
  1600.                 H := I - 1 else
  1601.                 L := I + 1;
  1602.             Until L > H;
  1603.             Result := -1;
  1604.           end else // find next
  1605.           if PrevPos >= Count - 1 then
  1606.             Result := -1 else
  1607.             if Item [PrevPos + 1] = Find then
  1608.               Result := PrevPos + 1 else
  1609.               Result := -1;
  1610.       end else // linear search
  1611.       begin
  1612.   
  1613.         For I := MaxI (PrevPos + 1, 0) to Count - 1 do
  1614.           if Item [I] = Find then
  1615.             begin
  1616.               Result := I;
  1617.               exit;
  1618.             end;
  1619.         Result := -1;
  1620.       end;
  1621.   End;
  1622.  
  1623. Function AInt64Array.GetAsString : String;
  1624. var I, L : Integer;
  1625.   Begin
  1626.     L := Count;
  1627.     if L = 0 then
  1628.       begin
  1629.         Result := '';
  1630.         exit;
  1631.       end;
  1632.     Result := IntToStr (Item [0]);
  1633.     For I := 1 to L - 1 do
  1634.       Result := Result + ',' + IntToStr (Item [I]);
  1635.     Result := Result;
  1636.   End;
  1637.  
  1638. Procedure AInt64Array.SetAsString (const S : String);
  1639. var F, G, L, C : Integer;
  1640.   Begin
  1641.     L := Length (S);
  1642.     if L = 0 then
  1643.       begin
  1644.         Count := 0;
  1645.         exit;
  1646.       end;
  1647.     L := 0;
  1648.     F := 2;
  1649.     C := Length (S);
  1650.     While F < C do
  1651.       begin
  1652.         G := 0;
  1653.         While (F + G < C) and (S [F + G] <> ',') do
  1654.           Inc (G);
  1655.         Inc (L);
  1656.         Count := L;
  1657.         if G = 0 then
  1658.           Item [L - 1] := 0 else
  1659.           Item [L - 1] := StrToInt (Copy (S, F, G));
  1660.         Inc (F, G + 1);
  1661.       end;
  1662.   End;
  1663.  
  1664. Procedure AInt64Array.Assign (const Source : TObject);
  1665. var I, L : Integer;
  1666.   Begin
  1667.     if Source is AInt64Array then
  1668.       begin
  1669.         L := AInt64Array (Source).Count;
  1670.         Count := L;
  1671.         For I := 0 to L - 1 do
  1672.           Item [I] := AInt64Array (Source).Item [I];
  1673.       end else
  1674.       inherited Assign (Source);
  1675.   End;
  1676.   
  1677. Function AInt64Array.IsEqual (const V : TObject) : Boolean;
  1678. var I, L : Integer;
  1679.   Begin
  1680.     if V is AInt64Array then
  1681.       begin
  1682.         L := AInt64Array (V).Count;
  1683.         Result := L = Count;
  1684.         if not Result then
  1685.           exit;
  1686.         For I := 0 to L - 1 do
  1687.           if Item [I] <> AInt64Array (V).Item [I] then
  1688.             begin
  1689.               Result := False;
  1690.               exit;
  1691.             end;
  1692.       end else
  1693.       Result := inherited IsEqual (V);
  1694.   End;
  1695.  
  1696. Function AInt64Array.AddArray (const V : AArray) : Integer;
  1697. var I, L : Integer;
  1698.   Begin
  1699.     if V is AInt64Array then
  1700.       begin
  1701.         Result := Count;
  1702.         L := V.Count;
  1703.         Count := Result + L;
  1704.         For I := 0 to L - 1 do
  1705.           Item [Result + I] := AInt64Array (V) [I];
  1706.       end else
  1707.       begin
  1708.         TypeError (ObjectClassName (self) + ' can not add array ' + ObjectClassName (V));
  1709.         Result := -1;
  1710.       end;
  1711.   End;
  1712.  
  1713. Procedure AInt64Array.Delete (const Idx : Integer; const Count : Integer);
  1714. var I, C, J, L : Integer;
  1715.   Begin
  1716.     J := MaxI (Idx, 0);
  1717.     C := GetCount;
  1718.     L := MinI (Count, C - J);
  1719.     if L > 0 then
  1720.       begin
  1721.         For I := J to J + C - 1 do
  1722.           SetItem (I, GetItem (I + Count));
  1723.         SetCount (C - L);
  1724.       end;
  1725.   End;
  1726.  
  1727. Procedure AInt64Array.Insert (const Idx : Integer; const Count : Integer);
  1728. var I, C, J, L : Integer;
  1729.   Begin
  1730.     if Count <= 0 then
  1731.       exit;
  1732.     C := GetCount;
  1733.     SetCount (C + Count);
  1734.     J := MinI (MaxI (Idx, 0), C);
  1735.     L := C - J;
  1736.     For I := C - 1 downto C - L do
  1737.       SetItem (I + Count, GetItem (I));
  1738.   End;
  1739.  
  1740.  
  1741.  
  1742. {                                                                              }
  1743. { ASingleArray                                                                 }
  1744. {                                                                              }
  1745. Procedure ASingleArray.ExchangeItems (const Idx1, Idx2 : Integer);
  1746. var I : Single;
  1747.   Begin
  1748.     I := Item [Idx1];
  1749.     Item [Idx1] := Item [Idx2];
  1750.     Item [Idx2] := I;
  1751.   End;
  1752.  
  1753. Function ASingleArray.AddItem (const Value : Single) : Integer;
  1754.   Begin
  1755.     Result := Count;
  1756.     Count := Result + 1;
  1757.     Item [Result] := Value;
  1758.   End;
  1759.  
  1760. Function ASingleArray.GetRange (const LoIdx, HiIdx : Integer) : SingleArray;
  1761. var I, L, H, C : Integer;
  1762.   Begin
  1763.     L := MaxI (0, LoIdx);
  1764.     H := MinI (Count - 1, HiIdx);
  1765.     C := H - L + 1;
  1766.     SetLength (Result, C);
  1767.     For I := 0 to C - 1 do
  1768.       Result [I] := Item [L + I];
  1769.   End;
  1770.  
  1771. Function ASingleArray.DuplicateRange (const LoIdx, HiIdx : Integer) : AArray;
  1772. var I, L, H, C : Integer;
  1773.   Begin
  1774.     Result := ASingleArray (CreateInstance);
  1775.     L := MaxI (0, LoIdx);
  1776.     H := MinI (Count - 1, HiIdx);
  1777.     C := H - L + 1;
  1778.     ASingleArray (Result).Count := C;
  1779.     For I := 0 to C - 1 do
  1780.       ASingleArray (Result) [I] := Item [L + I];
  1781.   End;
  1782.  
  1783. Procedure ASingleArray.SetRange (const LoIdx, HiIdx : Integer; const V : SingleArray);
  1784. var I, L, H, C : Integer;
  1785.   Begin
  1786.     L := MaxI (0, LoIdx);
  1787.     H := MinI (Count - 1, HiIdx);
  1788.     C := MinI (Length (V), H - L + 1);
  1789.     For I := 0 to C - 1 do
  1790.       Item [L + I] := V [I];
  1791.   End;
  1792.  
  1793. Procedure ASingleArray.Fill (const Idx, Count : Integer; const Value : Single);
  1794. var I : Integer;
  1795.   Begin
  1796.     For I := Idx to Idx + Count - 1 do
  1797.       Item [I] := Value;
  1798.   End;
  1799.  
  1800. Function ASingleArray.AddArray (const V : SingleArray) : Integer;
  1801.   Begin
  1802.     Result := Count;
  1803.     Count := Result + Length (V);
  1804.     Range [Result, Count - 1] := V;
  1805.   End;
  1806.  
  1807. Function ASingleArray.CompareItems (const Idx1, Idx2 : Integer) : TCompareResult;
  1808. var I, J : Single;
  1809.   Begin
  1810.     I := Item [Idx1];
  1811.     J := Item [Idx2];
  1812.     if I < J then
  1813.       Result := crLess else
  1814.     if I > J then
  1815.       Result := crGreater else
  1816.       Result := crEqual;
  1817.   End;
  1818.  
  1819. Function ASingleArray.PosNext (const Find : Single; const PrevPos : Integer; const IsSortedAscending : Boolean) : Integer;
  1820. var I, L, H : Integer;
  1821.     D       : Single;
  1822.   Begin
  1823.     if IsSortedAscending then // binary search
  1824.       begin
  1825.         if MaxI (PrevPos + 1, 0) = 0 then // find first
  1826.           begin
  1827.             L := 0;
  1828.             H := Count - 1;
  1829.             Repeat
  1830.               I := (L + H) div 2;
  1831.               D := Item [I];
  1832.               if D = Find then
  1833.                 begin
  1834.                   While (I > 0) and (Item [I - 1] = Find) do
  1835.                     Dec (I);
  1836.                   Result := I;
  1837.                   exit;
  1838.                 end else
  1839.               if D > Find then
  1840.                 H := I - 1 else
  1841.                 L := I + 1;
  1842.             Until L > H;
  1843.             Result := -1;
  1844.           end else // find next
  1845.           if PrevPos >= Count - 1 then
  1846.             Result := -1 else
  1847.             if Item [PrevPos + 1] = Find then
  1848.               Result := PrevPos + 1 else
  1849.               Result := -1;
  1850.       end else // linear search
  1851.       begin
  1852.   
  1853.         For I := MaxI (PrevPos + 1, 0) to Count - 1 do
  1854.           if Item [I] = Find then
  1855.             begin
  1856.               Result := I;
  1857.               exit;
  1858.             end;
  1859.         Result := -1;
  1860.       end;
  1861.   End;
  1862.  
  1863. Function ASingleArray.GetAsString : String;
  1864. var I, L : Integer;
  1865.   Begin
  1866.     L := Count;
  1867.     if L = 0 then
  1868.       begin
  1869.         Result := '';
  1870.         exit;
  1871.       end;
  1872.     Result := FloatToStr (Item [0]);
  1873.     For I := 1 to L - 1 do
  1874.       Result := Result + ',' + FloatToStr (Item [I]);
  1875.     Result := Result;
  1876.   End;
  1877.  
  1878. Procedure ASingleArray.SetAsString (const S : String);
  1879. var F, G, L, C : Integer;
  1880.   Begin
  1881.     L := Length (S);
  1882.     if L = 0 then
  1883.       begin
  1884.         Count := 0;
  1885.         exit;
  1886.       end;
  1887.     L := 0;
  1888.     F := 2;
  1889.     C := Length (S);
  1890.     While F < C do
  1891.       begin
  1892.         G := 0;
  1893.         While (F + G < C) and (S [F + G] <> ',') do
  1894.           Inc (G);
  1895.         Inc (L);
  1896.         Count := L;
  1897.         if G = 0 then
  1898.           Item [L - 1] := 0.0 else
  1899.           Item [L - 1] := StrToFloat (Copy (S, F, G));
  1900.         Inc (F, G + 1);
  1901.       end;
  1902.   End;
  1903.  
  1904. Procedure ASingleArray.Assign (const Source : TObject);
  1905. var I, L : Integer;
  1906.   Begin
  1907.     if Source is ASingleArray then
  1908.       begin
  1909.         L := ASingleArray (Source).Count;
  1910.         Count := L;
  1911.         For I := 0 to L - 1 do
  1912.           Item [I] := ASingleArray (Source).Item [I];
  1913.       end else
  1914.       inherited Assign (Source);
  1915.   End;
  1916.   
  1917. Function ASingleArray.IsEqual (const V : TObject) : Boolean;
  1918. var I, L : Integer;
  1919.   Begin
  1920.     if V is ASingleArray then
  1921.       begin
  1922.         L := ASingleArray (V).Count;
  1923.         Result := L = Count;
  1924.         if not Result then
  1925.           exit;
  1926.         For I := 0 to L - 1 do
  1927.           if Item [I] <> ASingleArray (V).Item [I] then
  1928.             begin
  1929.               Result := False;
  1930.               exit;
  1931.             end;
  1932.       end else
  1933.       Result := inherited IsEqual (V);
  1934.   End;
  1935.  
  1936. Function ASingleArray.AddArray (const V : AArray) : Integer;
  1937. var I, L : Integer;
  1938.   Begin
  1939.     if V is ASingleArray then
  1940.       begin
  1941.         Result := Count;
  1942.         L := V.Count;
  1943.         Count := Result + L;
  1944.         For I := 0 to L - 1 do
  1945.           Item [Result + I] := ASingleArray (V) [I];
  1946.       end else
  1947.       begin
  1948.         TypeError (ObjectClassName (self) + ' can not add array ' + ObjectClassName (V));
  1949.         Result := -1;
  1950.       end;
  1951.   End;
  1952.  
  1953. Procedure ASingleArray.Delete (const Idx : Integer; const Count : Integer);
  1954. var I, C, J, L : Integer;
  1955.   Begin
  1956.     J := MaxI (Idx, 0);
  1957.     C := GetCount;
  1958.     L := MinI (Count, C - J);
  1959.     if L > 0 then
  1960.       begin
  1961.         For I := J to J + C - 1 do
  1962.           SetItem (I, GetItem (I + Count));
  1963.         SetCount (C - L);
  1964.       end;
  1965.   End;
  1966.  
  1967. Procedure ASingleArray.Insert (const Idx : Integer; const Count : Integer);
  1968. var I, C, J, L : Integer;
  1969.   Begin
  1970.     if Count <= 0 then
  1971.       exit;
  1972.     C := GetCount;
  1973.     SetCount (C + Count);
  1974.     J := MinI (MaxI (Idx, 0), C);
  1975.     L := C - J;
  1976.     For I := C - 1 downto C - L do
  1977.       SetItem (I + Count, GetItem (I));
  1978.   End;
  1979.  
  1980.  
  1981.  
  1982. {                                                                              }
  1983. { ADoubleArray                                                                 }
  1984. {                                                                              }
  1985. Procedure ADoubleArray.ExchangeItems (const Idx1, Idx2 : Integer);
  1986. var I : Double;
  1987.   Begin
  1988.     I := Item [Idx1];
  1989.     Item [Idx1] := Item [Idx2];
  1990.     Item [Idx2] := I;
  1991.   End;
  1992.  
  1993. Function ADoubleArray.AddItem (const Value : Double) : Integer;
  1994.   Begin
  1995.     Result := Count;
  1996.     Count := Result + 1;
  1997.     Item [Result] := Value;
  1998.   End;
  1999.  
  2000. Function ADoubleArray.GetRange (const LoIdx, HiIdx : Integer) : DoubleArray;
  2001. var I, L, H, C : Integer;
  2002.   Begin
  2003.     L := MaxI (0, LoIdx);
  2004.     H := MinI (Count - 1, HiIdx);
  2005.     C := H - L + 1;
  2006.     SetLength (Result, C);
  2007.     For I := 0 to C - 1 do
  2008.       Result [I] := Item [L + I];
  2009.   End;
  2010.  
  2011. Function ADoubleArray.DuplicateRange (const LoIdx, HiIdx : Integer) : AArray;
  2012. var I, L, H, C : Integer;
  2013.   Begin
  2014.     Result := ADoubleArray (CreateInstance);
  2015.     L := MaxI (0, LoIdx);
  2016.     H := MinI (Count - 1, HiIdx);
  2017.     C := H - L + 1;
  2018.     ADoubleArray (Result).Count := C;
  2019.     For I := 0 to C - 1 do
  2020.       ADoubleArray (Result) [I] := Item [L + I];
  2021.   End;
  2022.  
  2023. Procedure ADoubleArray.SetRange (const LoIdx, HiIdx : Integer; const V : DoubleArray);
  2024. var I, L, H, C : Integer;
  2025.   Begin
  2026.     L := MaxI (0, LoIdx);
  2027.     H := MinI (Count - 1, HiIdx);
  2028.     C := MinI (Length (V), H - L + 1);
  2029.     For I := 0 to C - 1 do
  2030.       Item [L + I] := V [I];
  2031.   End;
  2032.  
  2033. Procedure ADoubleArray.Fill (const Idx, Count : Integer; const Value : Double);
  2034. var I : Integer;
  2035.   Begin
  2036.     For I := Idx to Idx + Count - 1 do
  2037.       Item [I] := Value;
  2038.   End;
  2039.  
  2040. Function ADoubleArray.AddArray (const V : DoubleArray) : Integer;
  2041.   Begin
  2042.     Result := Count;
  2043.     Count := Result + Length (V);
  2044.     Range [Result, Count - 1] := V;
  2045.   End;
  2046.  
  2047. Function ADoubleArray.CompareItems (const Idx1, Idx2 : Integer) : TCompareResult;
  2048. var I, J : Double;
  2049.   Begin
  2050.     I := Item [Idx1];
  2051.     J := Item [Idx2];
  2052.     if I < J then
  2053.       Result := crLess else
  2054.     if I > J then
  2055.       Result := crGreater else
  2056.       Result := crEqual;
  2057.   End;
  2058.  
  2059. Function ADoubleArray.PosNext (const Find : Double; const PrevPos : Integer; const IsSortedAscending : Boolean) : Integer;
  2060. var I, L, H : Integer;
  2061.     D       : Double;
  2062.   Begin
  2063.     if IsSortedAscending then // binary search
  2064.       begin
  2065.         if MaxI (PrevPos + 1, 0) = 0 then // find first
  2066.           begin
  2067.             L := 0;
  2068.             H := Count - 1;
  2069.             Repeat
  2070.               I := (L + H) div 2;
  2071.               D := Item [I];
  2072.               if D = Find then
  2073.                 begin
  2074.                   While (I > 0) and (Item [I - 1] = Find) do
  2075.                     Dec (I);
  2076.                   Result := I;
  2077.                   exit;
  2078.                 end else
  2079.               if D > Find then
  2080.                 H := I - 1 else
  2081.                 L := I + 1;
  2082.             Until L > H;
  2083.             Result := -1;
  2084.           end else // find next
  2085.           if PrevPos >= Count - 1 then
  2086.             Result := -1 else
  2087.             if Item [PrevPos + 1] = Find then
  2088.               Result := PrevPos + 1 else
  2089.               Result := -1;
  2090.       end else // linear search
  2091.       begin
  2092.   
  2093.         For I := MaxI (PrevPos + 1, 0) to Count - 1 do
  2094.           if Item [I] = Find then
  2095.             begin
  2096.               Result := I;
  2097.               exit;
  2098.             end;
  2099.         Result := -1;
  2100.       end;
  2101.   End;
  2102.  
  2103. Function ADoubleArray.GetAsString : String;
  2104. var I, L : Integer;
  2105.   Begin
  2106.     L := Count;
  2107.     if L = 0 then
  2108.       begin
  2109.         Result := '';
  2110.         exit;
  2111.       end;
  2112.     Result := FloatToStr (Item [0]);
  2113.     For I := 1 to L - 1 do
  2114.       Result := Result + ',' + FloatToStr (Item [I]);
  2115.     Result := Result;
  2116.   End;
  2117.  
  2118. Procedure ADoubleArray.SetAsString (const S : String);
  2119. var F, G, L, C : Integer;
  2120.   Begin
  2121.     L := Length (S);
  2122.     if L = 0 then
  2123.       begin
  2124.         Count := 0;
  2125.         exit;
  2126.       end;
  2127.     L := 0;
  2128.     F := 2;
  2129.     C := Length (S);
  2130.     While F < C do
  2131.       begin
  2132.         G := 0;
  2133.         While (F + G < C) and (S [F + G] <> ',') do
  2134.           Inc (G);
  2135.         Inc (L);
  2136.         Count := L;
  2137.         if G = 0 then
  2138.           Item [L - 1] := 0.0 else
  2139.           Item [L - 1] := StrToFloat (Copy (S, F, G));
  2140.         Inc (F, G + 1);
  2141.       end;
  2142.   End;
  2143.  
  2144. Procedure ADoubleArray.Assign (const Source : TObject);
  2145. var I, L : Integer;
  2146.   Begin
  2147.     if Source is ADoubleArray then
  2148.       begin
  2149.         L := ADoubleArray (Source).Count;
  2150.         Count := L;
  2151.         For I := 0 to L - 1 do
  2152.           Item [I] := ADoubleArray (Source).Item [I];
  2153.       end else
  2154.       inherited Assign (Source);
  2155.   End;
  2156.   
  2157. Function ADoubleArray.IsEqual (const V : TObject) : Boolean;
  2158. var I, L : Integer;
  2159.   Begin
  2160.     if V is ADoubleArray then
  2161.       begin
  2162.         L := ADoubleArray (V).Count;
  2163.         Result := L = Count;
  2164.         if not Result then
  2165.           exit;
  2166.         For I := 0 to L - 1 do
  2167.           if Item [I] <> ADoubleArray (V).Item [I] then
  2168.             begin
  2169.               Result := False;
  2170.               exit;
  2171.             end;
  2172.       end else
  2173.       Result := inherited IsEqual (V);
  2174.   End;
  2175.  
  2176. Function ADoubleArray.AddArray (const V : AArray) : Integer;
  2177. var I, L : Integer;
  2178.   Begin
  2179.     if V is ADoubleArray then
  2180.       begin
  2181.         Result := Count;
  2182.         L := V.Count;
  2183.         Count := Result + L;
  2184.         For I := 0 to L - 1 do
  2185.           Item [Result + I] := ADoubleArray (V) [I];
  2186.       end else
  2187.       begin
  2188.         TypeError (ObjectClassName (self) + ' can not add array ' + ObjectClassName (V));
  2189.         Result := -1;
  2190.       end;
  2191.   End;
  2192.  
  2193. Procedure ADoubleArray.Delete (const Idx : Integer; const Count : Integer);
  2194. var I, C, J, L : Integer;
  2195.   Begin
  2196.     J := MaxI (Idx, 0);
  2197.     C := GetCount;
  2198.     L := MinI (Count, C - J);
  2199.     if L > 0 then
  2200.       begin
  2201.         For I := J to J + C - 1 do
  2202.           SetItem (I, GetItem (I + Count));
  2203.         SetCount (C - L);
  2204.       end;
  2205.   End;
  2206.  
  2207. Procedure ADoubleArray.Insert (const Idx : Integer; const Count : Integer);
  2208. var I, C, J, L : Integer;
  2209.   Begin
  2210.     if Count <= 0 then
  2211.       exit;
  2212.     C := GetCount;
  2213.     SetCount (C + Count);
  2214.     J := MinI (MaxI (Idx, 0), C);
  2215.     L := C - J;
  2216.     For I := C - 1 downto C - L do
  2217.       SetItem (I + Count, GetItem (I));
  2218.   End;
  2219.  
  2220.  
  2221.  
  2222. {                                                                              }
  2223. { AExtendedArray                                                               }
  2224. {                                                                              }
  2225. Procedure AExtendedArray.ExchangeItems (const Idx1, Idx2 : Integer);
  2226. var I : Extended;
  2227.   Begin
  2228.     I := Item [Idx1];
  2229.     Item [Idx1] := Item [Idx2];
  2230.     Item [Idx2] := I;
  2231.   End;
  2232.  
  2233. Function AExtendedArray.AddItem (const Value : Extended) : Integer;
  2234.   Begin
  2235.     Result := Count;
  2236.     Count := Result + 1;
  2237.     Item [Result] := Value;
  2238.   End;
  2239.  
  2240. Function AExtendedArray.GetRange (const LoIdx, HiIdx : Integer) : ExtendedArray;
  2241. var I, L, H, C : Integer;
  2242.   Begin
  2243.     L := MaxI (0, LoIdx);
  2244.     H := MinI (Count - 1, HiIdx);
  2245.     C := H - L + 1;
  2246.     SetLength (Result, C);
  2247.     For I := 0 to C - 1 do
  2248.       Result [I] := Item [L + I];
  2249.   End;
  2250.  
  2251. Function AExtendedArray.DuplicateRange (const LoIdx, HiIdx : Integer) : AArray;
  2252. var I, L, H, C : Integer;
  2253.   Begin
  2254.     Result := AExtendedArray (CreateInstance);
  2255.     L := MaxI (0, LoIdx);
  2256.     H := MinI (Count - 1, HiIdx);
  2257.     C := H - L + 1;
  2258.     AExtendedArray (Result).Count := C;
  2259.     For I := 0 to C - 1 do
  2260.       AExtendedArray (Result) [I] := Item [L + I];
  2261.   End;
  2262.  
  2263. Procedure AExtendedArray.SetRange (const LoIdx, HiIdx : Integer; const V : ExtendedArray);
  2264. var I, L, H, C : Integer;
  2265.   Begin
  2266.     L := MaxI (0, LoIdx);
  2267.     H := MinI (Count - 1, HiIdx);
  2268.     C := MinI (Length (V), H - L + 1);
  2269.     For I := 0 to C - 1 do
  2270.       Item [L + I] := V [I];
  2271.   End;
  2272.  
  2273. Procedure AExtendedArray.Fill (const Idx, Count : Integer; const Value : Extended);
  2274. var I : Integer;
  2275.   Begin
  2276.     For I := Idx to Idx + Count - 1 do
  2277.       Item [I] := Value;
  2278.   End;
  2279.  
  2280. Function AExtendedArray.AddArray (const V : ExtendedArray) : Integer;
  2281.   Begin
  2282.     Result := Count;
  2283.     Count := Result + Length (V);
  2284.     Range [Result, Count - 1] := V;
  2285.   End;
  2286.  
  2287. Function AExtendedArray.CompareItems (const Idx1, Idx2 : Integer) : TCompareResult;
  2288. var I, J : Extended;
  2289.   Begin
  2290.     I := Item [Idx1];
  2291.     J := Item [Idx2];
  2292.     if I < J then
  2293.       Result := crLess else
  2294.     if I > J then
  2295.       Result := crGreater else
  2296.       Result := crEqual;
  2297.   End;
  2298.  
  2299. Function AExtendedArray.PosNext (const Find : Extended; const PrevPos : Integer; const IsSortedAscending : Boolean) : Integer;
  2300. var I, L, H : Integer;
  2301.     D       : Extended;
  2302.   Begin
  2303.     if IsSortedAscending then // binary search
  2304.       begin
  2305.         if MaxI (PrevPos + 1, 0) = 0 then // find first
  2306.           begin
  2307.             L := 0;
  2308.             H := Count - 1;
  2309.             Repeat
  2310.               I := (L + H) div 2;
  2311.               D := Item [I];
  2312.               if D = Find then
  2313.                 begin
  2314.                   While (I > 0) and (Item [I - 1] = Find) do
  2315.                     Dec (I);
  2316.                   Result := I;
  2317.                   exit;
  2318.                 end else
  2319.               if D > Find then
  2320.                 H := I - 1 else
  2321.                 L := I + 1;
  2322.             Until L > H;
  2323.             Result := -1;
  2324.           end else // find next
  2325.           if PrevPos >= Count - 1 then
  2326.             Result := -1 else
  2327.             if Item [PrevPos + 1] = Find then
  2328.               Result := PrevPos + 1 else
  2329.               Result := -1;
  2330.       end else // linear search
  2331.       begin
  2332.   
  2333.         For I := MaxI (PrevPos + 1, 0) to Count - 1 do
  2334.           if Item [I] = Find then
  2335.             begin
  2336.               Result := I;
  2337.               exit;
  2338.             end;
  2339.         Result := -1;
  2340.       end;
  2341.   End;
  2342.  
  2343. Function AExtendedArray.GetAsString : String;
  2344. var I, L : Integer;
  2345.   Begin
  2346.     L := Count;
  2347.     if L = 0 then
  2348.       begin
  2349.         Result := '';
  2350.         exit;
  2351.       end;
  2352.     Result := FloatToStr (Item [0]);
  2353.     For I := 1 to L - 1 do
  2354.       Result := Result + ',' + FloatToStr (Item [I]);
  2355.     Result := Result;
  2356.   End;
  2357.  
  2358. Procedure AExtendedArray.SetAsString (const S : String);
  2359. var F, G, L, C : Integer;
  2360.   Begin
  2361.     L := Length (S);
  2362.     if L = 0 then
  2363.       begin
  2364.         Count := 0;
  2365.         exit;
  2366.       end;
  2367.     L := 0;
  2368.     F := 2;
  2369.     C := Length (S);
  2370.     While F < C do
  2371.       begin
  2372.         G := 0;
  2373.         While (F + G < C) and (S [F + G] <> ',') do
  2374.           Inc (G);
  2375.         Inc (L);
  2376.         Count := L;
  2377.         if G = 0 then
  2378.           Item [L - 1] := 0.0 else
  2379.           Item [L - 1] := StrToFloat (Copy (S, F, G));
  2380.         Inc (F, G + 1);
  2381.       end;
  2382.   End;
  2383.  
  2384. Procedure AExtendedArray.Assign (const Source : TObject);
  2385. var I, L : Integer;
  2386.   Begin
  2387.     if Source is AExtendedArray then
  2388.       begin
  2389.         L := AExtendedArray (Source).Count;
  2390.         Count := L;
  2391.         For I := 0 to L - 1 do
  2392.           Item [I] := AExtendedArray (Source).Item [I];
  2393.       end else
  2394.       inherited Assign (Source);
  2395.   End;
  2396.   
  2397. Function AExtendedArray.IsEqual (const V : TObject) : Boolean;
  2398. var I, L : Integer;
  2399.   Begin
  2400.     if V is AExtendedArray then
  2401.       begin
  2402.         L := AExtendedArray (V).Count;
  2403.         Result := L = Count;
  2404.         if not Result then
  2405.           exit;
  2406.         For I := 0 to L - 1 do
  2407.           if Item [I] <> AExtendedArray (V).Item [I] then
  2408.             begin
  2409.               Result := False;
  2410.               exit;
  2411.             end;
  2412.       end else
  2413.       Result := inherited IsEqual (V);
  2414.   End;
  2415.  
  2416. Function AExtendedArray.AddArray (const V : AArray) : Integer;
  2417. var I, L : Integer;
  2418.   Begin
  2419.     if V is AExtendedArray then
  2420.       begin
  2421.         Result := Count;
  2422.         L := V.Count;
  2423.         Count := Result + L;
  2424.         For I := 0 to L - 1 do
  2425.           Item [Result + I] := AExtendedArray (V) [I];
  2426.       end else
  2427.       begin
  2428.         TypeError (ObjectClassName (self) + ' can not add array ' + ObjectClassName (V));
  2429.         Result := -1;
  2430.       end;
  2431.   End;
  2432.  
  2433. Procedure AExtendedArray.Delete (const Idx : Integer; const Count : Integer);
  2434. var I, C, J, L : Integer;
  2435.   Begin
  2436.     J := MaxI (Idx, 0);
  2437.     C := GetCount;
  2438.     L := MinI (Count, C - J);
  2439.     if L > 0 then
  2440.       begin
  2441.         For I := J to J + C - 1 do
  2442.           SetItem (I, GetItem (I + Count));
  2443.         SetCount (C - L);
  2444.       end;
  2445.   End;
  2446.  
  2447. Procedure AExtendedArray.Insert (const Idx : Integer; const Count : Integer);
  2448. var I, C, J, L : Integer;
  2449.   Begin
  2450.     if Count <= 0 then
  2451.       exit;
  2452.     C := GetCount;
  2453.     SetCount (C + Count);
  2454.     J := MinI (MaxI (Idx, 0), C);
  2455.     L := C - J;
  2456.     For I := C - 1 downto C - L do
  2457.       SetItem (I + Count, GetItem (I));
  2458.   End;
  2459.  
  2460.  
  2461.  
  2462. {                                                                              }
  2463. { APointerArray                                                                }
  2464. {                                                                              }
  2465. Procedure APointerArray.ExchangeItems (const Idx1, Idx2 : Integer);
  2466. var I : Pointer;
  2467.   Begin
  2468.     I := Item [Idx1];
  2469.     Item [Idx1] := Item [Idx2];
  2470.     Item [Idx2] := I;
  2471.   End;
  2472.  
  2473. Function APointerArray.AddItem (const Value : Pointer) : Integer;
  2474.   Begin
  2475.     Result := Count;
  2476.     Count := Result + 1;
  2477.     Item [Result] := Value;
  2478.   End;
  2479.  
  2480. Function APointerArray.GetRange (const LoIdx, HiIdx : Integer) : PointerArray;
  2481. var I, L, H, C : Integer;
  2482.   Begin
  2483.     L := MaxI (0, LoIdx);
  2484.     H := MinI (Count - 1, HiIdx);
  2485.     C := H - L + 1;
  2486.     SetLength (Result, C);
  2487.     For I := 0 to C - 1 do
  2488.       Result [I] := Item [L + I];
  2489.   End;
  2490.  
  2491. Function APointerArray.DuplicateRange (const LoIdx, HiIdx : Integer) : AArray;
  2492. var I, L, H, C : Integer;
  2493.   Begin
  2494.     Result := APointerArray (CreateInstance);
  2495.     L := MaxI (0, LoIdx);
  2496.     H := MinI (Count - 1, HiIdx);
  2497.     C := H - L + 1;
  2498.     APointerArray (Result).Count := C;
  2499.     For I := 0 to C - 1 do
  2500.       APointerArray (Result) [I] := Item [L + I];
  2501.   End;
  2502.  
  2503. Procedure APointerArray.SetRange (const LoIdx, HiIdx : Integer; const V : PointerArray);
  2504. var I, L, H, C : Integer;
  2505.   Begin
  2506.     L := MaxI (0, LoIdx);
  2507.     H := MinI (Count - 1, HiIdx);
  2508.     C := MinI (Length (V), H - L + 1);
  2509.     For I := 0 to C - 1 do
  2510.       Item [L + I] := V [I];
  2511.   End;
  2512.  
  2513. Procedure APointerArray.Fill (const Idx, Count : Integer; const Value : Pointer);
  2514. var I : Integer;
  2515.   Begin
  2516.     For I := Idx to Idx + Count - 1 do
  2517.       Item [I] := Value;
  2518.   End;
  2519.  
  2520. Function APointerArray.AddArray (const V : PointerArray) : Integer;
  2521.   Begin
  2522.     Result := Count;
  2523.     Count := Result + Length (V);
  2524.     Range [Result, Count - 1] := V;
  2525.   End;
  2526.  
  2527. Function APointerArray.PosNext (const Find : Pointer; const PrevPos : Integer) : Integer;
  2528. var I : Integer;
  2529.   Begin
  2530.         For I := MaxI (PrevPos + 1, 0) to Count - 1 do
  2531.           if Item [I] = Find then
  2532.             begin
  2533.               Result := I;
  2534.               exit;
  2535.             end;
  2536.         Result := -1;
  2537.   End;
  2538.  
  2539. Function APointerArray.GetAsString : String;
  2540. var I, L : Integer;
  2541.   Begin
  2542.     L := Count;
  2543.     if L = 0 then
  2544.       begin
  2545.         Result := '';
  2546.         exit;
  2547.       end;
  2548.     Result := PointerToStr (Item [0]);
  2549.     For I := 1 to L - 1 do
  2550.       Result := Result + ',' + PointerToStr (Item [I]);
  2551.     Result := Result;
  2552.   End;
  2553.  
  2554. Procedure APointerArray.SetAsString (const S : String);
  2555. var F, G, L, C : Integer;
  2556.   Begin
  2557.     L := Length (S);
  2558.     if L = 0 then
  2559.       begin
  2560.         Count := 0;
  2561.         exit;
  2562.       end;
  2563.     L := 0;
  2564.     F := 2;
  2565.     C := Length (S);
  2566.     While F < C do
  2567.       begin
  2568.         G := 0;
  2569.         While (F + G < C) and (S [F + G] <> ',') do
  2570.           Inc (G);
  2571.         Inc (L);
  2572.         Count := L;
  2573.         if G = 0 then
  2574.           Item [L - 1] := nil else
  2575.           Item [L - 1] := StrToPointer (Copy (S, F, G));
  2576.         Inc (F, G + 1);
  2577.       end;
  2578.   End;
  2579.  
  2580. Procedure APointerArray.Assign (const Source : TObject);
  2581. var I, L : Integer;
  2582.   Begin
  2583.     if Source is APointerArray then
  2584.       begin
  2585.         L := APointerArray (Source).Count;
  2586.         Count := L;
  2587.         For I := 0 to L - 1 do
  2588.           Item [I] := APointerArray (Source).Item [I];
  2589.       end else
  2590.       inherited Assign (Source);
  2591.   End;
  2592.   
  2593. Function APointerArray.IsEqual (const V : TObject) : Boolean;
  2594. var I, L : Integer;
  2595.   Begin
  2596.     if V is APointerArray then
  2597.       begin
  2598.         L := APointerArray (V).Count;
  2599.         Result := L = Count;
  2600.         if not Result then
  2601.           exit;
  2602.         For I := 0 to L - 1 do
  2603.           if Item [I] <> APointerArray (V).Item [I] then
  2604.             begin
  2605.               Result := False;
  2606.               exit;
  2607.             end;
  2608.       end else
  2609.       Result := inherited IsEqual (V);
  2610.   End;
  2611.  
  2612. Function APointerArray.AddArray (const V : AArray) : Integer;
  2613. var I, L : Integer;
  2614.   Begin
  2615.     if V is APointerArray then
  2616.       begin
  2617.         Result := Count;
  2618.         L := V.Count;
  2619.         Count := Result + L;
  2620.         For I := 0 to L - 1 do
  2621.           Item [Result + I] := APointerArray (V) [I];
  2622.       end else
  2623.       begin
  2624.         TypeError (ObjectClassName (self) + ' can not add array ' + ObjectClassName (V));
  2625.         Result := -1;
  2626.       end;
  2627.   End;
  2628.  
  2629. Procedure APointerArray.Delete (const Idx : Integer; const Count : Integer);
  2630. var I, C, J, L : Integer;
  2631.   Begin
  2632.     J := MaxI (Idx, 0);
  2633.     C := GetCount;
  2634.     L := MinI (Count, C - J);
  2635.     if L > 0 then
  2636.       begin
  2637.         For I := J to J + C - 1 do
  2638.           SetItem (I, GetItem (I + Count));
  2639.         SetCount (C - L);
  2640.       end;
  2641.   End;
  2642.  
  2643. Procedure APointerArray.Insert (const Idx : Integer; const Count : Integer);
  2644. var I, C, J, L : Integer;
  2645.   Begin
  2646.     if Count <= 0 then
  2647.       exit;
  2648.     C := GetCount;
  2649.     SetCount (C + Count);
  2650.     J := MinI (MaxI (Idx, 0), C);
  2651.     L := C - J;
  2652.     For I := C - 1 downto C - L do
  2653.       SetItem (I + Count, GetItem (I));
  2654.   End;
  2655.  
  2656.  
  2657.  
  2658. {                                                                              }
  2659. { AStringArray                                                                 }
  2660. {                                                                              }
  2661. Procedure AStringArray.ExchangeItems (const Idx1, Idx2 : Integer);
  2662. var I : String;
  2663.   Begin
  2664.     I := Item [Idx1];
  2665.     Item [Idx1] := Item [Idx2];
  2666.     Item [Idx2] := I;
  2667.   End;
  2668.  
  2669. Function AStringArray.AddItem (const Value : String) : Integer;
  2670.   Begin
  2671.     Result := Count;
  2672.     Count := Result + 1;
  2673.     Item [Result] := Value;
  2674.   End;
  2675.  
  2676. Function AStringArray.GetRange (const LoIdx, HiIdx : Integer) : StringArray;
  2677. var I, L, H, C : Integer;
  2678.   Begin
  2679.     L := MaxI (0, LoIdx);
  2680.     H := MinI (Count - 1, HiIdx);
  2681.     C := H - L + 1;
  2682.     SetLength (Result, C);
  2683.     For I := 0 to C - 1 do
  2684.       Result [I] := Item [L + I];
  2685.   End;
  2686.  
  2687. Function AStringArray.DuplicateRange (const LoIdx, HiIdx : Integer) : AArray;
  2688. var I, L, H, C : Integer;
  2689.   Begin
  2690.     Result := AStringArray (CreateInstance);
  2691.     L := MaxI (0, LoIdx);
  2692.     H := MinI (Count - 1, HiIdx);
  2693.     C := H - L + 1;
  2694.     AStringArray (Result).Count := C;
  2695.     For I := 0 to C - 1 do
  2696.       AStringArray (Result) [I] := Item [L + I];
  2697.   End;
  2698.  
  2699. Procedure AStringArray.SetRange (const LoIdx, HiIdx : Integer; const V : StringArray);
  2700. var I, L, H, C : Integer;
  2701.   Begin
  2702.     L := MaxI (0, LoIdx);
  2703.     H := MinI (Count - 1, HiIdx);
  2704.     C := MinI (Length (V), H - L + 1);
  2705.     For I := 0 to C - 1 do
  2706.       Item [L + I] := V [I];
  2707.   End;
  2708.  
  2709. Procedure AStringArray.Fill (const Idx, Count : Integer; const Value : String);
  2710. var I : Integer;
  2711.   Begin
  2712.     For I := Idx to Idx + Count - 1 do
  2713.       Item [I] := Value;
  2714.   End;
  2715.  
  2716. Function AStringArray.AddArray (const V : StringArray) : Integer;
  2717.   Begin
  2718.     Result := Count;
  2719.     Count := Result + Length (V);
  2720.     Range [Result, Count - 1] := V;
  2721.   End;
  2722.  
  2723. Function AStringArray.CompareItems (const Idx1, Idx2 : Integer) : TCompareResult;
  2724. var I, J : String;
  2725.   Begin
  2726.     I := Item [Idx1];
  2727.     J := Item [Idx2];
  2728.     if I < J then
  2729.       Result := crLess else
  2730.     if I > J then
  2731.       Result := crGreater else
  2732.       Result := crEqual;
  2733.   End;
  2734.  
  2735. Function AStringArray.PosNext (const Find : String; const PrevPos : Integer; const IsSortedAscending : Boolean) : Integer;
  2736. var I, L, H : Integer;
  2737.     D       : String;
  2738.   Begin
  2739.     if IsSortedAscending then // binary search
  2740.       begin
  2741.         if MaxI (PrevPos + 1, 0) = 0 then // find first
  2742.           begin
  2743.             L := 0;
  2744.             H := Count - 1;
  2745.             Repeat
  2746.               I := (L + H) div 2;
  2747.               D := Item [I];
  2748.               if D = Find then
  2749.                 begin
  2750.                   While (I > 0) and (Item [I - 1] = Find) do
  2751.                     Dec (I);
  2752.                   Result := I;
  2753.                   exit;
  2754.                 end else
  2755.               if D > Find then
  2756.                 H := I - 1 else
  2757.                 L := I + 1;
  2758.             Until L > H;
  2759.             Result := -1;
  2760.           end else // find next
  2761.           if PrevPos >= Count - 1 then
  2762.             Result := -1 else
  2763.             if Item [PrevPos + 1] = Find then
  2764.               Result := PrevPos + 1 else
  2765.               Result := -1;
  2766.       end else // linear search
  2767.       begin
  2768.   
  2769.         For I := MaxI (PrevPos + 1, 0) to Count - 1 do
  2770.           if Item [I] = Find then
  2771.             begin
  2772.               Result := I;
  2773.               exit;
  2774.             end;
  2775.         Result := -1;
  2776.       end;
  2777.   End;
  2778.  
  2779. Function AStringArray.GetAsString : String;
  2780. var I, L : Integer;
  2781.   Begin
  2782.     L := Count;
  2783.     if L = 0 then
  2784.       begin
  2785.         Result := '';
  2786.         exit;
  2787.       end;
  2788.     Result := UnquoteText (Item [0]);
  2789.     For I := 1 to L - 1 do
  2790.       Result := Result + ',' + UnquoteText (Item [I]);
  2791.     Result := Result;
  2792.   End;
  2793.  
  2794. Procedure AStringArray.SetAsString (const S : String);
  2795. var F, G, L, C : Integer;
  2796.   Begin
  2797.     L := Length (S);
  2798.     if L = 0 then
  2799.       begin
  2800.         Count := 0;
  2801.         exit;
  2802.       end;
  2803.     L := 0;
  2804.     F := 2;
  2805.     C := Length (S);
  2806.     While F < C do
  2807.       begin
  2808.         G := 0;
  2809.         While (F + G < C) and (S [F + G] <> ',') do
  2810.           Inc (G);
  2811.         Inc (L);
  2812.         Count := L;
  2813.         if G = 0 then
  2814.           Item [L - 1] := '' else
  2815.           Item [L - 1] := QuoteText (Copy (S, F, G));
  2816.         Inc (F, G + 1);
  2817.       end;
  2818.   End;
  2819.  
  2820. Procedure AStringArray.Assign (const Source : TObject);
  2821. var I, L : Integer;
  2822.   Begin
  2823.     if Source is AStringArray then
  2824.       begin
  2825.         L := AStringArray (Source).Count;
  2826.         Count := L;
  2827.         For I := 0 to L - 1 do
  2828.           Item [I] := AStringArray (Source).Item [I];
  2829.       end else
  2830.       inherited Assign (Source);
  2831.   End;
  2832.   
  2833. Function AStringArray.IsEqual (const V : TObject) : Boolean;
  2834. var I, L : Integer;
  2835.   Begin
  2836.     if V is AStringArray then
  2837.       begin
  2838.         L := AStringArray (V).Count;
  2839.         Result := L = Count;
  2840.         if not Result then
  2841.           exit;
  2842.         For I := 0 to L - 1 do
  2843.           if Item [I] <> AStringArray (V).Item [I] then
  2844.             begin
  2845.               Result := False;
  2846.               exit;
  2847.             end;
  2848.       end else
  2849.       Result := inherited IsEqual (V);
  2850.   End;
  2851.  
  2852. Function AStringArray.AddArray (const V : AArray) : Integer;
  2853. var I, L : Integer;
  2854.   Begin
  2855.     if V is AStringArray then
  2856.       begin
  2857.         Result := Count;
  2858.         L := V.Count;
  2859.         Count := Result + L;
  2860.         For I := 0 to L - 1 do
  2861.           Item [Result + I] := AStringArray (V) [I];
  2862.       end else
  2863.       begin
  2864.         TypeError (ObjectClassName (self) + ' can not add array ' + ObjectClassName (V));
  2865.         Result := -1;
  2866.       end;
  2867.   End;
  2868.  
  2869. Procedure AStringArray.Delete (const Idx : Integer; const Count : Integer);
  2870. var I, C, J, L : Integer;
  2871.   Begin
  2872.     J := MaxI (Idx, 0);
  2873.     C := GetCount;
  2874.     L := MinI (Count, C - J);
  2875.     if L > 0 then
  2876.       begin
  2877.         For I := J to J + C - 1 do
  2878.           SetItem (I, GetItem (I + Count));
  2879.         SetCount (C - L);
  2880.       end;
  2881.   End;
  2882.  
  2883. Procedure AStringArray.Insert (const Idx : Integer; const Count : Integer);
  2884. var I, C, J, L : Integer;
  2885.   Begin
  2886.     if Count <= 0 then
  2887.       exit;
  2888.     C := GetCount;
  2889.     SetCount (C + Count);
  2890.     J := MinI (MaxI (Idx, 0), C);
  2891.     L := C - J;
  2892.     For I := C - 1 downto C - L do
  2893.       SetItem (I + Count, GetItem (I));
  2894.   End;
  2895.  
  2896.  
  2897.  
  2898.  
  2899.  
  2900. {                                                                              }
  2901. { ABitArray                                                                    }
  2902. {                                                                              }
  2903. Function ABitArray.GetRange (const Idx : Integer) : LongWord;
  2904. var I : Integer;
  2905.   Begin
  2906.     Result := 0;
  2907.     For I := 0 to BitsPerLongWord - 1 do
  2908.       if Bit [Idx + I] then
  2909.         Result := Result or BitMaskTable [I];
  2910.   End;
  2911.  
  2912. Procedure ABitArray.SetRange (const Idx : Integer; const Value : LongWord);
  2913. var I : Integer;
  2914.     C : LongWord;
  2915.   Begin
  2916.     C := 1;
  2917.     For I := Idx to Idx + BitsPerLongWord - 1 do
  2918.       begin
  2919.         Bit [I] := Value and C <> 0;
  2920.         C := C shl 1;
  2921.       end;
  2922.   End;
  2923.  
  2924. Procedure ABitArray.Fill (const Idx, Count : Integer; const Value : Boolean);
  2925. var I : Integer;
  2926.   Begin
  2927.     For I := Idx to Idx + Count - 1 do
  2928.       Bit [I] := Value;
  2929.   End;
  2930.  
  2931. Function ABitArray.CompareRange (const LoIdx, HiIdx : Integer; const Value : Boolean) : Boolean;
  2932. var I : Integer;
  2933.   Begin
  2934.     For I := LoIdx to HiIdx do
  2935.       if Bit [I] <> Value then
  2936.         begin
  2937.           Result := False;
  2938.           exit;
  2939.         end;
  2940.     Result := True;
  2941.   End;
  2942.  
  2943. Procedure ABitArray.Assign (const Source : TObject);
  2944. var I, L : Integer;
  2945.   Begin
  2946.     if Source is ABitArray then
  2947.       begin
  2948.         L := AArray (Source).Count;
  2949.         Count := L;
  2950.         For I := 0 to L - 1 do
  2951.           Bit [I] := ABitArray (Source) [I];
  2952.       end else
  2953.       inherited Assign (Source);
  2954.   End;
  2955.  
  2956. Function ABitArray.IsEqual (const V : TObject) : Boolean;
  2957. var I, L : Integer;
  2958.   Begin
  2959.     if V is ABitArray then
  2960.       begin
  2961.         L := AArray (V).Count;
  2962.         if Count <> L then
  2963.           begin
  2964.             Result := False;
  2965.             exit;
  2966.           end;
  2967.         For I := 0 to L - 1 do
  2968.           if Bit [I] <> ABitArray (V) [I] then
  2969.             begin
  2970.               Result := False;
  2971.               exit;
  2972.             end;
  2973.         Result := True;
  2974.       end else
  2975.       Result := inherited IsEqual (V);
  2976.   End;
  2977.  
  2978. Procedure ABitArray.ExchangeItems (const Idx1, Idx2 : Integer);
  2979. var I : Boolean;
  2980.   Begin
  2981.     I := Bit [Idx1];
  2982.     Bit [Idx1] := Bit [Idx2];
  2983.     Bit [Idx2] := I;
  2984.   End;
  2985.  
  2986. Function ABitArray.AddItem (const Value : Boolean) : Integer;
  2987.   Begin
  2988.     Result := Count;
  2989.     Count := Result + 1;
  2990.     Bit [Result] := Value;
  2991.   End;
  2992.  
  2993. Function ABitArray.CompareItems (const Idx1, Idx2 : Integer) : TCompareResult;
  2994.   Begin
  2995.     Result := cUtils.Compare (Bit [Idx1], Bit [Idx2]);
  2996.   End;
  2997.  
  2998. Procedure ABitArray.Invert;
  2999. var I : Integer;
  3000.   Begin
  3001.     For I := 0 to Count - 1 do
  3002.       Bit [I] := not Bit [I];
  3003.   End;
  3004.  
  3005. Function ABitArray.Find (const Value : Boolean; const Start : Integer; const FindForward : Boolean) : Integer;
  3006. var I, C : Integer;
  3007.   Begin
  3008.     I := Start;
  3009.     C := Count;
  3010.     if FindForward then
  3011.       begin
  3012.         While (I < C) and (Bit [I] <> Value) do
  3013.           Inc (I);
  3014.         if I < C then
  3015.           Result := I else
  3016.           Result := -1;
  3017.       end else
  3018.       begin
  3019.         I := MinI (I, C);
  3020.         While (I >= 0) and (Bit [I] <> Value) do
  3021.           Dec (I);
  3022.         Result := I;
  3023.       end;
  3024.   End;
  3025.  
  3026. Function ABitArray.FindRange (const Value : Boolean; const Start : Integer; const Count : Integer; const FindForward : Boolean) : Integer;
  3027. var I, C, F : Integer;
  3028.   Begin
  3029.     I := Start;
  3030.     if FindForward then
  3031.       begin
  3032.         C := self.Count;
  3033.         F := 0;
  3034.         While (I + F < C) and (F < Count) do
  3035.           if Bit [I + F] = Value then
  3036.             Inc (F) else
  3037.             begin
  3038.               Inc (I, F + 1);
  3039.               F := 0;
  3040.             end;
  3041.         if F < Count then
  3042.           Result := -1 else
  3043.           Result := I;
  3044.       end else
  3045.       begin
  3046.         F := 0;
  3047.         While (I - F >= 0) and (F < Count) do
  3048.           if Bit [I - F] = Value then
  3049.             Inc (F) else
  3050.             begin
  3051.               Dec (I, F + 1);
  3052.               F := 0;
  3053.             end;
  3054.         if F < Count then
  3055.           Result := -1 else
  3056.           Result := I - F + 1;
  3057.       end;
  3058.   End;
  3059.  
  3060. Procedure ABitArray.Delete (const Idx : Integer; const Count : Integer);
  3061. var I, C : Integer;
  3062.   Begin
  3063.     C := GetCount;
  3064.     {$IFOPT R+}
  3065.     if (Idx < 0) or (Idx + Count > C) then
  3066.       IndexError (Idx);
  3067.     {$ENDIF}
  3068.     For I := Idx + Count to C - 1 do
  3069.       SetBit (I - Count, GetBit (I));
  3070.     SetCount (C - Count);
  3071.   End;
  3072.  
  3073. Procedure ABitArray.Insert (const Idx : Integer; const Count : Integer);
  3074. var I, C : Integer;
  3075.   Begin
  3076.     C := GetCount;
  3077.     {$IFOPT R+}
  3078.     if (Idx < 0) or (Idx > C) then
  3079.       IndexError (Idx);
  3080.     {$ENDIF}
  3081.     SetCount (C + Count);
  3082.     For I := Idx to C - 1 do
  3083.       SetBit (I + Count, GetBit (I));
  3084.     Fill (Idx, Idx + Count - 1, False);
  3085.   End;
  3086.  
  3087. Function ABitArray.DuplicateRange (const LoIdx, HiIdx : Integer) : AArray;
  3088. var I, C : Integer;
  3089.   Begin
  3090.     C := GetCount;
  3091.     {$IFOPT R+}
  3092.     if (LoIdx < 0) or (LoIdx > HiIdx) or (HiIdx >= C) then
  3093.       IndexError (HiIdx);
  3094.     {$ENDIF}
  3095.     Result := ABitArray (CreateInstance);
  3096.     C := HiIdx - LoIdx + 1;
  3097.     Result.Count := C;
  3098.     For I := 0 to C - 1 do
  3099.       ABitArray (Result) [I] := GetBit (LoIdx + I);
  3100.   End;
  3101.  
  3102. Function ABitArray.AddArray (const V : AArray) : Integer;
  3103. var I, C : Integer;
  3104.   Begin
  3105.     if V is ABitArray then
  3106.       begin
  3107.         Result := Count;
  3108.         C := ABitArray (V).Count;
  3109.         if C = 0 then
  3110.           exit;
  3111.         SetCount (Result + C);
  3112.         For I := 0 to C - 1 do
  3113.           SetBit (Result + I, ABitArray (V).GetBit (I));
  3114.       end else
  3115.       begin
  3116.         TypeError (ObjectClassName (self) + ' can not add array ' + ObjectClassName (V));
  3117.         Result := -1;
  3118.       end;
  3119.   End;
  3120.  
  3121.  
  3122.  
  3123. {                                                                              }
  3124. { AObjectArray                                                                 }
  3125. {                                                                              }
  3126. Procedure AObjectArray.Clear;
  3127.   Begin
  3128.     if IsItemOwner then
  3129.       FreeItems else
  3130.       ReleaseItems;
  3131.   End;
  3132.  
  3133. Procedure AObjectArray.Assign (const Source : TObject);
  3134. var I, L : Integer;
  3135.     V, S : TObject;
  3136.   Begin
  3137.     S := Source;
  3138.     if S is AObjectArray then
  3139.       begin
  3140.         FreeItems;
  3141.         IsItemOwner := AObjectArray (S).IsItemOwner;
  3142.         L := AArray (S).Count;
  3143.         Count := L;
  3144.         if GetIsItemOwner then
  3145.           For I := 0 to L - 1 do
  3146.             begin
  3147.               V := AObjectArray (S) [I];
  3148.               if V is AArray then
  3149.                 Item [I] := AArray (V).Duplicate else
  3150.                 Item [I] := V;
  3151.             end
  3152.         else
  3153.           For I := 0 to L - 1 do
  3154.             Item [I] := AObjectArray (S) [I];
  3155.       end else
  3156.       inherited Assign (Source);
  3157.   End;
  3158.  
  3159. Function AObjectArray.IsEqual (const V : TObject) : Boolean;
  3160. var I, L : Integer;
  3161.     A, B : TObject;
  3162.   Begin
  3163.     if V is AObjectArray then
  3164.       begin
  3165.         L := AArray (V).Count;
  3166.         if Count <> L then
  3167.           begin
  3168.             Result := False;
  3169.             exit;
  3170.           end;
  3171.         For I := 0 to L - 1 do
  3172.           begin
  3173.             A := Item [I];
  3174.             B := AObjectArray (V) [I];
  3175.             Result := A = B;
  3176.             if not Result then
  3177.               exit;
  3178.             end;
  3179.         Result := True;
  3180.       end else
  3181.       Result := inherited IsEqual (V);
  3182.   End;
  3183.  
  3184. Function AObjectArray.Compare (const V : TObject) : TCompareResult;
  3185. var I, C1, C2 : Integer;
  3186.     A, B : TObject;
  3187.   Begin
  3188.     if V is AObjectArray then
  3189.       begin
  3190.         C1 := GetCount;
  3191.         C2 := AObjectArray (V).GetCount;
  3192.         if C1 < C2 then
  3193.           Result := crLess else
  3194.         if C1 > C2 then
  3195.           Result := crGreater else
  3196.           begin
  3197.             Result := crEqual;
  3198.             For I := 0 to GetCount - 1 do
  3199.               begin
  3200.                 A := Item [I];
  3201.                 B := AObjectArray (V) [I];
  3202.                 if A <> B then
  3203.                   begin
  3204.                     Result := crUndefined;
  3205.                     exit;
  3206.                   end;
  3207.               end;
  3208.           end;
  3209.       end else
  3210.       Result := inherited Compare (V);
  3211.   End;
  3212.  
  3213. Procedure AObjectArray.ExchangeItems (const Idx1, Idx2 : Integer);
  3214. var I : TObject;
  3215.   Begin
  3216.     I := Item [Idx1];
  3217.     Item [Idx1] := Item [Idx2];
  3218.     Item [Idx2] := I;
  3219.   End;
  3220.  
  3221. Function AObjectArray.AddItem (const Value : TObject) : Integer;
  3222.   Begin
  3223.     Result := Count;
  3224.     Count := Result + 1;
  3225.     Item [Result] := Value;
  3226.   End;
  3227.  
  3228. Function AObjectArray.AddArray (const V : ObjectArray) : Integer;
  3229.   Begin
  3230.     Result := Count;
  3231.     Count := Result + Length (V);
  3232.     Range [Result, Count - 1] := V;
  3233.   End;
  3234.  
  3235. Function AObjectArray.AddArray (const V : AArray) : Integer;
  3236. var I, L : Integer;
  3237.   Begin
  3238.     if V is AObjectArray then
  3239.       begin
  3240.         Result := Count;
  3241.         L := V.Count;
  3242.         Count := Result + L;
  3243.         For I := 0 to L - 1 do
  3244.           Item [Result + I] := AObjectArray (V) [I];
  3245.       end else
  3246.       Result := inherited AddArray (V);
  3247.   End;
  3248.  
  3249. Procedure AObjectArray.Delete (const Idx, Count : Integer);
  3250. var I, C, J, L : Integer;
  3251.   Begin
  3252.     J := MaxI (Idx, 0);
  3253.     C := GetCount;
  3254.     L := MinI (Count, C - J);
  3255.     if L > 0 then
  3256.       begin
  3257.         For I := J to J + C - 1 do
  3258.           SetItem (Idx + I, GetItem (Idx + Count + I));
  3259.         SetCount (C - L);
  3260.       end;
  3261.   End;
  3262.  
  3263. Function AObjectArray.PosNext (const Find : TObject; const PrevPos : Integer) : Integer;
  3264. var I : Integer;
  3265.   Begin
  3266.     For I := MaxI (PrevPos + 1, 0) to Count - 1 do
  3267.       if Find = Item [I] then
  3268.         begin
  3269.           Result := I;
  3270.           exit;
  3271.         end;
  3272.     Result := -1;
  3273.   End;
  3274.  
  3275. Function AObjectArray.PosNext (var Item : TObject; const ClassType : TClass; const PrevPos : Integer) : Integer;
  3276. var I : Integer;
  3277.   Begin
  3278.     For I := MaxI (PrevPos + 1, 0) to Count - 1 do
  3279.       begin
  3280.         Item := GetItem (I);
  3281.         if Item.InheritsFrom (ClassType) then
  3282.           begin
  3283.             Result := I;
  3284.             exit;
  3285.           end;
  3286.       end;
  3287.     Item := nil;
  3288.     Result := -1;
  3289.   End;
  3290.  
  3291. Function AObjectArray.PosNext (var Item : TObject; const ClassName : String; const PrevPos : Integer) : Integer;
  3292. var I : Integer;
  3293.   Begin
  3294.     For I := MaxI (PrevPos + 1, 0) to Count - 1 do
  3295.       begin
  3296.         Item := GetItem (I);
  3297.         if Assigned (Item) and Item.ClassNameIs (ClassName) then
  3298.           begin
  3299.             Result := I;
  3300.             exit;
  3301.           end;
  3302.       end;
  3303.     Item := nil;
  3304.     Result := -1;
  3305.   End;
  3306.  
  3307. Function AObjectArray.Find (const ClassType : TClass; const Count : Integer) : TObject;
  3308. var I, J : Integer;
  3309.   Begin
  3310.     I := -1;
  3311.     For J := 1 to Count do
  3312.       begin
  3313.         I := PosNext (Result, ClassType, I);
  3314.         if I = -1 then
  3315.           break;
  3316.       end;
  3317.     if I = -1 then
  3318.       Result := nil;
  3319.   End;
  3320.  
  3321. Function AObjectArray.Find (const ClassName : String; const Count : Integer) : TObject;
  3322. var I, J : Integer;
  3323.   Begin
  3324.     I := -1;
  3325.     For J := 1 to Count do
  3326.       begin
  3327.         I := PosNext (Result, ClassName, I);
  3328.         if I = -1 then
  3329.           break;
  3330.       end;
  3331.     if I = -1 then
  3332.       Result := nil;
  3333.   End;
  3334.  
  3335. Function AObjectArray.FindAll (const ClassType : TClass) : ObjectArray;
  3336. var I : Integer;
  3337.     V : TObject;
  3338.   Begin
  3339.     SetLength (Result, 0);
  3340.     I := PosNext (V, ClassType);
  3341.     While I >= 0 do
  3342.       begin
  3343.         Append (Result, V);
  3344.         I := PosNext (V, ClassType, I);
  3345.       end;
  3346.   End;
  3347.  
  3348. Function AObjectArray.FindAll (const ClassName : String) : ObjectArray;
  3349. var I : Integer;
  3350.     V : TObject;
  3351.   Begin
  3352.     SetLength (Result, 0);
  3353.     I := PosNext (V, ClassName);
  3354.     While I >= 0 do
  3355.       begin
  3356.         Append (Result, V);
  3357.         I := PosNext (V, ClassName, I);
  3358.       end;
  3359.   End;
  3360.  
  3361. Function AObjectArray.CountItems (const ClassType : TClass) : Integer;
  3362. var I : Integer;
  3363.     V : TObject;
  3364.   Begin
  3365.     Result := 0;
  3366.     I := PosNext (V, ClassType);
  3367.     While I >= 0 do
  3368.       begin
  3369.         Inc (Result);
  3370.         I := PosNext (V, ClassType, I);
  3371.       end;
  3372.   End;
  3373.  
  3374. Function AObjectArray.CountItems (const ClassName : String) : Integer;
  3375. var I : Integer;
  3376.     V : TObject;
  3377.   Begin
  3378.     Result := 0;
  3379.     I := PosNext (V, ClassName);
  3380.     While I >= 0 do
  3381.       begin
  3382.         Inc (Result);
  3383.         I := PosNext (V, ClassName, I);
  3384.       end;
  3385.   End;
  3386.  
  3387. Function AObjectArray.CompareItems (const Idx1, Idx2 : Integer) : TCompareResult;
  3388. var A, B : TObject;
  3389.   Begin
  3390.     A := Item [Idx1];
  3391.     B := Item [Idx2];
  3392.     if A = B then
  3393.       Result := crEqual else
  3394.       Result := crUndefined;
  3395.   End;
  3396.  
  3397. Function AObjectArray.GetRange (const LoIdx, HiIdx : Integer) : ObjectArray;
  3398. var I, L, H, C : Integer;
  3399.   Begin
  3400.     L := MaxI (0, LoIdx);
  3401.     H := MinI (Count - 1, HiIdx);
  3402.     C := H - L  + 1;
  3403.     SetLength (Result, C);
  3404.     For I := 0 to C - 1 do
  3405.       Result [L + I] := Item [I];
  3406.   End;
  3407.  
  3408. Procedure AObjectArray.SetRange (const LoIdx, HiIdx : Integer; const V : ObjectArray);
  3409. var I, L, H, C : Integer;
  3410.   Begin
  3411.     L := MaxI (0, LoIdx);
  3412.     H := MinI (Count - 1, HiIdx);
  3413.     C := MinI (Length (V), H - L  + 1);
  3414.     For I := 0 to C - 1 do
  3415.       Item [L + I] := V [I];
  3416.   End;
  3417.  
  3418. Function AObjectArray.GetAsString : String;
  3419. var I, L : Integer;
  3420.     V : TObject;
  3421.   Begin
  3422.     Result := '';
  3423.     L := Count;
  3424.     For I := 0 to L - 1 do
  3425.       begin
  3426.         V := Item [I];
  3427.         Result := Result + PointerToStr (V);
  3428.         if I < L - 1 then
  3429.           Result := Result + ',';
  3430.       end;
  3431.   End;
  3432.  
  3433.  
  3434.  
  3435. {                                                                              }
  3436. { ARRAY IMPLEMENTATIONS                                                        }
  3437. {                                                                              }
  3438.  
  3439.  
  3440.  
  3441. {                                                                              }
  3442. { Allocation strategy used in array implementations to reduce memory copies:   }
  3443. {   i)   For Count <= 16 or for the first allocation: allocate the exact size. }
  3444. {   ii)  For growing blocks: pre-allocate 1/8th of NewCount.                   }
  3445. {   iii) For shrinking blocks: shrink actual allocation when Count is less     }
  3446. {        than half of the allocated size.                                      }
  3447. {                                                                              }
  3448.  
  3449. {                                                                              }
  3450. { TIntegerArray                                                                }
  3451. {                                                                              }
  3452. Procedure TIntegerArray.SetItem (const Idx : Integer; const Value : Integer);
  3453.   Begin
  3454.     {$IFOPT R+}
  3455.     if (Idx < 0) or (Idx >= FCount) then
  3456.       IndexError (Idx);
  3457.     {$ENDIF}
  3458.     FData [Idx] := Value;
  3459.   End;
  3460.  
  3461. Function TIntegerArray.GetItem (const Idx : Integer) : Integer;
  3462.   Begin
  3463.     {$IFOPT R+}
  3464.     if (Idx < 0) or (Idx >= FCount) then
  3465.       IndexError (Idx);
  3466.     {$ENDIF}
  3467.     Result := FData [Idx];
  3468.   End;
  3469.  
  3470. Function TIntegerArray.GetCount : Integer;
  3471.   Begin
  3472.     Result := FCount;
  3473.   End;
  3474.  
  3475. Procedure TIntegerArray.SetCount (const NewCount : Integer);
  3476. var L, N : Integer;
  3477.   Begin
  3478.     if FCount = NewCount then
  3479.       exit;
  3480.     FCount := NewCount;
  3481.  
  3482.     N := NewCount;
  3483.     L := Length (FData);
  3484.     if (N > 16) and (L > 0) then
  3485.       if N > L then
  3486.         N := N + N shr 3 else
  3487.       if N > L shr 1 then
  3488.         exit;
  3489.  
  3490.     if N <> L then
  3491.       SetLengthAndZero (FData, N);
  3492.   End;
  3493.  
  3494. Procedure TIntegerArray.Delete (const Idx : Integer; const Count : Integer = 1);
  3495.   Begin
  3496.     FCount := MaxI (FCount - Remove (FData, Idx, Count), 0);
  3497.     if FCount = 0 then
  3498.       FData := nil;
  3499.   End;
  3500.  
  3501. Procedure TIntegerArray.Insert (const Idx : Integer; const Count : Integer = 1);
  3502. var I : Integer;
  3503.   Begin
  3504.     I := ArrayInsert (FData, Idx, Count);
  3505.     if I >= 0 then
  3506.       Inc (FCount, Count);
  3507.   End;
  3508.  
  3509. Function TIntegerArray.GetRange (const LoIdx, HiIdx : Integer) : IntegerArray;
  3510. var L, H : Integer;
  3511.   Begin
  3512.     L := MaxI (0, LoIdx);
  3513.     H := MinI (HiIdx, FCount);
  3514.     if H >= L then
  3515.       Result := Copy (FData, L, H - L + 1) else
  3516.       Result := nil;
  3517.   End;
  3518.  
  3519. Procedure TIntegerArray.SetRange (const LoIdx, HiIdx : Integer; const V : IntegerArray);
  3520. var L, H, C : Integer;
  3521.   Begin
  3522.     L := MaxI (0, LoIdx);
  3523.     H := MinI (HiIdx, FCount);
  3524.     C := MaxI (MinI (Length (V), H - L + 1), 0);
  3525.     if C > 0 then
  3526.       Move (V [0], FData [L], C * Sizeof (Integer));
  3527.   End;
  3528.  
  3529. Constructor TIntegerArray.Create (const V : IntegerArray);
  3530.   Begin
  3531.     inherited Create;
  3532.     SetData (V);
  3533.   End;
  3534.  
  3535. class Function TIntegerArray.CreateInstance : AType;
  3536.   Begin
  3537.     Result := TIntegerArray.Create;
  3538.   End;
  3539.  
  3540. Procedure TIntegerArray.SetData (const Data : IntegerArray);
  3541.   Begin
  3542.     FData := Data;
  3543.     FCount := Length (FData);
  3544.   End;
  3545.  
  3546. Function TIntegerArray.DuplicateRange (const LoIdx, HiIdx : Integer) : AArray;
  3547. var L, H, C : Integer;
  3548.   Begin
  3549.     L := MaxI (0, LoIdx);
  3550.     H := MinI (HiIdx, FCount);
  3551.     C := MaxI (0, H - L + 1);
  3552.     Result := CreateInstance as TIntegerArray;
  3553.     TIntegerArray (Result).FCount := C;
  3554.     if C > 0 then
  3555.       TIntegerArray (Result).FData := Copy (FData, L, C);
  3556.   End;
  3557.  
  3558. Procedure TIntegerArray.Assign (const V : IntegerArray);
  3559.   Begin
  3560.     FData := Copy (V);
  3561.     FCount := Length (FData);
  3562.   End;
  3563.  
  3564. Procedure TIntegerArray.Assign (const V : array of Integer);
  3565.   Begin
  3566.     FData := AsIntegerArray (V);
  3567.     FCount := Length (FData);
  3568.   End;
  3569.  
  3570. Procedure TIntegerArray.Assign (const Source : TObject);
  3571.   Begin
  3572.     if Source is TIntegerArray then
  3573.       begin
  3574.         FCount := TIntegerArray (Source).FCount;
  3575.         FData := Copy (TIntegerArray (Source).FData, 0, FCount);
  3576.       end else
  3577.       inherited Assign (Source);
  3578.   End;
  3579.  
  3580.  
  3581. {                                                                              }
  3582. { TCardinalArray                                                               }
  3583. {                                                                              }
  3584. Procedure TCardinalArray.SetItem (const Idx : Integer; const Value : Cardinal);
  3585.   Begin
  3586.     {$IFOPT R+}
  3587.     if (Idx < 0) or (Idx >= FCount) then
  3588.       IndexError (Idx);
  3589.     {$ENDIF}
  3590.     FData [Idx] := Value;
  3591.   End;
  3592.  
  3593. Function TCardinalArray.GetItem (const Idx : Integer) : Cardinal;
  3594.   Begin
  3595.     {$IFOPT R+}
  3596.     if (Idx < 0) or (Idx >= FCount) then
  3597.       IndexError (Idx);
  3598.     {$ENDIF}
  3599.     Result := FData [Idx];
  3600.   End;
  3601.  
  3602. Function TCardinalArray.GetCount : Integer;
  3603.   Begin
  3604.     Result := FCount;
  3605.   End;
  3606.  
  3607. Procedure TCardinalArray.SetCount (const NewCount : Integer);
  3608. var L, N : Integer;
  3609.   Begin
  3610.     if FCount = NewCount then
  3611.       exit;
  3612.     FCount := NewCount;
  3613.  
  3614.     N := NewCount;
  3615.     L := Length (FData);
  3616.     if (N > 16) and (L > 0) then
  3617.       if N > L then
  3618.         N := N + N shr 3 else
  3619.       if N > L shr 1 then
  3620.         exit;
  3621.  
  3622.     if N <> L then
  3623.       SetLengthAndZero (FData, N);
  3624.   End;
  3625.  
  3626. Procedure TCardinalArray.Delete (const Idx : Integer; const Count : Integer = 1);
  3627.   Begin
  3628.     FCount := MaxI (FCount - Remove (FData, Idx, Count), 0);
  3629.     if FCount = 0 then
  3630.       FData := nil;
  3631.   End;
  3632.  
  3633. Procedure TCardinalArray.Insert (const Idx : Integer; const Count : Integer = 1);
  3634. var I : Integer;
  3635.   Begin
  3636.     I := ArrayInsert (FData, Idx, Count);
  3637.     if I >= 0 then
  3638.       Inc (FCount, Count);
  3639.   End;
  3640.  
  3641. Function TCardinalArray.GetRange (const LoIdx, HiIdx : Integer) : CardinalArray;
  3642. var L, H : Integer;
  3643.   Begin
  3644.     L := MaxI (0, LoIdx);
  3645.     H := MinI (HiIdx, FCount);
  3646.     if H >= L then
  3647.       Result := Copy (FData, L, H - L + 1) else
  3648.       Result := nil;
  3649.   End;
  3650.  
  3651. Procedure TCardinalArray.SetRange (const LoIdx, HiIdx : Integer; const V : CardinalArray);
  3652. var L, H, C : Integer;
  3653.   Begin
  3654.     L := MaxI (0, LoIdx);
  3655.     H := MinI (HiIdx, FCount);
  3656.     C := MaxI (MinI (Length (V), H - L + 1), 0);
  3657.     if C > 0 then
  3658.       Move (V [0], FData [L], C * Sizeof (Cardinal));
  3659.   End;
  3660.  
  3661. Constructor TCardinalArray.Create (const V : CardinalArray);
  3662.   Begin
  3663.     inherited Create;
  3664.     SetData (V);
  3665.   End;
  3666.  
  3667. class Function TCardinalArray.CreateInstance : AType;
  3668.   Begin
  3669.     Result := TCardinalArray.Create;
  3670.   End;
  3671.  
  3672. Procedure TCardinalArray.SetData (const Data : CardinalArray);
  3673.   Begin
  3674.     FData := Data;
  3675.     FCount := Length (FData);
  3676.   End;
  3677.  
  3678. Function TCardinalArray.DuplicateRange (const LoIdx, HiIdx : Integer) : AArray;
  3679. var L, H, C : Integer;
  3680.   Begin
  3681.     L := MaxI (0, LoIdx);
  3682.     H := MinI (HiIdx, FCount);
  3683.     C := MaxI (0, H - L + 1);
  3684.     Result := CreateInstance as TCardinalArray;
  3685.     TCardinalArray (Result).FCount := C;
  3686.     if C > 0 then
  3687.       TCardinalArray (Result).FData := Copy (FData, L, C);
  3688.   End;
  3689.  
  3690. Procedure TCardinalArray.Assign (const V : CardinalArray);
  3691.   Begin
  3692.     FData := Copy (V);
  3693.     FCount := Length (FData);
  3694.   End;
  3695.  
  3696. Procedure TCardinalArray.Assign (const V : array of Cardinal);
  3697.   Begin
  3698.     FData := AsCardinalArray (V);
  3699.     FCount := Length (FData);
  3700.   End;
  3701.  
  3702. Procedure TCardinalArray.Assign (const Source : TObject);
  3703.   Begin
  3704.     if Source is TCardinalArray then
  3705.       begin
  3706.         FCount := TCardinalArray (Source).FCount;
  3707.         FData := Copy (TCardinalArray (Source).FData, 0, FCount);
  3708.       end else
  3709.       inherited Assign (Source);
  3710.   End;
  3711.  
  3712.  
  3713. {                                                                              }
  3714. { TInt64Array                                                                  }
  3715. {                                                                              }
  3716. Procedure TInt64Array.SetItem (const Idx : Integer; const Value : Int64);
  3717.   Begin
  3718.     {$IFOPT R+}
  3719.     if (Idx < 0) or (Idx >= FCount) then
  3720.       IndexError (Idx);
  3721.     {$ENDIF}
  3722.     FData [Idx] := Value;
  3723.   End;
  3724.  
  3725. Function TInt64Array.GetItem (const Idx : Integer) : Int64;
  3726.   Begin
  3727.     {$IFOPT R+}
  3728.     if (Idx < 0) or (Idx >= FCount) then
  3729.       IndexError (Idx);
  3730.     {$ENDIF}
  3731.     Result := FData [Idx];
  3732.   End;
  3733.  
  3734. Function TInt64Array.GetCount : Integer;
  3735.   Begin
  3736.     Result := FCount;
  3737.   End;
  3738.  
  3739. Procedure TInt64Array.SetCount (const NewCount : Integer);
  3740. var L, N : Integer;
  3741.   Begin
  3742.     if FCount = NewCount then
  3743.       exit;
  3744.     FCount := NewCount;
  3745.  
  3746.     N := NewCount;
  3747.     L := Length (FData);
  3748.     if (N > 16) and (L > 0) then
  3749.       if N > L then
  3750.         N := N + N shr 3 else
  3751.       if N > L shr 1 then
  3752.         exit;
  3753.  
  3754.     if N <> L then
  3755.       SetLengthAndZero (FData, N);
  3756.   End;
  3757.  
  3758. Procedure TInt64Array.Delete (const Idx : Integer; const Count : Integer = 1);
  3759.   Begin
  3760.     FCount := MaxI (FCount - Remove (FData, Idx, Count), 0);
  3761.     if FCount = 0 then
  3762.       FData := nil;
  3763.   End;
  3764.  
  3765. Procedure TInt64Array.Insert (const Idx : Integer; const Count : Integer = 1);
  3766. var I : Integer;
  3767.   Begin
  3768.     I := ArrayInsert (FData, Idx, Count);
  3769.     if I >= 0 then
  3770.       Inc (FCount, Count);
  3771.   End;
  3772.  
  3773. Function TInt64Array.GetRange (const LoIdx, HiIdx : Integer) : Int64Array;
  3774. var L, H : Integer;
  3775.   Begin
  3776.     L := MaxI (0, LoIdx);
  3777.     H := MinI (HiIdx, FCount);
  3778.     if H >= L then
  3779.       Result := Copy (FData, L, H - L + 1) else
  3780.       Result := nil;
  3781.   End;
  3782.  
  3783. Procedure TInt64Array.SetRange (const LoIdx, HiIdx : Integer; const V : Int64Array);
  3784. var L, H, C : Integer;
  3785.   Begin
  3786.     L := MaxI (0, LoIdx);
  3787.     H := MinI (HiIdx, FCount);
  3788.     C := MaxI (MinI (Length (V), H - L + 1), 0);
  3789.     if C > 0 then
  3790.       Move (V [0], FData [L], C * Sizeof (Int64));
  3791.   End;
  3792.  
  3793. Constructor TInt64Array.Create (const V : Int64Array);
  3794.   Begin
  3795.     inherited Create;
  3796.     SetData (V);
  3797.   End;
  3798.  
  3799. class Function TInt64Array.CreateInstance : AType;
  3800.   Begin
  3801.     Result := TInt64Array.Create;
  3802.   End;
  3803.  
  3804. Procedure TInt64Array.SetData (const Data : Int64Array);
  3805.   Begin
  3806.     FData := Data;
  3807.     FCount := Length (FData);
  3808.   End;
  3809.  
  3810. Function TInt64Array.DuplicateRange (const LoIdx, HiIdx : Integer) : AArray;
  3811. var L, H, C : Integer;
  3812.   Begin
  3813.     L := MaxI (0, LoIdx);
  3814.     H := MinI (HiIdx, FCount);
  3815.     C := MaxI (0, H - L + 1);
  3816.     Result := CreateInstance as TInt64Array;
  3817.     TInt64Array (Result).FCount := C;
  3818.     if C > 0 then
  3819.       TInt64Array (Result).FData := Copy (FData, L, C);
  3820.   End;
  3821.  
  3822. Procedure TInt64Array.Assign (const V : Int64Array);
  3823.   Begin
  3824.     FData := Copy (V);
  3825.     FCount := Length (FData);
  3826.   End;
  3827.  
  3828. Procedure TInt64Array.Assign (const V : array of Int64);
  3829.   Begin
  3830.     FData := AsInt64Array (V);
  3831.     FCount := Length (FData);
  3832.   End;
  3833.  
  3834. Procedure TInt64Array.Assign (const Source : TObject);
  3835.   Begin
  3836.     if Source is TInt64Array then
  3837.       begin
  3838.         FCount := TInt64Array (Source).FCount;
  3839.         FData := Copy (TInt64Array (Source).FData, 0, FCount);
  3840.       end else
  3841.       inherited Assign (Source);
  3842.   End;
  3843.  
  3844.  
  3845. {                                                                              }
  3846. { TSingleArray                                                                 }
  3847. {                                                                              }
  3848. Procedure TSingleArray.SetItem (const Idx : Integer; const Value : Single);
  3849.   Begin
  3850.     {$IFOPT R+}
  3851.     if (Idx < 0) or (Idx >= FCount) then
  3852.       IndexError (Idx);
  3853.     {$ENDIF}
  3854.     FData [Idx] := Value;
  3855.   End;
  3856.  
  3857. Function TSingleArray.GetItem (const Idx : Integer) : Single;
  3858.   Begin
  3859.     {$IFOPT R+}
  3860.     if (Idx < 0) or (Idx >= FCount) then
  3861.       IndexError (Idx);
  3862.     {$ENDIF}
  3863.     Result := FData [Idx];
  3864.   End;
  3865.  
  3866. Function TSingleArray.GetCount : Integer;
  3867.   Begin
  3868.     Result := FCount;
  3869.   End;
  3870.  
  3871. Procedure TSingleArray.SetCount (const NewCount : Integer);
  3872. var L, N : Integer;
  3873.   Begin
  3874.     if FCount = NewCount then
  3875.       exit;
  3876.     FCount := NewCount;
  3877.  
  3878.     N := NewCount;
  3879.     L := Length (FData);
  3880.     if (N > 16) and (L > 0) then
  3881.       if N > L then
  3882.         N := N + N shr 3 else
  3883.       if N > L shr 1 then
  3884.         exit;
  3885.  
  3886.     if N <> L then
  3887.       SetLengthAndZero (FData, N);
  3888.   End;
  3889.  
  3890. Procedure TSingleArray.Delete (const Idx : Integer; const Count : Integer = 1);
  3891.   Begin
  3892.     FCount := MaxI (FCount - Remove (FData, Idx, Count), 0);
  3893.     if FCount = 0 then
  3894.       FData := nil;
  3895.   End;
  3896.  
  3897. Procedure TSingleArray.Insert (const Idx : Integer; const Count : Integer = 1);
  3898. var I : Integer;
  3899.   Begin
  3900.     I := ArrayInsert (FData, Idx, Count);
  3901.     if I >= 0 then
  3902.       Inc (FCount, Count);
  3903.   End;
  3904.  
  3905. Function TSingleArray.GetRange (const LoIdx, HiIdx : Integer) : SingleArray;
  3906. var L, H : Integer;
  3907.   Begin
  3908.     L := MaxI (0, LoIdx);
  3909.     H := MinI (HiIdx, FCount);
  3910.     if H >= L then
  3911.       Result := Copy (FData, L, H - L + 1) else
  3912.       Result := nil;
  3913.   End;
  3914.  
  3915. Procedure TSingleArray.SetRange (const LoIdx, HiIdx : Integer; const V : SingleArray);
  3916. var L, H, C : Integer;
  3917.   Begin
  3918.     L := MaxI (0, LoIdx);
  3919.     H := MinI (HiIdx, FCount);
  3920.     C := MaxI (MinI (Length (V), H - L + 1), 0);
  3921.     if C > 0 then
  3922.       Move (V [0], FData [L], C * Sizeof (Single));
  3923.   End;
  3924.  
  3925. Constructor TSingleArray.Create (const V : SingleArray);
  3926.   Begin
  3927.     inherited Create;
  3928.     SetData (V);
  3929.   End;
  3930.  
  3931. class Function TSingleArray.CreateInstance : AType;
  3932.   Begin
  3933.     Result := TSingleArray.Create;
  3934.   End;
  3935.  
  3936. Procedure TSingleArray.SetData (const Data : SingleArray);
  3937.   Begin
  3938.     FData := Data;
  3939.     FCount := Length (FData);
  3940.   End;
  3941.  
  3942. Function TSingleArray.DuplicateRange (const LoIdx, HiIdx : Integer) : AArray;
  3943. var L, H, C : Integer;
  3944.   Begin
  3945.     L := MaxI (0, LoIdx);
  3946.     H := MinI (HiIdx, FCount);
  3947.     C := MaxI (0, H - L + 1);
  3948.     Result := CreateInstance as TSingleArray;
  3949.     TSingleArray (Result).FCount := C;
  3950.     if C > 0 then
  3951.       TSingleArray (Result).FData := Copy (FData, L, C);
  3952.   End;
  3953.  
  3954. Procedure TSingleArray.Assign (const V : SingleArray);
  3955.   Begin
  3956.     FData := Copy (V);
  3957.     FCount := Length (FData);
  3958.   End;
  3959.  
  3960. Procedure TSingleArray.Assign (const V : array of Single);
  3961.   Begin
  3962.     FData := AsSingleArray (V);
  3963.     FCount := Length (FData);
  3964.   End;
  3965.  
  3966. Procedure TSingleArray.Assign (const Source : TObject);
  3967.   Begin
  3968.     if Source is TSingleArray then
  3969.       begin
  3970.         FCount := TSingleArray (Source).FCount;
  3971.         FData := Copy (TSingleArray (Source).FData, 0, FCount);
  3972.       end else
  3973.       inherited Assign (Source);
  3974.   End;
  3975.  
  3976.  
  3977. {                                                                              }
  3978. { TDoubleArray                                                                 }
  3979. {                                                                              }
  3980. Procedure TDoubleArray.SetItem (const Idx : Integer; const Value : Double);
  3981.   Begin
  3982.     {$IFOPT R+}
  3983.     if (Idx < 0) or (Idx >= FCount) then
  3984.       IndexError (Idx);
  3985.     {$ENDIF}
  3986.     FData [Idx] := Value;
  3987.   End;
  3988.  
  3989. Function TDoubleArray.GetItem (const Idx : Integer) : Double;
  3990.   Begin
  3991.     {$IFOPT R+}
  3992.     if (Idx < 0) or (Idx >= FCount) then
  3993.       IndexError (Idx);
  3994.     {$ENDIF}
  3995.     Result := FData [Idx];
  3996.   End;
  3997.  
  3998. Function TDoubleArray.GetCount : Integer;
  3999.   Begin
  4000.     Result := FCount;
  4001.   End;
  4002.  
  4003. Procedure TDoubleArray.SetCount (const NewCount : Integer);
  4004. var L, N : Integer;
  4005.   Begin
  4006.     if FCount = NewCount then
  4007.       exit;
  4008.     FCount := NewCount;
  4009.  
  4010.     N := NewCount;
  4011.     L := Length (FData);
  4012.     if (N > 16) and (L > 0) then
  4013.       if N > L then
  4014.         N := N + N shr 3 else
  4015.       if N > L shr 1 then
  4016.         exit;
  4017.  
  4018.     if N <> L then
  4019.       SetLengthAndZero (FData, N);
  4020.   End;
  4021.  
  4022. Procedure TDoubleArray.Delete (const Idx : Integer; const Count : Integer = 1);
  4023.   Begin
  4024.     FCount := MaxI (FCount - Remove (FData, Idx, Count), 0);
  4025.     if FCount = 0 then
  4026.       FData := nil;
  4027.   End;
  4028.  
  4029. Procedure TDoubleArray.Insert (const Idx : Integer; const Count : Integer = 1);
  4030. var I : Integer;
  4031.   Begin
  4032.     I := ArrayInsert (FData, Idx, Count);
  4033.     if I >= 0 then
  4034.       Inc (FCount, Count);
  4035.   End;
  4036.  
  4037. Function TDoubleArray.GetRange (const LoIdx, HiIdx : Integer) : DoubleArray;
  4038. var L, H : Integer;
  4039.   Begin
  4040.     L := MaxI (0, LoIdx);
  4041.     H := MinI (HiIdx, FCount);
  4042.     if H >= L then
  4043.       Result := Copy (FData, L, H - L + 1) else
  4044.       Result := nil;
  4045.   End;
  4046.  
  4047. Procedure TDoubleArray.SetRange (const LoIdx, HiIdx : Integer; const V : DoubleArray);
  4048. var L, H, C : Integer;
  4049.   Begin
  4050.     L := MaxI (0, LoIdx);
  4051.     H := MinI (HiIdx, FCount);
  4052.     C := MaxI (MinI (Length (V), H - L + 1), 0);
  4053.     if C > 0 then
  4054.       Move (V [0], FData [L], C * Sizeof (Double));
  4055.   End;
  4056.  
  4057. Constructor TDoubleArray.Create (const V : DoubleArray);
  4058.   Begin
  4059.     inherited Create;
  4060.     SetData (V);
  4061.   End;
  4062.  
  4063. class Function TDoubleArray.CreateInstance : AType;
  4064.   Begin
  4065.     Result := TDoubleArray.Create;
  4066.   End;
  4067.  
  4068. Procedure TDoubleArray.SetData (const Data : DoubleArray);
  4069.   Begin
  4070.     FData := Data;
  4071.     FCount := Length (FData);
  4072.   End;
  4073.  
  4074. Function TDoubleArray.DuplicateRange (const LoIdx, HiIdx : Integer) : AArray;
  4075. var L, H, C : Integer;
  4076.   Begin
  4077.     L := MaxI (0, LoIdx);
  4078.     H := MinI (HiIdx, FCount);
  4079.     C := MaxI (0, H - L + 1);
  4080.     Result := CreateInstance as TDoubleArray;
  4081.     TDoubleArray (Result).FCount := C;
  4082.     if C > 0 then
  4083.       TDoubleArray (Result).FData := Copy (FData, L, C);
  4084.   End;
  4085.  
  4086. Procedure TDoubleArray.Assign (const V : DoubleArray);
  4087.   Begin
  4088.     FData := Copy (V);
  4089.     FCount := Length (FData);
  4090.   End;
  4091.  
  4092. Procedure TDoubleArray.Assign (const V : array of Double);
  4093.   Begin
  4094.     FData := AsDoubleArray (V);
  4095.     FCount := Length (FData);
  4096.   End;
  4097.  
  4098. Procedure TDoubleArray.Assign (const Source : TObject);
  4099.   Begin
  4100.     if Source is TDoubleArray then
  4101.       begin
  4102.         FCount := TDoubleArray (Source).FCount;
  4103.         FData := Copy (TDoubleArray (Source).FData, 0, FCount);
  4104.       end else
  4105.       inherited Assign (Source);
  4106.   End;
  4107.  
  4108.  
  4109. {                                                                              }
  4110. { TExtendedArray                                                               }
  4111. {                                                                              }
  4112. Procedure TExtendedArray.SetItem (const Idx : Integer; const Value : Extended);
  4113.   Begin
  4114.     {$IFOPT R+}
  4115.     if (Idx < 0) or (Idx >= FCount) then
  4116.       IndexError (Idx);
  4117.     {$ENDIF}
  4118.     FData [Idx] := Value;
  4119.   End;
  4120.  
  4121. Function TExtendedArray.GetItem (const Idx : Integer) : Extended;
  4122.   Begin
  4123.     {$IFOPT R+}
  4124.     if (Idx < 0) or (Idx >= FCount) then
  4125.       IndexError (Idx);
  4126.     {$ENDIF}
  4127.     Result := FData [Idx];
  4128.   End;
  4129.  
  4130. Function TExtendedArray.GetCount : Integer;
  4131.   Begin
  4132.     Result := FCount;
  4133.   End;
  4134.  
  4135. Procedure TExtendedArray.SetCount (const NewCount : Integer);
  4136. var L, N : Integer;
  4137.   Begin
  4138.     if FCount = NewCount then
  4139.       exit;
  4140.     FCount := NewCount;
  4141.  
  4142.     N := NewCount;
  4143.     L := Length (FData);
  4144.     if (N > 16) and (L > 0) then
  4145.       if N > L then
  4146.         N := N + N shr 3 else
  4147.       if N > L shr 1 then
  4148.         exit;
  4149.  
  4150.     if N <> L then
  4151.       SetLengthAndZero (FData, N);
  4152.   End;
  4153.  
  4154. Procedure TExtendedArray.Delete (const Idx : Integer; const Count : Integer = 1);
  4155.   Begin
  4156.     FCount := MaxI (FCount - Remove (FData, Idx, Count), 0);
  4157.     if FCount = 0 then
  4158.       FData := nil;
  4159.   End;
  4160.  
  4161. Procedure TExtendedArray.Insert (const Idx : Integer; const Count : Integer = 1);
  4162. var I : Integer;
  4163.   Begin
  4164.     I := ArrayInsert (FData, Idx, Count);
  4165.     if I >= 0 then
  4166.       Inc (FCount, Count);
  4167.   End;
  4168.  
  4169. Function TExtendedArray.GetRange (const LoIdx, HiIdx : Integer) : ExtendedArray;
  4170. var L, H : Integer;
  4171.   Begin
  4172.     L := MaxI (0, LoIdx);
  4173.     H := MinI (HiIdx, FCount);
  4174.     if H >= L then
  4175.       Result := Copy (FData, L, H - L + 1) else
  4176.       Result := nil;
  4177.   End;
  4178.  
  4179. Procedure TExtendedArray.SetRange (const LoIdx, HiIdx : Integer; const V : ExtendedArray);
  4180. var L, H, C : Integer;
  4181.   Begin
  4182.     L := MaxI (0, LoIdx);
  4183.     H := MinI (HiIdx, FCount);
  4184.     C := MaxI (MinI (Length (V), H - L + 1), 0);
  4185.     if C > 0 then
  4186.       Move (V [0], FData [L], C * Sizeof (Extended));
  4187.   End;
  4188.  
  4189. Constructor TExtendedArray.Create (const V : ExtendedArray);
  4190.   Begin
  4191.     inherited Create;
  4192.     SetData (V);
  4193.   End;
  4194.  
  4195. class Function TExtendedArray.CreateInstance : AType;
  4196.   Begin
  4197.     Result := TExtendedArray.Create;
  4198.   End;
  4199.  
  4200. Procedure TExtendedArray.SetData (const Data : ExtendedArray);
  4201.   Begin
  4202.     FData := Data;
  4203.     FCount := Length (FData);
  4204.   End;
  4205.  
  4206. Function TExtendedArray.DuplicateRange (const LoIdx, HiIdx : Integer) : AArray;
  4207. var L, H, C : Integer;
  4208.   Begin
  4209.     L := MaxI (0, LoIdx);
  4210.     H := MinI (HiIdx, FCount);
  4211.     C := MaxI (0, H - L + 1);
  4212.     Result := CreateInstance as TExtendedArray;
  4213.     TExtendedArray (Result).FCount := C;
  4214.     if C > 0 then
  4215.       TExtendedArray (Result).FData := Copy (FData, L, C);
  4216.   End;
  4217.  
  4218. Procedure TExtendedArray.Assign (const V : ExtendedArray);
  4219.   Begin
  4220.     FData := Copy (V);
  4221.     FCount := Length (FData);
  4222.   End;
  4223.  
  4224. Procedure TExtendedArray.Assign (const V : array of Extended);
  4225.   Begin
  4226.     FData := AsExtendedArray (V);
  4227.     FCount := Length (FData);
  4228.   End;
  4229.  
  4230. Procedure TExtendedArray.Assign (const Source : TObject);
  4231.   Begin
  4232.     if Source is TExtendedArray then
  4233.       begin
  4234.         FCount := TExtendedArray (Source).FCount;
  4235.         FData := Copy (TExtendedArray (Source).FData, 0, FCount);
  4236.       end else
  4237.       inherited Assign (Source);
  4238.   End;
  4239.  
  4240.  
  4241. {                                                                              }
  4242. { TStringArray                                                                 }
  4243. {                                                                              }
  4244. Procedure TStringArray.SetItem (const Idx : Integer; const Value : String);
  4245.   Begin
  4246.     {$IFOPT R+}
  4247.     if (Idx < 0) or (Idx >= FCount) then
  4248.       IndexError (Idx);
  4249.     {$ENDIF}
  4250.     FData [Idx] := Value;
  4251.   End;
  4252.  
  4253. Function TStringArray.GetItem (const Idx : Integer) : String;
  4254.   Begin
  4255.     {$IFOPT R+}
  4256.     if (Idx < 0) or (Idx >= FCount) then
  4257.       IndexError (Idx);
  4258.     {$ENDIF}
  4259.     Result := FData [Idx];
  4260.   End;
  4261.  
  4262. Function TStringArray.GetCount : Integer;
  4263.   Begin
  4264.     Result := FCount;
  4265.   End;
  4266.  
  4267. Procedure TStringArray.SetCount (const NewCount : Integer);
  4268. var L, N : Integer;
  4269.   Begin
  4270.     if FCount = NewCount then
  4271.       exit;
  4272.     FCount := NewCount;
  4273.  
  4274.     N := NewCount;
  4275.     L := Length (FData);
  4276.     if (N > 16) and (L > 0) then
  4277.       if N > L then
  4278.         N := N + N shr 3 else
  4279.       if N > L shr 1 then
  4280.         exit;
  4281.  
  4282.     if N <> L then
  4283.       SetLength (FData, N);
  4284.   End;
  4285.  
  4286. Procedure TStringArray.Delete (const Idx : Integer; const Count : Integer = 1);
  4287.   Begin
  4288.     FCount := MaxI (FCount - Remove (FData, Idx, Count), 0);
  4289.     if FCount = 0 then
  4290.       FData := nil;
  4291.   End;
  4292.  
  4293. Procedure TStringArray.Insert (const Idx : Integer; const Count : Integer = 1);
  4294. var I : Integer;
  4295.   Begin
  4296.     I := ArrayInsert (FData, Idx, Count);
  4297.     if I >= 0 then
  4298.       Inc (FCount, Count);
  4299.   End;
  4300.  
  4301. Function TStringArray.GetRange (const LoIdx, HiIdx : Integer) : StringArray;
  4302. var L, H : Integer;
  4303.   Begin
  4304.     L := MaxI (0, LoIdx);
  4305.     H := MinI (HiIdx, FCount);
  4306.     if H >= L then
  4307.       Result := Copy (FData, L, H - L + 1) else
  4308.       Result := nil;
  4309.   End;
  4310.  
  4311. Procedure TStringArray.SetRange (const LoIdx, HiIdx : Integer; const V : StringArray);
  4312. var L, H, C : Integer;
  4313.   Begin
  4314.     L := MaxI (0, LoIdx);
  4315.     H := MinI (HiIdx, FCount);
  4316.     C := MaxI (MinI (Length (V), H - L + 1), 0);
  4317.     if C > 0 then
  4318.       Move (V [0], FData [L], C * Sizeof (String));
  4319.   End;
  4320.  
  4321. Constructor TStringArray.Create (const V : StringArray);
  4322.   Begin
  4323.     inherited Create;
  4324.     SetData (V);
  4325.   End;
  4326.  
  4327. class Function TStringArray.CreateInstance : AType;
  4328.   Begin
  4329.     Result := TStringArray.Create;
  4330.   End;
  4331.  
  4332. Procedure TStringArray.SetData (const Data : StringArray);
  4333.   Begin
  4334.     FData := Data;
  4335.     FCount := Length (FData);
  4336.   End;
  4337.  
  4338. Function TStringArray.DuplicateRange (const LoIdx, HiIdx : Integer) : AArray;
  4339. var L, H, C : Integer;
  4340.   Begin
  4341.     L := MaxI (0, LoIdx);
  4342.     H := MinI (HiIdx, FCount);
  4343.     C := MaxI (0, H - L + 1);
  4344.     Result := CreateInstance as TStringArray;
  4345.     TStringArray (Result).FCount := C;
  4346.     if C > 0 then
  4347.       TStringArray (Result).FData := Copy (FData, L, C);
  4348.   End;
  4349.  
  4350. Procedure TStringArray.Assign (const V : StringArray);
  4351.   Begin
  4352.     FData := Copy (V);
  4353.     FCount := Length (FData);
  4354.   End;
  4355.  
  4356. Procedure TStringArray.Assign (const V : array of String);
  4357.   Begin
  4358.     FData := AsStringArray (V);
  4359.     FCount := Length (FData);
  4360.   End;
  4361.  
  4362. Procedure TStringArray.Assign (const Source : TObject);
  4363.   Begin
  4364.     if Source is TStringArray then
  4365.       begin
  4366.         FCount := TStringArray (Source).FCount;
  4367.         FData := Copy (TStringArray (Source).FData, 0, FCount);
  4368.       end else
  4369.       inherited Assign (Source);
  4370.   End;
  4371.  
  4372.  
  4373.  
  4374.  
  4375. {                                                                              }
  4376. { TObjectArray                                                                 }
  4377. {                                                                              }
  4378. Procedure TObjectArray.FreeItems;
  4379.   Begin
  4380.     FreeObjectArray (FData);
  4381.     FData := nil;
  4382.     FCount := 0;
  4383.   End;
  4384.  
  4385. Procedure TObjectArray.ReleaseItems;
  4386.   Begin
  4387.     FData := nil;
  4388.     FCount := 0;
  4389.   End;
  4390.  
  4391. Function TObjectArray.GetIsItemOwner : Boolean;
  4392.   Begin
  4393.     Result := FIsItemOwner;
  4394.   End;
  4395.  
  4396. Procedure TObjectArray.SetIsItemOwner (const IsItemOwner : Boolean);
  4397.   Begin
  4398.     FIsItemOwner := IsItemOwner;
  4399.   End;
  4400.  
  4401. Procedure TObjectArray.SetItem (const Idx : Integer; const Value : TObject);
  4402. var V : TObject;
  4403.   Begin
  4404.     {$IFOPT R+}
  4405.     if (Idx < 0) or (Idx >= FCount) then
  4406.       IndexError (Idx);
  4407.     {$ENDIF}
  4408.     if FIsItemOwner then
  4409.       begin
  4410.         V := FData [Idx];
  4411.         if V = Value then
  4412.           exit;
  4413.         FreeAndNil (V);
  4414.       end;
  4415.     FData [Idx] := Value;
  4416.   End;
  4417.  
  4418. Function TObjectArray.GetItem (const Idx : Integer) : TObject;
  4419.   Begin
  4420.     {$IFOPT R+}
  4421.     if (Idx < 0) or (Idx >= FCount) then
  4422.       IndexError (Idx);
  4423.     {$ENDIF}
  4424.     Result := FData [Idx];
  4425.   End;
  4426.  
  4427. Function TObjectArray.ReleaseItem (const Idx : Integer) : TObject;
  4428.   Begin
  4429.     {$IFOPT R+}
  4430.     if (Idx < 0) or (Idx >= FCount) then
  4431.       IndexError (Idx);
  4432.     {$ENDIF}
  4433.     Result := FData [Idx];
  4434.     if Assigned (Result) and FIsItemOwner then
  4435.       FData [Idx] := nil;
  4436.   End;
  4437.  
  4438. Function TObjectArray.GetCount : Integer;
  4439.   Begin
  4440.     Result := FCount;
  4441.   End;
  4442.  
  4443. Procedure TObjectArray.SetCount (const NewCount : Integer);
  4444. var L, N : Integer;
  4445.   Begin
  4446.     if NewCount = FCount then
  4447.       exit;
  4448.  
  4449.     if (NewCount < FCount) and FIsItemOwner then
  4450.       FreeObjectArray (FData, NewCount, FCount - 1);
  4451.     FCount := NewCount;
  4452.  
  4453.     L := Length (FData);
  4454.     N := NewCount;
  4455.     if (N > 16) and (L > 0) then
  4456.       if N > L then
  4457.         N := N + N shr 3 else
  4458.       if N > L shr 1 then
  4459.         exit;
  4460.  
  4461.     if N <> L then
  4462.       SetLengthAndZero (FData, N);
  4463.   End;
  4464.  
  4465. Function TObjectArray.GetRange (const LoIdx, HiIdx : Integer) : ObjectArray;
  4466.   Begin
  4467.     Result := Copy (FData, LoIdx, MinI (HiIdx, FCount - 1) - LoIdx + 1);
  4468.   End;
  4469.  
  4470. Procedure TObjectArray.SetData (const Data : ObjectArray);
  4471.   Begin
  4472.     if FIsItemOwner then
  4473.       FreeItems;
  4474.     FData := Data;
  4475.     FCount := Length (FData);
  4476.   End;
  4477.  
  4478. Constructor TObjectArray.Create (const V : ObjectArray; const IsItemOwner : Boolean);
  4479.   Begin
  4480.     inherited Create;
  4481.     FData := V;
  4482.     FIsItemOwner := IsItemOwner;
  4483.     FCount := Length (FData);
  4484.   End;
  4485.  
  4486. class Function TObjectArray.CreateInstance : AType;
  4487.   Begin
  4488.     Result := TObjectArray.Create;
  4489.   End;
  4490.  
  4491. Destructor TObjectArray.Destroy;
  4492.   Begin
  4493.     if FIsItemOwner then
  4494.       FreeItems;
  4495.     inherited Destroy;
  4496.   End;
  4497.  
  4498. Function TObjectArray.DuplicateRange (const LoIdx, HiIdx : Integer) : AArray;
  4499. var I : Integer;
  4500.     V : TObject;
  4501.   Begin
  4502.     Result := CreateInstance as TObjectArray;
  4503.     For I := LoIdx to MinI (HiIdx, FCount - 1) do
  4504.       begin
  4505.         V := FData [I];
  4506.         if V is AType then
  4507.           V := AType (V).Duplicate;
  4508.         TObjectArray (Result).AddItem (V);
  4509.       end;
  4510.   End;
  4511.  
  4512. Procedure TObjectArray.Delete (const Idx : Integer; const Count : Integer = 1);
  4513.   Begin
  4514.     FCount := MaxI (FCount - Remove (FData, Idx, Count, FIsItemOwner), 0);
  4515.     if FCount = 0 then
  4516.       FData := nil;
  4517.   End;
  4518.  
  4519. Procedure TObjectArray.Insert (const Idx : Integer; const Count : Integer = 1);
  4520. var I : Integer;
  4521.   Begin
  4522.     I := ArrayInsert (FData, Idx, Count);
  4523.     if I >= 0 then
  4524.       Inc (FCount, Count);
  4525.   End;
  4526.  
  4527.  
  4528.  
  4529. {                                                                              }
  4530. { TFlatBitArray                                                                }
  4531. {                                                                              }
  4532. const
  4533.   TrueLongWord  : LongWord = $FFFFFFFF;
  4534.   FalseLongWord : LongWord = $00000000;
  4535.  
  4536. class Function TFlatBitArray.CreateInstance : AType;
  4537.   Begin
  4538.     Result := TFlatBitArray.Create;
  4539.   End;
  4540.  
  4541. Function TFlatBitArray.GetBit (const Idx : Integer) : Boolean;
  4542.   Begin
  4543.     {$IFOPT R+}
  4544.     if (Idx < 0) or (Idx >= FCount) then
  4545.       IndexError (Idx);
  4546.     {$ENDIF}
  4547.     Result := cUtils.IsBitSet (FData [Idx shr 5], Idx and 31);
  4548.   End;
  4549.  
  4550. Procedure TFlatBitArray.SetBit (const Idx : Integer; const Value : Boolean);
  4551. var L : ^LongWord;
  4552.   Begin
  4553.     {$IFOPT R+}
  4554.     if (Idx < 0) or (Idx >= FCount) then
  4555.       IndexError (Idx);
  4556.     {$ENDIF}
  4557.     L := @FData [Idx shr 5];
  4558.     if Value then
  4559.       L^ := cUtils.SetBit (L^, Idx and 31) else
  4560.       L^ := cUtils.ClearBit (L^, Idx and 31);
  4561.   End;
  4562.  
  4563. Function TFlatBitArray.GetCount : Integer;
  4564.   Begin
  4565.     Result := FCount;
  4566.   End;
  4567.  
  4568. Procedure TFlatBitArray.SetCount (const NewCount : Integer);
  4569.   Begin
  4570.     if NewCount = FCount then
  4571.       exit;
  4572.     SetLengthAndZero (FData, (NewCount + BitsPerLongWord - 1) div BitsPerLongWord);
  4573.     FCount := NewCount;
  4574.   End;
  4575.  
  4576. Function TFlatBitArray.GetRange (const Idx : Integer) : LongWord;
  4577. var F : Byte;
  4578.     I : Integer;
  4579.   Begin
  4580.     {$IFOPT R+}
  4581.     if (Idx < 0) or (Idx >= FCount) then
  4582.       IndexError (Idx);
  4583.     {$ENDIF}
  4584.     F := Idx and 31;
  4585.     I := Idx shr 5;
  4586.     if F = 0 then
  4587.       Result := FData [I] else
  4588.       begin
  4589.         Result := FData [I] shr F;
  4590.         if I + 1 < Length (FData) then
  4591.           Result := Result or (FData [I + 1] shl (BitsPerLongWord - F));
  4592.       end;
  4593.   End;
  4594.  
  4595. Procedure TFlatBitArray.SetRange (const Idx : Integer; const Value : LongWord);
  4596. var F : Byte;
  4597.     I : Integer;
  4598.   Begin
  4599.     {$IFOPT R+}
  4600.     if (Idx < 0) or (Idx >= FCount) then
  4601.       IndexError (Idx);
  4602.     {$ENDIF}
  4603.     F := Idx and 31;
  4604.     I := Idx shr 5;
  4605.     if F = 0 then
  4606.       FData [I] := Value else
  4607.       begin
  4608.         FData [I] := (FData [I] and LowBitMask (F))
  4609.                   or (Value shl F);
  4610.         if I + 1 < Length (FData) then
  4611.           FData [I + 1] := (FData [I + 1] and HighBitMask (F))
  4612.                         or (Value shr (BitsPerLongWord - F));
  4613.       end;
  4614.   End;
  4615.  
  4616. Function TFlatBitArray.CompareRange (const LoIdx, HiIdx : Integer; const Value : Boolean) : Boolean;
  4617. var B, I   : LongWord;
  4618.     IL, IH : Integer;
  4619.   Begin
  4620.     {$IFOPT R+}
  4621.     if (LoIdx < 0) or (LoIdx > HiIdx) or (HiIdx >= FCount) then
  4622.       IndexError (HiIdx);
  4623.     {$ENDIF}
  4624.  
  4625.     // Check bits in FData [IL]
  4626.     IL := LoIdx shr 5;
  4627.     IH := HiIdx shr 5;
  4628.     B := HighBitMask (LoIdx and 31);
  4629.     I := FData [IL];
  4630.     if Value then
  4631.       Result := I or B = I else
  4632.       Result := I and not B = I;
  4633.     if not Result or (IL = IH) then
  4634.       exit;
  4635.  
  4636.     // Check bits in FData [IH]
  4637.     B := LowBitMask (HiIdx and 31);
  4638.     I := FData [IH];
  4639.     if Value then
  4640.       Result := I or B = I else
  4641.       Result := I and not B = I;
  4642.     if not Result or (IH = IL + 1) then
  4643.       exit;
  4644.  
  4645.     // Check bits in FStore [IL + 1..IR - 1]
  4646.     For I := IL + 1 to IH - 1 do
  4647.       if (Value and (FData [I] <> TrueLongWord)) or
  4648.          (not Value and (FData [I] <> FalseLongWord)) then
  4649.         begin
  4650.           Result := False;
  4651.           exit;
  4652.         end;
  4653.  
  4654.     Result := True;
  4655.   End;
  4656.  
  4657. Procedure TFlatBitArray.Fill (const LoIdx, HiIdx : Integer; const Value : Boolean);
  4658. var B, I   : LongWord;
  4659.     IL, IH : Integer;
  4660.   Begin
  4661.     {$IFOPT R+}
  4662.     if (LoIdx < 0) or (LoIdx > HiIdx) or (HiIdx >= FCount) then
  4663.       IndexError (HiIdx);
  4664.     {$ENDIF}
  4665.  
  4666.     IL := LoIdx shr 5;
  4667.     IH := HiIdx shr 5;
  4668.  
  4669.     // Set bits in FData [IL]
  4670.     if IH = IL then
  4671.       B := RangeBitMask (LoIdx and 31, HiIdx and 31) else
  4672.       B := HighBitMask (LoIdx and 31);
  4673.     I := FData [IL];
  4674.     if Value then
  4675.       FData [IL] := I or B else
  4676.       FData [IL] := I and not B;
  4677.     if IH = IL then
  4678.       exit;
  4679.  
  4680.     // Set bits in FData [IH]
  4681.     B := LowBitMask (HiIdx and 31);
  4682.     I := FData [IH];
  4683.     if Value then
  4684.       FData [IH] := I or B else
  4685.       FData [IH] := I and not B;
  4686.     if IH = IL + 1 then
  4687.       exit;
  4688.  
  4689.     // Set bits in FData [IL + 1..IR - 1]
  4690.     For I := IL + 1 to IH - 1 do
  4691.       if Value then
  4692.         FData [I] := TrueLongWord else
  4693.         FData [I] := FalseLongWord;
  4694.   End;
  4695.  
  4696.  
  4697.   
  4698. {                                                                              }
  4699. { Self testing code                                                            }
  4700. {                                                                              }
  4701. Procedure SelfTest;
  4702. var I : Integer;
  4703.     F : TIntegerArray;
  4704.   Begin
  4705.     // TIntegerArray
  4706.     F := TIntegerArray.Create;
  4707.     For I := 0 to 16384 do
  4708.       Assert (F.AddItem (I) = I, 'Array.Add');
  4709.     Assert (F.Count = 16385, 'Array.Count');
  4710.     For I := 0 to 16384 do
  4711.       Assert (F [I] = I,     'Array.GetItem');
  4712.     For I := 0 to 16384 do
  4713.       F [I] := I + 1;
  4714.     For I := 0 to 16384 do
  4715.       Assert (F [I] = I + 1, 'Array.SetItem');
  4716.     F.Delete (0, 1);
  4717.     Assert (F.Count = 16384, 'Array.Delete');
  4718.     For I := 0 to 16383 do
  4719.       Assert (F [I] = I + 2, 'Array.Delete');
  4720.     F.Insert (0, 2);
  4721.     F [0] := 0;
  4722.     F [1] := 1;
  4723.     For I := 0 to 16384 do
  4724.       Assert (F [I] = I,     'Array.Insert');
  4725.     F.Count := 4;
  4726.     Assert (F.Count = 4,     'Array.SetCount');
  4727.     F [0] := 9;
  4728.     F [1] := -2;
  4729.     F [2] := 3;
  4730.     F [3] := 4;
  4731.     F.Sort;
  4732.     Assert (F [0] = -2,      'Array.Sort');
  4733.     Assert (F [1] = 3,       'Array.Sort');
  4734.     Assert (F [2] = 4,       'Array.Sort');
  4735.     Assert (F [3] = 9,       'Array.Sort');
  4736.     F.Clear;
  4737.     Assert (F.Count = 0,     'Array.Clear');
  4738.     F.Free;
  4739.   End;
  4740.  
  4741.  
  4742.  
  4743. end.
  4744.  
  4745.