lists.inc 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. {
  2. $Id$
  3. This file is part of the Free Component Library (FCL)
  4. Copyright (c) 1998 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. // Wouldn't it be better to return Nil if count is zero ?
  139. Result:=Items[0];
  140. end;
  141. function TList.IndexOf(Item: Pointer): Integer;
  142. begin
  143. Result:=0;
  144. While (Result<FCount) and (Flist^[Result]<>Item) do Result:=Result+1;
  145. If Result=FCount then Result:=-1;
  146. end;
  147. procedure TList.Insert(Index: Integer; Item: Pointer);
  148. begin
  149. If (Index<0) or (Index>FCount )then
  150. Error(SlistIndexError,Index);
  151. IF FCount=FCapacity Then Self.Expand;
  152. If Index<FCount then
  153. System.Move (Flist^[Index],Flist^[Index+1],(FCount-Index)*SizeOf(Pointer));
  154. FList^[Index]:=Item;
  155. FCount:=FCount+1;
  156. end;
  157. function TList.Last: Pointer;
  158. Var I : longint;
  159. begin
  160. // Wouldn't it be better to return nil if the count is zero ?
  161. Result:=Items[FCount-1];
  162. end;
  163. procedure TList.Move(CurIndex, NewIndex: Integer);
  164. Var Temp : Pointer;
  165. begin
  166. If ((CurIndex<0) or (CurIndex>Count-1)) then
  167. Error(SListIndexError,CurIndex);
  168. If (NewINdex<0) then
  169. Error(SlistIndexError,NewIndex);
  170. Temp:=FList^[CurIndex];
  171. Self.Delete(CurIndex);
  172. // ?? If NewIndex>CurIndex then NewIndex:=NewIndex-1;
  173. // Newindex changes when deleting ??
  174. Self.Insert (NewIndex,Temp);
  175. end;
  176. function TList.Remove(Item: Pointer): Integer;
  177. begin
  178. Result:=IndexOf(Item);
  179. If Result<>-1 then
  180. Self.Delete (Result);
  181. end;
  182. Procedure TList.Pack;
  183. Var {Last,I,J,}Runner : Longint;
  184. begin
  185. // Not the fastest; but surely correct
  186. For Runner:=Fcount-1 downto 0 do
  187. if Items[Runner]=Nil then Self.Delete(Runner);
  188. { The following may be faster in case of large and defragmented lists
  189. If count=0 then exit;
  190. Runner:=0;I:=0;
  191. TheLast:=Count;
  192. while runner<count do
  193. begin
  194. // Find first Nil
  195. While (FList^[Runner]<>Nil) and (Runner<Count) do Runner:=Runner+1;
  196. if Runner<Count do
  197. begin
  198. // Start searching for non-nil from last known nil+1
  199. if i<Runner then I:=Runner+1;
  200. While (Flist[I]^=Nil) and (I<Count) do I:=I+1;
  201. // Start looking for last non-nil of block.
  202. J:=I+1;
  203. While (Flist^[J]<>Nil) and (J<Count) do J:=J+1;
  204. // Move block and zero out
  205. Move (Flist^[I],Flist^[Runner],J*SizeOf(Pointer));
  206. FillWord (Flist^[I],(J-I)*WordRatio,0);
  207. // Update Runner and Last to point behind last block
  208. TheLast:=Runner+(J-I);
  209. If J=Count then
  210. begin
  211. // Shortcut, when J=Count we checked all pointers
  212. Runner:=Count
  213. else
  214. begin
  215. Runner:=TheLast;
  216. I:=j;
  217. end;
  218. end;
  219. Count:=TheLast;
  220. }
  221. end;
  222. // Needed by Sort method.
  223. Procedure QuickSort (Flist : PPointerList; L,R : Longint;
  224. Compare : TListSortCompare);
  225. Var I,J : Longint;
  226. P,Q : Pointer;
  227. begin
  228. Repeat
  229. I:=L;
  230. J:=R;
  231. P:=FList^[ (L+R) div 2 ];
  232. repeat
  233. While Compare(P,FList^[i])>0 Do I:=I+1;
  234. While Compare(P,FList^[J])<0 Do J:=J-1;
  235. If I<=J then
  236. begin
  237. Q:=Flist^[I];
  238. Flist^[I]:=FList^[J];
  239. FList^[J]:=Q;
  240. I:=I+1;
  241. J:=j-1;
  242. end;
  243. Until I>J;
  244. If L<J then QuickSort (FList,L,J,Compare);
  245. L:=I;
  246. Until I>=R;
  247. end;
  248. procedure TList.Sort(Compare: TListSortCompare);
  249. begin
  250. If Not Assigned(FList) or (FCount<2) then exit;
  251. QuickSort (Flist, 0, FCount-1,Compare);
  252. end;
  253. {****************************************************************************}
  254. {* TThreadList *}
  255. {****************************************************************************}
  256. constructor TThreadList.Create;
  257. begin
  258. end;
  259. destructor TThreadList.Destroy;
  260. begin
  261. end;
  262. procedure TThreadList.Add(Item: Pointer);
  263. begin
  264. end;
  265. procedure TThreadList.Clear;
  266. begin
  267. end;
  268. function TThreadList.LockList: TList;
  269. begin
  270. end;
  271. procedure TThreadList.Remove(Item: Pointer);
  272. begin
  273. end;
  274. procedure TThreadList.UnlockList;
  275. begin
  276. end;
  277. {
  278. $Log$
  279. Revision 1.5 1998-10-02 22:41:27 michael
  280. + Added exceptions for error handling
  281. Revision 1.4 1998/05/06 07:27:22 michael
  282. + Fixec index check in exchange method.
  283. Revision 1.3 1998/05/05 15:54:31 michael
  284. TList completely implemented
  285. Revision 1.2 1998/05/04 15:54:07 michael
  286. + Partial implementation of TList
  287. Revision 1.1 1998/05/04 14:30:12 michael
  288. * Split file according to Class; implemented dummys for all methods, so unit compiles.
  289. }