Ignore:
Timestamp:
Sep 18, 2012, 10:52:19 AM (12 years ago)
Author:
chronos
Message:
  • Modified: Moved all general methods from TGList to TGAbstractList. TGList implements some methods with memory oriented optimizations.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Generics/NativeGenerics/Units/GenericList.pas

    r423 r424  
    2727    function GetCount: TIndex; virtual; abstract;
    2828    procedure SetCount(const AValue: TIndex); virtual; abstract;
    29     procedure SetCapacity(const AValue: TIndex); virtual; abstract;
    30     function GetCapacity: TIndex; virtual; abstract;
    3129    function Get(Index: TIndex): TItem; virtual; abstract;
    3230    procedure Put(Index: TIndex; const AValue: TItem); virtual; abstract;
     31    procedure QuickSort(L, R : TIndex; Compare: TSortCompare);
    3332  public
     33    function Add(const Item: TItem): TIndex; virtual;
     34    procedure AddArray(Values: array of TItem);
     35    procedure AddList(List: TGAbstractList<TItem>);
     36    procedure AddListPart(List: TGAbstractList<TItem>; ItemIndex, ItemCount: TIndex);
     37    procedure Assign(Source: TGAbstractList<TItem>); virtual;
    3438    constructor Create; virtual;
    3539    procedure Clear; virtual;
    36     function Add(const Item: TItem): TIndex; virtual;
     40    function CompareItem(const Item1, Item2: TItem): Boolean; virtual; abstract;
     41    procedure CopyItems(CurIndex, NewIndex, ACount: TIndex); virtual;
     42    procedure Delete(const Index: TIndex); virtual;
     43    procedure DeleteItems(const Index, ACount: TIndex); virtual;
     44    function EqualTo(List: TGAbstractList<TItem>): Boolean; virtual;
     45    procedure Exchange(const Index1, Index2: TIndex); virtual;
     46    procedure Explode(Text, Separator: string; Converter: TFromStringConverter; SlicesCount: Integer = -1);
     47    function Extract(Item: TItem): TItem; virtual;
     48    procedure Fill(Start, Count: TIndex; Value: TItem); virtual;
     49    function GetArray(Index, ACount: TIndex): TItemArray; virtual;
     50    procedure GetList(List: TGAbstractList<TItem>; Index, ACount: TIndex); virtual;
     51    function IndexOfList(List: TGAbstractList<TItem>; Start: TIndex = 0): TIndex; virtual;
     52    procedure Insert(const Index: TIndex; Item: TItem); virtual;
     53    procedure InsertCount(const Index: TIndex; ACount: TIndex); virtual;
     54    procedure InsertList(const Index: TIndex; List: TGAbstractList<TItem>); virtual;
     55    procedure InsertArray(const Index: TIndex; Values: array of TItem); virtual;
     56    function IndexOf(Item: TItem; Start: TIndex = 0): TIndex; virtual;
     57    function Implode(Separator: string; Converter: TToStringConverter): string;
     58    procedure Move(const CurIndex, NewIndex: TIndex); virtual;
     59    procedure MoveItems(CurIndex, NewIndex, ACount: TIndex); virtual;
     60    procedure ReplaceArray(const Index: TIndex; Values: array of TItem); virtual;
     61    procedure ReplaceList(const Index: TIndex; Source: TGAbstractList<TItem>); virtual;
     62    procedure ReplaceListPart(const Index: TIndex; Source: TGAbstractList<TItem>;
     63      SourceIndex, SourceCount: TIndex); virtual;
     64    function Remove(const Item: TItem): TIndex;
     65    procedure Reverse;
     66    procedure Sort(Compare: TSortCompare); virtual;
     67    procedure SetArray(Values: array of TItem); virtual;
    3768    property Count: TIndex read GetCount write SetCount;
    38     property Capacity: TIndex read GetCapacity write SetCapacity;
    3969    property Items[Index: TIndex]: TItem read Get write Put; default;
    4070    property First: TItem read GetFirst write SetFirst;
     
    5080  protected
    5181    function Get(Index: TIndex): TItem; override;
    52     function GetCapacity: TIndex; override;
     82    function GetCapacity: TIndex;
    5383    function GetCount: TIndex; override;
    54     procedure SetCapacity(const AValue: TIndex); override;
     84    procedure SetCapacity(const AValue: TIndex);
    5585    procedure SetCapacityOptimized(const NewCapacity: TIndex);
    5686    procedure SetCount(const AValue: TIndex); override;
    5787    procedure Put(Index: TIndex; const AValue: TItem); override;
    58     procedure QuickSort(L, R : TIndex; Compare: TSortCompare);
    5988  public
    60     function Add(const Item: TItem): TIndex; override;
    61     procedure AddArray(Values: array of TItem);
    62     procedure AddList(List: TGList<TItem>);
    63     procedure AddListPart(List: TGList<TItem>; ItemIndex, ItemCount: TIndex);
    64     procedure Assign(Source: TGList<TItem>); virtual;
    65     procedure Delete(Index: TIndex); virtual;
    66     procedure DeleteItems(Index, Count: TIndex);
    67     function EqualTo(List: TGList<TItem>): Boolean;
    68     procedure Exchange(Index1, Index2: TIndex);
    69     procedure Explode(Text, Separator: string; Converter: TFromStringConverter; SlicesCount: Integer = -1);
    70     function Extract(Item: TItem): TItem;
    71     procedure Fill(Start, Count: TIndex; Value: TItem);
    72     function GetArray(Index, ACount: TIndex): TItemArray;
    73     procedure GetList(List: TGList<TItem>; Index, ACount: TIndex);
    74     function Implode(Separator: string; Converter: TToStringConverter): string;
    75     function IndexOf(Item: TItem; Start: TIndex = 0): TIndex;
    76     function IndexOfList(List: TGList<TItem>; Start: TIndex = 0): TIndex;
    77     procedure Insert(Index: TIndex; Item: TItem);
    78     procedure InsertList(Index: TIndex; List: TGList<TItem>);
    79     procedure InsertArray(Index: TIndex; Values: array of TItem);
    80     procedure InsertCount(Index: TIndex; ACount: TIndex);
    81     procedure Move(CurIndex, NewIndex: TIndex);
    82     procedure MoveItems(CurIndex, NewIndex, Count: TIndex);
    83     function Remove(Item: TItem): TIndex;
    84     procedure Reverse;
    85     procedure ReplaceArray(Index: TIndex; Values: array of TItem);
    86     procedure ReplaceList(Index: TIndex; Source: TGList<TItem>);
    87     procedure ReplaceListPart(Index: TIndex; Source: TGList<TItem>;
    88       SourceIndex, SourceCount: TIndex);
    89     procedure Sort(Compare: TSortCompare);
    90     procedure SetArray(Values: array of TItem);
     89    procedure Fill(Start, Count: TIndex; Value: TItem); override;
     90    procedure Clear; override;
     91    procedure ReplaceList(const Index: TIndex; Source: TGAbstractList<TItem>); override;
     92    function CompareItem(const Item1, Item2: TItem): Boolean; override;
     93    procedure CopyItems(CurIndex, NewIndex, ACount: TIndex); override;
     94    property Capacity: TIndex read GetCapacity write SetCapacity;
    9195  end;
    9296
     
    96100  public
    97101    OwnsObjects: Boolean;
    98     procedure Delete(Index: Integer); override;
     102    procedure Delete(const Index: Integer); override;
    99103    procedure Clear; override;
    100     procedure Assign(Source: TGList<TItem>); override;
     104    procedure Assign(Source: TGAbstractList<TItem>); override;
    101105    constructor Create; override;
    102106    destructor Destroy; override;
     
    108112    procedure Delete(Index: Integer); override;
    109113    procedure Clear; override;
    110     procedure Assign(Source: TGList<TItem>); override;
     114    procedure Assign(Source: TGAbstractList<TItem>); override;
    111115    constructor Create; override;
    112116    destructor Destroy; override;
     
    192196end;
    193197
     198procedure TGList<TItem>.Fill(Start, Count: TIndex; Value: TItem);
     199begin
     200  (*if SizeOf(Value) = 1 then System.FillByte(FItems[Start], Count, Byte(Value))
     201  else if SizeOf(Value) = 2 then System.FillWord(FItems[Start], Count, Word(Value))
     202  else if SizeOf(Value) = 4 then System.FillDWord(FItems[Start], Count, DWord(Value))
     203  else if SizeOf(Value) = 8 then System.FillQWord(FItems[Start], Count, QWord(Value))
     204  else*) inherited;
     205end;
     206
     207procedure TGList<TItem>.Clear;
     208begin
     209  inherited;
     210  Capacity := 0;
     211end;
     212
     213procedure TGList<TItem>.ReplaceList(const Index: TIndex; Source: TGAbstractList<TItem>
     214  );
     215begin
     216  if Source is TGList<TItem> then begin
     217    System.Move(TGList<TItem>(Source).FItems[0], FItems[Index], Source.Count * SizeOf(TItem));
     218  end else inherited;
     219end;
     220
    194221procedure TGList<TItem>.SetCount(const AValue: TIndex);
    195222begin
     
    201228end;
    202229
    203 function TGList<TItem>.GetArray(Index, ACount: TIndex): TItemArray;
     230function TGList<TItem>.CompareItem(const Item1, Item2: TItem): Boolean;
     231begin
     232  Result := CompareMem(Addr(Item1), Addr(Item2), SizeOf(TItem));
     233end;
     234
     235function TGList<TItem>.GetCount: TIndex;
     236begin
     237  Result := FCount;
     238end;
     239
     240procedure TGList<TItem>.CopyItems(CurIndex, NewIndex, ACount: TIndex);
     241begin
     242  System.Move(FItems[CurIndex], FItems[NewIndex], ACount * SizeOf(TItem));
     243end;
     244
     245{ TGObjectList }
     246
     247procedure TGObjectList<TItem>.Assign(Source: TGAbstractList<TItem>);
     248begin
     249  Clear;
     250  OwnsObjects := False;
     251  inherited;
     252end;
     253
     254procedure TGObjectList<TItem>.Put(Index: Integer; const AValue: TItem);
     255begin
     256  if OwnsObjects then FItems[Index].Free;
     257  inherited Put(Index, AValue);
     258end;
     259
     260procedure TGObjectList<TItem>.Delete(const Index: Integer);
     261begin
     262  if OwnsObjects then FItems[Index].Free;
     263  inherited Delete(Index);
     264end;
     265
     266procedure TGObjectList<TItem>.Clear;
    204267var
    205268  I: Integer;
    206269begin
    207   SetLength(Result, ACount);
     270  if OwnsObjects then begin
     271    I := 0;
     272    while I < Count do begin
     273      FItems[I].Free;
     274      I := I + 1;
     275    end;
     276  end;
     277  inherited Clear;
     278end;
     279
     280constructor TGObjectList<TItem>.Create;
     281begin
     282  inherited;
     283  OwnsObjects := True;
     284end;
     285
     286destructor TGObjectList<TItem>.Destroy;
     287begin
     288  Clear;
     289  inherited Destroy;
     290end;
     291
     292{ TGStringList }
     293
     294procedure TGStringList<TItem>.Assign(Source: TGAbstractList<TItem>);
     295begin
     296  Clear;
     297  inherited;
     298end;
     299
     300procedure TGStringList<TItem>.Delete(Index: Integer);
     301begin
     302  FItems[Index] := '';
     303  inherited Delete(Index);
     304end;
     305
     306procedure TGStringList<TItem>.Clear;
     307var
     308  I: Integer;
     309begin
    208310  I := 0;
    209311  while I < Count do begin
    210     Result[I] := FItems[Index + I];
    211     I := I + 1;
    212   end;
    213 end;
    214 
    215 procedure TGList<TItem>.GetList(List: TGList<TItem>; Index, ACount: TIndex);
    216 begin
    217  List.Clear;
    218  List.AddListPart(Self, Index, ACount);
    219 end;
    220 
    221 procedure TGList<TItem>.QuickSort(L, R: TIndex; Compare: TSortCompare);
     312    FItems[I] := '';
     313    I := I + 1;
     314  end;
     315  inherited Clear;
     316end;
     317
     318constructor TGStringList<TItem>.Create;
     319begin
     320  inherited;
     321end;
     322
     323destructor TGStringList<TItem>.Destroy;
     324begin
     325  Clear;
     326  inherited Destroy;
     327end;
     328
     329{ TGAbstractList<TItem> }
     330
     331function TGAbstractList<TItem>.GetLast: TItem;
     332begin
     333  if Count = 0 then
     334    raise EListError.CreateFmt(SListIndexError, [0])
     335  else
     336    Result := Items[Count - 1];
     337end;
     338
     339procedure TGAbstractList<TItem>.SetLast(const AValue: TItem);
     340begin
     341  if Count = 0 then
     342    raise EListError.CreateFmt(SListIndexError, [0])
     343  else
     344    Items[Count - 1] := AValue;
     345end;
     346
     347function TGAbstractList<TItem>.GetFirst: TItem;
     348begin
     349  if Count = 0 then
     350    raise EListError.CreateFmt(SListIndexError, [0])
     351  else
     352    Result := Items[0];
     353end;
     354
     355procedure TGAbstractList<TItem>.SetFirst(const AValue: TItem);
     356begin
     357  if Count = 0 then
     358    raise EListError.CreateFmt(SListIndexError, [0])
     359  else
     360    Items[0] := AValue;
     361end;
     362
     363procedure TGAbstractList<TItem>.QuickSort(L, R: TIndex; Compare: TSortCompare);
    222364var
    223365  I, J: TIndex;
     
    227369   I := L;
    228370   J := R;
    229    P := FItems[(L + R) div 2];
     371   P := Items[(L + R) div 2];
    230372   repeat
    231      while Compare(P, FItems[I]) > 0 do
     373     while Compare(P, Items[I]) > 0 do
    232374       I := I + 1;
    233      while Compare(P, FItems[J]) < 0 do
     375     while Compare(P, Items[J]) < 0 do
    234376       J := J - 1;
    235377     if I <= J then
    236378     begin
    237        Q := FItems[I];
    238        FItems[I] := FItems[J];
    239        FItems[J] := Q;
     379       Q := Items[I];
     380       Items[I] := Items[J];
     381       Items[J] := Q;
    240382       I := I + 1;
    241383       J := J - 1;
     
    248390end;
    249391
    250 procedure TGList<TItem>.Assign(Source: TGList<TItem>);
    251 var
    252   I: TIndex;
    253 begin
    254   Count := Source.Count;
    255   I := 0;
    256   while I < Count do begin
    257     FItems[I] := Source[I];
    258     I := I + 1;
    259   end;
    260 end;
    261 
    262 function TGList<TItem>.Extract(Item: TItem): TItem;
     392constructor TGAbstractList<TItem>.Create;
     393begin
     394end;
     395
     396procedure TGAbstractList<TItem>.Clear;
     397begin
     398  Count := 0;
     399end;
     400
     401procedure TGAbstractList<TItem>.Delete(const Index: TIndex);
     402begin
     403  DeleteItems(Index, 1);
     404end;
     405
     406procedure TGAbstractList<TItem>.DeleteItems(const Index, ACount: TIndex);
     407begin
     408  if (Index < 0) or (Index >= (Count - ACount)) then
     409    raise EListError.CreateFmt(SListIndexError, [Index]);
     410  CopyItems(Index + ACount, Index, Count - Index - ACount);
     411  //SetCapacityOptimized(Capacity - ACount);
     412  Count := Count - ACount;
     413end;
     414
     415function TGAbstractList<TItem>.EqualTo(List: TGAbstractList<TItem>): Boolean;
     416var
     417  I: TIndex;
     418begin
     419  Result := Count = List.Count;
     420  if Result then begin
     421    I := 0;
     422    while I < Count do begin
     423      if not CompareItem(Items[I], List.Items[I]) then begin
     424        Result := False;
     425        Break;
     426      end;
     427      I := I + 1;
     428    end;
     429  end;
     430end;
     431
     432procedure TGAbstractList<TItem>.Exchange(const Index1, Index2: TIndex);
     433var
     434  Temp: TItem;
     435begin
     436  if ((Index1 >= Count) or (Index1 < 0)) then
     437    raise EListError.CreateFmt(SListIndexError, [Index1]);
     438  if ((Index2 >= Count) or (Index2 < 0)) then
     439    raise EListError.CreateFmt(SListIndexError, [Index2]);
     440  Temp := Items[Index1];
     441  Items[Index1] := Items[Index2];
     442  Items[Index2] := Temp;
     443end;
     444
     445procedure TGAbstractList<TItem>.Explode(Text, Separator: string;
     446  Converter: TFromStringConverter; SlicesCount: Integer);
     447begin
     448  Clear;
     449  while (Pos(Separator, Text) > 0) and
     450  ((Count < (SlicesCount - 1)) or (SlicesCount = -1)) do begin
     451    Add(Converter(Copy(Text, 1, Pos(Separator, Text) - 1)));
     452    System.Delete(Text, 1, Pos(Separator, Text) + Length(Separator) - 1);
     453  end;
     454  Add(Converter(Text));
     455end;
     456
     457function TGAbstractList<TItem>.Extract(Item: TItem): TItem;
    263458var
    264459  I: TIndex;
     
    272467end;
    273468
    274 function TGList<TItem>.IndexOf(Item: TItem; Start: TIndex): TIndex;
    275 begin
    276   Result := Start;
    277   while (Result < FCount) and
    278   not CompareMem(Addr(FItems[Result]), Addr(Item), SizeOf(TItem)) do
    279     Result := Result + 1;
    280   if Result = FCount then Result := -1;
    281 end;
    282 
    283 procedure TGList<TItem>.Insert(Index: TIndex; Item: TItem);
    284 begin
    285   if (Index < 0) or (Index > FCount) then
    286     raise EListError.CreateFmt(SListIndexError, [Index]);
    287   InsertCount(Index, 1);
    288   FItems[Index] := Item;
    289 end;
    290 
    291 procedure TGList<TItem>.InsertList(Index: TIndex; List: TGList<TItem>);
    292 begin
    293   if (Index < 0) or (Index > FCount) then
    294     raise EListError.CreateFmt(SListIndexError, [Index]);
    295   InsertCount(Index, List.Count);
    296   ReplaceList(Index, List);
    297 end;
    298 
    299 function TGList<TItem>.IndexOfList(List: TGList<TItem>; Start: TIndex): TIndex;
     469procedure TGAbstractList<TItem>.Fill(Start, Count: TIndex; Value: TItem);
     470var
     471  I: TIndex;
     472begin
     473  I := Start;
     474  while I < Count do begin
     475    Items[I] := Value;
     476    I := I + 1;
     477  end;
     478end;
     479
     480function TGAbstractList<TItem>.GetArray(Index, ACount: TIndex): TItemArray;
     481var
     482  I: Integer;
     483begin
     484  SetLength(Result, ACount);
     485  I := 0;
     486  while I < Count do begin
     487    Result[I] := Items[Index + I];
     488    I := I + 1;
     489  end;
     490end;
     491
     492procedure TGAbstractList<TItem>.GetList(List: TGAbstractList<TItem>; Index, ACount: TIndex);
     493begin
     494  List.Clear;
     495  List.AddListPart(Self, Index, ACount);
     496end;
     497
     498function TGAbstractList<TItem>.IndexOfList(List: TGAbstractList<TItem>; Start: TIndex
     499  ): TIndex;
    300500var
    301501  I: TIndex;
     
    306506      I := 1;
    307507      while I < List.Count do begin
    308         if not CompareMem(Addr(FItems[Result + I]), Addr(List.FItems[I]), SizeOf(TItem)) then begin
     508        if not CompareItem(Items[Result + I], List.Items[I]) then begin
    309509          Result := -1;
    310510          Break;
     
    316516end;
    317517
    318 function TGList<TItem>.GetCount: TIndex;
    319 begin
    320   Result := FCount;
    321 end;
    322 
    323 procedure TGList<TItem>.Move(CurIndex, NewIndex: TIndex);
    324 var
    325   Temp: TItem;
    326 begin
    327   if ((CurIndex < 0) or (CurIndex > Count - 1)) then
    328     raise EListError.CreateFmt(SListIndexError, [CurIndex]);
    329   if ((NewIndex < 0) or (NewIndex > Count -1)) then
    330     raise EListError.CreateFmt(SlistIndexError, [NewIndex]);
    331   Temp := FItems[CurIndex];
    332   if NewIndex > CurIndex then begin
    333     System.Move(FItems[CurIndex + 1], FItems[CurIndex], (NewIndex - CurIndex) * SizeOf(TItem));
    334   end else
    335   if NewIndex < CurIndex then begin
    336     System.Move(FItems[NewIndex], FItems[NewIndex + 1], (CurIndex - NewIndex) * SizeOf(TItem));
    337   end;
    338   FItems[NewIndex] := Temp;
    339   //Delete(CurIndex);
    340   //Insert(NewIndex, Temp);
    341 end;
    342 
    343 procedure TGList<TItem>.MoveItems(CurIndex, NewIndex, Count: TIndex);
    344 var
    345   S: Integer;
    346   D: Integer;
    347 begin
    348   if CurIndex < NewIndex then begin
    349     S := CurIndex + Count - 1;
    350     D := NewIndex + Count - 1;
    351     while S >= CurIndex do begin
    352       Move(S, D);
    353       S := S - 1;
    354       D := D - 1;
     518function TGAbstractList<TItem>.IndexOf(Item: TItem; Start: TIndex): TIndex;
     519begin
     520  Result := Start;
     521  while (Result < Count) and (not CompareItem(Items[Result], Item)) do
     522    Result := Result + 1;
     523  if Result = Count then Result := -1;
     524end;
     525
     526procedure TGAbstractList<TItem>.Insert(const Index: TIndex; Item: TItem);
     527begin
     528  if (Index > Count) then
     529    raise EListError.CreateFmt(SListIndexError, [Index]);
     530  InsertCount(Index, 1);
     531  Items[Index] := Item;
     532end;
     533
     534procedure TGAbstractList<TItem>.InsertList(const Index: TIndex; List: TGAbstractList<TItem>);
     535begin
     536  if (Index < 0) or (Index > Count) then
     537    raise EListError.CreateFmt(SListIndexError, [Index]);
     538  InsertCount(Index, List.Count);
     539  ReplaceList(Index, List);
     540end;
     541
     542procedure TGAbstractList<TItem>.InsertArray(const Index: TIndex;
     543  Values: array of TItem);
     544begin
     545  if (Index < 0) or (Index > Count) then
     546    raise EListError.CreateFmt(SListIndexError, [Index]);
     547  InsertCount(Index, Length(Values));
     548  ReplaceArray(Index, Values);
     549end;
     550
     551procedure TGAbstractList<TItem>.InsertCount(const Index: TIndex; ACount: TIndex);
     552begin
     553  if (Index < 0) or (Index > Count) then
     554    raise EListError.CreateFmt(SListIndexError, [Index]);
     555  Count := Count + ACount;
     556  CopyItems(Index, Index + ACount, Count - ACount - Index);
     557end;
     558
     559function TGAbstractList<TItem>.Implode(Separator: string;
     560  Converter: TToStringConverter): string;
     561var
     562  I: TIndex;
     563begin
     564  Result := '';
     565  I := 0;
     566  while I < Count do begin
     567    Result := Result + Converter(Items[I]);
     568    if I < (Count - 1) then
     569      Result := Result + Separator;
     570    I := I + 1;
     571  end;
     572end;
     573
     574procedure TGAbstractList<TItem>.CopyItems(CurIndex, NewIndex, ACount: TIndex);
     575var
     576  I: Integer;
     577begin
     578  if CurIndex > NewIndex then begin
     579    I := 0;
     580    while I < ACount do begin
     581      Items[NewIndex] := Items[CurIndex];
     582      CurIndex := CurIndex + 1;
     583      NewIndex := NewIndex + 1;
     584      I := I + 1;
    355585    end;
    356   end else
    357   if CurIndex > NewIndex then begin
    358     S := CurIndex;
    359     D := NewIndex;
    360     while S < (CurIndex + Count) do begin
    361       Move(S, D);
    362       S := S + 1;
    363       D := D + 1;
     586  end else begin
     587    I := ACount - 1;
     588    NewIndex := NewIndex + ACount - 1;
     589    CurIndex := CurIndex + ACount - 1;
     590    while I >= 0 do begin
     591      Items[NewIndex] := Items[CurIndex];
     592      NewIndex := NewIndex - 1;
     593      CurIndex := CurIndex - 1;
     594      I := I - 1;
    364595    end;
    365596  end;
    366597end;
    367598
    368 function TGList<TItem>.Remove(Item: TItem): TIndex;
     599procedure TGAbstractList<TItem>.Move(const CurIndex, NewIndex: TIndex);
     600begin
     601  MoveItems(CurIndex, NewIndex, 1);
     602end;
     603
     604procedure TGAbstractList<TItem>.MoveItems(CurIndex, NewIndex,
     605  ACount: TIndex);
     606var
     607  I: Integer;
     608  Temp: TGList<TItem>;
     609begin
     610  try
     611    Temp := TGList<TItem>.Create;
     612    Temp.AddListPart(Self, NewIndex, ACount);
     613    CopyItems(CurIndex, NewIndex, ACount);
     614    ReplaceList(CurIndex, Temp);
     615  finally
     616    Temp.Free;
     617  end;
     618end;
     619
     620procedure TGAbstractList<TItem>.ReplaceArray(const Index: TIndex;
     621  Values: array of TItem);
     622var
     623  I: TIndex;
     624begin
     625  I := 0;
     626  while I < Length(Values) do begin
     627    Items[Index + I] := Values[I];
     628    I := I + 1;
     629  end;
     630end;
     631
     632procedure TGAbstractList<TItem>.ReplaceList(const Index: TIndex; Source: TGAbstractList<TItem>
     633  );
     634var
     635  I: TIndex;
     636begin
     637  I := 0;
     638  while I < Source.Count do begin
     639    Items[Index + I] := Source[I];
     640    I := I + 1;
     641  end;
     642end;
     643
     644procedure TGAbstractList<TItem>.ReplaceListPart(const Index: TIndex;
     645  Source: TGAbstractList<TItem>; SourceIndex, SourceCount: TIndex);
     646var
     647  I: TIndex;
     648begin
     649  I := 0;
     650  while I < SourceCount do begin
     651    Items[Index + I] := Source[SourceIndex + I];
     652    I := I + 1;
     653  end;
     654end;
     655
     656function TGAbstractList<TItem>.Remove(const Item: TItem): TIndex;
    369657begin
    370658  Result := IndexOf(Item);
     
    373661end;
    374662
    375 function TGList<TItem>.EqualTo(List: TGList<TItem>): Boolean;
    376 var
    377   I: TIndex;
    378 begin
    379   Result := Count = List.Count;
    380   if Result then begin
    381     I := 0;
    382     while I < Count do begin
    383       if not CompareMem(Addr(FItems[I]), Addr(List.FItems[I]), SizeOf(TItem)) then begin
    384         Result := False;
    385         Break;
    386       end;
    387       I := I + 1;
    388     end;
    389   end;
    390 end;
    391 
    392 procedure TGList<TItem>.Reverse;
     663procedure TGAbstractList<TItem>.Reverse;
    393664var
    394665  I: TIndex;
     
    401672end;
    402673
    403 procedure TGList<TItem>.ReplaceArray(Index: TIndex;
    404   Values: array of TItem);
    405 var
    406   I: TIndex;
    407 begin
    408   I := 0;
    409   while I < Length(Values) do begin
    410     Items[Index + I] := Values[I];
    411     I := I + 1;
    412   end;
    413 end;
    414 
    415 procedure TGList<TItem>.ReplaceList(Index: TIndex; Source: TGList<TItem>);
    416 var
    417   I: TIndex;
    418 begin
    419   I := 0;
    420   while I < Source.Count do begin
    421     Items[Index + I] := Source[I];
    422     I := I + 1;
    423   end;
    424 end;
    425 
    426 procedure TGList<TItem>.ReplaceListPart(Index: TIndex; Source: TGList<TItem>;
    427   SourceIndex, SourceCount: TIndex);
    428 var
    429   I: TIndex;
    430 begin
    431   I := 0;
    432   while I < SourceCount do begin
    433     Items[Index + I] := Source[SourceIndex + I];
    434     I := I + 1;
    435   end;
    436 end;
    437 
    438 procedure TGList<TItem>.Sort(Compare: TSortCompare);
    439 begin
    440   if FCount > 1 then
    441     QuickSort(0, FCount - 1, Compare);
    442 end;
    443 
    444 procedure TGList<TItem>.AddArray(Values: array of TItem);
    445 var
    446   I: TIndex;
    447 begin
     674procedure TGAbstractList<TItem>.Sort(Compare: TSortCompare);
     675begin
     676  if Count > 1 then
     677    QuickSort(0, Count - 1, Compare);
     678end;
     679
     680procedure TGAbstractList<TItem>.SetArray(Values: array of TItem);
     681var
     682  I: TIndex;
     683begin
     684  Clear;
    448685  I := 0;
    449686  while I <= High(Values) do begin
     
    451688    I := I + 1;
    452689  end;
    453 end;
    454 
    455 procedure TGList<TItem>.SetArray(Values: array of TItem);
    456 var
    457   I: TIndex;
    458 begin
    459   Clear;
    460   I := 0;
    461   while I <= High(Values) do begin
    462     Add(Values[I]);
    463     I := I + 1;
    464   end;
    465 end;
    466 
    467 procedure TGList<TItem>.InsertArray(Index: TIndex; Values: array of TItem);
    468 begin
    469   if (Index < 0) or (Index > FCount) then
    470     raise EListError.CreateFmt(SListIndexError, [Index]);
    471   InsertCount(Index, Length(Values));
    472   ReplaceArray(Index, Values);
    473 end;
    474 
    475 procedure TGList<TItem>.InsertCount(Index: TIndex; ACount: TIndex);
    476 begin
    477   if (Index < 0) or (Index > FCount) then
    478     raise EListError.CreateFmt(SListIndexError, [Index]);
    479   Count := Count + ACount;
    480   if Index < FCount then
    481     System.Move(FItems[Index], FItems[Index + ACount], (FCount - ACount - Index) * SizeOf(TItem));
    482 end;
    483 
    484 function TGList<TItem>.Implode(Separator: string; Converter: TToStringConverter): string;
    485 var
    486   I: TIndex;
    487 begin
    488   Result := '';
    489   I := 0;
    490   while I < Count do begin
    491     Result := Result + Converter(FItems[I]);
    492     if I < (Count - 1) then
    493       Result := Result + Separator;
    494     I := I + 1;
    495   end;
    496 end;
    497 
    498 procedure TGList<TItem>.Explode(Text, Separator: string; Converter: TFromStringConverter; SlicesCount: Integer = -1);
    499 begin
    500   Clear;
    501   while (Pos(Separator, Text) > 0) and
    502   ((Count < (SlicesCount - 1)) or (SlicesCount = -1)) do begin
    503     Add(Converter(Copy(Text, 1, Pos(Separator, Text) - 1)));
    504     System.Delete(Text, 1, Pos(Separator, Text) + Length(Separator) - 1);
    505   end;
    506   Add(Converter(Text));
    507 end;
    508 
    509 function TGList<TItem>.Add(const Item: TItem): TIndex;
    510 begin
    511   Count := Count + 1;
    512   Result := FCount - 1;
    513   Items[Result] := Item;
    514 end;
    515 
    516 procedure TGList<TItem>.AddList(List: TGList<TItem>);
    517 var
    518   I: TIndex;
    519 begin
    520   I := 0;
    521   while I < List.Count do begin
    522     Add(List[I]);
    523     I := I + 1;
    524   end;
    525 end;
    526 
    527 procedure TGList<TItem>.AddListPart(List: TGList<TItem>; ItemIndex, ItemCount: TIndex);
    528 var
    529   I: TIndex;
    530   J: TIndex;
    531 begin
    532   I := Count;
    533   J := ItemIndex;
    534   Count := Count + ItemCount;
    535   while I < Count do begin
    536     Items[I] := List[J];
    537     I := I + 1;
    538     J := J + 1;
    539   end;
    540 end;
    541 
    542 procedure TGList<TItem>.Delete(Index: TIndex);
    543 begin
    544   if (Index < 0) or (Index >= FCount) then
    545     raise EListError.CreateFmt(SListIndexError, [Index]);
    546   FCount := FCount - 1;
    547   System.Move(FItems[Index + 1], FItems[Index], (FCount - Index) * SizeOf(TItem));
    548   SetCapacityOptimized(Capacity - 1);
    549 end;
    550 
    551 procedure TGList<TItem>.DeleteItems(Index, Count: TIndex);
    552 var
    553   I: TIndex;
    554 begin
    555   I := Index;
    556   while I < (Index + Count) do begin
    557     Delete(Index);
    558     I := I + 1;
    559   end;
    560 end;
    561 
    562 procedure TGList<TItem>.Fill(Start, Count: TIndex; Value: TItem);
    563 var
    564   I: TIndex;
    565 begin
    566   I := Start;
    567   while I < Count do begin
    568     FItems[I] := Value;
    569     I := I + 1;
    570   end;
    571 end;
    572 
    573 procedure TGList<TItem>.Exchange(Index1, Index2: TIndex);
    574 var
    575   Temp: TItem;
    576 begin
    577   if ((Index1 >= FCount) or (Index1 < 0)) then
    578     raise EListError.CreateFmt(SListIndexError, [Index1]);
    579   if ((Index2 >= FCount) or (Index2 < 0)) then
    580     raise EListError.CreateFmt(SListIndexError, [Index2]);
    581   Temp := FItems[Index1];
    582   FItems[Index1] := FItems[Index2];
    583   FItems[Index2] := Temp;
    584 end;
    585 
    586 { TGObjectList }
    587 
    588 procedure TGObjectList<TItem>.Assign(Source: TGList<TItem>);
    589 begin
    590   Clear;
    591   OwnsObjects := False;
    592   inherited;
    593 end;
    594 
    595 procedure TGObjectList<TItem>.Put(Index: Integer; const AValue: TItem);
    596 begin
    597   if OwnsObjects then FItems[Index].Free;
    598   inherited Put(Index, AValue);
    599 end;
    600 
    601 procedure TGObjectList<TItem>.Delete(Index: Integer);
    602 begin
    603   if OwnsObjects then FItems[Index].Free;
    604   inherited Delete(Index);
    605 end;
    606 
    607 procedure TGObjectList<TItem>.Clear;
    608 var
    609   I: Integer;
    610 begin
    611   if OwnsObjects then begin
    612     I := 0;
    613     while I < Count do begin
    614       FItems[I].Free;
    615       I := I + 1;
    616     end;
    617   end;
    618   inherited Clear;
    619 end;
    620 
    621 constructor TGObjectList<TItem>.Create;
    622 begin
    623   inherited;
    624   OwnsObjects := True;
    625 end;
    626 
    627 destructor TGObjectList<TItem>.Destroy;
    628 begin
    629   Clear;
    630   inherited Destroy;
    631 end;
    632 
    633 { TGStringList }
    634 
    635 procedure TGStringList<TItem>.Assign(Source: TGList<TItem>);
    636 begin
    637   Clear;
    638   inherited;
    639 end;
    640 
    641 procedure TGStringList<TItem>.Delete(Index: Integer);
    642 begin
    643   FItems[Index] := '';
    644   inherited Delete(Index);
    645 end;
    646 
    647 procedure TGStringList<TItem>.Clear;
    648 var
    649   I: Integer;
    650 begin
    651   I := 0;
    652   while I < Count do begin
    653     FItems[I] := '';
    654     I := I + 1;
    655   end;
    656   inherited Clear;
    657 end;
    658 
    659 constructor TGStringList<TItem>.Create;
    660 begin
    661   inherited;
    662 end;
    663 
    664 destructor TGStringList<TItem>.Destroy;
    665 begin
    666   Clear;
    667   inherited Destroy;
    668 end;
    669 
    670 { TGAbstractList<TItem> }
    671 
    672 function TGAbstractList<TItem>.GetLast: TItem;
    673 begin
    674   if Count = 0 then
    675     raise EListError.CreateFmt(SListIndexError, [0])
    676   else
    677     Result := Items[Count - 1];
    678 end;
    679 
    680 procedure TGAbstractList<TItem>.SetLast(const AValue: TItem);
    681 begin
    682   if Count = 0 then
    683     raise EListError.CreateFmt(SListIndexError, [0])
    684   else
    685     Items[Count - 1] := AValue;
    686 end;
    687 
    688 function TGAbstractList<TItem>.GetFirst: TItem;
    689 begin
    690   if Count = 0 then
    691     raise EListError.CreateFmt(SListIndexError, [0])
    692   else
    693     Result := Items[0];
    694 end;
    695 
    696 procedure TGAbstractList<TItem>.SetFirst(const AValue: TItem);
    697 begin
    698   if Count = 0 then
    699     raise EListError.CreateFmt(SListIndexError, [0])
    700   else
    701     Items[0] := AValue;
    702 end;
    703 
    704 constructor TGAbstractList<TItem>.Create;
    705 begin
    706 end;
    707 
    708 procedure TGAbstractList<TItem>.Clear;
    709 begin
    710   Count := 0;
    711   Capacity := 0;
    712690end;
    713691
     
    719697end;
    720698
     699procedure TGAbstractList<TItem>.AddArray(Values: array of TItem);
     700var
     701  I: TIndex;
     702begin
     703  I := 0;
     704  while I <= High(Values) do begin
     705    Add(Values[I]);
     706    I := I + 1;
     707  end;
     708end;
     709
     710procedure TGAbstractList<TItem>.AddList(List: TGAbstractList<TItem>);
     711begin
     712  Count := Count + List.Count;
     713  ReplaceList(Count - List.Count, List);
     714end;
     715
     716procedure TGAbstractList<TItem>.AddListPart(List: TGAbstractList<TItem>; ItemIndex,
     717  ItemCount: TIndex);
     718begin
     719  Count := Count + ItemCount;
     720  ReplaceListPart(Count - ItemCount, List, ItemIndex, ItemCount);
     721end;
     722
     723procedure TGAbstractList<TItem>.Assign(Source: TGAbstractList<TItem>);
     724begin
     725  Count := Source.Count;
     726  ReplaceList(0, Source);
     727end;
     728
    721729{ TGFileList<TItem> }
    722730
Note: See TracChangeset for help on using the changeset viewer.