simplelinkedlist.pas 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. unit simplelinkedlist;
  2. {$mode objfpc}
  3. interface
  4. Type
  5. TLinkedListItem = Class
  6. Public
  7. Next : TLinkedListItem;
  8. end;
  9. TLinkedListItemClass = Class of TLinkedListItem;
  10. { TLinkedListVisitor }
  11. TLinkedListVisitor = Class
  12. Function Visit(Item : TLinkedListItem) : Boolean; virtual; abstract;
  13. end;
  14. { TLinkedList }
  15. TLinkedList = Class
  16. private
  17. FItemClass: TLinkedListItemClass;
  18. FRoot: TLinkedListItem;
  19. function GetCount: Integer;
  20. Public
  21. Constructor Create(AnItemClass : TLinkedListItemClass); virtual;
  22. Destructor Destroy; override;
  23. Procedure Clear;
  24. Function Add : TLinkedListItem;
  25. Procedure ForEach(Visitor: TLinkedListVisitor);
  26. Procedure RemoveItem(Item : TLinkedListItem; FreeItem : Boolean = False);
  27. Property Root : TLinkedListItem Read FRoot;
  28. Property ItemClass : TLinkedListItemClass Read FItemClass;
  29. Property Count : Integer Read GetCount;
  30. end;
  31. implementation
  32. uses sysutils;
  33. { TLinkedList }
  34. function TLinkedList.GetCount: Integer;
  35. Var
  36. I : TLinkedListItem;
  37. begin
  38. I:=FRoot;
  39. Result:=0;
  40. While I<>Nil do
  41. begin
  42. I:=I.Next;
  43. Inc(Result);
  44. end;
  45. end;
  46. constructor TLinkedList.Create(AnItemClass: TLinkedListItemClass);
  47. begin
  48. FItemClass:=AnItemClass;
  49. end;
  50. destructor TLinkedList.Destroy;
  51. begin
  52. Clear;
  53. inherited Destroy;
  54. end;
  55. procedure TLinkedList.Clear;
  56. Var
  57. I : TLinkedListItem;
  58. begin
  59. // Can't use visitor, because it'd kill the next pointer...
  60. I:=FRoot;
  61. While I<>Nil do
  62. begin
  63. FRoot:=I;
  64. I:=I.Next;
  65. FRoot.Next:=Nil;
  66. FreeAndNil(FRoot);
  67. end;
  68. end;
  69. function TLinkedList.Add: TLinkedListItem;
  70. begin
  71. Result:=FItemClass.Create;
  72. Result.Next:=FRoot;
  73. FRoot:=Result;
  74. end;
  75. procedure TLinkedList.ForEach(Visitor : TLinkedListVisitor);
  76. Var
  77. I : TLinkedListItem;
  78. begin
  79. I:=FRoot;
  80. While (I<>Nil) and Visitor.Visit(I) do
  81. I:=I.Next;
  82. end;
  83. procedure TLinkedList.RemoveItem(Item: TLinkedListItem; FreeItem : Boolean = False);
  84. Var
  85. I : TLinkedListItem;
  86. begin
  87. If (Item<>Nil) and (FRoot<>Nil) then
  88. begin
  89. If (Item=FRoot) then
  90. FRoot:=Item.Next
  91. else
  92. begin
  93. I:=FRoot;
  94. While (I.Next<>Nil) and (I.Next<>Item) do
  95. I:=I.Next;
  96. If (I.Next=Item) then
  97. I.Next:=Item.Next;
  98. end;
  99. If FreeItem Then
  100. Item.Free;
  101. end;
  102. end;
  103. end.