Update Files

This commit is contained in:
2025-01-22 16:18:30 +01:00
parent ed4603cf95
commit a36294b518
16718 changed files with 2960346 additions and 0 deletions

View File

@ -0,0 +1,162 @@
/*
* 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;
/**
ArraySort provides a stable implementation of merge sort through its `sort`
method. It should be used instead of `Array.sort` in cases where the order
of equal elements has to be retained on all targets.
**/
class ArraySort {
/**
Sorts Array `a` according to the comparison function `cmp`, where
`cmp(x,y)` returns 0 if `x == y`, a positive Int if `x > y` and a
negative Int if `x < y`.
This operation modifies Array `a` in place.
This operation is stable: The order of equal elements is preserved.
If `a` or `cmp` are null, the result is unspecified.
**/
static public function sort<T>(a:Array<T>, cmp:T->T->Int) {
rec(a, cmp, 0, a.length);
}
static function rec<T>(a:Array<T>, cmp, from, to) {
var middle = (from + to) >> 1;
if (to - from < 12) {
if (to <= from)
return;
for (i in (from + 1)...to) {
var j = i;
while (j > from) {
if (compare(a, cmp, j, j - 1) < 0)
swap(a, j - 1, j);
else
break;
j--;
}
}
return;
}
rec(a, cmp, from, middle);
rec(a, cmp, middle, to);
doMerge(a, cmp, from, middle, to, middle - from, to - middle);
}
static function doMerge<T>(a:Array<T>, cmp, from, pivot, to, len1, len2) {
var first_cut, second_cut, len11, len22, new_mid;
if (len1 == 0 || len2 == 0)
return;
if (len1 + len2 == 2) {
if (compare(a, cmp, pivot, from) < 0)
swap(a, pivot, from);
return;
}
if (len1 > len2) {
len11 = len1 >> 1;
first_cut = from + len11;
second_cut = lower(a, cmp, pivot, to, first_cut);
len22 = second_cut - pivot;
} else {
len22 = len2 >> 1;
second_cut = pivot + len22;
first_cut = upper(a, cmp, from, pivot, second_cut);
len11 = first_cut - from;
}
rotate(a, cmp, first_cut, pivot, second_cut);
new_mid = first_cut + len22;
doMerge(a, cmp, from, first_cut, new_mid, len11, len22);
doMerge(a, cmp, new_mid, second_cut, to, len1 - len11, len2 - len22);
}
static function rotate<T>(a:Array<T>, cmp:T->T->Int, from, mid, to) {
var n;
if (from == mid || mid == to)
return;
n = gcd(to - from, mid - from);
while (n-- != 0) {
var val = a[from + n];
var shift = mid - from;
var p1 = from + n, p2 = from + n + shift;
while (p2 != from + n) {
a[p1] = a[p2];
p1 = p2;
if (to - p2 > shift)
p2 += shift;
else
p2 = from + (shift - (to - p2));
}
a[p1] = val;
}
}
static function gcd(m, n) {
while (n != 0) {
var t = m % n;
m = n;
n = t;
}
return m;
}
static function upper<T>(a:Array<T>, cmp, from, to, val) {
var len = to - from, half, mid;
while (len > 0) {
half = len >> 1;
mid = from + half;
if (compare(a, cmp, val, mid) < 0)
len = half;
else {
from = mid + 1;
len = len - half - 1;
}
}
return from;
}
static function lower<T>(a:Array<T>, cmp, from, to, val) {
var len = to - from, half, mid;
while (len > 0) {
half = len >> 1;
mid = from + half;
if (compare(a, cmp, mid, val) < 0) {
from = mid + 1;
len = len - half - 1;
} else
len = half;
}
return from;
}
static function swap<T>(a:Array<T>, i, j) {
var tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
static inline function compare<T>(a:Array<T>, cmp:T->T->Int, i, j) {
return cmp(a[i], a[j]);
}
}

View File

@ -0,0 +1,269 @@
/*
* 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;
/**
BalancedTree allows key-value mapping with arbitrary keys, as long as they
can be ordered. By default, `Reflect.compare` is used in the `compare`
method, which can be overridden in subclasses.
Operations have a logarithmic average and worst-case cost.
Iteration over keys and values, using `keys` and `iterator` respectively,
are in-order.
**/
class BalancedTree<K, V> implements haxe.Constraints.IMap<K, V> {
var root:TreeNode<K, V>;
/**
Creates a new BalancedTree, which is initially empty.
**/
public function new() {}
/**
Binds `key` to `value`.
If `key` is already bound to a value, that binding disappears.
If `key` is null, the result is unspecified.
**/
public function set(key:K, value:V) {
root = setLoop(key, value, root);
}
/**
Returns the value `key` is bound to.
If `key` is not bound to any value, `null` is returned.
If `key` is null, the result is unspecified.
**/
public function get(key:K):Null<V> {
var node = root;
while (node != null) {
var c = compare(key, node.key);
if (c == 0)
return node.value;
if (c < 0)
node = node.left;
else
node = node.right;
}
return null;
}
/**
Removes the current binding of `key`.
If `key` has no binding, `this` BalancedTree is unchanged and false is
returned.
Otherwise the binding of `key` is removed and true is returned.
If `key` is null, the result is unspecified.
**/
public function remove(key:K) {
try {
root = removeLoop(key, root);
return true;
} catch (e:String) {
return false;
}
}
/**
Tells if `key` is bound to a value.
This method returns true even if `key` is bound to null.
If `key` is null, the result is unspecified.
**/
public function exists(key:K) {
var node = root;
while (node != null) {
var c = compare(key, node.key);
if (c == 0)
return true;
else if (c < 0)
node = node.left;
else
node = node.right;
}
return false;
}
/**
Iterates over the bound values of `this` BalancedTree.
This operation is performed in-order.
**/
public function iterator():Iterator<V> {
var ret = [];
iteratorLoop(root, ret);
return ret.iterator();
}
/**
See `Map.keyValueIterator`
**/
@:runtime public inline function keyValueIterator():KeyValueIterator<K, V> {
return new haxe.iterators.MapKeyValueIterator(this);
}
/**
Iterates over the keys of `this` BalancedTree.
This operation is performed in-order.
**/
public function keys():Iterator<K> {
var ret = [];
keysLoop(root, ret);
return ret.iterator();
}
public function copy():BalancedTree<K, V> {
var copied = new BalancedTree<K, V>();
copied.root = root;
return copied;
}
function setLoop(k:K, v:V, node:TreeNode<K, V>) {
if (node == null)
return new TreeNode<K, V>(null, k, v, null);
var c = compare(k, node.key);
return if (c == 0) new TreeNode<K, V>(node.left, k, v, node.right, node.get_height()); else if (c < 0) {
var nl = setLoop(k, v, node.left);
balance(nl, node.key, node.value, node.right);
} else {
var nr = setLoop(k, v, node.right);
balance(node.left, node.key, node.value, nr);
}
}
function removeLoop(k:K, node:TreeNode<K, V>) {
if (node == null)
throw "Not_found";
var c = compare(k, node.key);
return if (c == 0) merge(node.left,
node.right); else if (c < 0) balance(removeLoop(k, node.left), node.key, node.value,
node.right); else balance(node.left, node.key, node.value, removeLoop(k, node.right));
}
static function iteratorLoop<K,V>(node:TreeNode<K, V>, acc:Array<V>) {
if (node != null) {
iteratorLoop(node.left, acc);
acc.push(node.value);
iteratorLoop(node.right, acc);
}
}
function keysLoop(node:TreeNode<K, V>, acc:Array<K>) {
if (node != null) {
keysLoop(node.left, acc);
acc.push(node.key);
keysLoop(node.right, acc);
}
}
function merge(t1, t2) {
if (t1 == null)
return t2;
if (t2 == null)
return t1;
var t = minBinding(t2);
return balance(t1, t.key, t.value, removeMinBinding(t2));
}
function minBinding(t:TreeNode<K, V>) {
return if (t == null) throw "Not_found"; else if (t.left == null) t; else minBinding(t.left);
}
function removeMinBinding(t:TreeNode<K, V>) {
return if (t.left == null) t.right; else balance(removeMinBinding(t.left), t.key, t.value, t.right);
}
function balance(l:TreeNode<K, V>, k:K, v:V, r:TreeNode<K, V>):TreeNode<K, V> {
var hl = l.get_height();
var hr = r.get_height();
return if (hl > hr + 2) {
if (l.left.get_height() >= l.right.get_height())
new TreeNode<K, V>(l.left, l.key, l.value, new TreeNode<K, V>(l.right, k, v, r));
else
new TreeNode<K, V>(new TreeNode<K, V>(l.left, l.key, l.value, l.right.left), l.right.key, l.right.value,
new TreeNode<K, V>(l.right.right, k, v, r));
} else if (hr > hl + 2) {
if (r.right.get_height() > r.left.get_height())
new TreeNode<K, V>(new TreeNode<K, V>(l, k, v, r.left), r.key, r.value, r.right);
else
new TreeNode<K, V>(new TreeNode<K, V>(l, k, v, r.left.left), r.left.key, r.left.value,
new TreeNode<K, V>(r.left.right, r.key, r.value, r.right));
} else {
new TreeNode<K, V>(l, k, v, r, (hl > hr ? hl : hr) + 1);
}
}
function compare(k1:K, k2:K) {
return Reflect.compare(k1, k2);
}
public function toString() {
return root == null ? '{}' : '{${root.toString()}}';
}
/**
Removes all keys from `this` BalancedTree.
**/
public function clear():Void {
root = null;
}
}
/**
A tree node of `haxe.ds.BalancedTree`.
**/
class TreeNode<K, V> {
public var left:TreeNode<K, V>;
public var right:TreeNode<K, V>;
public var key:K;
public var value:V;
var _height:Int;
public function new(l, k, v, r, h = -1) {
left = l;
key = k;
value = v;
right = r;
if (h == -1)
_height = (left.get_height() > right.get_height() ? left.get_height() : right.get_height()) + 1;
else
_height = h;
}
extern public inline function get_height()
return this == null ? 0 : _height;
public function toString() {
return (left == null ? "" : left.toString() + ", ") + '$key=$value' + (right == null ? "" : ", " + right.toString());
}
}

View File

@ -0,0 +1,32 @@
/*
* 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;
/**
Either represents values which are either of type `L` (Left) or type `R`
(Right).
**/
enum Either<L, R> {
Left(v:L);
Right(v:R);
}

View File

@ -0,0 +1,70 @@
/*
* 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;
/**
EnumValueMap allows mapping of enum value keys to arbitrary values.
Keys are compared by value and recursively over their parameters. If any
parameter is not an enum value, `Reflect.compare` is used to compare them.
**/
class EnumValueMap<K:EnumValue, V> extends haxe.ds.BalancedTree<K, V> implements haxe.Constraints.IMap<K, V> {
override function compare(k1:EnumValue, k2:EnumValue):Int {
var d = k1.getIndex() - k2.getIndex();
if (d != 0)
return d;
var p1 = k1.getParameters();
var p2 = k2.getParameters();
if (p1.length == 0 && p2.length == 0)
return 0;
return compareArgs(p1, p2);
}
function compareArgs(a1:Array<Dynamic>, a2:Array<Dynamic>):Int {
var ld = a1.length - a2.length;
if (ld != 0)
return ld;
for (i in 0...a1.length) {
var d = compareArg(a1[i], a2[i]);
if (d != 0)
return d;
}
return 0;
}
function compareArg(v1:Dynamic, v2:Dynamic):Int {
return if (Reflect.isEnumValue(v1) && Reflect.isEnumValue(v2)) {
compare(v1, v2);
} else if (Std.isOfType(v1, Array) && Std.isOfType(v2, Array)) {
compareArgs(v1, v2);
} else {
Reflect.compare(v1, v2);
}
}
override function copy():EnumValueMap<K, V> {
var copied = new EnumValueMap<K, V>();
copied.root = root;
return copied;
}
}

View File

@ -0,0 +1,212 @@
/*
* 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 cell of `haxe.ds.GenericStack`.
@see https://haxe.org/manual/std-GenericStack.html
**/
#if (flash || cpp)
@:generic
#end
class GenericCell<T> {
public var elt:T;
public var next:GenericCell<T>;
public function new(elt, next) {
this.elt = elt;
this.next = next;
}
}
#if cpp
@:generic
#if cppia
private class GenericStackIterator<T> {
public var current:GenericCell<T>;
public function hasNext():Bool {
return current != null;
}
public function next():T {
var result = current.elt;
current = current.next;
return result;
}
public function new(head) {
current = head;
}
}
#else
private class GenericStackIterator<T> extends cpp.FastIterator<T> {
public var current:GenericCell<T>;
override public function hasNext():Bool {
return current != null;
}
override public function next():T {
var result = current.elt;
current = current.next;
return result;
}
public function new(head) {
current = head;
}
}
#end
#end
/**
A stack of elements.
This class is generic, which means one type is generated for each type
parameter T on static targets. For example:
- `new GenericStack<Int>()` generates `GenericStack_Int`
- `new GenericStack<String>()` generates `GenericStack_String`
The generated name is an implementation detail and should not be relied
upon.
@see https://haxe.org/manual/std-GenericStack.html
**/
#if (flash || cpp)
@:generic
#end
class GenericStack<T> {
public var head:GenericCell<T>;
/**
Creates a new empty GenericStack.
**/
public function new() {}
/**
Pushes element `item` onto the stack.
**/
public inline function add(item:T) {
head = new GenericCell<T>(item, head);
}
/**
Returns the topmost stack element without removing it.
If the stack is empty, null is returned.
**/
public inline function first():Null<T> {
return if (head == null) null else head.elt;
}
/**
Returns the topmost stack element and removes it.
If the stack is empty, null is returned.
**/
public inline function pop():Null<T> {
var k = head;
if (k == null)
return null;
else {
head = k.next;
return k.elt;
}
}
/**
Tells if the stack is empty.
**/
public inline function isEmpty():Bool {
return (head == null);
}
/**
Removes the first element which is equal to `v` according to the `==`
operator.
This method traverses the stack until it finds a matching element and
unlinks it, returning true.
If no matching element is found, false is returned.
**/
public function remove(v:T):Bool {
var prev:GenericCell<T> = null;
var l = head;
while (l != null) {
if (l.elt == v) {
if (prev == null)
head = l.next;
else
prev.next = l.next;
break;
}
prev = l;
l = l.next;
}
return (l != null);
}
#if cpp
/**
Returns an iterator over the elements of `this` GenericStack.
**/
public function iterator():Iterator<T> {
return new GenericStackIterator<T>(head);
}
#else
/**
Returns an iterator over the elements of `this` GenericStack.
**/
public function iterator():Iterator<T> {
var l = head;
return {
hasNext: function() {
return l != null;
},
next: function() {
var k = l;
l = k.next;
return k.elt;
}
};
}
#end
/**
Returns a String representation of `this` GenericStack.
**/
public function toString() {
var a = new Array();
var l = head;
while (l != null) {
a.push(l.elt);
l = l.next;
}
return "{" + a.join(",") + "}";
}
}

View File

@ -0,0 +1,120 @@
/*
* 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 haxe.iterators.HashMapKeyValueIterator;
/**
HashMap allows mapping of hashable objects to arbitrary values.
See `Map` for documentation details.
@see https://haxe.org/manual/std-Map.html
**/
abstract HashMap<K:{function hashCode():Int;}, V>(HashMapData<K, V>) {
/**
Creates a new HashMap.
**/
public inline function new() {
this = new HashMapData();
}
/**
See `Map.set`
**/
@:arrayAccess public inline function set(k:K, v:V) {
this.keys.set(k.hashCode(), k);
this.values.set(k.hashCode(), v);
}
/**
See `Map.get`
**/
@:arrayAccess public inline function get(k:K) {
return this.values.get(k.hashCode());
}
/**
See `Map.exists`
**/
public inline function exists(k:K) {
return this.values.exists(k.hashCode());
}
/**
See `Map.remove`
**/
public inline function remove(k:K) {
this.values.remove(k.hashCode());
return this.keys.remove(k.hashCode());
}
/**
See `Map.keys`
**/
public inline function keys() {
return this.keys.iterator();
}
/**
See `Map.copy`
**/
public function copy():HashMap<K, V> {
var copied = new HashMapData();
copied.keys = this.keys.copy();
copied.values = this.values.copy();
return cast copied;
}
/**
See `Map.iterator`
**/
public inline function iterator() {
return this.values.iterator();
}
/**
See `Map.keyValueIterator`
**/
public inline function keyValueIterator():HashMapKeyValueIterator<K, V> {
return new HashMapKeyValueIterator(cast this);
}
/**
See `Map.clear`
**/
public inline function clear():Void {
this.keys.clear();
this.values.clear();
}
}
private class HashMapData<K:{function hashCode():Int;}, V> {
public var keys:IntMap<K>;
public var values:IntMap<V>;
public inline function new() {
keys = new IntMap();
values = new IntMap();
}
}

View File

@ -0,0 +1,99 @@
/*
* 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;
/**
IntMap allows mapping of Int keys to arbitrary values.
See `Map` for documentation details.
@see https://haxe.org/manual/std-Map.html
**/
extern class IntMap<T> implements haxe.Constraints.IMap<Int, T> {
/**
Creates a new IntMap.
**/
function new():Void;
/**
See `Map.set`
**/
function set(key:Int, value:T):Void;
/**
See `Map.get`
**/
function get(key:Int):Null<T>;
/**
See `Map.exists`
**/
function exists(key:Int):Bool;
/**
See `Map.remove`
**/
function remove(key:Int):Bool;
/**
See `Map.keys`
(cs, java) Implementation detail: Do not `set()` any new value while
iterating, as it may cause a resize, which will break iteration.
**/
function keys():Iterator<Int>;
/**
See `Map.iterator`
(cs, java) Implementation detail: Do not `set()` any new value while
iterating, as it may cause a resize, which will break iteration.
**/
function iterator():Iterator<T>;
/**
See `Map.keyValueIterator`
**/
#if eval
@:runtime inline function keyValueIterator():KeyValueIterator<Int, T> {
return new haxe.iterators.MapKeyValueIterator(this);
}
#else
function keyValueIterator():KeyValueIterator<Int, T>;
#end
/**
See `Map.copy`
**/
function copy():IntMap<T>;
/**
See `Map.toString`
**/
function toString():String;
/**
See `Map.clear`
**/
function clear():Void;
}

View File

@ -0,0 +1,313 @@
/*
* 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 linked-list of elements. The list is composed of element container objects
that are chained together. It is optimized so that adding or removing an
element does not imply copying the whole list content every time.
@see https://haxe.org/manual/std-List.html
**/
class List<T> {
private var h:ListNode<T>;
private var q:ListNode<T>;
/**
The length of `this` List.
**/
public var length(default, null):Int;
/**
Creates a new empty list.
**/
public function new() {
length = 0;
}
/**
Adds element `item` at the end of `this` List.
`this.length` increases by 1.
**/
public function add(item:T) {
var x = ListNode.create(item, null);
if (h == null)
h = x;
else
q.next = x;
q = x;
length++;
}
/**
Adds element `item` at the beginning of `this` List.
`this.length` increases by 1.
**/
public function push(item:T) {
var x = ListNode.create(item, h);
h = x;
if (q == null)
q = x;
length++;
}
/**
Returns the first element of `this` List, or null if no elements exist.
This function does not modify `this` List.
**/
public function first():Null<T> {
return if (h == null) null else h.item;
}
/**
Returns the last element of `this` List, or null if no elements exist.
This function does not modify `this` List.
**/
public function last():Null<T> {
return if (q == null) null else q.item;
}
/**
Returns the first element of `this` List, or null if no elements exist.
The element is removed from `this` List.
**/
public function pop():Null<T> {
if (h == null)
return null;
var x = h.item;
h = h.next;
if (h == null)
q = null;
length--;
return x;
}
/**
Tells if `this` List is empty.
**/
public function isEmpty():Bool {
return (h == null);
}
/**
Empties `this` List.
This function does not traverse the elements, but simply sets the
internal references to null and `this.length` to 0.
**/
public function clear():Void {
h = null;
q = null;
length = 0;
}
/**
Removes the first occurrence of `v` in `this` List.
If `v` is found by checking standard equality, it is removed from `this`
List and the function returns true.
Otherwise, false is returned.
**/
public function remove(v:T):Bool {
var prev:ListNode<T> = null;
var l = h;
while (l != null) {
if (l.item == v) {
if (prev == null)
h = l.next;
else
prev.next = l.next;
if (q == l)
q = prev;
length--;
return true;
}
prev = l;
l = l.next;
}
return false;
}
/**
Returns an iterator on the elements of the list.
**/
public inline function iterator():ListIterator<T> {
return new ListIterator<T>(h);
}
/**
Returns an iterator of the List indices and values.
**/
@:pure @:runtime public inline function keyValueIterator():ListKeyValueIterator<T> {
return new ListKeyValueIterator(h);
}
/**
Returns a string representation of `this` List.
The result is enclosed in { } with the individual elements being
separated by a comma.
**/
public function toString() {
var s = new StringBuf();
var first = true;
var l = h;
s.add("{");
while (l != null) {
if (first)
first = false;
else
s.add(", ");
s.add(Std.string(l.item));
l = l.next;
}
s.add("}");
return s.toString();
}
/**
Returns a string representation of `this` List, with `sep` separating
each element.
**/
public function join(sep:String) {
var s = new StringBuf();
var first = true;
var l = h;
while (l != null) {
if (first)
first = false;
else
s.add(sep);
s.add(l.item);
l = l.next;
}
return s.toString();
}
/**
Returns a list filtered with `f`. The returned list will contain all
elements for which `f(x) == true`.
**/
public function filter(f:T->Bool) {
var l2 = new List();
var l = h;
while (l != null) {
var v = l.item;
l = l.next;
if (f(v))
l2.add(v);
}
return l2;
}
/**
Returns a new list where all elements have been converted by the
function `f`.
**/
public function map<X>(f:T->X):List<X> {
var b = new List();
var l = h;
while (l != null) {
var v = l.item;
l = l.next;
b.add(f(v));
}
return b;
}
}
#if neko
private extern class ListNode<T> extends neko.NativeArray<Dynamic> {
var item(get, set):T;
var next(get, set):ListNode<T>;
private inline function get_item():T
return this[0];
private inline function set_item(v:T):T
return this[0] = v;
private inline function get_next():ListNode<T>
return this[1];
private inline function set_next(v:ListNode<T>):ListNode<T>
return this[1] = v;
inline static function create<T>(item:T, next:ListNode<T>):ListNode<T> {
return untyped __dollar__array(item, next);
}
}
#else
private class ListNode<T> {
public var item:T;
public var next:ListNode<T>;
public function new(item:T, next:ListNode<T>) {
this.item = item;
this.next = next;
}
extern public inline static function create<T>(item:T, next:ListNode<T>):ListNode<T> {
return new ListNode(item, next);
}
}
#end
private class ListIterator<T> {
var head:ListNode<T>;
public inline function new(head:ListNode<T>) {
this.head = head;
}
public inline function hasNext():Bool {
return head != null;
}
public inline function next():T {
var val = head.item;
head = head.next;
return val;
}
}
private class ListKeyValueIterator<T> {
var idx:Int;
var head:ListNode<T>;
public inline function new(head:ListNode<T>) {
this.head = head;
this.idx = 0;
}
public inline function hasNext():Bool {
return head != null;
}
public inline function next():{key:Int, value:T} {
var val = head.item;
head = head.next;
return {value: val, key: idx++};
}
}

View File

@ -0,0 +1,149 @@
/*
* 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;
/**
ListSort provides a stable implementation of merge sort through its `sort`
method. It has a O(N.log(N)) complexity and does not require additional memory allocation.
**/
class ListSort {
// Note : we prefer [inline] over [@:generic] here since we want to inline the comparison function as well
/**
Sorts List `lst` according to the comparison function `cmp`, where
`cmp(x,y)` returns 0 if `x == y`, a positive Int if `x > y` and a
negative Int if `x < y`.
This operation modifies List `a` in place and returns its head once modified.
The `prev` of the head is set to the tail of the sorted list.
If `list` or `cmp` are null, the result is unspecified.
**/
public static inline function sort<T:{prev:T, next:T}>(list:T, cmp:T->T->Int):T {
// ported from http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
if (list == null)
return null;
var insize = 1, nmerges, psize = 0, qsize = 0;
var p, q, e, tail:T = null;
while (true) {
p = list;
list = null;
tail = null;
nmerges = 0;
while (p != null) {
nmerges++;
q = p;
psize = 0;
for (i in 0...insize) {
psize++;
q = q.next;
if (q == null)
break;
}
qsize = insize;
while (psize > 0 || (qsize > 0 && q != null)) {
if (psize == 0) {
e = q;
q = q.next;
qsize--;
} else if (qsize == 0 || q == null || cmp(p, q) <= 0) {
e = p;
p = p.next;
psize--;
} else {
e = q;
q = q.next;
qsize--;
}
if (tail != null)
tail.next = e;
else
list = e;
e.prev = tail;
tail = e;
}
p = q;
}
tail.next = null;
if (nmerges <= 1)
break;
insize *= 2;
}
list.prev = tail;
return list;
}
/**
Same as `sort` but on single linked list.
**/
public static inline function sortSingleLinked<T:{next:T}>(list:T, cmp:T->T->Int):T {
if (list == null)
return null;
var insize = 1, nmerges, psize = 0, qsize = 0;
var p, q, e, tail:T;
while (true) {
p = list;
list = null;
tail = null;
nmerges = 0;
while (p != null) {
nmerges++;
q = p;
psize = 0;
for (i in 0...insize) {
psize++;
q = q.next;
if (q == null)
break;
}
qsize = insize;
while (psize > 0 || (qsize > 0 && q != null)) {
if (psize == 0) {
e = q;
q = q.next;
qsize--;
} else if (qsize == 0 || q == null || cmp(p, q) <= 0) {
e = p;
p = p.next;
psize--;
} else {
e = q;
q = q.next;
qsize--;
}
if (tail != null)
tail.next = e;
else
list = e;
tail = e;
}
p = q;
}
tail.next = null;
if (nmerges <= 1)
break;
insize *= 2;
}
return list;
}
}

View File

@ -0,0 +1,197 @@
/*
* 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 haxe.ds.StringMap;
import haxe.ds.IntMap;
import haxe.ds.HashMap;
import haxe.ds.ObjectMap;
import haxe.ds.WeakMap;
import haxe.ds.EnumValueMap;
import haxe.Constraints.IMap;
/**
Map allows key to value mapping for arbitrary value types, and many key
types.
This is a multi-type abstract, it is instantiated as one of its
specialization types depending on its type parameters.
A Map can be instantiated without explicit type parameters. Type inference
will then determine the type parameters from the usage.
Maps can also be created with `[key1 => value1, key2 => value2]` syntax.
Map is an abstract type, it is not available at runtime.
@see https://haxe.org/manual/std-Map.html
**/
@:transitive
@:multiType(@:followWithAbstracts K)
abstract Map<K, V>(IMap<K, V>) {
/**
Creates a new Map.
This becomes a constructor call to one of the specialization types in
the output. The rules for that are as follows:
1. if `K` is a `String`, `haxe.ds.StringMap` is used
2. if `K` is an `Int`, `haxe.ds.IntMap` is used
3. if `K` is an `EnumValue`, `haxe.ds.EnumValueMap` is used
4. if `K` is any other class or structure, `haxe.ds.ObjectMap` is used
5. if `K` is any other type, it causes a compile-time error
(Cpp) Map does not use weak keys on `ObjectMap` by default.
**/
public function new();
/**
Maps `key` to `value`.
If `key` already has a mapping, the previous value disappears.
If `key` is `null`, the result is unspecified.
**/
public inline function set(key:K, value:V)
this.set(key, value);
/**
Returns the current mapping of `key`.
If no such mapping exists, `null` is returned.
Note that a check like `map.get(key) == null` can hold for two reasons:
1. the map has no mapping for `key`
2. the map has a mapping with a value of `null`
If it is important to distinguish these cases, `exists()` should be
used.
If `key` is `null`, the result is unspecified.
**/
@:arrayAccess public inline function get(key:K)
return this.get(key);
/**
Returns true if `key` has a mapping, false otherwise.
If `key` is `null`, the result is unspecified.
**/
public inline function exists(key:K)
return this.exists(key);
/**
Removes the mapping of `key` and returns true if such a mapping existed,
false otherwise.
If `key` is `null`, the result is unspecified.
**/
public inline function remove(key:K)
return this.remove(key);
/**
Returns an Iterator over the keys of `this` Map.
The order of keys is undefined.
**/
public inline function keys():Iterator<K> {
return this.keys();
}
/**
Returns an Iterator over the values of `this` Map.
The order of values is undefined.
**/
public inline function iterator():Iterator<V> {
return this.iterator();
}
/**
Returns an Iterator over the keys and values of `this` Map.
The order of values is undefined.
**/
public inline function keyValueIterator():KeyValueIterator<K, V> {
return this.keyValueIterator();
}
/**
Returns a shallow copy of `this` map.
The order of values is undefined.
**/
public inline function copy():Map<K, V> {
return cast this.copy();
}
/**
Returns a String representation of `this` Map.
The exact representation depends on the platform and key-type.
**/
public inline function toString():String {
return this.toString();
}
/**
Removes all keys from `this` Map.
**/
public inline function clear():Void {
this.clear();
}
@:arrayAccess @:noCompletion public inline function arrayWrite(k:K, v:V):V {
this.set(k, v);
return v;
}
@:to static inline function toStringMap<K:String, V>(t:IMap<K, V>):StringMap<V> {
return new StringMap<V>();
}
@:to static inline function toIntMap<K:Int, V>(t:IMap<K, V>):IntMap<V> {
return new IntMap<V>();
}
@:to static inline function toEnumValueMapMap<K:EnumValue, V>(t:IMap<K, V>):EnumValueMap<K, V> {
return new EnumValueMap<K, V>();
}
@:to static inline function toObjectMap<K:{}, V>(t:IMap<K, V>):ObjectMap<K, V> {
return new ObjectMap<K, V>();
}
@:from static inline function fromStringMap<V>(map:StringMap<V>):Map<String, V> {
return cast map;
}
@:from static inline function fromIntMap<V>(map:IntMap<V>):Map<Int, V> {
return cast map;
}
@:from static inline function fromObjectMap<K:{}, V>(map:ObjectMap<K, V>):Map<K, V> {
return cast map;
}
}

View File

@ -0,0 +1,102 @@
/*
* 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;
/**
ObjectMap allows mapping of object keys to arbitrary values.
On static targets, the keys are considered to be strong references. Refer
to `haxe.ds.WeakMap` for a weak reference version.
See `Map` for documentation details.
@see https://haxe.org/manual/std-Map.html
**/
extern class ObjectMap<K:{}, V> implements haxe.Constraints.IMap<K, V> {
/**
Creates a new ObjectMap.
**/
function new():Void;
/**
See `Map.set`
**/
function set(key:K, value:V):Void;
/**
See `Map.get`
**/
function get(key:K):Null<V>;
/**
See `Map.exists`
**/
function exists(key:K):Bool;
/**
See `Map.remove`
**/
function remove(key:K):Bool;
/**
See `Map.keys`
(cs, java) Implementation detail: Do not `set()` any new value while
iterating, as it may cause a resize, which will break iteration.
**/
function keys():Iterator<K>;
/**
See `Map.iterator`
(cs, java) Implementation detail: Do not `set()` any new value while
iterating, as it may cause a resize, which will break iteration.
**/
function iterator():Iterator<V>;
/**
See `Map.keyValueIterator`
**/
#if eval
@:runtime inline function keyValueIterator():KeyValueIterator<K, V> {
return new haxe.iterators.MapKeyValueIterator(this);
}
#else
function keyValueIterator():KeyValueIterator<K, V>;
#end
/**
See `Map.copy`
**/
function copy():ObjectMap<K, V>;
/**
See `Map.toString`
**/
function toString():String;
/**
See `Map.clear`
**/
function clear():Void;
}

View File

@ -0,0 +1,34 @@
/*
* 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;
/**
An Option is a wrapper type which can either have a value (Some) or not a
value (None).
@see https://haxe.org/manual/std-Option.html
**/
enum Option<T> {
Some(v:T);
None;
}

View File

@ -0,0 +1,62 @@
/*
* 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;
/**
`ReadOnlyArray` is an abstract over an ordinary `Array` which only exposes
APIs that don't modify the instance, hence "read-only".
Note that this doesn't necessarily mean that the instance is *immutable*.
Other code holding a reference to the underlying `Array` can still modify it,
and the reference can be obtained with a `cast`.
**/
@:forward(copy, filter, indexOf, iterator, keyValueIterator, join, lastIndexOf, map, slice, contains, toString)
abstract ReadOnlyArray<T>(Array<T>) from Array<T> to Iterable<T> {
/**
The length of `this` Array.
**/
public var length(get, never):Int;
inline function get_length()
return this.length;
@:arrayAccess inline function get(i:Int)
return this[i];
/**
Returns a new Array by appending the elements of `a` to the elements of
`this` Array.
This operation does not modify `this` Array.
If `a` is the empty Array `[]`, a copy of `this` Array is returned.
The length of the returned Array is equal to the sum of `this.length`
and `a.length`.
If `a` is `null`, the result is unspecified.
**/
public inline function concat(a:ReadOnlyArray<T>):Array<T> {
return this.concat(cast a);
}
}

View File

@ -0,0 +1,99 @@
/*
* 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;
/**
StringMap allows mapping of String keys to arbitrary values.
See `Map` for documentation details.
@see https://haxe.org/manual/std-Map.html
**/
extern class StringMap<T> implements haxe.Constraints.IMap<String, T> {
/**
Creates a new StringMap.
**/
function new():Void;
/**
See `Map.set`
**/
function set(key:String, value:T):Void;
/**
See `Map.get`
**/
function get(key:String):Null<T>;
/**
See `Map.exists`
**/
function exists(key:String):Bool;
/**
See `Map.remove`
**/
function remove(key:String):Bool;
/**
See `Map.keys`
(cs, java) Implementation detail: Do not `set()` any new value while
iterating, as it may cause a resize, which will break iteration.
**/
function keys():Iterator<String>;
/**
See `Map.iterator`
(cs, java) Implementation detail: Do not `set()` any new value while
iterating, as it may cause a resize, which will break iteration.
**/
function iterator():Iterator<T>;
/**
See `Map.keyValueIterator`
**/
#if eval
@:runtime inline function keyValueIterator():KeyValueIterator<String, T> {
return new haxe.iterators.MapKeyValueIterator(this);
}
#else
function keyValueIterator():KeyValueIterator<String, T>;
#end
/**
See `Map.copy`
**/
function copy():StringMap<T>;
/**
See `Map.toString`
**/
function toString():String;
/**
See `Map.clear`
**/
function clear():Void;
}

View File

@ -0,0 +1,357 @@
/*
* 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;
#if cpp
using cpp.NativeArray;
#end
private typedef VectorData<T> =
#if flash10
flash.Vector<T>
#elseif neko
neko.NativeArray<T>
#elseif cs
cs.NativeArray<T>
#elseif java
java.NativeArray<T>
#elseif lua
lua.Table<Int, T>
#elseif eval
eval.Vector<T>
#else
Array<T>
#end
/**
A Vector is a storage of fixed size. It can be faster than Array on some
targets, and is never slower.
@see https://haxe.org/manual/std-vector.html
**/
abstract Vector<T>(VectorData<T>) {
/**
Creates a new Vector of length `length`.
Initially `this` Vector contains `length` neutral elements:
- always null on dynamic targets
- 0, 0.0 or false for Int, Float and Bool respectively on static targets
- null for other types on static targets
If `length` is less than or equal to 0, the result is unspecified.
**/
public inline function new(length:Int) {
#if flash10
this = new flash.Vector<T>(length, true);
#elseif neko
this = untyped __dollar__amake(length);
#elseif js
this = js.Syntax.construct(Array, length);
#elseif cs
this = new cs.NativeArray(length);
#elseif java
this = new java.NativeArray(length);
#elseif cpp
this = NativeArray.create(length);
#elseif python
this = python.Syntax.code("[{0}]*{1}", null, length);
#elseif lua
this = untyped __lua_table__({length: length});
#elseif eval
this = new eval.Vector(length);
#else
this = [];
untyped this.length = length;
#end
}
/**
Returns the value at index `index`.
If `index` is negative or exceeds `this.length`, the result is
unspecified.
**/
@:op([]) public inline function get(index:Int):T {
#if cpp
return this.unsafeGet(index);
#elseif python
return python.internal.ArrayImpl.unsafeGet(this, index);
#elseif eval
return this[index];
#else
return this[index];
#end
}
/**
Sets the value at index `index` to `val`.
If `index` is negative or exceeds `this.length`, the result is
unspecified.
**/
@:op([]) public inline function set(index:Int, val:T):T {
#if cpp
return this.unsafeSet(index, val);
#elseif python
return python.internal.ArrayImpl.unsafeSet(this, index, val);
#elseif eval
return this[index] = val;
#else
return this[index] = val;
#end
}
/**
Returns the length of `this` Vector.
**/
public var length(get, never):Int;
inline function get_length():Int {
#if neko
return untyped __dollar__asize(this);
#elseif cs
return this.Length;
#elseif java
return this.length;
#elseif python
return this.length;
#else
return untyped this.length;
#end
}
/**
Copies `length` of elements from `src` Vector, beginning at `srcPos` to
`dest` Vector, beginning at `destPos`
The results are unspecified if `length` results in out-of-bounds access,
or if `src` or `dest` are null
**/
public static #if (cs || java || neko || cpp || eval) inline #end function blit<T>(src:Vector<T>, srcPos:Int, dest:Vector<T>, destPos:Int, len:Int):Void {
#if neko
untyped __dollar__ablit(dest, destPos, src, srcPos, len);
#elseif java
java.lang.System.arraycopy(src, srcPos, dest, destPos, len);
#elseif cs
cs.system.Array.Copy(cast src, srcPos, cast dest, destPos, len);
#elseif cpp
dest.toData().blit(destPos, src.toData(), srcPos, len);
#elseif eval
src.toData().blit(srcPos, dest.toData(), destPos, len);
#else
if (src == dest) {
if (srcPos < destPos) {
var i = srcPos + len;
var j = destPos + len;
for (k in 0...len) {
i--;
j--;
src[j] = src[i];
}
} else if (srcPos > destPos) {
var i = srcPos;
var j = destPos;
for (k in 0...len) {
src[j] = src[i];
i++;
j++;
}
}
} else {
for (i in 0...len) {
dest[destPos + i] = src[srcPos + i];
}
}
#end
}
/**
Creates a new Array, copy the content from the Vector to it, and returns it.
**/
public #if (flash || cpp || js || java || eval) inline #end function toArray():Array<T> {
#if cpp
return this.copy();
#elseif python
return this.copy();
#elseif js
return this.slice(0);
#elseif eval
return this.toArray();
#else
var a = new Array();
var len = length;
#if (neko)
// prealloc good size
if (len > 0)
a[len - 1] = get(0);
#end
for (i in 0...len)
a[i] = get(i);
return a;
#end
}
/**
Extracts the data of `this` Vector.
This returns the internal representation type.
**/
public inline function toData():VectorData<T>
return cast this;
/**
Initializes a new Vector from `data`.
Since `data` is the internal representation of Vector, this is a no-op.
If `data` is null, the corresponding Vector is also `null`.
**/
static public inline function fromData<T>(data:VectorData<T>):Vector<T>
return cast data;
/**
Creates a new Vector by copying the elements of `array`.
This always creates a copy, even on platforms where the internal
representation is Array.
The elements are not copied and retain their identity, so
`a[i] == Vector.fromArrayCopy(a).get(i)` is true for any valid i.
If `array` is null, the result is unspecified.
**/
static public inline function fromArrayCopy<T>(array:Array<T>):Vector<T> {
#if python
return cast array.copy();
#elseif flash10
return fromData(flash.Vector.ofArray(array));
#elseif java
return fromData(java.Lib.nativeArray(array, false));
#elseif cs
return fromData(cs.Lib.nativeArray(array, false));
#elseif cpp
return cast array.copy();
#elseif js
return fromData(array.slice(0));
#elseif eval
return fromData(eval.Vector.fromArrayCopy(array));
#else
// TODO: Optimize this for others?
var vec = new Vector<T>(array.length);
for (i in 0...array.length)
vec.set(i, array[i]);
return vec;
#end
}
/**
Returns a shallow copy of `this` Vector.
The elements are not copied and retain their identity, so
`a[i] == a.copy()[i]` is true for any valid `i`. However,
`a == a.copy()` is always false.
**/
#if cs extern #end public inline function copy<T>():Vector<T> {
#if eval
return fromData(this.copy());
#else
var r = new Vector<T>(length);
Vector.blit(cast this, 0, r, 0, length);
return r;
#end
}
/**
Returns a string representation of `this` Vector, with `sep` separating
each element.
The result of this operation is equal to `Std.string(this[0]) + sep +
Std.string(this[1]) + sep + ... + sep + Std.string(this[this.length-1])`
If `this` Vector has length 0, the result is the empty String `""`.
If `this` has exactly one element, the result is equal to a call to
`Std.string(this[0])`.
If `sep` is null, the result is unspecified.
**/
#if cs extern #end public inline function join<T>(sep:String):String {
#if (flash10 || cpp || eval)
return this.join(sep);
#else
var b = new StringBuf();
var len = length;
for (i in 0...len) {
b.add(Std.string(get(i)));
if (i < len - 1) {
b.add(sep);
}
}
return b.toString();
#end
}
/**
Creates a new Vector by applying function `f` to all elements of `this`.
The order of elements is preserved.
If `f` is null, the result is unspecified.
**/
#if cs extern #end public inline function map<S>(f:T->S):Vector<S> {
#if eval
return fromData(this.map(f));
#else
var length = length;
var r = new Vector<S>(length);
var len = length;
for (i in 0...len) {
var v = f(get(i));
r.set(i, v);
}
return r;
#end
}
/**
Sorts `this` Vector according to the comparison function `f`, where
`f(x,y)` returns 0 if x == y, a positive Int if x > y and a
negative Int if x < y.
This operation modifies `this` Vector in place.
The sort operation is not guaranteed to be stable, which means that the
order of equal elements may not be retained.
If `f` is null, the result is unspecified.
**/
public inline function sort(f:T->T->Int):Void {
#if (neko || cs || java || eval)
throw "not yet supported";
#elseif lua
haxe.ds.ArraySort.sort(cast this, f);
#else
this.sort(f);
#end
}
}

