diff --git a/std/cpp/_std/haxe/ds/WeakRef.hx b/std/cpp/_std/haxe/ds/WeakRef.hx new file mode 100644 index 00000000000..f3c6bffdbb5 --- /dev/null +++ b/std/cpp/_std/haxe/ds/WeakRef.hx @@ -0,0 +1,36 @@ +/* + * Copyright (C)2005-2019 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package haxe.ds; + +@:coreApi +class WeakRef { + var h:Dynamic; + + public function new(target:T) { + h = untyped __global__.__hxcpp_weak_ref_create(target); + } + + public function get():Null { + return untyped __global__.__hxcpp_weak_ref_get(h); + } +} diff --git a/std/haxe/ds/WeakRef.hx b/std/haxe/ds/WeakRef.hx new file mode 100644 index 00000000000..66a49b4973f --- /dev/null +++ b/std/haxe/ds/WeakRef.hx @@ -0,0 +1,45 @@ +/* + * Copyright (C)2005-2019 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package haxe.ds; + +/** + A weak reference to an object. The reference does not prevent the + target from being collected by the garbage collector. + + If the target has been collected, `get()` returns `null`. +**/ +class WeakRef { + /** + Creates a new weak reference to `target`. + **/ + public function new(target:T) { + throw new haxe.exceptions.NotImplementedException("Not implemented for this platform"); + } + + /** + Returns the referenced object, or `null` if it has been collected. + **/ + public function get():Null { + return null; + } +} diff --git a/std/js/_std/haxe/ds/WeakMap.hx b/std/js/_std/haxe/ds/WeakMap.hx new file mode 100644 index 00000000000..61b9ad75251 --- /dev/null +++ b/std/js/_std/haxe/ds/WeakMap.hx @@ -0,0 +1,76 @@ +/* + * Copyright (C)2005-2019 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package haxe.ds; + +@:coreApi(check = Off) +class WeakMap implements haxe.Constraints.IMap { + var h:js.lib.WeakMap; + + public inline function new():Void { + h = new js.lib.WeakMap(); + } + + public inline function set(key:K, value:V):Void { + h.set(cast key, value); + } + + public inline function get(key:K):Null { + return h.get(cast key); + } + + public inline function exists(key:K):Bool { + return h.has(cast key); + } + + public inline function remove(key:K):Bool { + return h.delete(cast key); + } + + public function keys():Iterator { + throw new haxe.exceptions.NotImplementedException("JS WeakMaps do not support enumeration"); + } + + public function iterator():Iterator { + throw new haxe.exceptions.NotImplementedException("JS WeakMaps do not support enumeration"); + } + + public inline function keyValueIterator():KeyValueIterator { + throw new haxe.exceptions.NotImplementedException("JS WeakMaps do not support enumeration"); + } + + public function copy():WeakMap { + throw new haxe.exceptions.NotImplementedException("JS WeakMaps do not support enumeration"); + } + + public function toString():String { + throw new haxe.exceptions.NotImplementedException("JS WeakMaps do not support enumeration"); + } + + public inline function clear():Void { + h = new js.lib.WeakMap(); + } + + public function size():Int { + throw new haxe.exceptions.NotImplementedException("JS WeakMaps do not support enumeration"); + } +} diff --git a/std/js/_std/haxe/ds/WeakRef.hx b/std/js/_std/haxe/ds/WeakRef.hx new file mode 100644 index 00000000000..049bdd5ce0f --- /dev/null +++ b/std/js/_std/haxe/ds/WeakRef.hx @@ -0,0 +1,36 @@ +/* + * Copyright (C)2005-2019 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package haxe.ds; + +@:coreApi +class WeakRef { + var h:js.lib.WeakRef; + + public inline function new(target:T) { + h = new js.lib.WeakRef(target); + } + + public inline function get():Null { + return h.deref(); + } +} diff --git a/std/jvm/_std/haxe/ds/WeakMap.hx b/std/jvm/_std/haxe/ds/WeakMap.hx index 69183d4d0a7..a6c16b818d2 100644 --- a/std/jvm/_std/haxe/ds/WeakMap.hx +++ b/std/jvm/_std/haxe/ds/WeakMap.hx @@ -68,6 +68,12 @@ import java.lang.ref.ReferenceQueue; cachedIndex = -1; #end queue = new ReferenceQueue(); + nBuckets = 4; + hashes = new NativeArray(4); + entries = new NativeArray(4); + _size = 0; + nOccupied = 0; + upperBound = Std.int(4 * HASH_UPPER + .5); } @:analyzer(ignore) @@ -418,13 +424,13 @@ import java.lang.ref.ReferenceQueue; } public function clear():Void { - hashes = null; - entries = null; queue = new ReferenceQueue(); - nBuckets = 0; + nBuckets = 4; + hashes = new NativeArray(4); + entries = new NativeArray(4); _size = 0; nOccupied = 0; - upperBound = 0; + upperBound = Std.int(4 * HASH_UPPER + .5); #if !no_map_cache cachedEntry = null; cachedIndex = -1; @@ -465,7 +471,7 @@ import java.lang.ref.ReferenceQueue; // guarantee: Whatever this function is, it will never return 0 nor 1 extern private static inline function hash(s:Dynamic):HashType { - var k:Int = untyped s.hashCode(); + var k:Int = (cast s : java.lang.Object).hashCode(); // k *= 357913941; // k ^= k << 24; // k += ~357913941; @@ -512,7 +518,7 @@ private class Entry extends WeakReference { } final inline public function keyEquals(k:K):Bool { - return k != null && untyped k.equals(get()); + return k != null && (cast k : java.lang.Object).equals(get()); } } diff --git a/std/jvm/_std/haxe/ds/WeakRef.hx b/std/jvm/_std/haxe/ds/WeakRef.hx new file mode 100644 index 00000000000..c6bc8b0a058 --- /dev/null +++ b/std/jvm/_std/haxe/ds/WeakRef.hx @@ -0,0 +1,38 @@ +/* + * Copyright (C)2005-2019 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package haxe.ds; + +import java.lang.ref.WeakReference; + +@:coreApi +class WeakRef { + var h:WeakReference; + + public function new(target:T) { + h = new WeakReference(target); + } + + public function get():Null { + return h.get(); + } +} diff --git a/std/lua/_std/haxe/ds/WeakMap.hx b/std/lua/_std/haxe/ds/WeakMap.hx new file mode 100644 index 00000000000..cffe1464f5a --- /dev/null +++ b/std/lua/_std/haxe/ds/WeakMap.hx @@ -0,0 +1,108 @@ +/* + * Copyright (C)2005-2019 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package haxe.ds; + +@:coreApi(check = Off) +class WeakMap implements haxe.Constraints.IMap { + var h:Dynamic; + + public inline function new():Void { + h = lua.Syntax.code("setmetatable({}, {__mode = 'k'})"); + } + + public inline function set(key:K, value:V):Void { + untyped h[key] = value; + } + + public inline function get(key:K):Null { + return untyped h[key]; + } + + public inline function exists(key:K):Bool { + return untyped h[key] != null; + } + + public function remove(key:K):Bool { + untyped { + if (h[key] == null) + return false; + h[key] = null; + return true; + } + } + + public function keys():Iterator + untyped { + var cur = next(h, null); + return { + next: function() { + var ret = cur; + cur = untyped next(h, cur); + return ret; + }, + hasNext: function() return cur != null + } + } + + public function iterator():Iterator { + var itr = keys(); + return untyped { + hasNext: itr.hasNext, + next: function() return h[itr.next()] + }; + } + + @:runtime public inline function keyValueIterator():KeyValueIterator { + return new haxe.iterators.MapKeyValueIterator(this); + } + + public function copy():WeakMap { + var copied = new WeakMap(); + for (key in keys()) + copied.set(key, get(key)); + return copied; + } + + public function toString():String { + var s = new StringBuf(); + s.add("["); + var it = keys(); + for (i in it) { + s.add(Std.string(i)); + s.add(" => "); + s.add(Std.string(get(i))); + if (it.hasNext()) + s.add(", "); + } + s.add("]"); + return s.toString(); + } + + public inline function clear():Void { + h = lua.Syntax.code("setmetatable({}, {__mode = 'k'})"); + } + + public function size():Int { + return lua.Syntax.code("(function() local s = 0; for _ in pairs({0}) do s = s + 1 end; return s end)()", h); + } +} diff --git a/std/lua/_std/haxe/ds/WeakRef.hx b/std/lua/_std/haxe/ds/WeakRef.hx new file mode 100644 index 00000000000..4eb291eb3ae --- /dev/null +++ b/std/lua/_std/haxe/ds/WeakRef.hx @@ -0,0 +1,36 @@ +/* + * Copyright (C)2005-2019 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package haxe.ds; + +@:coreApi +class WeakRef { + var h:Dynamic; + + public inline function new(target:T) { + h = lua.Syntax.code("setmetatable({[1] = {0}}, {__mode = 'v'})", target); + } + + public inline function get():Null { + return untyped h[1]; + } +} diff --git a/std/php/_std/haxe/ds/WeakMap.hx b/std/php/_std/haxe/ds/WeakMap.hx new file mode 100644 index 00000000000..c48d8c4f91d --- /dev/null +++ b/std/php/_std/haxe/ds/WeakMap.hx @@ -0,0 +1,97 @@ +/* + * Copyright (C)2005-2019 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package haxe.ds; + +@:coreApi(check = Off) +class WeakMap implements haxe.Constraints.IMap { + var h:Dynamic; + + public function new():Void { + h = php.Syntax.code("new \\WeakMap()"); + } + + public function set(key:K, value:V):Void { + php.Syntax.code("{0}->offsetSet({1}, {2})", h, key, value); + } + + public function get(key:K):Null { + if (!exists(key)) + return null; + return php.Syntax.code("{0}->offsetGet({1})", h, key); + } + + public function exists(key:K):Bool { + return php.Syntax.code("{0}->offsetExists({1})", h, key); + } + + public function remove(key:K):Bool { + if (!exists(key)) + return false; + php.Syntax.code("{0}->offsetUnset({1})", h, key); + return true; + } + + public function keys():Iterator { + var arr:php.NativeArray = php.Syntax.code("iterator_to_array({0}, false)", php.Syntax.code("(function() { foreach ({0} as $k => $v) { yield $k; } })()", h)); + return php.Lib.toHaxeArray(arr).iterator(); + } + + public function iterator():Iterator { + var arr:php.NativeArray = php.Syntax.code("iterator_to_array({0}, false)", php.Syntax.code("(function() { foreach ({0} as $v) { yield $v; } })()", h)); + return php.Lib.toHaxeArray(arr).iterator(); + } + + @:runtime public inline function keyValueIterator():KeyValueIterator { + return new haxe.iterators.MapKeyValueIterator(this); + } + + public function copy():WeakMap { + var copied = new WeakMap(); + for (key in keys()) + copied.set(key, get(key)); + return copied; + } + + public function toString():String { + var s = new StringBuf(); + s.add("["); + var it = keys(); + for (i in it) { + s.add(Std.string(i)); + s.add(" => "); + s.add(Std.string(get(i))); + if (it.hasNext()) + s.add(", "); + } + s.add("]"); + return s.toString(); + } + + public function clear():Void { + h = php.Syntax.code("new \\WeakMap()"); + } + + public function size():Int { + return php.Syntax.code("count({0})", h); + } +} diff --git a/std/php/_std/haxe/ds/WeakRef.hx b/std/php/_std/haxe/ds/WeakRef.hx new file mode 100644 index 00000000000..f5af7c4cc92 --- /dev/null +++ b/std/php/_std/haxe/ds/WeakRef.hx @@ -0,0 +1,36 @@ +/* + * Copyright (C)2005-2019 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package haxe.ds; + +@:coreApi +class WeakRef { + var h:Dynamic; + + public function new(target:T) { + h = php.Syntax.code("\\WeakReference::create({0})", target); + } + + public function get():Null { + return php.Syntax.code("{0}->get()", h); + } +} diff --git a/std/python/_std/haxe/ds/WeakMap.hx b/std/python/_std/haxe/ds/WeakMap.hx new file mode 100644 index 00000000000..bd76e49647e --- /dev/null +++ b/std/python/_std/haxe/ds/WeakMap.hx @@ -0,0 +1,97 @@ +/* + * Copyright (C)2005-2019 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package haxe.ds; + +import python.lib.Weakref.WeakKeyDictionary; + +@:coreApi(check = Off) +class WeakMap implements haxe.Constraints.IMap { + var h:WeakKeyDictionary; + + public function new():Void { + h = new WeakKeyDictionary(); + } + + public function set(key:K, value:V):Void { + h.setItem(key, value); + } + + public inline function get(key:K):Null { + if (h.contains(key)) + return h.getItem(key); + return null; + } + + public inline function exists(key:K):Bool { + return h.contains(key); + } + + public function remove(key:K):Bool { + if (!h.contains(key)) + return false; + h.delItem(key); + return true; + } + + public function keys():Iterator { + return h.keys(); + } + + public function iterator():Iterator { + return h.values(); + } + + @:runtime public inline function keyValueIterator():KeyValueIterator { + return new haxe.iterators.MapKeyValueIterator(this); + } + + public function copy():WeakMap { + var copied = new WeakMap(); + for (key in keys()) + copied.set(key, get(key)); + return copied; + } + + public function toString():String { + var s = new StringBuf(); + s.add("["); + var it = keys(); + for (i in it) { + s.add(Std.string(i)); + s.add(" => "); + s.add(Std.string(get(i))); + if (it.hasNext()) + s.add(", "); + } + s.add("]"); + return s.toString(); + } + + public inline function clear():Void { + h.clear(); + } + + public inline function size():Int { + return h.len(); + } +} diff --git a/std/python/_std/haxe/ds/WeakRef.hx b/std/python/_std/haxe/ds/WeakRef.hx new file mode 100644 index 00000000000..b50052068ca --- /dev/null +++ b/std/python/_std/haxe/ds/WeakRef.hx @@ -0,0 +1,36 @@ +/* + * Copyright (C)2005-2019 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package haxe.ds; + +@:coreApi +class WeakRef { + var h:Dynamic; + + public function new(target:T) { + h = python.Syntax.code("__import__('weakref').ref({0})", target); + } + + public function get():Null { + return python.Syntax.code("{0}()", h); + } +} diff --git a/std/python/lib/Weakref.hx b/std/python/lib/Weakref.hx index 7f620a33fb2..aaf61454582 100644 --- a/std/python/lib/Weakref.hx +++ b/std/python/lib/Weakref.hx @@ -22,6 +22,9 @@ package python.lib; +import python.NativeIterator; +import python.internal.UBuiltins; + @:pythonImport("weakref") extern class Weakref { static function ref(object:T):WeakrefCallable; @@ -36,3 +39,19 @@ extern class PythonFinalizer { function new(obj:{}, func:Dynamic, held:Dynamic); function detach():Bool; } + +@:pythonImport("weakref", "WeakKeyDictionary") +extern class WeakKeyDictionary { + function new():Void; + + @:native("__setitem__") function setItem(key:K, value:V):Void; + @:native("__getitem__") function getItem(key:K):V; + @:native("__delitem__") function delItem(key:K):Void; + @:native("__contains__") function contains(key:K):Bool; + @:native("__len__") function len():Int; + + function keys():NativeIterator; + function values():NativeIterator; + + function clear():Void; +} diff --git a/tests/unit/src/unit/TestMain.hx b/tests/unit/src/unit/TestMain.hx index 0f8ac6eb9de..574ede30065 100644 --- a/tests/unit/src/unit/TestMain.hx +++ b/tests/unit/src/unit/TestMain.hx @@ -97,6 +97,7 @@ function main() { new TestMapComprehension(), new TestMacro(), new TestGcFinalizer(), + new TestWeakRef(), new TestKeyValueIterator(), new TestFieldVariance(), new TestConstrainedMonomorphs(), diff --git a/tests/unit/src/unit/TestWeakRef.hx b/tests/unit/src/unit/TestWeakRef.hx new file mode 100644 index 00000000000..ff27c0c9c10 --- /dev/null +++ b/tests/unit/src/unit/TestWeakRef.hx @@ -0,0 +1,137 @@ +package unit; + +class TestWeakRef extends Test { + #if (js || lua || python || php || (cpp && !cppia) || jvm) + function testWeakRefGet() { + var obj = {value: 42}; + var ref = new haxe.ds.WeakRef(obj); + eq(ref.get().value, 42); + t(obj != null); + } + + function testWeakRefIdentity() { + var obj = {value: 1}; + var ref = new haxe.ds.WeakRef(obj); + t(ref.get() == obj); + } + #end + + #if (js || lua || python || php || (cpp && !cppia) || flash || jvm) + function testWeakMapSetGet() { + var wm = new haxe.ds.WeakMap(); + var key1 = {id: 1}; + var key2 = {id: 2}; + wm.set(key1, "one"); + wm.set(key2, "two"); + eq(wm.get(key1), "one"); + eq(wm.get(key2), "two"); + } + + function testWeakMapExists() { + var wm = new haxe.ds.WeakMap(); + var key = {id: 1}; + f(wm.exists(key)); + wm.set(key, "val"); + t(wm.exists(key)); + } + + function testWeakMapRemove() { + var wm = new haxe.ds.WeakMap(); + var key = {id: 1}; + f(wm.remove(key)); + wm.set(key, "val"); + t(wm.remove(key)); + f(wm.exists(key)); + } + + function testWeakMapOverwrite() { + var wm = new haxe.ds.WeakMap(); + var key = {id: 1}; + wm.set(key, "first"); + wm.set(key, "second"); + eq(wm.get(key), "second"); + } + + function testWeakMapMissing() { + var wm = new haxe.ds.WeakMap(); + var key = {id: 1}; + eq(wm.get(key), null); + } + + function testWeakMapClear() { + var wm = new haxe.ds.WeakMap(); + var key = {id: 1}; + wm.set(key, "val"); + wm.clear(); + f(wm.exists(key)); + } + #end + + #if (lua || python || php || (cpp && !cppia) || flash || jvm) + function testWeakMapIteration() { + var wm = new haxe.ds.WeakMap(); + var key1 = {id: 1}; + var key2 = {id: 2}; + wm.set(key1, "one"); + wm.set(key2, "two"); + + var count = 0; + var foundOne = false; + var foundTwo = false; + for (v in wm) { + if (v == "one") + foundOne = true; + if (v == "two") + foundTwo = true; + count++; + } + eq(count, 2); + t(foundOne); + t(foundTwo); + t(key1 != null); + t(key2 != null); + } + + function testWeakMapKeys() { + var wm = new haxe.ds.WeakMap(); + var key1 = {id: 1}; + var key2 = {id: 2}; + wm.set(key1, "one"); + wm.set(key2, "two"); + + var count = 0; + for (_ in wm.keys()) { + count++; + } + eq(count, 2); + t(key1 != null); + t(key2 != null); + } + + function testWeakMapSize() { + var wm = new haxe.ds.WeakMap(); + var key1 = {id: 1}; + var key2 = {id: 2}; + wm.set(key1, "one"); + wm.set(key2, "two"); + eq(wm.size(), 2); + t(key1 != null); + t(key2 != null); + } + #end + + #if js + function testWeakMapJsEnumerationThrows() { + var wm = new haxe.ds.WeakMap(); + exc(function() wm.keys()); + exc(function() wm.iterator()); + exc(function() wm.size()); + } + #end + + #if !(js || lua || python || php || (cpp && !cppia) || jvm || flash) + function testNotImplemented() { + noAssert(); + } + #end +}