/std/cs/_std/Array.hx

https://gitlab.com/ezeql/haxe · Haxe · 483 lines · 401 code · 61 blank · 21 comment · 76 complexity · f23f1e8f8fe18372098780e80d3d07d2 MD5 · raw file

  1. /*
  2. * Copyright (C)2005-2012 Haxe Foundation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. * DEALINGS IN THE SOFTWARE.
  21. */
  22. import cs.NativeArray;
  23. #if core_api_serialize
  24. @:meta(System.Serializable)
  25. #end
  26. @:final class Array<T> implements ArrayAccess<T> {
  27. public var length(default,null) : Int;
  28. private var __a:NativeArray<T>;
  29. #if erase_generics
  30. inline private static function ofNative<X>(native:NativeArray<Dynamic>):Array<X>
  31. {
  32. return new Array(native);
  33. }
  34. #else
  35. inline private static function ofNative<X>(native:NativeArray<X>):Array<X>
  36. {
  37. return new Array(native);
  38. }
  39. #end
  40. inline private static function alloc<Y>(size:Int):Array<Y>
  41. {
  42. return new Array(new NativeArray(size));
  43. }
  44. @:overload public function new() : Void
  45. {
  46. this.length = 0;
  47. this.__a = new NativeArray(0);
  48. }
  49. #if erase_generics
  50. @:overload private function new(native:NativeArray<Dynamic>)
  51. {
  52. this.length = native.Length;
  53. this.__a = untyped native;
  54. }
  55. #else
  56. @:overload private function new(native:NativeArray<T>)
  57. {
  58. this.length = native.Length;
  59. this.__a = native;
  60. }
  61. #end
  62. public function concat( a : Array<T> ) : Array<T>
  63. {
  64. var len = length + a.length;
  65. var retarr = new NativeArray(len);
  66. cs.system.Array.Copy(__a, 0, retarr, 0, length);
  67. cs.system.Array.Copy(a.__a, 0, retarr, length, a.length);
  68. return ofNative(retarr);
  69. }
  70. private function concatNative( a : NativeArray<T> ) : Void
  71. {
  72. var __a = __a;
  73. var len = length + a.Length;
  74. if (__a.Length >= len)
  75. {
  76. cs.system.Array.Copy(a, 0, __a, length, length);
  77. } else {
  78. var newarr = new NativeArray(len);
  79. cs.system.Array.Copy(__a, 0, newarr, 0, length);
  80. cs.system.Array.Copy(a, 0, newarr, length, a.Length);
  81. this.__a = newarr;
  82. }
  83. this.length = len;
  84. }
  85. public function indexOf( x : T, ?fromIndex:Int ) : Int
  86. {
  87. var len = length, i:Int = (fromIndex == null) ? 0 : fromIndex;
  88. if (i < 0)
  89. {
  90. i += len;
  91. if (i < 0) i = 0;
  92. }
  93. else if (i >= len)
  94. {
  95. return -1;
  96. }
  97. return cs.system.Array.IndexOf(__a, x, i, len - i);
  98. }
  99. public function lastIndexOf( x : T, ?fromIndex:Int ) : Int
  100. {
  101. var len = length, i:Int = (fromIndex == null) ? len - 1 : fromIndex;
  102. if (i >= len)
  103. {
  104. i = len - 1;
  105. }
  106. else if (i < 0)
  107. {
  108. i += len;
  109. if (i < 0) return -1;
  110. }
  111. return cs.system.Array.LastIndexOf(__a, x, i, i + 1);
  112. }
  113. public function join( sep : String ) : String
  114. {
  115. var buf = new StringBuf();
  116. var i = -1;
  117. var first = true;
  118. var length = length;
  119. while (++i < length)
  120. {
  121. if (first)
  122. first = false;
  123. else
  124. buf.add(sep);
  125. buf.add(__a[i]);
  126. }
  127. return buf.toString();
  128. }
  129. public function pop() : Null<T>
  130. {
  131. var __a = __a;
  132. var length = length;
  133. if (length > 0)
  134. {
  135. var val = __a[--length];
  136. __a[length] = null;
  137. this.length = length;
  138. return val;
  139. } else {
  140. return null;
  141. }
  142. }
  143. public function push(x : T) : Int
  144. {
  145. if (length >= __a.Length)
  146. {
  147. var newLen = (length << 1) + 1;
  148. var newarr = new NativeArray(newLen);
  149. __a.CopyTo(newarr, 0);
  150. this.__a = newarr;
  151. }
  152. __a[length] = x;
  153. return ++length;
  154. }
  155. public function reverse() : Void
  156. {
  157. var i = 0;
  158. var l = this.length;
  159. var a = this.__a;
  160. var half = l >> 1;
  161. l -= 1;
  162. while ( i < half )
  163. {
  164. var tmp = a[i];
  165. a[i] = a[l-i];
  166. a[l-i] = tmp;
  167. i += 1;
  168. }
  169. }
  170. public function shift() : Null<T>
  171. {
  172. var l = this.length;
  173. if( l == 0 )
  174. return null;
  175. var a = this.__a;
  176. var x = a[0];
  177. l -= 1;
  178. cs.system.Array.Copy(a, 1, a, 0, length-1);
  179. a[l] = null;
  180. this.length = l;
  181. return x;
  182. }
  183. public function slice( pos : Int, ?end : Int ) : Array<T>
  184. {
  185. if( pos < 0 ){
  186. pos = this.length + pos;
  187. if( pos < 0 )
  188. pos = 0;
  189. }
  190. if( end == null )
  191. end = this.length;
  192. else if( end < 0 )
  193. end = this.length + end;
  194. if( end > this.length )
  195. end = this.length;
  196. var len = end - pos;
  197. if ( len < 0 ) return new Array();
  198. var newarr = new NativeArray(len);
  199. cs.system.Array.Copy(__a, pos, newarr, 0, len);
  200. return ofNative(newarr);
  201. }
  202. public function sort( f : T -> T -> Int ) : Void
  203. {
  204. if (length == 0)
  205. return;
  206. quicksort(0, length - 1, f);
  207. }
  208. private function quicksort( lo : Int, hi : Int, f : T -> T -> Int ) : Void
  209. {
  210. var buf = __a;
  211. var i = lo, j = hi;
  212. var p = buf[(i + j) >> 1];
  213. while ( i <= j )
  214. {
  215. while ( i < hi && f(buf[i], p) < 0 ) i++;
  216. while ( j > lo && f(buf[j], p) > 0 ) j--;
  217. if ( i <= j )
  218. {
  219. var t = buf[i];
  220. buf[i++] = buf[j];
  221. buf[j--] = t;
  222. }
  223. }
  224. if( lo < j ) quicksort( lo, j, f );
  225. if( i < hi ) quicksort( i, hi, f );
  226. }
  227. public function splice( pos : Int, len : Int ) : Array<T>
  228. {
  229. if( len < 0 ) return new Array();
  230. if( pos < 0 ) {
  231. pos = this.length + pos;
  232. if( pos < 0 ) pos = 0;
  233. }
  234. if( pos > this.length ) {
  235. pos = 0;
  236. len = 0;
  237. } else if( pos + len > this.length ) {
  238. len = this.length - pos;
  239. if( len < 0 ) len = 0;
  240. }
  241. var a = this.__a;
  242. var ret = new NativeArray(len);
  243. cs.system.Array.Copy(a, pos, ret, 0, len);
  244. var ret = ofNative(ret);
  245. var end = pos + len;
  246. cs.system.Array.Copy(a, end, a, pos, this.length - end);
  247. this.length -= len;
  248. while( --len >= 0 )
  249. a[this.length + len] = null;
  250. return ret;
  251. }
  252. private function spliceVoid( pos : Int, len : Int ) : Void
  253. {
  254. if( len < 0 ) return;
  255. if( pos < 0 ) {
  256. pos = this.length + pos;
  257. if( pos < 0 ) pos = 0;
  258. }
  259. if( pos > this.length ) {
  260. pos = 0;
  261. len = 0;
  262. } else if( pos + len > this.length ) {
  263. len = this.length - pos;
  264. if( len < 0 ) len = 0;
  265. }
  266. var a = this.__a;
  267. var end = pos + len;
  268. cs.system.Array.Copy(a, end, a, pos, this.length - end);
  269. this.length -= len;
  270. while( --len >= 0 )
  271. a[this.length + len] = null;
  272. }
  273. public function toString() : String
  274. {
  275. var ret = new StringBuf();
  276. var a = __a;
  277. ret.add("[");
  278. var first = true;
  279. for (i in 0...length)
  280. {
  281. if (first)
  282. first = false;
  283. else
  284. ret.add(",");
  285. ret.add(a[i]);
  286. }
  287. ret.add("]");
  288. return ret.toString();
  289. }
  290. public function unshift( x : T ) : Void
  291. {
  292. var __a = __a;
  293. var length = length;
  294. if (length >= __a.Length)
  295. {
  296. var newLen = (length << 1) + 1;
  297. var newarr = new NativeArray(newLen);
  298. cs.system.Array.Copy(__a, 0, newarr, 1, length);
  299. this.__a = newarr;
  300. } else {
  301. cs.system.Array.Copy(__a, 0, __a, 1, length);
  302. }
  303. this.__a[0] = x;
  304. ++this.length;
  305. }
  306. public function insert( pos : Int, x : T ) : Void
  307. {
  308. var l = this.length;
  309. if( pos < 0 ) {
  310. pos = l + pos;
  311. if( pos < 0 ) pos = 0;
  312. }
  313. if ( pos >= l ) {
  314. this.push(x);
  315. return;
  316. } else if (pos == 0) {
  317. this.unshift(x);
  318. return;
  319. }
  320. if (l >= __a.Length)
  321. {
  322. var newLen = (length << 1) + 1;
  323. var newarr = new NativeArray(newLen);
  324. cs.system.Array.Copy(__a, 0, newarr, 0, pos);
  325. newarr[pos] = x;
  326. cs.system.Array.Copy(__a, pos, newarr, pos + 1, l - pos);
  327. this.__a = newarr;
  328. ++this.length;
  329. } else {
  330. var __a = __a;
  331. cs.system.Array.Copy(__a, pos, __a, pos + 1, l - pos);
  332. cs.system.Array.Copy(__a, 0, __a, 0, pos);
  333. __a[pos] = x;
  334. ++this.length;
  335. }
  336. }
  337. public function remove( x : T ) : Bool
  338. {
  339. var __a = __a;
  340. var i = -1;
  341. var length = length;
  342. while (++i < length)
  343. {
  344. if (__a[i] == x)
  345. {
  346. cs.system.Array.Copy(__a, i + 1, __a, i, length - i - 1);
  347. __a[--this.length] = null;
  348. return true;
  349. }
  350. }
  351. return false;
  352. }
  353. public function map<S>( f : T -> S ) : Array<S> {
  354. var ret = [];
  355. for (elt in this)
  356. ret.push(f(elt));
  357. return ret;
  358. }
  359. public function filter( f : T -> Bool ) : Array<T> {
  360. var ret = [];
  361. for (elt in this)
  362. if (f(elt))
  363. ret.push(elt);
  364. return ret;
  365. }
  366. public function copy() : Array<T>
  367. {
  368. var len = length;
  369. var __a = __a;
  370. var newarr = new NativeArray(len);
  371. cs.system.Array.Copy(__a, 0, newarr, 0, len);
  372. return ofNative(newarr);
  373. }
  374. public inline function iterator() : Iterator<T>
  375. {
  376. return new ArrayIterator<T>(this);
  377. }
  378. private function __get(idx:Int):T
  379. {
  380. return if ((cast idx : UInt) >= length) null else __a[idx];
  381. }
  382. private function __set(idx:Int, v:T):T
  383. {
  384. var idx:UInt = idx;
  385. var __a = __a;
  386. if (idx >= __a.Length)
  387. {
  388. var len = idx + 1;
  389. if (idx == __a.Length)
  390. len = (idx << 1) + 1;
  391. var newArr = new NativeArray<T>(len);
  392. __a.CopyTo(newArr, 0);
  393. this.__a = __a = newArr;
  394. }
  395. if (idx >= length)
  396. this.length = idx + 1;
  397. return __a[idx] = v;
  398. }
  399. private inline function __unsafe_get(idx:Int):T
  400. {
  401. return __a[idx];
  402. }
  403. private inline function __unsafe_set(idx:Int, val:T):T
  404. {
  405. return __a[idx] = val;
  406. }
  407. }
  408. @:final
  409. private class ArrayIterator<T>
  410. {
  411. var arr:Array<T>;
  412. var len:Int;
  413. var i:Int;
  414. public inline function new(a:Array<T>)
  415. {
  416. arr = a;
  417. len = a.length;
  418. i = 0;
  419. }
  420. public inline function hasNext():Bool return i < len;
  421. public inline function next():T return arr[i++];
  422. }