Changeset 30 for trunk/Components/TemplateGenerics/Generic/GenericList.inc
- Timestamp:
- Sep 8, 2012, 9:28:39 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:ignore
-
old new 3 3 backup 4 4 tunneler.exe 5 heaptrclog.trc
-
- Property svn:ignore
-
trunk/Components/TemplateGenerics
-
Property svn:ignore
set to
lib
-
Property svn:ignore
set to
-
trunk/Components/TemplateGenerics/Generic/GenericList.inc
r29 r30 1 1 {$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) 2 13 3 14 TGList = class; … … 13 24 FItems: array of TGListItem; 14 25 FCount: TGListIndex; 26 FUpdateCount: Integer; 27 FOnUpdate: TNotifyEvent; 15 28 function Get(Index: TGListIndex): TGListItem; 16 29 function GetCapacity: TGListIndex; … … 21 34 procedure SetLast(AValue: TGListItem); 22 35 procedure SetFirst(AValue: TGListItem); 36 procedure QuickSort(L, R : TGListIndex; Compare: TGListSortCompare); 37 protected 23 38 procedure Put(Index: TGListIndex; const AValue: TGListItem); virtual; 24 39 procedure SetCount(const AValue: TGListIndex); virtual; 25 procedure QuickSort(L, R : TGListIndex; Compare: TGListSortCompare);26 40 public 41 type 42 PItem = ^TGListItem; 43 function CompareMem(P1, P2: Pointer; Length: cardinal): Boolean; inline; 27 44 function Add(Item: TGListItem): TGListIndex; 28 45 procedure AddArray(Values: array of TGListItem); 29 46 procedure AddList(List: TGList); 47 procedure AddListPart(List: TGList; ItemIndex, ItemCount: TGListIndex); 30 48 procedure Assign(Source: TGList); virtual; 49 constructor Create; virtual; 31 50 procedure Clear; virtual; 32 51 procedure Delete(Index: TGListIndex); virtual; … … 38 57 property First: TGListItem read GetFirst write SetFirst; 39 58 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); 41 62 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; 43 64 function IndexOfList(List: TGList; Start: TGListIndex = 0): TGListIndex; 65 function IndexOfArray(Values: array of TGListItem; Start: TGListIndex = 0): TGListIndex; 44 66 procedure Insert(Index: TGListIndex; Item: TGListItem); 45 67 procedure InsertList(Index: TGListIndex; List: TGList); 46 68 procedure InsertArray(Index: TGListIndex; Values: array of TGListItem); 69 procedure InsertCount(Index: TGListIndex; ACount: TGListIndex); 47 70 procedure Move(CurIndex, NewIndex: TGListIndex); 48 71 procedure MoveItems(CurIndex, NewIndex, Count: TGListIndex); 49 72 function Remove(Item: TGListItem): TGListIndex; 50 73 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); 52 79 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; 54 84 property Count: TGListIndex read FCount write SetCount; 55 85 property Capacity: TGListIndex read GetCapacity write SetCapacity; 56 86 property Items[Index: TGListIndex]: TGListItem read Get write Put; default; 57 87 property Last: TGListItem read GetLast write SetLast; 88 property OnUpdate: TNotifyEvent read FOnUpdate write FOnUpdate; 58 89 end; 59 90 … … 73 104 { TGList } 74 105 75 procedure TGList.Replace(Index: TGListIndex; Source: TGList); 106 constructor TGList.Create; 107 begin 108 FCount := 0; 109 end; 110 111 procedure TGList.GetBuffer(Index: TGListIndex; var Buffer; Count: TGListIndex); 112 var 113 P: PItem; 114 I: TGListIndex; 115 begin 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; 125 end; 126 127 procedure TGList.ReplaceBuffer(Index: TGListIndex; var Buffer; Count: TGListIndex); 128 var 129 P: PItem; 130 I: TGListIndex; 131 begin 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; 141 end; 142 143 procedure TGList.ReplaceArray(Index: TGListIndex; Values: array of TGListItem); 144 var 145 I: TGListIndex; 146 begin 147 I := 0; 148 while I < Length(Values) do begin 149 Items[Index + I] := Values[I]; 150 I := I + 1; 151 end; 152 Update; 153 end; 154 155 procedure TGList.ReplaceList(Index: TGListIndex; Source: TGList); 76 156 var 77 157 I: TGListIndex; … … 82 162 I := I + 1; 83 163 end; 164 Update; 165 end; 166 167 procedure TGList.ReplaceListPart(Index: TGListIndex; Source: TGList; 168 SourceIndex, SourceCount: TGListIndex); 169 var 170 I: TGListIndex; 171 begin 172 I := 0; 173 while I < SourceCount do begin 174 Items[Index + I] := Source[SourceIndex + I]; 175 I := I + 1; 176 end; 177 Update; 84 178 end; 85 179 … … 143 237 end; 144 238 145 function TGList.GetArray : TGListItemArray;239 function TGList.GetArray(Index, ACount: TGListIndex): TGListItemArray; 146 240 var 147 241 I: Integer; 148 242 begin 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; 249 end; 250 251 procedure TGList.GetList(List: TGList; Index, ACount: TGListIndex); 252 begin 253 List.Clear; 254 List.AddListPart(Self, Index, ACount); 155 255 end; 156 256 … … 194 294 I := I + 1; 195 295 end; 296 Update; 196 297 end; 197 298 … … 208 309 end; 209 310 311 function TGList.CompareMem(P1, P2: Pointer; Length: cardinal): Boolean; 312 var 313 I: Cardinal; 314 begin 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; 325 end; 326 210 327 function TGList.IndexOf(Item: TGListItem; Start: TGListIndex): TGListIndex; 211 328 begin 212 329 Result := Start; 213 330 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 215 333 Result := Result + 1; 216 334 if Result = FCount then Result := -1; … … 219 337 procedure TGList.Insert(Index: TGListIndex; Item: TGListItem); 220 338 begin 221 if (Index < 0) or (Index > FCount 339 if (Index < 0) or (Index > FCount) then 222 340 raise EListError.CreateFmt(SListIndexError, [Index]); 223 if FCount = Capacity then SetCapacityOptimized(Capacity + 1); 341 InsertCount(Index, 1); 342 FItems[Index] := Item; 343 Update; 344 end; 345 346 procedure TGList.InsertList(Index: TGListIndex; List: TGList); 347 begin 348 if (Index < 0) or (Index > FCount) then 349 raise EListError.CreateFmt(SListIndexError, [Index]); 350 InsertCount(Index, List.Count); 351 ReplaceList(Index, List); 352 end; 353 354 procedure TGList.InsertArray(Index: TGListIndex; Values: array of TGListItem); 355 begin 356 if (Index < 0) or (Index > FCount) then 357 raise EListError.CreateFmt(SListIndexError, [Index]); 358 InsertCount(Index, Length(Values)); 359 ReplaceArray(Index, Values); 360 end; 361 362 procedure TGList.InsertCount(Index: TGListIndex; ACount: TGListIndex); 363 begin 364 if (Index < 0) or (Index > FCount) then 365 raise EListError.CreateFmt(SListIndexError, [Index]); 366 Count := Count + ACount; 224 367 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; 239 370 end; 240 371 … … 258 389 end; 259 390 391 function TGList.IndexOfArray(Values: array of TGListItem; Start: TGListIndex): TGListIndex; 392 var 393 I: TGListIndex; 394 begin 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; 408 end; 409 260 410 function TGList.GetLast: TGListItem; 261 411 begin … … 308 458 //Delete(CurIndex); 309 459 //Insert(NewIndex, Temp); 460 Update; 310 461 end; 311 462 … … 333 484 end; 334 485 end; 486 Update; 335 487 end; 336 488 … … 339 491 Result := IndexOf(Item); 340 492 if Result <> -1 then 341 Delete(Result); 493 Delete(Result) 494 else raise Exception.CreateFmt(SItemNotFound, [0]); 342 495 end; 343 496 … … 368 521 I := I + 1; 369 522 end; 523 Update; 370 524 end; 371 525 … … 374 528 if FCount > 1 then 375 529 QuickSort(0, FCount - 1, Compare); 530 Update; 376 531 end; 377 532 … … 385 540 I := I + 1; 386 541 end; 387 end; 388 389 procedure TGList.SetArray(Values: TGListItemArray); 542 Update; 543 end; 544 545 procedure TGList.SetArray(Values: array of TGListItem); 390 546 var 391 547 I: TGListIndex; … … 399 555 end; 400 556 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; 557 procedure TGList.BeginUpdate; 558 begin 559 Inc(FUpdateCount); 560 end; 561 562 procedure TGList.EndUpdate; 563 begin 564 Dec(FUpdateCount); 565 Update; 566 end; 567 568 procedure TGList.Update; 569 begin 570 if Assigned(FOnUpdate) and (FUpdateCount = 0) then FOnUpdate(Self); 410 571 end; 411 572 … … 440 601 Result := FCount - 1; 441 602 FItems[Result] := Item; 603 Update; 442 604 end; 443 605 … … 445 607 var 446 608 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; 610 begin 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; 620 end; 621 622 procedure TGList.AddListPart(List: TGList; ItemIndex, ItemCount: TGListIndex); 623 var 624 I: TGListIndex; 625 J: TGListIndex; 626 begin 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; 453 636 end; 454 637 … … 466 649 System.Move(FItems[Index + 1], FItems[Index], (FCount - Index) * SizeOf(TGListItem)); 467 650 SetCapacityOptimized(Capacity - 1); 651 Update; 468 652 end; 469 653 … … 477 661 I := I + 1; 478 662 end; 663 Update; 479 664 end; 480 665 … … 488 673 I := I + 1; 489 674 end; 675 Update; 490 676 end; 491 677 … … 501 687 FItems[Index1] := FItems[Index2]; 502 688 FItems[Index2] := Temp; 689 Update; 503 690 end; 504 691
Note:
See TracChangeset
for help on using the changeset viewer.