Changeset 90 for trunk/Packages/TemplateGenerics/Generic/GenericList.inc
- Timestamp:
- Sep 7, 2012, 6:45:53 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Packages/TemplateGenerics/Generic/GenericList.inc
r84 r90 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; 27 43 function CompareMem(P1, P2: Pointer; Length: cardinal): Boolean; inline; 28 44 function Add(Item: TGListItem): TGListIndex; … … 41 57 property First: TGListItem read GetFirst write SetFirst; 42 58 procedure Fill(Start, Count: TGListIndex; Value: TGListItem); 43 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); 44 62 function Implode(Separator: string; Converter: TGListToStringConverter): string; 45 63 function IndexOf(Item: TGListItem; Start: TGListIndex = 0): TGListIndex; virtual; 46 64 function IndexOfList(List: TGList; Start: TGListIndex = 0): TGListIndex; 65 function IndexOfArray(Values: array of TGListItem; Start: TGListIndex = 0): TGListIndex; 47 66 procedure Insert(Index: TGListIndex; Item: TGListItem); 48 67 procedure InsertList(Index: TGListIndex; List: TGList); 49 68 procedure InsertArray(Index: TGListIndex; Values: array of TGListItem); 69 procedure InsertCount(Index: TGListIndex; ACount: TGListIndex); 50 70 procedure Move(CurIndex, NewIndex: TGListIndex); 51 71 procedure MoveItems(CurIndex, NewIndex, Count: TGListIndex); 52 72 function Remove(Item: TGListItem): TGListIndex; 53 73 procedure Reverse; 74 procedure ReplaceArray(Index: TGListIndex; Values: array of TGListItem); 54 75 procedure ReplaceList(Index: TGListIndex; Source: TGList); 55 76 procedure ReplaceListPart(Index: TGListIndex; Source: TGList; 56 77 SourceIndex, SourceCount: TGListIndex); 78 procedure ReplaceBuffer(Index: TGListIndex; var Buffer; Count: TGListIndex); 57 79 procedure Sort(Compare: TGListSortCompare); 58 80 procedure SetArray(Values: array of TGListItem); 81 procedure BeginUpdate; 82 procedure EndUpdate; 83 procedure Update; 59 84 property Count: TGListIndex read FCount write SetCount; 60 85 property Capacity: TGListIndex read GetCapacity write SetCapacity; 61 86 property Items[Index: TGListIndex]: TGListItem read Get write Put; default; 62 87 property Last: TGListItem read GetLast write SetLast; 88 property OnUpdate: TNotifyEvent read FOnUpdate write FOnUpdate; 63 89 end; 64 90 … … 83 109 end; 84 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 85 155 procedure TGList.ReplaceList(Index: TGListIndex; Source: TGList); 86 156 var … … 92 162 I := I + 1; 93 163 end; 164 Update; 94 165 end; 95 166 … … 104 175 I := I + 1; 105 176 end; 177 Update; 106 178 end; 107 179 … … 165 237 end; 166 238 167 function TGList.GetArray : TGListItemArray;239 function TGList.GetArray(Index, ACount: TGListIndex): TGListItemArray; 168 240 var 169 241 I: Integer; 170 242 begin 171 SetLength(Result, Count); 172 I := 0; 173 while I < Count do begin 174 Result[I] := FItems[I]; 175 I := I + 1; 176 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); 177 255 end; 178 256 … … 216 294 I := I + 1; 217 295 end; 296 Update; 218 297 end; 219 298 … … 250 329 Result := Start; 251 330 while (Result < FCount) and 252 not CompareMem(@FItems[Result], @Item, SizeOf(TGListItem)) do253 //not (CompareByte(FItems[Result], Item, SizeOf(TGListItem)) = 0) do331 // not CompareMem(@FItems[Result], @Item, SizeOf(TGListItem)) do 332 not (CompareByte(FItems[Result], Item, SizeOf(TGListItem)) = 0) do 254 333 Result := Result + 1; 255 334 if Result = FCount then Result := -1; … … 258 337 procedure TGList.Insert(Index: TGListIndex; Item: TGListItem); 259 338 begin 260 if (Index < 0) or (Index > FCount 339 if (Index < 0) or (Index > FCount) then 261 340 raise EListError.CreateFmt(SListIndexError, [Index]); 262 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; 263 367 if Index < FCount then 264 System.Move(FItems[Index], FItems[Index + 1], (FCount - Index) * SizeOf(TGListItem)); 265 FItems[Index] := Item; 266 FCount := FCount + 1; 267 end; 268 269 procedure TGList.InsertList(Index: TGListIndex; List: TGList); 270 var 271 I: TGListIndex; 272 begin 273 I := 0; 274 while (I < List.Count) do begin 275 Insert(Index + I, List[I]); 276 I := I + 1; 277 end; 368 System.Move(FItems[Index], FItems[Index + ACount], (FCount - ACount - Index) * SizeOf(TGListItem)); 369 Update; 278 370 end; 279 371 … … 297 389 end; 298 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 299 410 function TGList.GetLast: TGListItem; 300 411 begin … … 347 458 //Delete(CurIndex); 348 459 //Insert(NewIndex, Temp); 460 Update; 349 461 end; 350 462 … … 372 484 end; 373 485 end; 486 Update; 374 487 end; 375 488 … … 378 491 Result := IndexOf(Item); 379 492 if Result <> -1 then 380 Delete(Result); 493 Delete(Result) 494 else raise Exception.CreateFmt(SItemNotFound, [0]); 381 495 end; 382 496 … … 407 521 I := I + 1; 408 522 end; 523 Update; 409 524 end; 410 525 … … 413 528 if FCount > 1 then 414 529 QuickSort(0, FCount - 1, Compare); 530 Update; 415 531 end; 416 532 … … 424 540 I := I + 1; 425 541 end; 542 Update; 426 543 end; 427 544 … … 438 555 end; 439 556 440 procedure TGList.InsertArray(Index: TGListIndex; Values: array of TGListItem); 441 var 442 I: TGListIndex; 443 begin 444 I := 0; 445 while I <= High(Values) do begin 446 Insert(Index + I, Values[I]); 447 I := I + 1; 448 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); 449 571 end; 450 572 … … 479 601 Result := FCount - 1; 480 602 FItems[Result] := Item; 603 Update; 481 604 end; 482 605 … … 494 617 J := J + 1; 495 618 end; 619 Update; 496 620 end; 497 621 … … 509 633 J := J + 1; 510 634 end; 635 Update; 511 636 end; 512 637 … … 524 649 System.Move(FItems[Index + 1], FItems[Index], (FCount - Index) * SizeOf(TGListItem)); 525 650 SetCapacityOptimized(Capacity - 1); 651 Update; 526 652 end; 527 653 … … 535 661 I := I + 1; 536 662 end; 663 Update; 537 664 end; 538 665 … … 546 673 I := I + 1; 547 674 end; 675 Update; 548 676 end; 549 677 … … 559 687 FItems[Index1] := FItems[Index2]; 560 688 FItems[Index2] := Temp; 689 Update; 561 690 end; 562 691
Note:
See TracChangeset
for help on using the changeset viewer.