Ignore:
Timestamp:
Sep 8, 2012, 9:28:39 PM (12 years ago)
Author:
chronos
Message:
  • Updated: Component versions.
  • Added: Missing forms.
Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk

    • Property svn:ignore
      •  

        old new  
        33backup
        44tunneler.exe
         5heaptrclog.trc
  • trunk/Components/TemplateGenerics

    • Property svn:ignore set to
      lib
  • trunk/Components/TemplateGenerics/Generic/GenericList.inc

    r29 r30  
    11{$IFDEF INTERFACE}
     2
     3  // TGList implemented using templates
     4  // - item operations (Add, Insert, ReplaceArray, Get, Set, IndexOf,
     5  //   Extract, Delete, Exchange)
     6  // - item range operations (DeleteItems, InsertItems, ReplaceItems,
     7  //   Move, Fill)
     8  // - other TGList operations (AddList, InsertList,
     9  //   ReplaceList, GetList, IndexOfList)
     10  // - dynamic array operations (AddArray, InsertArray,
     11  //   ReplaceArray, GetArray, IndexOfArray)
     12  // - all items operations (Clear, Reverse, Sort)
    213
    314  TGList = class;
     
    1324    FItems: array of TGListItem;
    1425    FCount: TGListIndex;
     26    FUpdateCount: Integer;
     27    FOnUpdate: TNotifyEvent;
    1528    function Get(Index: TGListIndex): TGListItem;
    1629    function GetCapacity: TGListIndex;
     
    2134    procedure SetLast(AValue: TGListItem);
    2235    procedure SetFirst(AValue: TGListItem);
     36    procedure QuickSort(L, R : TGListIndex; Compare: TGListSortCompare);
     37  protected
    2338    procedure Put(Index: TGListIndex; const AValue: TGListItem); virtual;
    2439    procedure SetCount(const AValue: TGListIndex); virtual;
    25     procedure QuickSort(L, R : TGListIndex; Compare: TGListSortCompare);
    2640  public
     41    type
     42      PItem = ^TGListItem;
     43    function CompareMem(P1, P2: Pointer; Length: cardinal): Boolean; inline;
    2744    function Add(Item: TGListItem): TGListIndex;
    2845    procedure AddArray(Values: array of TGListItem);
    2946    procedure AddList(List: TGList);
     47    procedure AddListPart(List: TGList; ItemIndex, ItemCount: TGListIndex);
    3048    procedure Assign(Source: TGList); virtual;
     49    constructor Create; virtual;
    3150    procedure Clear; virtual;
    3251    procedure Delete(Index: TGListIndex); virtual;
     
    3857    property First: TGListItem read GetFirst write SetFirst;
    3958    procedure Fill(Start, Count: TGListIndex; Value: TGListItem);
    40     function GetArray: TGListItemArray;
     59    function GetArray(Index, ACount: TGListIndex): TGListItemArray;
     60    procedure GetList(List: TGList; Index, ACount: TGListIndex);
     61    procedure GetBuffer(Index: TGListIndex; var Buffer; Count: TGListIndex);
    4162    function Implode(Separator: string; Converter: TGListToStringConverter): string;
    42     function IndexOf(Item: TGListItem; Start: TGListIndex = 0): TGListIndex;
     63    function IndexOf(Item: TGListItem; Start: TGListIndex = 0): TGListIndex; virtual;
    4364    function IndexOfList(List: TGList; Start: TGListIndex = 0): TGListIndex;
     65    function IndexOfArray(Values: array of TGListItem; Start: TGListIndex = 0): TGListIndex;
    4466    procedure Insert(Index: TGListIndex; Item: TGListItem);
    4567    procedure InsertList(Index: TGListIndex; List: TGList);
    4668    procedure InsertArray(Index: TGListIndex; Values: array of TGListItem);
     69    procedure InsertCount(Index: TGListIndex; ACount: TGListIndex);
    4770    procedure Move(CurIndex, NewIndex: TGListIndex);
    4871    procedure MoveItems(CurIndex, NewIndex, Count: TGListIndex);
    4972    function Remove(Item: TGListItem): TGListIndex;
    5073    procedure Reverse;
    51     procedure Replace(Index: TGListIndex; Source: TGList);
     74    procedure ReplaceArray(Index: TGListIndex; Values: array of TGListItem);
     75    procedure ReplaceList(Index: TGListIndex; Source: TGList);
     76    procedure ReplaceListPart(Index: TGListIndex; Source: TGList;
     77      SourceIndex, SourceCount: TGListIndex);
     78    procedure ReplaceBuffer(Index: TGListIndex; var Buffer; Count: TGListIndex);
    5279    procedure Sort(Compare: TGListSortCompare);
    53     procedure SetArray(Values: TGListItemArray);
     80    procedure SetArray(Values: array of TGListItem);
     81    procedure BeginUpdate;
     82    procedure EndUpdate;
     83    procedure Update;
    5484    property Count: TGListIndex read FCount write SetCount;
    5585    property Capacity: TGListIndex read GetCapacity write SetCapacity;
    5686    property Items[Index: TGListIndex]: TGListItem read Get write Put; default;
    5787    property Last: TGListItem read GetLast write SetLast;
     88    property OnUpdate: TNotifyEvent read FOnUpdate write FOnUpdate;
    5889  end;
    5990 
     
    73104{ TGList }
    74105
    75 procedure TGList.Replace(Index: TGListIndex; Source: TGList);
     106constructor TGList.Create;
     107begin
     108  FCount := 0;
     109end;
     110
     111procedure TGList.GetBuffer(Index: TGListIndex; var Buffer; Count: TGListIndex);
     112var
     113  P: PItem;
     114  I: TGListIndex;
     115begin
     116  if (Index + Count) > FCount then
     117    raise EListError.CreateFmt(SListIndexError, [Index + Count]);
     118  P := PItem(@Buffer);
     119  I := 0;
     120  while I < Count do begin
     121    P^ := Items[Index + I];
     122    Inc(P, 1);
     123    I := I + 1;
     124  end;
     125end;
     126
     127procedure TGList.ReplaceBuffer(Index: TGListIndex; var Buffer; Count: TGListIndex);
     128var
     129  P: PItem;
     130  I: TGListIndex;
     131begin
     132  if (Index + Count) > FCount then
     133    raise EListError.CreateFmt(SListIndexError, [Index + Count]);
     134  P := PItem(@Buffer);
     135  I := 0;
     136  while I < Count do begin
     137    Items[Index + I] := P^;
     138    Inc(P, 1);
     139    I := I + 1;
     140  end;
     141end;
     142
     143procedure TGList.ReplaceArray(Index: TGListIndex; Values: array of TGListItem);
     144var
     145  I: TGListIndex;
     146begin
     147  I := 0;
     148  while I < Length(Values) do begin
     149    Items[Index + I] := Values[I];
     150    I := I + 1;
     151  end;
     152  Update;
     153end;
     154
     155procedure TGList.ReplaceList(Index: TGListIndex; Source: TGList);
    76156var
    77157  I: TGListIndex;
     
    82162    I := I + 1;
    83163  end;
     164  Update;
     165end;
     166
     167procedure TGList.ReplaceListPart(Index: TGListIndex; Source: TGList;
     168  SourceIndex, SourceCount: TGListIndex);
     169var
     170  I: TGListIndex;
     171begin
     172  I := 0;
     173  while I < SourceCount do begin
     174    Items[Index + I] := Source[SourceIndex + I];
     175    I := I + 1;
     176  end;
     177  Update;
    84178end;
    85179
     
    143237end;
    144238
    145 function TGList.GetArray: TGListItemArray;
     239function TGList.GetArray(Index, ACount: TGListIndex): TGListItemArray;
    146240var
    147241  I: Integer;
    148242begin
    149   SetLength(Result, Count);
    150   I := 0;
    151   while I < Count do begin
    152     Result[I] := FItems[I];
    153     I := I + 1;
    154   end;
     243  SetLength(Result, ACount);
     244  I := 0;
     245  while I < Count do begin
     246    Result[I] := FItems[Index + I];
     247    I := I + 1;
     248  end;
     249end;
     250
     251procedure TGList.GetList(List: TGList; Index, ACount: TGListIndex);
     252begin
     253  List.Clear;
     254  List.AddListPart(Self, Index, ACount);
    155255end;
    156256
     
    194294    I := I + 1;
    195295  end;
     296  Update;
    196297end;
    197298
     
    208309end;
    209310
     311function TGList.CompareMem(P1, P2: Pointer; Length: cardinal): Boolean;
     312var
     313  I: Cardinal;
     314begin
     315  Result := True;
     316  I := 0;
     317  if (P1) <> (P2) then
     318    while Result and (I < Length) do
     319    begin
     320      Result := PByte(P1)^ = PByte(P2)^;
     321      Inc(I);
     322      Inc(pchar(P1));
     323      Inc(pchar(P2));
     324    end;
     325end;
     326
    210327function TGList.IndexOf(Item: TGListItem; Start: TGListIndex): TGListIndex;
    211328begin
    212329  Result := Start;
    213330  while (Result < FCount) and
    214   not CompareMem(Addr(FItems[Result]), Addr(Item), SizeOf(TGListItem)) do
     331//  not CompareMem(@FItems[Result], @Item, SizeOf(TGListItem)) do
     332  not (CompareByte(FItems[Result], Item, SizeOf(TGListItem)) = 0) do
    215333    Result := Result + 1;
    216334  if Result = FCount then Result := -1;
     
    219337procedure TGList.Insert(Index: TGListIndex; Item: TGListItem);
    220338begin
    221   if (Index < 0) or (Index > FCount ) then
     339  if (Index < 0) or (Index > FCount) then
    222340    raise EListError.CreateFmt(SListIndexError, [Index]);
    223   if FCount = Capacity then SetCapacityOptimized(Capacity + 1);
     341  InsertCount(Index, 1);
     342  FItems[Index] := Item;
     343  Update;
     344end;
     345
     346procedure TGList.InsertList(Index: TGListIndex; List: TGList);
     347begin
     348  if (Index < 0) or (Index > FCount) then
     349    raise EListError.CreateFmt(SListIndexError, [Index]);
     350  InsertCount(Index, List.Count);
     351  ReplaceList(Index, List);
     352end;
     353
     354procedure TGList.InsertArray(Index: TGListIndex; Values: array of TGListItem);
     355begin
     356  if (Index < 0) or (Index > FCount) then
     357    raise EListError.CreateFmt(SListIndexError, [Index]);
     358  InsertCount(Index, Length(Values));
     359  ReplaceArray(Index, Values);
     360end;
     361
     362procedure TGList.InsertCount(Index: TGListIndex; ACount: TGListIndex);
     363begin
     364  if (Index < 0) or (Index > FCount) then
     365    raise EListError.CreateFmt(SListIndexError, [Index]);
     366  Count := Count + ACount;
    224367  if Index < FCount then
    225     System.Move(FItems[Index], FItems[Index + 1], (FCount - Index) * SizeOf(TGListItem));
    226   FItems[Index] := Item;
    227   FCount := FCount + 1;
    228 end;
    229 
    230 procedure TGList.InsertList(Index: TGListIndex; List: TGList);
    231 var
    232   I: TGListIndex;
    233 begin
    234   I := 0;
    235   while (I < List.Count) do begin
    236     Insert(Index + I, List[I]);
    237     I := I + 1;
    238   end;
     368    System.Move(FItems[Index], FItems[Index + ACount], (FCount - ACount - Index) * SizeOf(TGListItem));
     369  Update;
    239370end;
    240371
     
    258389end;
    259390
     391function TGList.IndexOfArray(Values: array of TGListItem; Start: TGListIndex): TGListIndex;
     392var
     393  I: TGListIndex;
     394begin
     395  if Length(Values) > 0 then begin
     396    Result := IndexOf(Values[0], Start);
     397    if Result <> -1 then begin
     398      I := 1;
     399      while I < Length(Values) do begin
     400        if not CompareMem(Addr(FItems[Result + I]), Addr(Values[I]), SizeOf(TGListItem)) then begin
     401          Result := -1;
     402          Break;
     403        end;
     404        I := I + 1;
     405      end;
     406    end;
     407  end else Result := -1;
     408end;
     409
    260410function TGList.GetLast: TGListItem;
    261411begin
     
    308458  //Delete(CurIndex);
    309459  //Insert(NewIndex, Temp);
     460  Update;
    310461end;
    311462
     
    333484    end;
    334485  end;
     486  Update;
    335487end;
    336488
     
    339491  Result := IndexOf(Item);
    340492  if Result <> -1 then
    341     Delete(Result);
     493    Delete(Result)
     494    else raise Exception.CreateFmt(SItemNotFound, [0]);
    342495end;
    343496
     
    368521    I := I + 1;
    369522  end;
     523  Update;
    370524end;
    371525
     
    374528  if FCount > 1 then
    375529    QuickSort(0, FCount - 1, Compare);
     530  Update;
    376531end;
    377532
     
    385540    I := I + 1;
    386541  end;
    387 end;
    388 
    389 procedure TGList.SetArray(Values: TGListItemArray);
     542  Update;
     543end;
     544
     545procedure TGList.SetArray(Values: array of TGListItem);
    390546var
    391547  I: TGListIndex;
     
    399555end;
    400556
    401 procedure TGList.InsertArray(Index: TGListIndex; Values: array of TGListItem);
    402 var
    403   I: TGListIndex;
    404 begin
    405   I := 0;
    406   while I <= High(Values) do begin
    407     Insert(Index + I, Values[I]);
    408     I := I + 1;
    409   end;
     557procedure TGList.BeginUpdate;
     558begin
     559  Inc(FUpdateCount);
     560end;
     561
     562procedure TGList.EndUpdate;
     563begin
     564  Dec(FUpdateCount);
     565  Update;
     566end;
     567
     568procedure TGList.Update;
     569begin
     570  if Assigned(FOnUpdate) and (FUpdateCount = 0) then FOnUpdate(Self);
    410571end;
    411572
     
    440601  Result := FCount - 1;
    441602  FItems[Result] := Item;
     603  Update;
    442604end;
    443605
     
    445607var
    446608  I: TGListIndex;
    447 begin
    448   I := 0;
    449   while I < List.Count do begin
    450     Add(List[I]);
    451     I := I + 1;
    452   end;
     609  J: TGListIndex;
     610begin
     611  I := Count;
     612  J := 0;
     613  Count := Count + List.Count;
     614  while I < Count do begin
     615    Items[I] := List[J];
     616    I := I + 1;
     617    J := J + 1;
     618  end;
     619  Update;
     620end;
     621
     622procedure TGList.AddListPart(List: TGList; ItemIndex, ItemCount: TGListIndex);
     623var
     624  I: TGListIndex;
     625  J: TGListIndex;
     626begin
     627  I := Count;
     628  J := ItemIndex;
     629  Count := Count + ItemCount;
     630  while I < Count do begin
     631    Items[I] := List[J];
     632    I := I + 1;
     633    J := J + 1;
     634  end;
     635  Update;
    453636end;
    454637
     
    466649  System.Move(FItems[Index + 1], FItems[Index], (FCount - Index) * SizeOf(TGListItem));
    467650  SetCapacityOptimized(Capacity - 1);
     651  Update;
    468652end;
    469653
     
    477661    I := I + 1;
    478662  end;
     663  Update;
    479664end;
    480665
     
    488673    I := I + 1;
    489674  end;
     675  Update;
    490676end;
    491677
     
    501687  FItems[Index1] := FItems[Index2];
    502688  FItems[Index2] := Temp;
     689  Update;
    503690end;
    504691
Note: See TracChangeset for help on using the changeset viewer.