contnrs.pp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. {
  2. $Id$
  3. This file is part of the Free Component Library (FCL)
  4. Copyright (c) 2002 by Florian Klaempfl
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$ifdef fpc}
  12. {$mode objfpc}
  13. {$endif}
  14. unit contnrs;
  15. interface
  16. uses
  17. SysUtils,Classes;
  18. Type
  19. TObjectList = class(TList)
  20. private
  21. ffreeobjects : boolean;
  22. Protected
  23. Procedure Notify(Ptr: Pointer; Action: TListNotification); override;
  24. function GetItem(Index: Integer): TObject;
  25. Procedure SetItem(Index: Integer; AObject: TObject);
  26. public
  27. constructor create;
  28. constructor create(freeobjects : boolean);
  29. function Add(AObject: TObject): Integer;
  30. function Extract(Item: TObject): TObject;
  31. function Remove(AObject: TObject): Integer;
  32. function IndexOf(AObject: TObject): Integer;
  33. function FindInstanceOf(AClass: TClass; AExact: Boolean; AStartAt: Integer): Integer;
  34. Procedure Insert(Index: Integer; AObject: TObject);
  35. function First: TObject;
  36. Function Last: TObject;
  37. property OwnsObjects: Boolean read FFreeObjects write FFreeObjects;
  38. property Items[Index: Integer]: TObject read GetItem write SetItem; default;
  39. end;
  40. TComponentList = class(TObjectList)
  41. Private
  42. FNotifier : TComponent;
  43. Protected
  44. Procedure Notify(Ptr: Pointer; Action: TListNotification); override;
  45. Function GetItems(Index: Integer): TComponent;
  46. Procedure SetItems(Index: Integer; AComponent: TComponent);
  47. Procedure HandleFreeNotify(Sender: TObject; AComponent: TComponent);
  48. public
  49. destructor Destroy; override;
  50. Function Add(AComponent: TComponent): Integer;
  51. Function Extract(Item: TComponent): TComponent;
  52. Function Remove(AComponent: TComponent): Integer;
  53. Function IndexOf(AComponent: TComponent): Integer;
  54. Function First: TComponent;
  55. Function Last: TComponent;
  56. Procedure Insert(Index: Integer; AComponent: TComponent);
  57. property Items[Index: Integer]: TComponent read GetItems write SetItems; default;
  58. end;
  59. TClassList = class(TList)
  60. protected
  61. Function GetItems(Index: Integer): TClass;
  62. Procedure SetItems(Index: Integer; AClass: TClass);
  63. public
  64. Function Add(AClass: TClass): Integer;
  65. Function Extract(Item: TClass): TClass;
  66. Function Remove(AClass: TClass): Integer;
  67. Function IndexOf(AClass: TClass): Integer;
  68. Function First: TClass;
  69. Function Last: TClass;
  70. Procedure Insert(Index: Integer; AClass: TClass);
  71. property Items[Index: Integer]: TClass read GetItems write SetItems; default;
  72. end;
  73. TOrderedList = class(TObject)
  74. private
  75. FList: TList;
  76. protected
  77. Procedure PushItem(AItem: Pointer); virtual; abstract;
  78. Function PopItem: Pointer; virtual;
  79. Function PeekItem: Pointer; virtual;
  80. property List: TList read FList;
  81. public
  82. constructor Create;
  83. destructor Destroy; override;
  84. Function Count: Integer;
  85. Function AtLeast(ACount: Integer): Boolean;
  86. Function Push(AItem: Pointer): Pointer;
  87. Function Pop: Pointer;
  88. Function Peek: Pointer;
  89. end;
  90. { TStack class }
  91. TStack = class(TOrderedList)
  92. protected
  93. Procedure PushItem(AItem: Pointer); override;
  94. end;
  95. { TObjectStack class }
  96. TObjectStack = class(TStack)
  97. public
  98. Function Push(AObject: TObject): TObject;
  99. Function Pop: TObject;
  100. Function Peek: TObject;
  101. end;
  102. { TQueue class }
  103. TQueue = class(TOrderedList)
  104. protected
  105. Procedure PushItem(AItem: Pointer); override;
  106. end;
  107. { TObjectQueue class }
  108. TObjectQueue = class(TQueue)
  109. public
  110. Function Push(AObject: TObject): TObject;
  111. Function Pop: TObject;
  112. Function Peek: TObject;
  113. end;
  114. implementation
  115. constructor tobjectlist.create(freeobjects : boolean);
  116. begin
  117. inherited create;
  118. ffreeobjects:=freeobjects;
  119. end;
  120. Constructor tobjectlist.create;
  121. begin
  122. inherited create;
  123. ffreeobjects:=True;
  124. end;
  125. Procedure TObjectList.Notify(Ptr: Pointer; Action: TListNotification);
  126. begin
  127. if FFreeObjects then
  128. if (Action=lnDeleted) then
  129. TObject(Ptr).Free;
  130. inherited Notify(Ptr,Action);
  131. end;
  132. Function TObjectList.GetItem(Index: Integer): TObject;
  133. begin
  134. Result:=TObject(Inherited Get(Index));
  135. end;
  136. Procedure TObjectList.SetItem(Index: Integer; AObject: TObject);
  137. Var
  138. O : TObject;
  139. begin
  140. if OwnsObjects then
  141. begin
  142. O:=GetItem(Index);
  143. O.Free;
  144. end;
  145. Put(Index,Pointer(AObject));
  146. end;
  147. Function TObjectList.Add(AObject: TObject): Integer;
  148. begin
  149. Result:=Inherited Add(Pointer(AObject));
  150. end;
  151. Function TObjectList.Extract(Item: TObject): TObject;
  152. begin
  153. Result:=Tobject(Inherited Extract(Pointer(Item)));
  154. end;
  155. Function TObjectList.Remove(AObject: TObject): Integer;
  156. begin
  157. Result:=Inherited Remove(Pointer(AObject));
  158. end;
  159. Function TObjectList.IndexOf(AObject: TObject): Integer;
  160. begin
  161. Result:=Inherited indexOF(Pointer(AObject));
  162. end;
  163. Function TObjectList.FindInstanceOf(AClass: TClass; AExact: Boolean; AStartAt : Integer): Integer;
  164. Var
  165. I : Integer;
  166. begin
  167. I:=AStartAt;
  168. Result:=-1;
  169. If AExact then
  170. While (I<Count) and (Result=-1) do
  171. If Items[i].ClassType=AClass then
  172. Result:=I
  173. else
  174. Inc(I)
  175. else
  176. While (I<Count) and (Result=-1) do
  177. If Items[i].InheritsFrom(AClass) then
  178. Result:=I
  179. else
  180. Inc(I);
  181. end;
  182. Procedure TObjectList.Insert(Index: Integer; AObject: TObject);
  183. begin
  184. Inherited Insert(Index,Pointer(AObject));
  185. end;
  186. Function TObjectList.First: TObject;
  187. begin
  188. Result := TObject(Inherited First);
  189. end;
  190. Function TObjectList.Last: TObject;
  191. begin
  192. Result := TObject(Inherited Last);
  193. end;
  194. { TListComponent }
  195. Type
  196. TlistComponent = Class(TComponent)
  197. Private
  198. Flist : TComponentList;
  199. Public
  200. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  201. end;
  202. procedure TlistComponent.Notification(AComponent: TComponent;
  203. Operation: TOperation);
  204. begin
  205. If (Operation=opremove) then
  206. Flist.HandleFreeNotify(Self,AComponent);
  207. inherited;
  208. end;
  209. { TComponentList }
  210. Function TComponentList.Add(AComponent: TComponent): Integer;
  211. begin
  212. Result:=Inherited Add(AComponent);
  213. end;
  214. destructor TComponentList.Destroy;
  215. begin
  216. FNotifier.Free;
  217. inherited;
  218. end;
  219. Function TComponentList.Extract(Item: TComponent): TComponent;
  220. begin
  221. Result:=TComponent(Inherited Extract(Item));
  222. end;
  223. Function TComponentList.First: TComponent;
  224. begin
  225. Result:=TComponent(Inherited First);
  226. end;
  227. Function TComponentList.GetItems(Index: Integer): TComponent;
  228. begin
  229. Result:=TComponent(Inherited Items[Index]);
  230. end;
  231. Procedure TComponentList.HandleFreeNotify(Sender: TObject;
  232. AComponent: TComponent);
  233. begin
  234. Extract(Acomponent);
  235. end;
  236. Function TComponentList.IndexOf(AComponent: TComponent): Integer;
  237. begin
  238. Result:=Inherited IndexOf(AComponent);
  239. end;
  240. Procedure TComponentList.Insert(Index: Integer; AComponent: TComponent);
  241. begin
  242. Inherited Insert(Index,Acomponent)
  243. end;
  244. Function TComponentList.Last: TComponent;
  245. begin
  246. Result:=TComponent(Inherited Last);
  247. end;
  248. Procedure TComponentList.Notify(Ptr: Pointer; Action: TListNotification);
  249. begin
  250. If FNotifier=NIl then
  251. begin
  252. FNotifier:=TlistComponent.Create(nil);
  253. TlistComponent(FNotifier).FList:=Self;
  254. end;
  255. If Assigned(Ptr) then
  256. With TComponent(Ptr) do
  257. case Action of
  258. lnAdded : FreeNotification(FNotifier);
  259. lnExtracted, lnDeleted: RemoveFreeNotification(FNotifier);
  260. end;
  261. inherited Notify(Ptr, Action);
  262. end;
  263. Function TComponentList.Remove(AComponent: TComponent): Integer;
  264. begin
  265. Result:=Inherited Remove(AComponent);
  266. end;
  267. Procedure TComponentList.SetItems(Index: Integer; AComponent: TComponent);
  268. begin
  269. Put(Index,AComponent);
  270. end;
  271. { TClassList }
  272. Function TClassList.Add(AClass: TClass): Integer;
  273. begin
  274. Result:=Inherited Add(Pointer(AClass));
  275. end;
  276. Function TClassList.Extract(Item: TClass): TClass;
  277. begin
  278. Result:=TClass(Inherited Extract(Pointer(Item)));
  279. end;
  280. Function TClassList.First: TClass;
  281. begin
  282. Result:=TClass(Inherited First);
  283. end;
  284. Function TClassList.GetItems(Index: Integer): TClass;
  285. begin
  286. Result:=TClass(Inherited Items[Index]);
  287. end;
  288. Function TClassList.IndexOf(AClass: TClass): Integer;
  289. begin
  290. Result:=Inherited IndexOf(Pointer(AClass));
  291. end;
  292. Procedure TClassList.Insert(Index: Integer; AClass: TClass);
  293. begin
  294. Inherited Insert(index,Pointer(AClass));
  295. end;
  296. Function TClassList.Last: TClass;
  297. begin
  298. Result:=TClass(Inherited Last);
  299. end;
  300. Function TClassList.Remove(AClass: TClass): Integer;
  301. begin
  302. Result:=Inherited Remove(Pointer(AClass));
  303. end;
  304. Procedure TClassList.SetItems(Index: Integer; AClass: TClass);
  305. begin
  306. Put(Index,Pointer(Aclass));
  307. end;
  308. { TOrderedList }
  309. Function TOrderedList.AtLeast(ACount: Integer): Boolean;
  310. begin
  311. Result:=(FList.Count>=Acount)
  312. end;
  313. Function TOrderedList.Count: Integer;
  314. begin
  315. Result:=FList.Count;
  316. end;
  317. constructor TOrderedList.Create;
  318. begin
  319. FList:=Tlist.Create;
  320. end;
  321. destructor TOrderedList.Destroy;
  322. begin
  323. FList.Free;
  324. end;
  325. Function TOrderedList.Peek: Pointer;
  326. begin
  327. If AtLeast(1) then
  328. Result:=PeekItem
  329. else
  330. Result:=Nil;
  331. end;
  332. Function TOrderedList.PeekItem: Pointer;
  333. begin
  334. With Flist do
  335. Result:=Items[Count-1]
  336. end;
  337. Function TOrderedList.Pop: Pointer;
  338. begin
  339. If Atleast(1) then
  340. Result:=PopItem
  341. else
  342. Result:=Nil;
  343. end;
  344. Function TOrderedList.PopItem: Pointer;
  345. begin
  346. With FList do
  347. If Count>0 then
  348. begin
  349. Result:=Items[Count-1];
  350. Delete(Count-1);
  351. end
  352. else
  353. Result:=Nil;
  354. end;
  355. Function TOrderedList.Push(AItem: Pointer): Pointer;
  356. begin
  357. PushItem(Aitem);
  358. Result:=AItem;
  359. end;
  360. { TStack }
  361. Procedure TStack.PushItem(AItem: Pointer);
  362. begin
  363. FList.Add(Aitem);
  364. end;
  365. { TObjectStack }
  366. Function TObjectStack.Peek: TObject;
  367. begin
  368. Result:=TObject(Inherited Peek);
  369. end;
  370. Function TObjectStack.Pop: TObject;
  371. begin
  372. Result:=TObject(Inherited Pop);
  373. end;
  374. Function TObjectStack.Push(AObject: TObject): TObject;
  375. begin
  376. Result:=TObject(Inherited Push(Pointer(AObject)));
  377. end;
  378. { TQueue }
  379. Procedure TQueue.PushItem(AItem: Pointer);
  380. begin
  381. With Flist Do
  382. Insert(0,AItem);
  383. end;
  384. { TObjectQueue }
  385. Function TObjectQueue.Peek: TObject;
  386. begin
  387. Result:=TObject(Inherited Peek);
  388. end;
  389. Function TObjectQueue.Pop: TObject;
  390. begin
  391. Result:=TObject(Inherited Pop);
  392. end;
  393. Function TObjectQueue.Push(AObject: TObject): TObject;
  394. begin
  395. Result:=TObject(Inherited Push(Pointer(Aobject)));
  396. end;
  397. end.
  398. {
  399. $Log$
  400. Revision 1.9 2004-12-24 09:18:38 michael
  401. + Changed FreeAndNil to simple free (From Mattias Gaertner)
  402. Revision 1.8 2004/12/22 15:33:24 peter
  403. * fixed compile
  404. Revision 1.7 2004/12/22 12:05:41 michael
  405. + Fixed bug 3461
  406. Revision 1.6 2002/09/07 15:15:24 peter
  407. * old logs removed and tabs fixed
  408. Revision 1.5 2002/08/09 09:48:28 michael
  409. + mode directive added plus some types fixed
  410. Revision 1.4 2002/08/09 09:44:33 michael
  411. + Implemented stack and queue (untested)
  412. Revision 1.3 2002/07/26 11:26:26 michael
  413. + Initial implementation. Untested
  414. Revision 1.2 2002/07/21 12:04:49 michael
  415. + No optional parameters in 1.0.6
  416. Revision 1.1 2002/07/16 13:34:39 florian
  417. + skeleton for contnr.pp added
  418. }