|
@@ -22,6 +22,105 @@
|
|
|
|
|
|
package haxe.ds;
|
|
package haxe.ds;
|
|
|
|
|
|
|
|
+import js.lib.Object;
|
|
|
|
+import haxe.Constraints.IMap;
|
|
|
|
+import haxe.DynamicAccess;
|
|
|
|
+
|
|
|
|
+#if (js_es >= 5)
|
|
|
|
+@:coreApi class StringMap<T> implements IMap<String, T> {
|
|
|
|
+ var h:Dynamic;
|
|
|
|
+
|
|
|
|
+ public inline function new() {
|
|
|
|
+ h = Object.create(null);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public inline function exists(key:String):Bool {
|
|
|
|
+ return Object.prototype.hasOwnProperty.call(h, key);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public inline function get(key:String):Null<T> {
|
|
|
|
+ return h[cast key];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public inline function set(key:String, value:T):Void {
|
|
|
|
+ h[cast key] = value;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public inline function remove(key:String):Bool {
|
|
|
|
+ return if (exists(key)) {
|
|
|
|
+ js.Syntax.delete(h, key); true;
|
|
|
|
+ } else {
|
|
|
|
+ false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public inline function keys():Iterator<String> {
|
|
|
|
+ return keysIterator(h);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public inline function iterator():Iterator<T> {
|
|
|
|
+ return valueIterator(h);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public inline function keyValueIterator():KeyValueIterator<String, T> {
|
|
|
|
+ return kvIterator(h);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public inline function copy():StringMap<T> {
|
|
|
|
+ return createCopy(h);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public inline function clear():Void {
|
|
|
|
+ h = Object.create(null);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public inline function toString():String {
|
|
|
|
+ return stringify(h);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // impl
|
|
|
|
+
|
|
|
|
+ static function keysIterator(h:Dynamic):Iterator<String> {
|
|
|
|
+ var keys = Object.keys(h), len = keys.length, idx = 0;
|
|
|
|
+ return {
|
|
|
|
+ hasNext: () -> idx < len,
|
|
|
|
+ next: () -> keys[idx++]
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ static function valueIterator<T>(h:Dynamic):Iterator<T> {
|
|
|
|
+ var keys = Object.keys(h), len = keys.length, idx = 0;
|
|
|
|
+ return {
|
|
|
|
+ hasNext: () -> idx < len,
|
|
|
|
+ next: () -> h[cast keys[idx++]]
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ static function kvIterator<T>(h:Dynamic):KeyValueIterator<String, T> {
|
|
|
|
+ var keys = Object.keys(h), len = keys.length, idx = 0;
|
|
|
|
+ return {
|
|
|
|
+ hasNext: () -> idx < len,
|
|
|
|
+ next: () -> {var k = keys[idx++]; {key: k, value: h[cast k]}}
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ static function createCopy<T>(h:Dynamic):StringMap<T> {
|
|
|
|
+ var copy = new StringMap();
|
|
|
|
+ js.Syntax.code("for (var key in {0}) {1}[key] = {0}[key]", h, copy.h);
|
|
|
|
+ return copy;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @:analyzer(no_optimize)
|
|
|
|
+ static function stringify(h:Dynamic):String {
|
|
|
|
+ var s = "{", first = true;
|
|
|
|
+ js.Syntax.code("for (var key in {0}) {", h);
|
|
|
|
+ js.Syntax.code("\tif ({0}) {0} = false; else {1} += ',';", first, s);
|
|
|
|
+ js.Syntax.code("\t{0} += key + ' => ' + {1}({2}[key]);", s, Std.string, h);
|
|
|
|
+ js.Syntax.code("}");
|
|
|
|
+ return s + "}";
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+#else
|
|
private class StringMapIterator<T> {
|
|
private class StringMapIterator<T> {
|
|
var map:StringMap<T>;
|
|
var map:StringMap<T>;
|
|
var keys:Array<String>;
|
|
var keys:Array<String>;
|
|
@@ -168,3 +267,4 @@ private class StringMapIterator<T> {
|
|
untyped __js__("var __map_reserved = {};");
|
|
untyped __js__("var __map_reserved = {};");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+#end
|