List.hx 5.6 KB

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