Array.hx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  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 java.lang.System;
  23. import java.NativeArray;
  24. /**
  25. An Array is a storage for values. You can access it using indexes or
  26. with its API. On the server side, it's often better to use a [List] which
  27. is less memory and CPU consuming, unless you really need indexed access.
  28. **/
  29. @:classCode('
  30. public Array(T[] _native)
  31. {
  32. this.__a = _native;
  33. this.length = _native.length;
  34. }
  35. ')
  36. @:final @:coreApi class Array<T> implements ArrayAccess<T> {
  37. /**
  38. The length of the Array
  39. **/
  40. public var length(default,null) : Int;
  41. private var __a:NativeArray<T>;
  42. @:functionCode('
  43. return new Array<X>(_native);
  44. ')
  45. private static function ofNative<X>(native:NativeArray<X>):Array<X>
  46. {
  47. return null;
  48. }
  49. @:functionCode('
  50. return new Array<Y>((Y[]) ((java.lang.Object)new java.lang.Object[size]));
  51. ')
  52. private static function alloc<Y>(size:Int):Array<Y>
  53. {
  54. return null;
  55. }
  56. /**
  57. Creates a new Array.
  58. **/
  59. public function new() : Void
  60. {
  61. this.length = 0;
  62. this.__a = new NativeArray(0);
  63. }
  64. /**
  65. Returns a new Array by appending [a] to [this].
  66. **/
  67. public function concat( a : Array<T> ) : Array<T>
  68. {
  69. var length = length;
  70. var len = length + a.length;
  71. var retarr = new NativeArray(len);
  72. System.arraycopy(__a, 0, retarr, 0, length);
  73. System.arraycopy(a.__a, 0, retarr, length, a.length);
  74. return ofNative(retarr);
  75. }
  76. private function concatNative( a : NativeArray<T> ) : Void
  77. {
  78. var __a = __a;
  79. var length = length;
  80. var len = length + a.length;
  81. if (__a.length >= len)
  82. {
  83. System.arraycopy(a, 0, __a, length, length);
  84. } else {
  85. var newarr = new NativeArray(len);
  86. System.arraycopy(__a, 0, newarr, 0, length);
  87. System.arraycopy(a, 0, newarr, length, a.length);
  88. this.__a = newarr;
  89. }
  90. this.length = len;
  91. }
  92. /**
  93. Returns a representation of an array with [sep] for separating each element.
  94. **/
  95. public function join( sep : String ) : String
  96. {
  97. var buf = new StringBuf();
  98. var i = -1;
  99. var first = true;
  100. var length = length;
  101. while (++i < length)
  102. {
  103. if (first)
  104. first = false;
  105. else
  106. buf.add(sep);
  107. buf.add(__a[i]);
  108. }
  109. return buf.toString();
  110. }
  111. /**
  112. Removes the last element of the array and returns it.
  113. **/
  114. public function pop() : Null<T>
  115. {
  116. var __a = __a;
  117. var length = length;
  118. if (length > 0)
  119. {
  120. var val = __a[--length];
  121. __a[length] = null;
  122. this.length = length;
  123. return val;
  124. } else {
  125. return null;
  126. }
  127. }
  128. /**
  129. Adds the element [x] at the end of the array.
  130. **/
  131. public function push(x : T) : Int
  132. {
  133. var length = length;
  134. if (length >= __a.length)
  135. {
  136. var newLen = (length << 1) + 1;
  137. var newarr = new NativeArray(newLen);
  138. System.arraycopy(__a, 0, newarr, 0, __a.length);
  139. this.__a = newarr;
  140. }
  141. __a[length] = x;
  142. return ++this.length;
  143. }
  144. /**
  145. Reverse the order of elements of the Array.
  146. **/
  147. public function reverse() : Void
  148. {
  149. var i = 0;
  150. var l = this.length;
  151. var a = this.__a;
  152. var half = l >> 1;
  153. l -= 1;
  154. while ( i < half )
  155. {
  156. var tmp = a[i];
  157. a[i] = a[l-i];
  158. a[l-i] = tmp;
  159. i += 1;
  160. }
  161. }
  162. /**
  163. Removes the first element and returns it.
  164. **/
  165. public function shift() : Null<T>
  166. {
  167. var l = this.length;
  168. if( l == 0 )
  169. return null;
  170. var a = this.__a;
  171. var x = a[0];
  172. l -= 1;
  173. System.arraycopy(a, 1, a, 0, length-1);
  174. a[l] = null;
  175. this.length = l;
  176. return x;
  177. }
  178. /**
  179. Copies the range of the array starting at [pos] up to,
  180. but not including, [end]. Both [pos] and [end] can be
  181. negative to count from the end: -1 is the last item in
  182. the array.
  183. **/
  184. public function slice( pos : Int, ?end : Int ) : Array<T>
  185. {
  186. if( pos < 0 ){
  187. pos = this.length + pos;
  188. if( pos < 0 )
  189. pos = 0;
  190. }
  191. if( end == null )
  192. end = this.length;
  193. else if( end < 0 )
  194. end = this.length + end;
  195. if( end > this.length )
  196. end = this.length;
  197. var len = end - pos;
  198. if ( len < 0 ) return new Array();
  199. var newarr = new NativeArray(len);
  200. System.arraycopy(__a, pos, newarr, 0, len);
  201. return ofNative(newarr);
  202. }
  203. /**
  204. Sort the Array according to the comparison public function [f].
  205. [f(x,y)] should return [0] if [x == y], [>0] if [x > y]
  206. and [<0] if [x < y].
  207. **/
  208. public function sort( f : T -> T -> Int ) : Void
  209. {
  210. if (length == 0)
  211. return;
  212. quicksort(0, length - 1, f);
  213. }
  214. /**
  215. quicksort author: tong disktree
  216. http://blog.disktree.net/2008/10/26/array-sort-performance.html
  217. */
  218. private function quicksort( lo : Int, hi : Int, f : T -> T -> Int ) : Void
  219. {
  220. var buf = __a;
  221. var i = lo, j = hi;
  222. var p = buf[(i + j) >> 1];
  223. while ( i <= j )
  224. {
  225. while ( f(buf[i], p) < 0 ) i++;
  226. while ( f(buf[j], p) > 0 ) j--;
  227. if ( i <= j )
  228. {
  229. var t = buf[i];
  230. buf[i++] = buf[j];
  231. buf[j--] = t;
  232. }
  233. }
  234. if( lo < j ) quicksort( lo, j, f );
  235. if( i < hi ) quicksort( i, hi, f );
  236. }
  237. /**
  238. Removes [len] elements starting from [pos] an returns them.
  239. **/
  240. public function splice( pos : Int, len : Int ) : Array<T>
  241. {
  242. if( len < 0 ) return new Array();
  243. if( pos < 0 ) {
  244. pos = this.length + pos;
  245. if( pos < 0 ) pos = 0;
  246. }
  247. if( pos > this.length ) {
  248. pos = 0;
  249. len = 0;
  250. } else if( pos + len > this.length ) {
  251. len = this.length - pos;
  252. if( len < 0 ) len = 0;
  253. }
  254. var a = this.__a;
  255. var ret = new NativeArray(len);
  256. System.arraycopy(a, pos, ret, 0, len);
  257. var ret = ofNative(ret);
  258. var end = pos + len;
  259. System.arraycopy(a, end, a, pos, this.length - end);
  260. this.length -= len;
  261. while( --len >= 0 )
  262. a[this.length + len] = null;
  263. return ret;
  264. }
  265. private function spliceVoid( pos : Int, len : Int ) : Void
  266. {
  267. if( len < 0 ) return;
  268. if( pos < 0 ) {
  269. pos = this.length + pos;
  270. if( pos < 0 ) pos = 0;
  271. }
  272. if( pos > this.length ) {
  273. pos = 0;
  274. len = 0;
  275. } else if( pos + len > this.length ) {
  276. len = this.length - pos;
  277. if( len < 0 ) len = 0;
  278. }
  279. var a = this.__a;
  280. var end = pos + len;
  281. System.arraycopy(a, end, a, pos, this.length - end);
  282. this.length -= len;
  283. while( --len >= 0 )
  284. a[this.length + len] = null;
  285. }
  286. /**
  287. Returns a displayable representation of the Array content.
  288. **/
  289. public function toString() : String
  290. {
  291. var ret = new StringBuf();
  292. var a = __a;
  293. ret.add("[");
  294. var first = true;
  295. for (i in 0...length)
  296. {
  297. if (first)
  298. first = false;
  299. else
  300. ret.add(",");
  301. ret.add(a[i]);
  302. }
  303. ret.add("]");
  304. return ret.toString();
  305. }
  306. /**
  307. Adds the element [x] at the start of the array.
  308. **/
  309. public function unshift( x : T ) : Void
  310. {
  311. var __a = __a;
  312. var length = length;
  313. if (length >= __a.length)
  314. {
  315. var newLen = (length << 1) + 1;
  316. var newarr = new NativeArray(newLen);
  317. System.arraycopy(__a, 0, newarr, 1, length);
  318. this.__a = newarr;
  319. } else {
  320. System.arraycopy(__a, 0, __a, 1, length);
  321. }
  322. this.__a[0] = x;
  323. ++this.length;
  324. }
  325. /**
  326. Inserts the element [x] at the position [pos].
  327. All elements after [pos] are moved one index ahead.
  328. **/
  329. public function insert( pos : Int, x : T ) : Void
  330. {
  331. var l = this.length;
  332. if( pos < 0 ) {
  333. pos = l + pos;
  334. if( pos < 0 ) pos = 0;
  335. }
  336. if ( pos >= l ) {
  337. this.push(x);
  338. return;
  339. } else if (pos == 0) {
  340. this.unshift(x);
  341. return;
  342. }
  343. if (l >= __a.length)
  344. {
  345. var newLen = (length << 1) + 1;
  346. var newarr = new NativeArray(newLen);
  347. System.arraycopy(__a, 0, newarr, 0, pos);
  348. newarr[pos] = x;
  349. System.arraycopy(__a, pos, newarr, pos + 1, l - pos);
  350. this.__a = newarr;
  351. ++this.length;
  352. } else {
  353. var __a = __a;
  354. System.arraycopy(__a, pos, __a, pos + 1, l - pos);
  355. System.arraycopy(__a, 0, __a, 0, pos);
  356. __a[pos] = x;
  357. ++this.length;
  358. }
  359. }
  360. /**
  361. Removes the first occurence of [x].
  362. Returns false if [x] was not present.
  363. Elements are compared by using standard equality.
  364. **/
  365. public function remove( x : T ) : Bool
  366. {
  367. var __a = __a;
  368. var i = -1;
  369. var length = length;
  370. while (++i < length)
  371. {
  372. if (__a[i] == x)
  373. {
  374. System.arraycopy(__a, i + 1, __a, i, length - i - 1);
  375. __a[--this.length] = null;
  376. return true;
  377. }
  378. }
  379. return false;
  380. }
  381. /**
  382. Returns a copy of the Array. The values are not
  383. copied, only the Array structure.
  384. **/
  385. public function copy() : Array<T>
  386. {
  387. var len = length;
  388. var __a = __a;
  389. var newarr = new NativeArray(len);
  390. System.arraycopy(__a, 0, newarr, 0, len);
  391. return ofNative(newarr);
  392. }
  393. /**
  394. Returns an iterator of the Array values.
  395. **/
  396. public function iterator() : Iterator<T>
  397. {
  398. var i = 0;
  399. var len = length;
  400. return
  401. {
  402. hasNext:function() return i < len,
  403. next:function() return __a[i++]
  404. };
  405. }
  406. public function map<S>( f : T -> S ) : Array<S> {
  407. var ret = [];
  408. for (elt in this)
  409. ret.push(f(elt));
  410. return ret;
  411. }
  412. public function filter( f : T -> Bool ) : Array<T> {
  413. var ret = [];
  414. for (elt in this)
  415. if (f(elt))
  416. ret.push(elt);
  417. return ret;
  418. }
  419. private function __get(idx:Int):T
  420. {
  421. var __a = __a;
  422. if (idx >= __a.length || idx < 0)
  423. return null;
  424. return __a[idx];
  425. }
  426. private function __set(idx:Int, v:T):T
  427. {
  428. var __a = __a;
  429. if (idx >= __a.length)
  430. {
  431. var newl = idx + 1;
  432. if (idx == __a.length)
  433. newl = (idx << 1) + 1;
  434. var newArr = new NativeArray<T>(newl);
  435. if (length > 0)
  436. System.arraycopy(__a, 0, newArr, 0, length);
  437. this.__a = __a = newArr;
  438. }
  439. if (idx >= length)
  440. this.length = idx + 1;
  441. return __a[idx] = v;
  442. }
  443. private inline function __unsafe_get(idx:Int):T
  444. {
  445. return __a[idx];
  446. }
  447. private inline function __unsafe_set(idx:Int, val:T):T
  448. {
  449. return __a[idx] = val;
  450. }
  451. }