Quick.Arrays.pas 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. { ***************************************************************************
  2. Copyright (c) 2016-2019 Kike Pérez
  3. Unit : Quick.Arrays
  4. Description : Multifuntional Arrays
  5. Author : Kike Pérez
  6. Version : 1.2
  7. Created : 24/03/2019
  8. Modified : 16/10/2019
  9. This file is part of QuickLib: https://github.com/exilon/QuickLib
  10. ***************************************************************************
  11. Licensed under the Apache License, Version 2.0 (the "License");
  12. you may not use this file except in compliance with the License.
  13. You may obtain a copy of the License at
  14. http://www.apache.org/licenses/LICENSE-2.0
  15. Unless required by applicable law or agreed to in writing, software
  16. distributed under the License is distributed on an "AS IS" BASIS,
  17. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. See the License for the specific language governing permissions and
  19. limitations under the License.
  20. *************************************************************************** }
  21. unit Quick.Arrays;
  22. {$i QuickLib.inc}
  23. interface
  24. uses
  25. SysUtils,
  26. Generics.Defaults,
  27. Generics.Collections,
  28. Quick.Value;
  29. type
  30. TXArray<T> = record
  31. type
  32. TEnumerator = class(Generics.Collections.TEnumerator<T>)
  33. private
  34. fArray : ^TArray<T>;
  35. fIndex : Integer;
  36. protected
  37. function DoGetCurrent: T; override;
  38. function DoMoveNext: Boolean; override;
  39. public
  40. constructor Create(var aArray: TArray<T>);
  41. end;
  42. private
  43. fArray : TArray<T>;
  44. function GetItem(Index : Integer) : T;
  45. procedure SetItem(Index : Integer; const aValue : T);
  46. function GetCapacity: Integer;
  47. function GetCount: Integer;
  48. procedure SetCapacity(const Value: Integer);
  49. public
  50. function GetEnumerator: TEnumerator<T>;
  51. property AsArray : TArray<T> read fArray;
  52. property Items[Index : Integer] : T read GetItem write SetItem; default;
  53. property Count : Integer read GetCount;
  54. property Capacity : Integer read GetCapacity write SetCapacity;
  55. function Add(aValue : T) : Integer;
  56. procedure Insert(aItem : T; aIndex : Integer);
  57. procedure Delete(aIndex : Integer);
  58. procedure Remove(aItem : T);
  59. function Contains(aItem : T) : Boolean;
  60. function IndexOf(aItem : T) : Integer;
  61. class operator Implicit(const Value : TxArray<T>) : TArray<T>;
  62. class operator Implicit(const Value : TArray<T>) : TxArray<T>;
  63. end;
  64. TPair = record
  65. Name : string;
  66. Value : string;
  67. constructor Create(const aName, aValue : string);
  68. end;
  69. TPairArray = TArray<TPair>;
  70. PPairArray = ^TPairArray;
  71. TPairXArray = TXArray<TPair>;
  72. TFlexArray = TXArray<TFlexValue>;
  73. TFlexPairArray = TArray<TFlexPair>;
  74. TPairArrayHelper = record helper for TPairArray
  75. public
  76. function GetValue(const aName : string) : string;
  77. function GetPair(const aName : string) : TPair;
  78. function Add(aPair : TPair) : Integer; overload;
  79. function Add(const aName, aValue : string) : Integer; overload;
  80. procedure AddOrUpdate(const aName, aValue : string);
  81. function Exists(const aName : string) : Boolean;
  82. function Remove(const aName : string) : Boolean;
  83. function Count : Integer;
  84. property Items[const aName : string] : string read GetValue write AddOrUpdate;
  85. end;
  86. TFlexPairArrayHelper = record helper for TFlexPairArray
  87. public
  88. function GetValue(const aName : string) : TFlexValue;
  89. function GetPair(const aName : string) : TFlexPair;
  90. function Add(aFlexPair : TFlexPair) : Integer; overload;
  91. function Add(const aName: string; aValue : TFlexValue): Integer; overload;
  92. procedure AddOrUpdate(const aName : string; aValue : TFlexValue);
  93. function Exists(const aName : string) : Boolean;
  94. function Remove(const aName : string) : Boolean;
  95. function Count : Integer;
  96. property Items[const aName : string] : TFlexValue read GetValue write AddOrUpdate;
  97. end;
  98. implementation
  99. { TxArray }
  100. function TxArray<T>.GetItem(Index : Integer) : T;
  101. begin
  102. Result := fArray[Index];
  103. end;
  104. procedure TXArray<T>.SetCapacity(const Value: Integer);
  105. begin
  106. if Value = High(fArray) then Exit;
  107. if Value < 0 then SetLength(fArray,1)
  108. else SetLength(fArray, Value);
  109. end;
  110. procedure TxArray<T>.SetItem(Index : Integer; const aValue : T);
  111. begin
  112. fArray[Index] := aValue;
  113. end;
  114. function TXArray<T>.GetCapacity: Integer;
  115. begin
  116. Result := High(fArray) + 1;
  117. end;
  118. function TXArray<T>.GetCount: Integer;
  119. begin
  120. Result := High(fArray) + 1;
  121. end;
  122. function TxArray<T>.GetEnumerator: TEnumerator<T>;
  123. begin
  124. Result := TEnumerator.Create(fArray);
  125. end;
  126. function TxArray<T>.Add(aValue : T) : Integer;
  127. begin
  128. SetLength(fArray, Length(fArray) + 1);
  129. fArray[High(fArray)] := aValue;
  130. Result := High(fArray);
  131. end;
  132. procedure TxArray<T>.Delete(aIndex : Integer);
  133. begin
  134. System.Delete(fArray,aIndex,1);
  135. end;
  136. procedure TxArray<T>.Remove(aItem : T);
  137. var
  138. nindex : Integer;
  139. begin
  140. nindex := IndexOf(aItem);
  141. if nindex > -1 then System.Delete(fArray,nindex,1);
  142. end;
  143. procedure TxArray<T>.Insert(aItem : T; aIndex : Integer);
  144. begin
  145. System.Insert(aItem,fArray,aIndex);
  146. end;
  147. function TxArray<T>.Contains(aItem : T) : Boolean;
  148. var
  149. icomparer : IEqualityComparer<T>;
  150. i : Integer;
  151. begin
  152. Result := False;
  153. icomparer := TEqualityComparer<T>.Default;
  154. for i := Low(fArray) to High(fArray) do
  155. begin
  156. if icomparer.Equals(fArray[i],aItem) then Exit(True);
  157. end;
  158. end;
  159. function TxArray<T>.IndexOf(aItem : T) : Integer;
  160. var
  161. icomparer : IEqualityComparer<T>;
  162. i : Integer;
  163. begin
  164. icomparer := TEqualityComparer<T>.Default;
  165. for i := Low(fArray) to High(fArray) do
  166. begin
  167. if icomparer.Equals(fArray[i],aItem) then Exit(i);
  168. end;
  169. Result := -1;
  170. end;
  171. class operator TxArray<T>.Implicit(const Value : TxArray<T>) : TArray<T>;
  172. begin
  173. Result := Value.fArray;
  174. end;
  175. class operator TXArray<T>.Implicit(const Value: TArray<T>): TxArray<T>;
  176. begin
  177. Result.fArray := Value;
  178. end;
  179. { TXArray<T>.TEnumerator }
  180. constructor TXArray<T>.TEnumerator.Create(var aArray: TArray<T>);
  181. begin
  182. fIndex := -1;
  183. fArray := @aArray;
  184. end;
  185. function TXArray<T>.TEnumerator.DoGetCurrent: T;
  186. begin
  187. Result := TArray<T>(fArray^)[fIndex];
  188. end;
  189. function TXArray<T>.TEnumerator.DoMoveNext: Boolean;
  190. begin
  191. Inc(fIndex);
  192. Result := fIndex < High(TArray<T>(fArray^))+1;
  193. end;
  194. { TFlexPairArrayHelper }
  195. function TFlexPairArrayHelper.Add(const aName: string; aValue : TFlexValue): Integer;
  196. begin
  197. SetLength(Self,Length(Self)+1);
  198. Self[High(Self)].Name := aName;
  199. Self[High(Self)].Value := aValue;
  200. Result := High(Self);
  201. end;
  202. function TFlexPairArrayHelper.Count: Integer;
  203. begin
  204. Result := High(Self) + 1;
  205. end;
  206. function TFlexPairArrayHelper.Add(aFlexPair: TFlexPair): Integer;
  207. begin
  208. SetLength(Self,Length(Self)+1);
  209. Self[High(Self)] := aFlexPair;
  210. Result := High(Self);
  211. end;
  212. function TFlexPairArrayHelper.Exists(const aName: string): Boolean;
  213. var
  214. i : Integer;
  215. begin
  216. Result := False;
  217. for i := Low(Self) to High(Self) do
  218. begin
  219. if CompareText(Self[i].Name,aName) = 0 then Exit(True)
  220. end;
  221. end;
  222. function TFlexPairArrayHelper.GetPair(const aName: string): TFlexPair;
  223. var
  224. i : Integer;
  225. begin
  226. for i := Low(Self) to High(Self) do
  227. begin
  228. if CompareText(Self[i].Name,aName) = 0 then Exit(Self[i]);
  229. end;
  230. end;
  231. function TFlexPairArrayHelper.GetValue(const aName: string): TFlexValue;
  232. var
  233. i : Integer;
  234. begin
  235. Result.Clear;
  236. for i := Low(Self) to High(Self) do
  237. begin
  238. if CompareText(Self[i].Name,aName) = 0 then Exit(Self[i].Value);
  239. end;
  240. end;
  241. function TFlexPairArrayHelper.Remove(const aName: string): Boolean;
  242. var
  243. i : Integer;
  244. begin
  245. for i := Low(Self) to High(Self) do
  246. begin
  247. if CompareText(Self[i].Name,aName) = 0 then
  248. begin
  249. System.Delete(Self,i,1);
  250. Exit(True);
  251. end;
  252. end;
  253. Result := False;
  254. end;
  255. procedure TFlexPairArrayHelper.AddOrUpdate(const aName : string; aValue : TFlexValue);
  256. var
  257. i : Integer;
  258. begin
  259. for i := Low(Self) to High(Self) do
  260. begin
  261. if CompareText(Self[i].Name,aName) = 0 then
  262. begin
  263. Self[i].Value := aValue;
  264. Exit;
  265. end;
  266. end;
  267. //if not exists add it
  268. Self.Add(aName,aValue);
  269. end;
  270. { TPair }
  271. constructor TPair.Create(const aName, aValue: string);
  272. begin
  273. Name := aName;
  274. Value := aValue;
  275. end;
  276. { TPairArrayHelper }
  277. function TPairArrayHelper.Add(aPair: TPair): Integer;
  278. begin
  279. SetLength(Self,Length(Self)+1);
  280. Self[High(Self)] := aPair;
  281. Result := High(Self);
  282. end;
  283. function TPairArrayHelper.Add(const aName, aValue: string): Integer;
  284. begin
  285. SetLength(Self,Length(Self)+1);
  286. Self[High(Self)].Name := aName;
  287. Self[High(Self)].Value := aValue;
  288. Result := High(Self);
  289. end;
  290. procedure TPairArrayHelper.AddOrUpdate(const aName, aValue: string);
  291. var
  292. i : Integer;
  293. begin
  294. for i := Low(Self) to High(Self) do
  295. begin
  296. if CompareText(Self[i].Name,aName) = 0 then
  297. begin
  298. Self[i].Value := aValue;
  299. Exit;
  300. end;
  301. end;
  302. //if not exists add it
  303. Self.Add(aName,aValue);
  304. end;
  305. function TPairArrayHelper.Count: Integer;
  306. begin
  307. Result := High(Self) + 1;
  308. end;
  309. function TPairArrayHelper.Exists(const aName: string): Boolean;
  310. var
  311. i : Integer;
  312. begin
  313. Result := False;
  314. for i := Low(Self) to High(Self) do
  315. begin
  316. if CompareText(Self[i].Name,aName) = 0 then Exit(True)
  317. end;
  318. end;
  319. function TPairArrayHelper.GetPair(const aName: string): TPair;
  320. var
  321. i : Integer;
  322. begin
  323. for i := Low(Self) to High(Self) do
  324. begin
  325. if CompareText(Self[i].Name,aName) = 0 then Exit(Self[i]);
  326. end;
  327. end;
  328. function TPairArrayHelper.GetValue(const aName: string): string;
  329. var
  330. i : Integer;
  331. begin
  332. Result := '';
  333. for i := Low(Self) to High(Self) do
  334. begin
  335. if CompareText(Self[i].Name,aName) = 0 then Exit(Self[i].Value);
  336. end;
  337. end;
  338. function TPairArrayHelper.Remove(const aName: string): Boolean;
  339. var
  340. i : Integer;
  341. begin
  342. for i := Low(Self) to High(Self) do
  343. begin
  344. if CompareText(Self[i].Name,aName) = 0 then
  345. begin
  346. System.Delete(Self,i,1);
  347. Exit(True);
  348. end;
  349. end;
  350. Result := False;
  351. end;
  352. end.