IntHash.hx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. * Copyright (c) 2005, The haXe Project Contributors
  3. * All rights reserved.
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. *
  7. * - Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * - Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  15. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  16. * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
  17. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  19. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  20. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  22. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  23. * DAMAGE.
  24. */
  25. /**
  26. Hashtable over a set of elements, using [Int] as keys.
  27. On Flash and Javascript, the underlying structure is an Object.
  28. **/
  29. class IntHash<T> {
  30. private var h : #if flash9 flash.utils.Dictionary #elseif php ArrayAccess<Int> #else Dynamic #end;
  31. /**
  32. Creates a new empty hashtable.
  33. **/
  34. public function new() : Void {
  35. #if flash9
  36. h = new flash.utils.Dictionary();
  37. #elseif flash
  38. h = untyped __new__(_global["Object"]);
  39. #elseif neko
  40. h = untyped __dollar__hnew(0);
  41. #elseif js
  42. h = untyped __js__("{}");
  43. untyped if( h.__proto__ != null ) {
  44. h.__proto__ = null;
  45. __js__("delete")(h.__proto__);
  46. };
  47. #elseif php
  48. h = untyped __call__('array');
  49. #end
  50. }
  51. /**
  52. Set a value for the given key.
  53. **/
  54. public function set( key : Int, value : T ) : Void {
  55. #if flash
  56. untyped h[key] = value;
  57. #elseif js
  58. untyped h[key] = value;
  59. #elseif neko
  60. untyped __dollar__hset(h,key,value,null);
  61. #elseif php
  62. untyped __php__("$this->h[$key] = $value");
  63. #end
  64. }
  65. /**
  66. Get a value for the given key.
  67. **/
  68. public function get( key : Int ) : Null<T> {
  69. #if flash
  70. return untyped h[key];
  71. #elseif js
  72. return untyped h[key];
  73. #elseif neko
  74. return untyped __dollar__hget(h,key,null);
  75. #elseif php
  76. if(!exists(key)) return null;
  77. return untyped h[key];
  78. #else
  79. return null;
  80. #end
  81. }
  82. /**
  83. Tells if a value exists for the given key.
  84. In particular, it's useful to tells if a key has
  85. a [null] value versus no value.
  86. **/
  87. public function exists( key : Int ) : Bool {
  88. #if flash9
  89. return untyped h.hasOwnProperty(key);
  90. #elseif flash
  91. return untyped h["hasOwnProperty"](key);
  92. #elseif js
  93. return untyped h[key] != null;
  94. #elseif neko
  95. return untyped __dollar__hmem(h,key,null);
  96. #elseif php
  97. return untyped __php__("array_key_exists")(key, h);
  98. #else
  99. return false;
  100. #end
  101. }
  102. /**
  103. Removes a hashtable entry. Returns [true] if
  104. there was such entry.
  105. **/
  106. public function remove( key : Int ) : Bool {
  107. #if flash9
  108. if( untyped !h.hasOwnProperty(key) ) return false;
  109. untyped __delete__(h,key);
  110. return true;
  111. #elseif flash
  112. if( untyped !h["hasOwnProperty"](key) ) return false;
  113. untyped __delete__(h,key);
  114. return true;
  115. #elseif js
  116. if( untyped h[key] == null ) return false;
  117. untyped __js__("delete")(h[key]);
  118. return true;
  119. #elseif neko
  120. return untyped __dollar__hremove(h,key,null);
  121. #elseif php
  122. return untyped __call__("_hx_array_remove_at", h, key);
  123. #else
  124. return false;
  125. #end
  126. }
  127. /**
  128. Returns an iterator of all keys in the hashtable.
  129. **/
  130. public function keys() : Iterator<Int> {
  131. #if flash9
  132. return untyped (__keys__(h)).iterator();
  133. #elseif flash
  134. var l : Array<Int> = untyped __keys__(h);
  135. for( x in 0...l.length )
  136. l[x] = Std.int(l[x]);
  137. return l.iterator();
  138. #elseif js
  139. var a = new Array();
  140. untyped __js__("
  141. for( x in this.h )
  142. a.push(x);
  143. ");
  144. return a.iterator();
  145. #elseif neko
  146. var l = new List<Int>();
  147. untyped __dollar__hiter(h,function(k,_) { l.push(k); });
  148. return l.iterator();
  149. #elseif php
  150. return untyped __call__("_hx_array_iterator", __call__("array_keys", h));
  151. #else
  152. return null;
  153. #end
  154. }
  155. /**
  156. Returns an iterator of all values in the hashtable.
  157. **/
  158. public function iterator() : Iterator<T> {
  159. #if flash9
  160. return untyped {
  161. ref : h,
  162. it : keys(),
  163. hasNext : function() { return this.it.hasNext(); },
  164. next : function() { var i = this.it.next(); return this.ref[i]; }
  165. };
  166. #elseif flash
  167. return untyped {
  168. ref : h,
  169. it : keys(),
  170. hasNext : function() { return this.it[__unprotect__("hasNext")](); },
  171. next : function() { var i = this.it[__unprotect__("next")](); return this.ref[i]; }
  172. };
  173. #elseif js
  174. return untyped {
  175. ref : h,
  176. it : keys(),
  177. hasNext : function() { return this.it.hasNext(); },
  178. next : function() { var i = this.it.next(); return this.ref[i]; }
  179. };
  180. #elseif neko
  181. var l = new List<T>();
  182. untyped __dollar__hiter(h,function(_,v) { l.push(v); });
  183. return l.iterator();
  184. #elseif php
  185. return untyped __call__("_hx_array_iterator", __call__("array_values", h));
  186. #else
  187. return null;
  188. #end
  189. }
  190. /**
  191. Returns an displayable representation of the hashtable content.
  192. **/
  193. public function toString() {
  194. var s = new StringBuf();
  195. s.add("{");
  196. var it = keys();
  197. for( i in it ) {
  198. s.add(i);
  199. s.add(" => ");
  200. s.add(Std.string(get(i)));
  201. if( it.hasNext() )
  202. s.add(", ");
  203. }
  204. s.add("}");
  205. return s.toString();
  206. }
  207. }