List.hx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  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. /**
  23. A linked-list of elements. The list is composed of two-elements arrays
  24. that are chained together. It's optimized so that adding or removing an
  25. element doesn't imply to copy the whole array content everytime.
  26. **/
  27. class List<T> {
  28. private var h : Array<Dynamic>;
  29. private var q : Array<Dynamic>;
  30. /**
  31. The number of elements in this list.
  32. **/
  33. public var length(default,null) : Int;
  34. /**
  35. Creates a new empty list.
  36. **/
  37. public function new() {
  38. length = 0;
  39. }
  40. /**
  41. Add an element at the end of the list.
  42. **/
  43. public function add( item : T ) {
  44. var x:Array<Dynamic> = #if neko untyped __dollar__array(item,null) #else [item] #end;
  45. if( h == null )
  46. h = x;
  47. else
  48. q[1] = x;
  49. q = x;
  50. length++;
  51. }
  52. /**
  53. Push an element at the beginning of the list.
  54. **/
  55. public function push( item : T ) {
  56. var x : Array<Dynamic> = #if neko
  57. untyped __dollar__array(item,h)
  58. #else
  59. [item,h]
  60. #end;
  61. h = x;
  62. if( q == null )
  63. q = x;
  64. length++;
  65. }
  66. /**
  67. Returns the first element of the list, or null
  68. if the list is empty.
  69. **/
  70. public function first() : Null<T> {
  71. return if( h == null ) null else h[0];
  72. }
  73. /**
  74. Returns the last element of the list, or null
  75. if the list is empty.
  76. **/
  77. public function last() : Null<T> {
  78. return if( q == null ) null else q[0];
  79. }
  80. /**
  81. Removes the first element of the list and
  82. returns it or simply returns null if the
  83. list is empty.
  84. **/
  85. public function pop() : Null<T> {
  86. if( h == null )
  87. return null;
  88. var x = h[0];
  89. h = h[1];
  90. if( h == null )
  91. q = null;
  92. length--;
  93. return x;
  94. }
  95. /**
  96. Tells if a list is empty.
  97. **/
  98. public function isEmpty() : Bool {
  99. return (h == null);
  100. }
  101. /**
  102. Makes the list empty.
  103. **/
  104. public function clear() : Void {
  105. h = null;
  106. q = null;
  107. length = 0;
  108. }
  109. /**
  110. Remove the first element that is [== v] from the list.
  111. Returns [true] if an element was removed, [false] otherwise.
  112. **/
  113. public function remove( v : T ) : Bool {
  114. var prev = null;
  115. var l = h;
  116. while( l != null ) {
  117. if( l[0] == v ) {
  118. if( prev == null )
  119. h = l[1];
  120. else
  121. prev[1] = l[1];
  122. if( q == l )
  123. q = prev;
  124. length--;
  125. return true;
  126. }
  127. prev = l;
  128. l = l[1];
  129. }
  130. return false;
  131. }
  132. /**
  133. Returns an iterator on the elements of the list.
  134. **/
  135. public function iterator() : Iterator<T> {
  136. #if (java || cs)
  137. var h = h;
  138. return cast {
  139. hasNext : function() {
  140. return (h != null);
  141. },
  142. next : function() {
  143. {
  144. if( h == null )
  145. return null;
  146. var x = h[0];
  147. h = h[1];
  148. return x;
  149. }
  150. }
  151. }
  152. #else
  153. return cast {
  154. h : h,
  155. hasNext : function() {
  156. return untyped (__this__.h != null);
  157. },
  158. next : function() {
  159. untyped {
  160. if( __this__.h == null )
  161. return null;
  162. var x = __this__.h[0];
  163. __this__.h = __this__.h[1];
  164. return x;
  165. }
  166. }
  167. }
  168. #end
  169. }
  170. /**
  171. Returns a displayable representation of the String.
  172. **/
  173. public function toString() {
  174. var s = new StringBuf();
  175. var first = true;
  176. var l = h;
  177. s.add("{");
  178. while( l != null ) {
  179. if( first )
  180. first = false;
  181. else
  182. s.add(", ");
  183. s.add(Std.string(l[0]));
  184. l = l[1];
  185. }
  186. s.add("}");
  187. return s.toString();
  188. }
  189. /**
  190. Join the element of the list by using the separator [sep].
  191. **/
  192. public function join(sep : String) {
  193. var s = new StringBuf();
  194. var first = true;
  195. var l = h;
  196. while( l != null ) {
  197. if( first )
  198. first = false;
  199. else
  200. s.add(sep);
  201. s.add(l[0]);
  202. l = l[1];
  203. }
  204. return s.toString();
  205. }
  206. /**
  207. Returns a list filtered with [f]. The returned list
  208. will contain all elements [x] for which [f(x) = true].
  209. **/
  210. public function filter( f : T -> Bool ) {
  211. var l2 = new List();
  212. var l = h;
  213. while( l != null ) {
  214. var v = l[0];
  215. l = l[1];
  216. if( f(v) )
  217. l2.add(v);
  218. }
  219. return l2;
  220. }
  221. /**
  222. Returns a new list where all elements have been converted
  223. by the function [f].
  224. **/
  225. public function map<X>(f : T -> X) : List<X> {
  226. var b = new List();
  227. var l = h;
  228. while( l != null ) {
  229. var v = l[0];
  230. l = l[1];
  231. b.add(f(v));
  232. }
  233. return b;
  234. }
  235. }