lists.inc 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. {
  2. $Id$
  3. This file is part of the Free Component Library (FCL)
  4. Copyright (c) 1999-2000 by the Free Pascal development team
  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. {****************************************************************************}
  12. {* TList *}
  13. {****************************************************************************}
  14. { TList = class(TObject)
  15. private
  16. FList: PPointerList;
  17. FCount: Integer;
  18. FCapacity: Integer;
  19. }
  20. Const
  21. // Ratio of Pointer and Word Size.
  22. WordRatio = SizeOf(Pointer) Div SizeOf(Word);
  23. function TList.Get(Index: Integer): Pointer;
  24. begin
  25. If (Index<0) or (Index>FCount) then
  26. Error(SListIndexError,Index);
  27. Result:=FList^[Index];
  28. end;
  29. procedure TList.Grow;
  30. begin
  31. // Only for compatibility with Delphi. Not needed.
  32. end;
  33. procedure TList.Put(Index: Integer; Item: Pointer);
  34. begin
  35. if (Index<0) or (Index>=FCount) then
  36. Error(SListIndexError,Index);
  37. Flist^[Index]:=Item;
  38. end;
  39. procedure TList.SetCapacity(NewCapacity: Integer);
  40. Var NewList,ToFree : PPointerList;
  41. begin
  42. If (NewCapacity<0) or (NewCapacity>MaxListSize) then
  43. Error (SListCapacityError,NewCapacity);
  44. If NewCapacity>FCapacity then
  45. begin
  46. GetMem (NewList,NewCapacity*SizeOf(Pointer));
  47. If NewList=Nil then
  48. //!! Find another one here !!
  49. Error (SListCapacityError,NewCapacity);
  50. If Assigned(FList) then
  51. begin
  52. System.Move (FList^,NewList^,FCapacity*Sizeof(Pointer));
  53. FillWord (NewList^[FCapacity],(NewCapacity-FCapacity)*WordRatio, 0);
  54. FreeMem (Flist,FCapacity*SizeOf(Pointer));
  55. end;
  56. Flist:=NewList;
  57. FCapacity:=NewCapacity;
  58. end
  59. else if NewCapacity<FCapacity then
  60. begin
  61. If NewCapacity<0 then
  62. Error (SListCapacityError,NEwCapacity);
  63. ToFree:=Flist+NewCapacity*SizeOf(Pointer);
  64. FreeMem (ToFree, (FCapacity-NewCapacity)*SizeOf(Pointer));
  65. FCapacity:=NewCapacity;
  66. end;
  67. end;
  68. procedure TList.SetCount(NewCount: Integer);
  69. begin
  70. If (NewCount<0) or (NewCount>MaxListSize)then
  71. Error(SListCountError,NewCount);
  72. If NewCount<FCount then
  73. FCount:=NewCount
  74. else If NewCount>FCount then
  75. begin
  76. If NewCount>FCapacity then
  77. SetCapacity (NewCount);
  78. If FCount<NewCount then
  79. FillWord (Flist^[FCount],(NewCount-FCount)* WordRatio ,0);
  80. FCount:=Newcount;
  81. end;
  82. end;
  83. destructor TList.Destroy;
  84. begin
  85. Self.Clear;
  86. inherited Destroy;
  87. end;
  88. Function TList.Add(Item: Pointer): Integer;
  89. begin
  90. Self.Insert (Count,Item);
  91. Result:=Count-1;
  92. end;
  93. Procedure TList.Clear;
  94. begin
  95. If Assigned(FList) then
  96. begin
  97. FreeMem (Flist,FCapacity*SizeOf(Pointer));
  98. FList:=Nil;
  99. FCapacity:=0;
  100. FCount:=0;
  101. end;
  102. end;
  103. Procedure TList.Delete(Index: Integer);
  104. begin
  105. If (Index<0) or (Index>=FCount) then
  106. Error (SListIndexError,Index);
  107. FCount:=FCount-1;
  108. System.Move (FList^[Index+1],FList^[Index],(FCount-Index)*SizeOf(Pointer));
  109. end;
  110. class procedure TList.Error(const Msg: string; Data: Integer);
  111. begin
  112. //!! Find a way to get call address
  113. Raise EListError.CreateFmt(Msg,[Data]);
  114. end;
  115. procedure TList.Exchange(Index1, Index2: Integer);
  116. var Temp : Pointer;
  117. begin
  118. If ((Index1>=FCount) or (Index1<0)) then
  119. Error(SListIndexError,Index1);
  120. If ((Index2>=FCount) or (Index2<0)) then
  121. Error(SListIndexError,Index2);
  122. Temp:=FList^[Index1];
  123. FList^[Index1]:=FList^[Index2];
  124. FList^[Index2]:=Temp;
  125. end;
  126. function TList.Expand: TList;
  127. Var IncSize : Longint;
  128. begin
  129. if FCount<FCapacity then exit;
  130. IncSize:=4;
  131. if FCapacity>3 then IncSize:=IncSize+4;
  132. if FCapacity>8 then IncSize:=IncSize+8;
  133. SetCapacity(FCapacity+IncSize);
  134. Result:=Self;
  135. end;
  136. function TList.First: Pointer;
  137. begin
  138. If FCount=0 then
  139. Result:=Nil
  140. else
  141. Result:=Items[0];
  142. end;
  143. function TList.IndexOf(Item: Pointer): Integer;
  144. begin
  145. Result:=0;
  146. While (Result<FCount) and (Flist^[Result]<>Item) do Result:=Result+1;
  147. If Result=FCount then Result:=-1;
  148. end;
  149. procedure TList.Insert(Index: Integer; Item: Pointer);
  150. begin
  151. If (Index<0) or (Index>FCount )then
  152. Error(SlistIndexError,Index);
  153. IF FCount=FCapacity Then Self.Expand;
  154. If Index<FCount then
  155. System.Move (Flist^[Index],Flist^[Index+1],(FCount-Index)*SizeOf(Pointer));
  156. FList^[Index]:=Item;
  157. FCount:=FCount+1;
  158. end;
  159. function TList.Last: Pointer;
  160. begin
  161. // Wouldn't it be better to return nil if the count is zero ?
  162. If FCount=0 then
  163. Result:=Nil
  164. else
  165. Result:=Items[FCount-1];
  166. end;
  167. procedure TList.Move(CurIndex, NewIndex: Integer);
  168. Var Temp : Pointer;
  169. begin
  170. If ((CurIndex<0) or (CurIndex>Count-1)) then
  171. Error(SListIndexError,CurIndex);
  172. If (NewINdex<0) then
  173. Error(SlistIndexError,NewIndex);
  174. Temp:=FList^[CurIndex];
  175. Self.Delete(CurIndex);
  176. // ?? If NewIndex>CurIndex then NewIndex:=NewIndex-1;
  177. // Newindex changes when deleting ??
  178. Self.Insert (NewIndex,Temp);
  179. end;
  180. function TList.Remove(Item: Pointer): Integer;
  181. begin
  182. Result:=IndexOf(Item);
  183. If Result<>-1 then
  184. Self.Delete (Result);
  185. end;
  186. Procedure TList.Pack;
  187. Var {Last,I,J,}Runner : Longint;
  188. begin
  189. // Not the fastest; but surely correct
  190. For Runner:=Fcount-1 downto 0 do
  191. if Items[Runner]=Nil then Self.Delete(Runner);
  192. { The following may be faster in case of large and defragmented lists
  193. If count=0 then exit;
  194. Runner:=0;I:=0;
  195. TheLast:=Count;
  196. while runner<count do
  197. begin
  198. // Find first Nil
  199. While (FList^[Runner]<>Nil) and (Runner<Count) do Runner:=Runner+1;
  200. if Runner<Count do
  201. begin
  202. // Start searching for non-nil from last known nil+1
  203. if i<Runner then I:=Runner+1;
  204. While (Flist[I]^=Nil) and (I<Count) do I:=I+1;
  205. // Start looking for last non-nil of block.
  206. J:=I+1;
  207. While (Flist^[J]<>Nil) and (J<Count) do J:=J+1;
  208. // Move block and zero out
  209. Move (Flist^[I],Flist^[Runner],J*SizeOf(Pointer));
  210. FillWord (Flist^[I],(J-I)*WordRatio,0);
  211. // Update Runner and Last to point behind last block
  212. TheLast:=Runner+(J-I);
  213. If J=Count then
  214. begin
  215. // Shortcut, when J=Count we checked all pointers
  216. Runner:=Count
  217. else
  218. begin
  219. Runner:=TheLast;
  220. I:=j;
  221. end;
  222. end;
  223. Count:=TheLast;
  224. }
  225. end;
  226. // Needed by Sort method.
  227. Procedure QuickSort (Flist : PPointerList; L,R : Longint;
  228. Compare : TListSortCompare);
  229. Var I,J : Longint;
  230. P,Q : Pointer;
  231. begin
  232. Repeat
  233. I:=L;
  234. J:=R;
  235. P:=FList^[ (L+R) div 2 ];
  236. repeat
  237. While Compare(P,FList^[i])>0 Do I:=I+1;
  238. While Compare(P,FList^[J])<0 Do J:=J-1;
  239. If I<=J then
  240. begin
  241. Q:=Flist^[I];
  242. Flist^[I]:=FList^[J];
  243. FList^[J]:=Q;
  244. I:=I+1;
  245. J:=j-1;
  246. end;
  247. Until I>J;
  248. If L<J then QuickSort (FList,L,J,Compare);
  249. L:=I;
  250. Until I>=R;
  251. end;
  252. procedure TList.Sort(Compare: TListSortCompare);
  253. begin
  254. If Not Assigned(FList) or (FCount<2) then exit;
  255. QuickSort (Flist, 0, FCount-1,Compare);
  256. end;
  257. {****************************************************************************}
  258. {* TThreadList *}
  259. {****************************************************************************}
  260. constructor TThreadList.Create;
  261. begin
  262. end;
  263. destructor TThreadList.Destroy;
  264. begin
  265. end;
  266. procedure TThreadList.Add(Item: Pointer);
  267. begin
  268. end;
  269. procedure TThreadList.Clear;
  270. begin
  271. end;
  272. function TThreadList.LockList: TList;
  273. begin
  274. LockList:=nil;
  275. end;
  276. procedure TThreadList.Remove(Item: Pointer);
  277. begin
  278. end;
  279. procedure TThreadList.UnlockList;
  280. begin
  281. end;
  282. {
  283. $Log$
  284. Revision 1.10 2000-01-07 01:24:33 peter
  285. * updated copyright to 2000
  286. Revision 1.9 2000/01/06 01:20:33 peter
  287. * moved out of packages/ back to topdir
  288. Revision 1.1 2000/01/03 19:33:07 peter
  289. * moved to packages dir
  290. Revision 1.7 1999/04/13 12:46:16 michael
  291. + Some bug fixes by Romio
  292. Revision 1.6 1999/04/08 10:18:52 peter
  293. * makefile updates
  294. }