gmap.pp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. {
  2. This file is part of the Free Pascal FCL library.
  3. BSD parts (c) 2011 Vlado Boza
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY;without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. {$mode objfpc}
  11. unit gmap;
  12. interface
  13. uses gset;
  14. type
  15. generic TMapCompare<TPair, TKeyCompare>=class
  16. class function c(a,b :TPair):boolean;
  17. end;
  18. { TMapIterator }
  19. generic TMapIterator<TKey, TValue, TPair, TNode>=class
  20. public
  21. type PNode=^TNode;
  22. TLMapIterator = specialize TMapIterator<TKey, TValue, TPair, TNode>;
  23. var FNode:PNode;
  24. type PValue=^TValue;
  25. function GetData:TPair;inline;
  26. function GetKey:TKey;inline;
  27. function GetValue:TValue;inline;
  28. function GetMutable:PValue;inline;
  29. procedure SetValue(value:TValue);inline;
  30. function MoveNext:boolean;inline;
  31. function Next:boolean;inline;
  32. function Prev:boolean;inline;
  33. function GetEnumerator: TLMapIterator; inline;
  34. property Data:TPair read GetData;
  35. property Key:TKey read GetKey;
  36. property Value:TValue read GetValue write SetValue;
  37. property MutableValue:PValue read GetMutable;
  38. property Current : TPair read GetData;
  39. end;
  40. generic TMap<TKey, TValue, TCompare>=class
  41. public
  42. type
  43. TPair=record
  44. Value:TValue;
  45. Key:TKey;
  46. end;
  47. TMCompare = specialize TMapCompare<TPair, TCompare>;
  48. TMSet = specialize TSet<TPair, TMCompare>;
  49. TIterator = specialize TMapIterator<TKey, TValue, TPair, TMSet.Node>;
  50. PTValue = ^TValue;
  51. PTPair = ^TPair;
  52. var
  53. private
  54. FSet:TMSet;
  55. public
  56. function Find(key:TKey):TIterator;inline;
  57. function FindLess(key:TKey):TIterator;inline;
  58. function FindLessEqual(key:TKey):TIterator;inline;
  59. function FindGreater(key:TKey):TIterator;inline;
  60. function FindGreaterEqual(key:TKey):TIterator;inline;
  61. function GetValue(key:TKey):TValue;inline;
  62. function TryGetValue(key:TKey; out Value: TValue): boolean;inline;
  63. procedure Insert(key:TKey; value:TValue);inline;
  64. function InsertAndGetIterator(key:TKey; value:TValue):TIterator;inline;
  65. function Min:TIterator;inline;
  66. function Max:TIterator;inline;
  67. procedure Delete(key:TKey);inline;
  68. function Size:SizeUInt;inline;
  69. function IsEmpty:boolean;inline;
  70. function GetEnumerator: TIterator; inline;
  71. constructor Create;
  72. destructor Destroy;override;
  73. property Items[i : TKey]: TValue read GetValue write Insert; default;
  74. end;
  75. implementation
  76. class function TMapCompare.c(a,b: TPair):boolean;
  77. begin
  78. c:= TKeyCompare.c(a.Key, b.Key);
  79. end;
  80. constructor TMap.Create;
  81. begin
  82. FSet:=TMSet.Create;
  83. end;
  84. destructor TMap.Destroy;
  85. begin
  86. FSet.Destroy;
  87. end;
  88. procedure TMap.Delete(key:TKey);inline;
  89. var Pair:TPair;
  90. begin
  91. Pair.Key:=key;
  92. FSet.Delete(Pair);
  93. end;
  94. function TMap.Find(key:TKey):TIterator;inline;
  95. var Pair:TPair; ret:TIterator;
  96. begin
  97. Pair.Key:=key;
  98. ret := TIterator.create;
  99. ret.FNode:=FSet.NFind(Pair);
  100. if ret.FNode = nil then begin
  101. ret.Destroy; ret := nil;
  102. end;
  103. Find := ret;
  104. end;
  105. function TMap.FindLess(key:TKey):TIterator;inline;
  106. var Pair:TPair; ret:TIterator;
  107. begin
  108. Pair.Key:=key;
  109. ret := TIterator.create;
  110. ret.FNode:=FSet.NFindLess(Pair);
  111. if ret.FNode = nil then begin
  112. ret.Destroy; ret := nil;
  113. end;
  114. FindLess := ret;
  115. end;
  116. function TMap.FindLessEqual(key:TKey):TIterator;inline;
  117. var Pair:TPair; ret:TIterator;
  118. begin
  119. Pair.Key:=key;
  120. ret := TIterator.create;
  121. ret.FNode:=FSet.NFindLessEqual(Pair);
  122. if ret.FNode = nil then begin
  123. ret.Destroy; ret := nil;
  124. end;
  125. FindLessEqual := ret;
  126. end;
  127. function TMap.FindGreater(key:TKey):TIterator;inline;
  128. var Pair:TPair; ret:TIterator;
  129. begin
  130. Pair.Key:=key;
  131. ret := TIterator.create;
  132. ret.FNode:=FSet.NFindGreater(Pair);
  133. if ret.FNode = nil then begin
  134. ret.Destroy; ret := nil;
  135. end;
  136. FindGreater := ret;
  137. end;
  138. function TMap.FindGreaterEqual(key:TKey):TIterator;inline;
  139. var Pair:TPair; ret:TIterator;
  140. begin
  141. Pair.Key:=key;
  142. ret := TIterator.create;
  143. ret.FNode:=FSet.NFindGreaterEqual(Pair);
  144. if ret.FNode = nil then begin
  145. ret.Destroy; ret := nil;
  146. end;
  147. FindGreaterEqual := ret;
  148. end;
  149. function TMap.GetValue(key:TKey):TValue;inline;
  150. var Pair:TPair;
  151. begin
  152. Pair.Key:=key;
  153. GetValue:=FSet.NFind(Pair)^.Data.Value;
  154. end;
  155. function TMap.TryGetValue(key: TKey; out Value: TValue): boolean;
  156. var Pair:TPair;
  157. Node: TMSet.PNode;
  158. begin
  159. Pair.Key:=key;
  160. Node := FSet.NFind(Pair);
  161. Result := Node <> nil;
  162. if Result then
  163. Value := Node^.Data.Value;
  164. end;
  165. procedure TMap.Insert(key:TKey; value:TValue);inline;
  166. var Pair:TPair;
  167. begin
  168. Pair.Key:=key;
  169. FSet.NInsert(Pair)^.Data.Value := value;
  170. end;
  171. function TMap.InsertAndGetIterator(key:TKey; value:TValue):TIterator;inline;
  172. var Pair:TPair; ret:TIterator;
  173. begin
  174. ret := TIterator.create;
  175. Pair.Key:=key;
  176. ret.FNode := FSet.NInsert(Pair);
  177. ret.FNode^.Data.Value := value;
  178. InsertAndGetIterator := ret;
  179. end;
  180. function TMap.Min:TIterator;inline;
  181. var ret:TIterator;
  182. begin
  183. ret := TIterator.create;
  184. ret.FNode:=FSet.NMin;
  185. if ret.FNode = nil then begin
  186. ret.Destroy; ret := nil;
  187. end;
  188. Min := ret;
  189. end;
  190. function TMap.Max:TIterator;inline;
  191. var ret:TIterator;
  192. begin
  193. ret := TIterator.create;
  194. ret.FNode:=FSet.NMax;
  195. if ret.FNode = nil then begin
  196. ret.Destroy; ret := nil;
  197. end;
  198. Max := ret;
  199. end;
  200. function TMap.Size:SizeUInt;inline;
  201. begin
  202. Size:=FSet.Size;
  203. end;
  204. function TMap.IsEmpty:boolean;inline;
  205. begin
  206. IsEmpty:=FSet.IsEmpty;
  207. end;
  208. function TMap.GetEnumerator: TIterator;
  209. begin
  210. result:=titerator.create;
  211. end;
  212. function TMapIterator.GetData:TPair;inline;
  213. begin
  214. GetData:=FNode^.Data;
  215. end;
  216. function TMapIterator.GetKey:TKey;inline;
  217. begin
  218. GetKey:=FNode^.Data.Key;
  219. end;
  220. function TMapIterator.GetValue:TValue;inline;
  221. begin
  222. GetValue:=FNode^.Data.Value;
  223. end;
  224. function TMapIterator.GetMutable:PValue;inline;
  225. begin
  226. GetMutable:=@(FNode^.Data.Value);
  227. end;
  228. procedure TMapIterator.SetValue(value:TValue);inline;
  229. begin
  230. FNode^.Data.Value := value;
  231. end;
  232. function TMapIterator.MoveNext: boolean;
  233. var temp:PNode;
  234. begin
  235. if(FNode=nil) then exit(false);
  236. if(FNode^.Right<>nil) then begin
  237. temp:=FNode^.Right;
  238. while(temp^.Left<>nil) do temp:=temp^.Left;
  239. end
  240. else begin
  241. temp:=FNode;
  242. while(true) do begin
  243. if(temp^.Parent=nil) then begin temp:=temp^.Parent; break; end;
  244. if(temp^.Parent^.Left=temp) then begin temp:=temp^.Parent; break; end;
  245. temp:=temp^.Parent;
  246. end;
  247. end;
  248. if (temp = nil) then exit(false);
  249. FNode:=temp;
  250. MoveNext:=true;
  251. end;
  252. function TMapIterator.Next:boolean;inline;
  253. var temp:PNode;
  254. begin
  255. if(FNode=nil) then exit(false);
  256. if(FNode^.Right<>nil) then begin
  257. temp:=FNode^.Right;
  258. while(temp^.Left<>nil) do temp:=temp^.Left;
  259. end
  260. else begin
  261. temp:=FNode;
  262. while(true) do begin
  263. if(temp^.Parent=nil) then begin temp:=temp^.Parent; break; end;
  264. if(temp^.Parent^.Left=temp) then begin temp:=temp^.Parent; break; end;
  265. temp:=temp^.Parent;
  266. end;
  267. end;
  268. if (temp = nil) then exit(false);
  269. FNode:=temp;
  270. Next:=true;
  271. end;
  272. function TMapIterator.Prev:boolean;inline;
  273. var temp:PNode;
  274. begin
  275. if(FNode=nil) then exit(false);
  276. if(FNode^.Left<>nil) then begin
  277. temp:=FNode^.Left;
  278. while(temp^.Right<>nil) do temp:=temp^.Right;
  279. end
  280. else begin
  281. temp:=FNode;
  282. while(true) do begin
  283. if(temp^.Parent=nil) then begin temp:=temp^.Parent; break; end;
  284. if(temp^.Parent^.Right=temp) then begin temp:=temp^.Parent; break; end;
  285. temp:=temp^.Parent;
  286. end;
  287. end;
  288. if (temp = nil) then exit(false);
  289. FNode:=temp;
  290. Prev:=true;
  291. end;
  292. function TMapIterator.GetEnumerator: TLMapIterator;
  293. begin
  294. result:=Self;
  295. end;
  296. end.