View File

@ -0,0 +1,107 @@
/*
* 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;
/**
WeakMap allows mapping of object keys to arbitrary values.
The keys are considered to be weak references on static targets.
See `Map` for documentation details.
@see https://haxe.org/manual/std-Map.html
**/
class WeakMap<K:{}, V> implements haxe.Constraints.IMap<K, V> {
/**
Creates a new WeakMap.
**/
public function new():Void {
throw new haxe.exceptions.NotImplementedException("Not implemented for this platform");
}
/**
See `Map.set`
**/
public function set(key:K, value:V):Void {}
/**
See `Map.get`
**/
public function get(key:K):Null<V> {
return null;
}
/**
See `Map.exists`
**/
public function exists(key:K):Bool {
return false;
}
/**
See `Map.remove`
**/
public function remove(key:K):Bool {
return false;
}
/**
See `Map.keys`
**/
public function keys():Iterator<K> {
return null;
}
/**
See `Map.iterator`
**/
public function iterator():Iterator<V> {
return null;
}
/**
See `Map.keyValueIterator`
**/
public inline function keyValueIterator():KeyValueIterator<K, V> {
return null;
}
/**
See `Map.copy`
**/
public function copy():WeakMap<K, V> {
return null;
}
/**
See `Map.toString`
**/
public function toString():String {
return null;
}
/**
See `Map.clear`
**/
public function clear():Void {}
}