Quick.Arrays.pas 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  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 type
  43. arrayofT = array of T;
  44. ParrayofT = ^arrayofT;
  45. private
  46. fArray : TArray<T>;
  47. function GetItem(Index : Integer) : T;
  48. procedure SetItem(Index : Integer; const aValue : T);
  49. function GetCapacity: Integer;
  50. function GetCount: Integer;
  51. procedure SetCapacity(const Value: Integer);
  52. function GetPArray: ParrayofT;
  53. public
  54. function GetEnumerator: TEnumerator<T>;
  55. property AsArray : TArray<T> read fArray;
  56. property Items[Index : Integer] : T read GetItem write SetItem; default;
  57. property Count : Integer read GetCount;
  58. property Capacity : Integer read GetCapacity write SetCapacity;
  59. function Add(aValue : T) : Integer;
  60. procedure Insert(aItem : T; aIndex : Integer);
  61. procedure Delete(aIndex : Integer);
  62. procedure Remove(aItem : T);
  63. function Contains(aItem : T) : Boolean;
  64. function IndexOf(aItem : T) : Integer;
  65. property PArray : ParrayofT read GetPArray;
  66. class operator Implicit(const Value : TxArray<T>) : TArray<T>;
  67. class operator Implicit(const Value : TArray<T>) : TxArray<T>;
  68. end;
  69. TPair = record
  70. Name : string;
  71. Value : string;
  72. constructor Create(const aName, aValue : string);
  73. end;
  74. TPairArray = TArray<TPair>;
  75. PPairArray = ^TPairArray;
  76. TPairXArray = TXArray<TPair>;
  77. TFlexArray = TXArray<TFlexValue>;
  78. TFlexPairArray = TArray<TFlexPair>;
  79. TPairArrayHelper = record helper for TPairArray
  80. public
  81. function GetValue(const aName : string) : string;
  82. function GetPair(const aName : string) : TPair;
  83. function Add(aPair : TPair) : Integer; overload;
  84. function Add(const aName, aValue : string) : Integer; overload;
  85. procedure AddOrUpdate(const aName, aValue : string);
  86. function Exists(const aName : string) : Boolean;
  87. function Remove(const aName : string) : Boolean;
  88. function Count : Integer;
  89. property Items[const aName : string] : string read GetValue write AddOrUpdate;
  90. end;
  91. TFlexPairArrayHelper = record helper for TFlexPairArray
  92. public
  93. function GetValue(const aName : string) : TFlexValue;
  94. function GetPair(const aName : string) : TFlexPair;
  95. function Add(aFlexPair : TFlexPair) : Integer; overload;
  96. function Add(const aName: string; aValue : TFlexValue): Integer; overload;
  97. procedure AddOrUpdate(const aName : string; aValue : TFlexValue);
  98. function Exists(const aName : string) : Boolean;
  99. function Remove(const aName : string) : Boolean;
  100. function Count : Integer;
  101. property Items[const aName : string] : TFlexValue read GetValue write AddOrUpdate;
  102. end;
  103. implementation
  104. { TxArray }
  105. function TxArray<T>.GetItem(Index : Integer) : T;
  106. begin
  107. Result := fArray[Index];
  108. end;
  109. function TXArray<T>.GetPArray: ParrayofT;
  110. begin
  111. Pointer(Result) := fArray;
  112. end;
  113. procedure TXArray<T>.SetCapacity(const Value: Integer);
  114. begin
  115. if Value = High(fArray) then Exit;
  116. if Value < 0 then SetLength(fArray,1)
  117. else SetLength(fArray, Value);
  118. end;
  119. procedure TxArray<T>.SetItem(Index : Integer; const aValue : T);
  120. begin
  121. fArray[Index] := aValue;
  122. end;
  123. function TXArray<T>.GetCapacity: Integer;
  124. begin
  125. Result := High(fArray) + 1;
  126. end;
  127. function TXArray<T>.GetCount: Integer;
  128. begin
  129. Result := High(fArray) + 1;
  130. end;
  131. function TxArray<T>.GetEnumerator: TEnumerator<T>;
  132. begin
  133. Result := TEnumerator.Create(fArray);
  134. end;
  135. function TxArray<T>.Add(aValue : T) : Integer;
  136. begin
  137. SetLength(fArray, Length(fArray) + 1);
  138. fArray[High(fArray)] := aValue;
  139. Result := High(fArray);
  140. end;
  141. procedure TxArray<T>.Delete(aIndex : Integer);
  142. begin
  143. System.Delete(fArray,aIndex,1);
  144. end;
  145. procedure TxArray<T>.Remove(aItem : T);
  146. var
  147. nindex : Integer;
  148. begin
  149. nindex := IndexOf(aItem);
  150. if nindex > -1 then System.Delete(fArray,nindex,1);
  151. end;
  152. procedure TxArray<T>.Insert(aItem : T; aIndex : Integer);
  153. begin
  154. System.Insert(aItem,fArray,aIndex);
  155. end;
  156. function TxArray<T>.Contains(aItem : T) : Boolean;
  157. var
  158. icomparer : IEqualityComparer<T>;
  159. i : Integer;
  160. begin
  161. Result := False;
  162. icomparer := TEqualityComparer<T>.Default;
  163. for i := Low(fArray) to High(fArray) do
  164. begin
  165. if icomparer.Equals(fArray[i],aItem) then Exit(True);
  166. end;
  167. end;
  168. function TxArray<T>.IndexOf(aItem : T) : Integer;
  169. var
  170. icomparer : IEqualityComparer<T>;
  171. i : Integer;
  172. begin
  173. icomparer := TEqualityComparer<T>.Default;
  174. for i := Low(fArray) to High(fArray) do
  175. begin
  176. if icomparer.Equals(fArray[i],aItem) then Exit(i);
  177. end;
  178. Result := -1;
  179. end;
  180. class operator TxArray<T>.Implicit(const Value : TxArray<T>) : TArray<T>;
  181. begin
  182. Result := Value.fArray;
  183. end;
  184. class operator TXArray<T>.Implicit(const Value: TArray<T>): TxArray<T>;
  185. begin
  186. Result.fArray := Value;
  187. end;
  188. { TXArray<T>.TEnumerator }
  189. constructor TXArray<T>.TEnumerator.Create(var aArray: TArray<T>);
  190. begin
  191. fIndex := -1;
  192. fArray := @aArray;
  193. end;
  194. function TXArray<T>.TEnumerator.DoGetCurrent: T;
  195. begin
  196. Result := TArray<T>(fArray^)[fIndex];
  197. end;
  198. function TXArray<T>.TEnumerator.DoMoveNext: Boolean;
  199. begin
  200. Inc(fIndex);
  201. Result := fIndex < High(TArray<T>(fArray^))+1;
  202. end;
  203. { TFlexPairArrayHelper }
  204. function TFlexPairArrayHelper.Add(const aName: string; aValue : TFlexValue): Integer;
  205. begin
  206. SetLength(Self,Length(Self)+1);
  207. Self[High(Self)].Name := aName;
  208. Self[High(Self)].Value := aValue;
  209. Result := High(Self);
  210. end;
  211. function TFlexPairArrayHelper.Count: Integer;
  212. begin
  213. Result := High(Self) + 1;
  214. end;
  215. function TFlexPairArrayHelper.Add(aFlexPair: TFlexPair): Integer;
  216. begin
  217. SetLength(Self,Length(Self)+1);
  218. Self[High(Self)] := aFlexPair;
  219. Result := High(Self);
  220. end;
  221. function TFlexPairArrayHelper.Exists(const aName: string): Boolean;
  222. var
  223. i : Integer;
  224. begin
  225. Result := False;
  226. for i := Low(Self) to High(Self) do
  227. begin
  228. if CompareText(Self[i].Name,aName) = 0 then Exit(True)
  229. end;
  230. end;
  231. function TFlexPairArrayHelper.GetPair(const aName: string): TFlexPair;
  232. var
  233. i : Integer;
  234. begin
  235. for i := Low(Self) to High(Self) do
  236. begin
  237. if CompareText(Self[i].Name,aName) = 0 then Exit(Self[i]);
  238. end;
  239. end;
  240. function TFlexPairArrayHelper.GetValue(const aName: string): TFlexValue;
  241. var
  242. i : Integer;
  243. begin
  244. Result.Clear;
  245. for i := Low(Self) to High(Self) do
  246. begin
  247. if CompareText(Self[i].Name,aName) = 0 then Exit(Self[i].Value);
  248. end;
  249. end;
  250. function TFlexPairArrayHelper.Remove(const aName: string): Boolean;
  251. var
  252. i : Integer;
  253. begin
  254. for i := Low(Self) to High(Self) do
  255. begin
  256. if CompareText(Self[i].Name,aName) = 0 then
  257. begin
  258. System.Delete(Self,i,1);
  259. Exit(True);
  260. end;
  261. end;
  262. Result := False;
  263. end;
  264. procedure TFlexPairArrayHelper.AddOrUpdate(const aName : string; aValue : TFlexValue);
  265. var
  266. i : Integer;
  267. begin
  268. for i := Low(Self) to High(Self) do
  269. begin
  270. if CompareText(Self[i].Name,aName) = 0 then
  271. begin
  272. Self[i].Value := aValue;
  273. Exit;
  274. end;
  275. end;
  276. //if not exists add it
  277. Self.Add(aName,aValue);
  278. end;
  279. { TPair }
  280. constructor TPair.Create(const aName, aValue: string);
  281. begin
  282. Name := aName;
  283. Value := aValue;
  284. end;
  285. { TPairArrayHelper }
  286. function TPairArrayHelper.Add(aPair: TPair): Integer;
  287. begin
  288. SetLength(Self,Length(Self)+1);
  289. Self[High(Self)] := aPair;
  290. Result := High(Self);
  291. end;
  292. function TPairArrayHelper.Add(const aName, aValue: string): Integer;
  293. begin
  294. SetLength(Self,Length(Self)+1);
  295. Self[High(Self)].Name := aName;
  296. Self[High(Self)].Value := aValue;
  297. Result := High(Self);
  298. end;
  299. procedure TPairArrayHelper.AddOrUpdate(const aName, aValue: string);
  300. var
  301. i : Integer;
  302. begin
  303. for i := Low(Self) to High(Self) do
  304. begin
  305. if CompareText(Self[i].Name,aName) = 0 then
  306. begin
  307. Self[i].Value := aValue;
  308. Exit;
  309. end;
  310. end;
  311. //if not exists add it
  312. Self.Add(aName,aValue);
  313. end;
  314. function TPairArrayHelper.Count: Integer;
  315. begin
  316. Result := High(Self) + 1;
  317. end;
  318. function TPairArrayHelper.Exists(const aName: string): Boolean;
  319. var
  320. i : Integer;
  321. begin
  322. Result := False;
  323. for i := Low(Self) to High(Self) do
  324. begin
  325. if CompareText(Self[i].Name,aName) = 0 then Exit(True)
  326. end;
  327. end;
  328. function TPairArrayHelper.GetPair(const aName: string): TPair;
  329. var
  330. i : Integer;
  331. begin
  332. for i := Low(Self) to High(Self) do
  333. begin
  334. if CompareText(Self[i].Name,aName) = 0 then Exit(Self[i]);
  335. end;
  336. end;
  337. function TPairArrayHelper.GetValue(const aName: string): string;
  338. var
  339. i : Integer;
  340. begin
  341. Result := '';
  342. for i := Low(Self) to High(Self) do
  343. begin
  344. if CompareText(Self[i].Name,aName) = 0 then Exit(Self[i].Value);
  345. end;
  346. end;
  347. function TPairArrayHelper.Remove(const aName: string): Boolean;
  348. var
  349. i : Integer;
  350. begin
  351. for i := Low(Self) to High(Self) do
  352. begin
  353. if CompareText(Self[i].Name,aName) = 0 then
  354. begin
  355. System.Delete(Self,i,1);
  356. Exit(True);
  357. end;
  358. end;
  359. Result := False;
  360. end;
  361. end.