Advertisement
Guest User

Delphi 7. Contnrs.pas

a guest
Mar 28th, 2014
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 19.25 KB | None | 0 0
  1. { *********************************************************************** }
  2. {                                                                         }
  3. { Delphi Runtime Library                                                  }
  4. {                                                                         }
  5. { Copyright (c) 1995-2001 Borland Software Corporation                    }
  6. {                                                                         }
  7. { *********************************************************************** }
  8.  
  9. unit Contnrs;
  10.  
  11. interface
  12.  
  13. uses
  14.   SysUtils, Classes;
  15.  
  16. type
  17.  
  18. { TObjectList class }
  19.  
  20.   TObjectList = class(TList)
  21.   private
  22.     FOwnsObjects: Boolean;
  23.   protected
  24.     procedure Notify(Ptr: Pointer; Action: TListNotification); override;
  25.     function GetItem(Index: Integer): TObject;
  26.     procedure SetItem(Index: Integer; AObject: TObject);
  27.   public
  28.     constructor Create; overload;
  29.     constructor Create(AOwnsObjects: Boolean); overload;
  30.  
  31.     function Add(AObject: TObject): Integer;
  32.     function Extract(Item: TObject): TObject;
  33.     function Remove(AObject: TObject): Integer;
  34.     function IndexOf(AObject: TObject): Integer;
  35.     function FindInstanceOf(AClass: TClass; AExact: Boolean = True; AStartAt: Integer = 0): Integer;
  36.     procedure Insert(Index: Integer; AObject: TObject);
  37.     function First: TObject;
  38.     function Last: TObject;
  39.     property OwnsObjects: Boolean read FOwnsObjects write FOwnsObjects;
  40.     property Items[Index: Integer]: TObject read GetItem write SetItem; default;
  41.   end;
  42.  
  43. { TComponentList class }
  44.  
  45.   TComponentList = class(TObjectList)
  46.   private
  47.     FNexus: TComponent;
  48.   protected
  49.     procedure Notify(Ptr: Pointer; Action: TListNotification); override;
  50.     function GetItems(Index: Integer): TComponent;
  51.     procedure SetItems(Index: Integer; AComponent: TComponent);
  52.     procedure HandleFreeNotify(Sender: TObject; AComponent: TComponent);
  53.   public
  54.     destructor Destroy; override;
  55.  
  56.     function Add(AComponent: TComponent): Integer;
  57.     function Extract(Item: TComponent): TComponent;
  58.     function Remove(AComponent: TComponent): Integer;
  59.     function IndexOf(AComponent: TComponent): Integer;
  60.     function First: TComponent;
  61.     function Last: TComponent;
  62.     procedure Insert(Index: Integer; AComponent: TComponent);
  63.     property Items[Index: Integer]: TComponent read GetItems write SetItems; default;
  64.   end;
  65.  
  66. { TClassList class }
  67.  
  68.   TClassList = class(TList)
  69.   protected
  70.     function GetItems(Index: Integer): TClass;
  71.     procedure SetItems(Index: Integer; AClass: TClass);
  72.   public
  73.     function Add(AClass: TClass): Integer;
  74.     function Extract(Item: TClass): TClass;
  75.     function Remove(AClass: TClass): Integer;
  76.     function IndexOf(AClass: TClass): Integer;
  77.     function First: TClass;
  78.     function Last: TClass;
  79.     procedure Insert(Index: Integer; AClass: TClass);
  80.     property Items[Index: Integer]: TClass read GetItems write SetItems; default;
  81.   end;
  82.  
  83. { TOrdered class }
  84.  
  85.   TOrderedList = class(TObject)
  86.   private
  87.     FList: TList;
  88.   protected
  89.     procedure PushItem(AItem: Pointer); virtual; abstract;
  90.     function PopItem: Pointer; virtual;
  91.     function PeekItem: Pointer; virtual;
  92.     property List: TList read FList;
  93.   public
  94.     constructor Create;
  95.     destructor Destroy; override;
  96.  
  97.     function Count: Integer;
  98.     function AtLeast(ACount: Integer): Boolean;
  99.     function Push(AItem: Pointer): Pointer;
  100.     function Pop: Pointer;
  101.     function Peek: Pointer;
  102.   end;
  103.  
  104. { TStack class }
  105.  
  106.   TStack = class(TOrderedList)
  107.   protected
  108.     procedure PushItem(AItem: Pointer); override;
  109.   end;
  110.  
  111. { TObjectStack class }
  112.  
  113.   TObjectStack = class(TStack)
  114.   public
  115.     function Push(AObject: TObject): TObject;
  116.     function Pop: TObject;
  117.     function Peek: TObject;
  118.   end;
  119.  
  120. { TQueue class }
  121.  
  122.   TQueue = class(TOrderedList)
  123.   protected
  124.     procedure PushItem(AItem: Pointer); override;
  125.   end;
  126.  
  127. { TObjectQueue class }
  128.  
  129.   TObjectQueue = class(TQueue)
  130.   public
  131.     function Push(AObject: TObject): TObject;
  132.     function Pop: TObject;
  133.     function Peek: TObject;
  134.   end;
  135.  
  136. { TBucketList, Hashed associative list }
  137.  
  138.   TCustomBucketList = class;
  139.  
  140.   TBucketItem = record
  141.     Item, Data: Pointer;
  142.   end;
  143.   TBucketItemArray = array of TBucketItem;
  144.  
  145.   TBucket = record
  146.     Count: Integer;
  147.     Items: TBucketItemArray;
  148.   end;
  149.   TBucketArray = array of TBucket;
  150.  
  151.   TBucketProc = procedure(AInfo, AItem, AData: Pointer; out AContinue: Boolean);
  152.  
  153.   TCustomBucketList = class(TObject)
  154.   private
  155.     FBuckets: TBucketArray;
  156.     FBucketCount: Integer;
  157.     FListLocked: Boolean;
  158.     FClearing: Boolean;
  159.     function GetData(AItem: Pointer): Pointer;
  160.     procedure SetData(AItem: Pointer; const AData: Pointer);
  161.     procedure SetBucketCount(const Value: Integer);
  162.   protected
  163.     property Buckets: TBucketArray read FBuckets;
  164.     property BucketCount: Integer read FBucketCount write SetBucketCount;
  165.  
  166.     function BucketFor(AItem: Pointer): Integer; virtual; abstract;
  167.  
  168.     function FindItem(AItem: Pointer; out ABucket, AIndex: Integer): Boolean; virtual;
  169.     function AddItem(ABucket: Integer; AItem, AData: Pointer): Pointer; virtual;
  170.     function DeleteItem(ABucket: Integer; AIndex: Integer): Pointer; virtual;
  171.   public
  172.     destructor Destroy; override;
  173.     procedure Clear;
  174.  
  175.     function Add(AItem, AData: Pointer): Pointer;
  176.     function Remove(AItem: Pointer): Pointer;
  177.  
  178.     function ForEach(AProc: TBucketProc; AInfo: Pointer = nil): Boolean;
  179.     procedure Assign(AList: TCustomBucketList);
  180.  
  181.     function Exists(AItem: Pointer): Boolean;
  182.     function Find(AItem: Pointer; out AData: Pointer): Boolean;
  183.     property Data[AItem: Pointer]: Pointer read GetData write SetData; default;
  184.   end;
  185.  
  186. { TBucketList }
  187.  
  188.   TBucketListSizes = (bl2, bl4, bl8, bl16, bl32, bl64, bl128, bl256);
  189.  
  190.   TBucketList = class(TCustomBucketList)
  191.   private
  192.     FBucketMask: Byte;
  193.   protected
  194.     function BucketFor(AItem: Pointer): Integer; override;
  195.   public
  196.     constructor Create(ABuckets: TBucketListSizes = bl16);
  197.   end;
  198.  
  199. { TObjectBucketList }
  200.  
  201.   TObjectBucketList = class(TBucketList)
  202.   protected
  203.     function GetData(AItem: TObject): TObject;
  204.     procedure SetData(AItem: TObject; const AData: TObject);
  205.   public
  206.     function Add(AItem, AData: TObject): TObject;
  207.     function Remove(AItem: TObject): TObject;
  208.  
  209.     property Data[AItem: TObject]: TObject read GetData write SetData; default;
  210.   end;
  211.  
  212. { Easy access error message }
  213.  
  214. procedure RaiseListError(const ATemplate: string; const AData: array of const);
  215.  
  216. implementation
  217.  
  218. uses
  219.   RTLConsts, Math;
  220.  
  221. { Easy access error message }
  222.  
  223. procedure RaiseListError(const ATemplate: string; const AData: array of const);
  224.  
  225.   function ReturnAddr: Pointer;
  226.   asm
  227.     MOV EAX,[EBP+4]
  228.   end;
  229.  
  230. begin
  231.   raise EListError.CreateFmt(ATemplate, AData) at ReturnAddr;
  232. end;
  233.  
  234. { TObjectList }
  235.  
  236. function TObjectList.Add(AObject: TObject): Integer;
  237. begin
  238.   Result := inherited Add(AObject);
  239. end;
  240.  
  241. constructor TObjectList.Create;
  242. begin
  243.   inherited Create;
  244.   FOwnsObjects := True;
  245. end;
  246.  
  247. constructor TObjectList.Create(AOwnsObjects: Boolean);
  248. begin
  249.   inherited Create;
  250.   FOwnsObjects := AOwnsObjects;
  251. end;
  252.  
  253. function TObjectList.Extract(Item: TObject): TObject;
  254. begin
  255.   Result := TObject(inherited Extract(Item));
  256. end;
  257.  
  258. function TObjectList.FindInstanceOf(AClass: TClass; AExact: Boolean;
  259.   AStartAt: Integer): Integer;
  260. var
  261.   I: Integer;
  262. begin
  263.   Result := -1;
  264.   for I := AStartAt to Count - 1 do
  265.     if (AExact and
  266.         (Items[I].ClassType = AClass)) or
  267.        (not AExact and
  268.         Items[I].InheritsFrom(AClass)) then
  269.     begin
  270.       Result := I;
  271.       break;
  272.     end;
  273. end;
  274.  
  275. function TObjectList.First: TObject;
  276. begin
  277.   Result := TObject(inherited First);
  278. end;
  279.  
  280. function TObjectList.GetItem(Index: Integer): TObject;
  281. begin
  282.   Result := inherited Items[Index];
  283. end;
  284.  
  285. function TObjectList.IndexOf(AObject: TObject): Integer;
  286. begin
  287.   Result := inherited IndexOf(AObject);
  288. end;
  289.  
  290. procedure TObjectList.Insert(Index: Integer; AObject: TObject);
  291. begin
  292.   inherited Insert(Index, AObject);
  293. end;
  294.  
  295. function TObjectList.Last: TObject;
  296. begin
  297.   Result := TObject(inherited Last);
  298. end;
  299.  
  300. procedure TObjectList.Notify(Ptr: Pointer; Action: TListNotification);
  301. begin
  302.   if OwnsObjects then
  303.     if Action = lnDeleted then
  304.       TObject(Ptr).Free;
  305.   inherited Notify(Ptr, Action);
  306. end;
  307.  
  308. function TObjectList.Remove(AObject: TObject): Integer;
  309. begin
  310.   Result := inherited Remove(AObject);
  311. end;
  312.  
  313. procedure TObjectList.SetItem(Index: Integer; AObject: TObject);
  314. begin
  315.   inherited Items[Index] := AObject;
  316. end;
  317.  
  318.  
  319. { TComponentListNexus }
  320. { used by TComponentList to get free notification }
  321.  
  322. type
  323.   TComponentListNexusEvent = procedure(Sender: TObject; AComponent: TComponent) of object;
  324.   TComponentListNexus = class(TComponent)
  325.   private
  326.     FOnFreeNotify: TComponentListNexusEvent;
  327.   protected
  328.     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  329.   public
  330.     property OnFreeNotify: TComponentListNexusEvent read FOnFreeNotify write FOnFreeNotify;
  331.   end;
  332.  
  333. { TComponentListNexus }
  334.  
  335. procedure TComponentListNexus.Notification(AComponent: TComponent; Operation: TOperation);
  336. begin
  337.   if (Operation = opRemove) and Assigned(FOnFreeNotify) then
  338.     FOnFreeNotify(Self, AComponent);
  339.   inherited Notification(AComponent, Operation);
  340. end;
  341.  
  342. { TComponentList }
  343.  
  344. function TComponentList.Add(AComponent: TComponent): Integer;
  345. begin
  346.   Result := inherited Add(AComponent);
  347. end;
  348.  
  349. destructor TComponentList.Destroy;
  350. begin
  351.   inherited Destroy;
  352.   FNexus.Free;
  353. end;
  354.  
  355. function TComponentList.Extract(Item: TComponent): TComponent;
  356. begin
  357.   Result := TComponent(inherited Extract(Item));
  358. end;
  359.  
  360. function TComponentList.First: TComponent;
  361. begin
  362.   Result := TComponent(inherited First);
  363. end;
  364.  
  365. function TComponentList.GetItems(Index: Integer): TComponent;
  366. begin
  367.   Result := TComponent(inherited Items[Index]);
  368. end;
  369.  
  370. procedure TComponentList.HandleFreeNotify(Sender: TObject; AComponent: TComponent);
  371. begin
  372.   Extract(AComponent);
  373. end;
  374.  
  375. function TComponentList.IndexOf(AComponent: TComponent): Integer;
  376. begin
  377.   Result := inherited IndexOf(AComponent);
  378. end;
  379.  
  380. procedure TComponentList.Insert(Index: Integer; AComponent: TComponent);
  381. begin
  382.   inherited Insert(Index, AComponent);
  383. end;
  384.  
  385. function TComponentList.Last: TComponent;
  386. begin
  387.   Result := TComponent(inherited Last);
  388. end;
  389.  
  390. procedure TComponentList.Notify(Ptr: Pointer; Action: TListNotification);
  391. begin
  392.   if not Assigned(FNexus) then
  393.   begin
  394.     FNexus := TComponentListNexus.Create(nil);
  395.     TComponentListNexus(FNexus).OnFreeNotify := HandleFreeNotify;
  396.   end;
  397.   case Action of
  398.     lnAdded:
  399.       if Ptr <> nil then
  400.         TComponent(Ptr).FreeNotification(FNexus);
  401.     lnExtracted,
  402.     lnDeleted:
  403.       if Ptr <> nil then
  404.         TComponent(Ptr).RemoveFreeNotification(FNexus);
  405.   end;
  406.   inherited Notify(Ptr, Action);
  407. end;
  408.  
  409. function TComponentList.Remove(AComponent: TComponent): Integer;
  410. begin
  411.   Result := inherited Remove(AComponent);
  412. end;
  413.  
  414. procedure TComponentList.SetItems(Index: Integer; AComponent: TComponent);
  415. begin
  416.   inherited Items[Index] := AComponent;
  417. end;
  418.  
  419. { TClassList }
  420.  
  421. function TClassList.Add(AClass: TClass): Integer;
  422. begin
  423.   Result := inherited Add(AClass);
  424. end;
  425.  
  426. function TClassList.Extract(Item: TClass): TClass;
  427. begin
  428.   Result := TClass(inherited Extract(Item));
  429. end;
  430.  
  431. function TClassList.First: TClass;
  432. begin
  433.   Result := TClass(inherited First);
  434. end;
  435.  
  436. function TClassList.GetItems(Index: Integer): TClass;
  437. begin
  438.   Result := TClass(inherited Items[Index]);
  439. end;
  440.  
  441. function TClassList.IndexOf(AClass: TClass): Integer;
  442. begin
  443.   Result := inherited IndexOf(AClass);
  444. end;
  445.  
  446. procedure TClassList.Insert(Index: Integer; AClass: TClass);
  447. begin
  448.   inherited Insert(Index, AClass);
  449. end;
  450.  
  451. function TClassList.Last: TClass;
  452. begin
  453.   Result := TClass(inherited Last);
  454. end;
  455.  
  456. function TClassList.Remove(AClass: TClass): Integer;
  457. begin
  458.   Result := inherited Remove(AClass);
  459. end;
  460.  
  461. procedure TClassList.SetItems(Index: Integer; AClass: TClass);
  462. begin
  463.   inherited Items[Index] := AClass;
  464. end;
  465.  
  466. { TOrderedList }
  467.  
  468. function TOrderedList.AtLeast(ACount: integer): boolean;
  469. begin
  470.   Result := List.Count >= ACount;
  471. end;
  472.  
  473. function TOrderedList.Peek: Pointer;
  474. begin
  475.   Result := PeekItem;
  476. end;
  477.  
  478. function TOrderedList.Pop: Pointer;
  479. begin
  480.   Result := PopItem;
  481. end;
  482.  
  483. function TOrderedList.Push(AItem: Pointer): Pointer;
  484. begin
  485.   PushItem(AItem);
  486.   Result := AItem;
  487. end;
  488.  
  489. function TOrderedList.Count: Integer;
  490. begin
  491.   Result := List.Count;
  492. end;
  493.  
  494. constructor TOrderedList.Create;
  495. begin
  496.   inherited Create;
  497.   FList := TList.Create;
  498. end;
  499.  
  500. destructor TOrderedList.Destroy;
  501. begin
  502.   List.Free;
  503.   inherited Destroy;
  504. end;
  505.  
  506. function TOrderedList.PeekItem: Pointer;
  507. begin
  508.   Result := List[List.Count-1];
  509. end;
  510.  
  511. function TOrderedList.PopItem: Pointer;
  512. begin
  513.   Result := PeekItem;
  514.   List.Delete(List.Count-1);
  515. end;
  516.  
  517. { TStack }
  518.  
  519. procedure TStack.PushItem(AItem: Pointer);
  520. begin
  521.   List.Add(AItem);
  522. end;
  523.  
  524. { TObjectStack }
  525.  
  526. function TObjectStack.Peek: TObject;
  527. begin
  528.   Result := TObject(inherited Peek);
  529. end;
  530.  
  531. function TObjectStack.Pop: TObject;
  532. begin
  533.   Result := TObject(inherited Pop);
  534. end;
  535.  
  536. function TObjectStack.Push(AObject: TObject): TObject;
  537. begin
  538.   Result := TObject(inherited Push(AObject));
  539. end;
  540.  
  541. { TQueue }
  542.  
  543. procedure TQueue.PushItem(AItem: Pointer);
  544. begin
  545.   List.Insert(0, AItem);
  546. end;
  547.  
  548. { TObjectQueue }
  549.  
  550. function TObjectQueue.Peek: TObject;
  551. begin
  552.   Result := TObject(inherited Peek);
  553. end;
  554.  
  555. function TObjectQueue.Pop: TObject;
  556. begin
  557.   Result := TObject(inherited Pop);
  558. end;
  559.  
  560. function TObjectQueue.Push(AObject: TObject): TObject;
  561. begin
  562.   Result := TObject(inherited Push(AObject));
  563. end;
  564.  
  565. { TCustomBucketList }
  566.  
  567. function TCustomBucketList.Add(AItem, AData: Pointer): Pointer;
  568. var
  569.   LBucket: Integer;
  570.   LIndex: Integer;
  571. begin
  572.   if FListLocked then
  573.     raise EListError.Create(SBucketListLocked);
  574.   if FindItem(AItem, LBucket, LIndex) then
  575.     raise EListError.CreateFmt(SDuplicateItem, [Integer(AItem)])
  576.   else
  577.     Result := AddItem(LBucket, AItem, AData);
  578. end;
  579.  
  580. function TCustomBucketList.AddItem(ABucket: Integer; AItem, AData: Pointer): Pointer;
  581. var
  582.   LDelta, LSize: Integer;
  583. begin
  584.   with Buckets[ABucket] do
  585.   begin
  586.     LSize := Length(Items);
  587.     if Count = LSize then
  588.     begin
  589.       if LSize > 64 then
  590.         LDelta := LSize div 4
  591.       else if LSize > 8 then
  592.         LDelta := 16
  593.       else
  594.         LDelta := 4;
  595.       SetLength(Items, LSize + LDelta);
  596.     end;
  597.  
  598.     with Items[Count] do
  599.     begin
  600.       Item := AItem;
  601.       Data := AData;
  602.     end;
  603.     Inc(Count);
  604.   end;
  605.   Result := AData;
  606. end;
  607.  
  608. procedure AssignProc(AInfo, AItem, AData: Pointer; out AContinue: Boolean);
  609. begin
  610.   TCustomBucketList(AInfo).Add(AItem, AData);
  611. end;
  612.  
  613. procedure TCustomBucketList.Assign(AList: TCustomBucketList);
  614. begin
  615.   Clear;
  616.   AList.ForEach(AssignProc, Self);
  617. end;
  618.  
  619. procedure TCustomBucketList.Clear;
  620. var
  621.   LBucket, LIndex: Integer;
  622. begin
  623.   if FListLocked then
  624.     raise EListError.Create(SBucketListLocked);
  625.  
  626.   FClearing := True;
  627.   try
  628.     for LBucket := 0 to BucketCount - 1 do
  629.     begin
  630.       for LIndex := Buckets[LBucket].Count - 1 downto 0 do
  631.         DeleteItem(LBucket, LIndex);
  632.  
  633.       SetLength(Buckets[LBucket].Items, 0);
  634.       Buckets[LBucket].Count := 0;
  635.     end;
  636.   finally
  637.     FClearing := False;
  638.   end;
  639. end;
  640.  
  641. function TCustomBucketList.DeleteItem(ABucket, AIndex: Integer): Pointer;
  642. begin
  643.   with Buckets[ABucket] do
  644.   begin
  645.     Result := Items[AIndex].Data;
  646.    
  647.     if not FClearing then
  648.     begin
  649.       if Count = 1 then
  650.         SetLength(Items, 0)
  651.       else
  652.         System.Move(Items[AIndex + 1], Items[AIndex],
  653.                     (Count - AIndex) * SizeOf(TBucketItem));
  654.       Dec(Count);
  655.     end;
  656.   end;
  657. end;
  658.  
  659. destructor TCustomBucketList.Destroy;
  660. begin
  661.   Clear;
  662.   inherited Destroy;
  663. end;
  664.  
  665. function TCustomBucketList.Exists(AItem: Pointer): Boolean;
  666. var
  667.   LBucket, LIndex: Integer;
  668. begin
  669.   Result := FindItem(AItem, LBucket, LIndex);
  670. end;
  671.  
  672. function TCustomBucketList.Find(AItem: Pointer; out AData: Pointer): Boolean;
  673. var
  674.   LBucket, LIndex: Integer;
  675. begin
  676.   Result := FindItem(AItem, LBucket, LIndex);
  677.   if Result then
  678.     AData := Buckets[LBucket].Items[LIndex].Data;
  679. end;
  680.  
  681. function TCustomBucketList.FindItem(AItem: Pointer; out ABucket, AIndex: Integer): Boolean;
  682. var
  683.   I: Integer;
  684. begin
  685.   Result := False;
  686.   ABucket := BucketFor(AItem);
  687.   with FBuckets[ABucket] do
  688.     for I := 0 to Count - 1 do
  689.       if Items[I].Item = AItem then
  690.       begin
  691.         AIndex := I;
  692.         Result := True;
  693.         Break;
  694.       end;
  695. end;
  696.  
  697. function TCustomBucketList.ForEach(AProc: TBucketProc; AInfo: Pointer): Boolean;
  698. var
  699.   LBucket, LIndex: Integer;
  700.   LOldListLocked: Boolean;
  701. begin
  702.   Result := True;
  703.   LOldListLocked := FListLocked;
  704.   FListLocked := True;
  705.   try
  706.     for LBucket := 0 to BucketCount - 1 do
  707.       with Buckets[LBucket] do
  708.         for LIndex := Count - 1 downto 0 do
  709.         begin
  710.           with Items[LIndex] do
  711.             AProc(AInfo, Item, Data, Result);
  712.           if not Result then
  713.             Exit;
  714.         end;
  715.   finally
  716.     FListLocked := LOldListLocked;
  717.   end;
  718. end;
  719.  
  720. function TCustomBucketList.GetData(AItem: Pointer): Pointer;
  721. var
  722.   LBucket, LIndex: Integer;
  723. begin
  724.   if not FindItem(AItem, LBucket, LIndex) then
  725.     raise EListError.CreateFmt(SItemNotFound, [Integer(AItem)]);
  726.   Result := Buckets[LBucket].Items[LIndex].Data;
  727. end;
  728.  
  729. function TCustomBucketList.Remove(AItem: Pointer): Pointer;
  730. var
  731.   LBucket, LIndex: Integer;
  732. begin
  733.   if FListLocked then
  734.     raise EListError.Create(SBucketListLocked);
  735.   Result := nil;
  736.   if FindItem(AItem, LBucket, LIndex) then
  737.     Result := DeleteItem(LBucket, LIndex);
  738. end;
  739.  
  740. procedure TCustomBucketList.SetBucketCount(const Value: Integer);
  741. begin
  742.   if Value <> FBucketCount then
  743.   begin
  744.     FBucketCount := Value;
  745.     SetLength(FBuckets, FBucketCount);
  746.   end;
  747. end;
  748.  
  749. procedure TCustomBucketList.SetData(AItem: Pointer; const AData: Pointer);
  750. var
  751.   LBucket, LIndex: Integer;
  752. begin
  753.   if not FindItem(AItem, LBucket, LIndex) then
  754.     raise EListError.CreateFmt(SItemNotFound, [Integer(AItem)]);
  755.   Buckets[LBucket].Items[LIndex].Data := AData;
  756. end;
  757.  
  758. { TBucketList }
  759.  
  760. function TBucketList.BucketFor(AItem: Pointer): Integer;
  761. begin
  762.   // this can be overridden with your own calculation but remember to
  763.   //  keep it in sync with your bucket count.
  764.   Result := LongRec(AItem).Bytes[1] and FBucketMask;
  765. end;
  766.  
  767. constructor TBucketList.Create(ABuckets: TBucketListSizes);
  768. const
  769.   cBucketMasks: array [TBucketListSizes] of Byte =
  770.     ($01, $03, $07, $0F, $1F, $3F, $7F, $FF);
  771. begin
  772.   inherited Create;
  773.   FBucketMask := CBucketMasks[ABuckets];
  774.   BucketCount := FBucketMask + 1;
  775. end;
  776.  
  777. { TObjectBucketList }
  778.  
  779. function TObjectBucketList.Add(AItem, AData: TObject): TObject;
  780. begin
  781.   Result := TObject(inherited Add(AItem, AData));
  782. end;
  783.  
  784. function TObjectBucketList.GetData(AItem: TObject): TObject;
  785. begin
  786.   Result := TObject(inherited Data[AItem]);
  787. end;
  788.  
  789. function TObjectBucketList.Remove(AItem: TObject): TObject;
  790. begin
  791.   Result := TObject(inherited Remove(AItem));
  792. end;
  793.  
  794. procedure TObjectBucketList.SetData(AItem: TObject; const AData: TObject);
  795. begin
  796.   inherited Data[AItem] := AData;
  797. end;
  798.  
  799. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement