Alexander Kuzmenko 7 лет назад
Родитель
Сommit
4a7a9bf570

+ 4 - 0
extra/CHANGES.txt

@@ -1,5 +1,9 @@
 XXXX-XX-XX:
 
+	General improvements and optimizations:
+
+	php : Optimized haxe.ds.Vector (VectorData is not Array anymore)
+
 	Bugfixes:
 
 	php : Escape `$` in field names of anonymous objects (#7230)

+ 8 - 0
std/php/Syntax.hx

@@ -276,4 +276,12 @@ extern class Syntax {
         Add errors suppression operator `@` before `expression`
     **/
     static function suppress<T>( expression:T ) : T;
+
+    /**
+        Generates `clone $value`.
+        @see http://php.net/manual/en/language.oop5.cloning.php
+     */
+    static inline function clone<T>(value:T):T {
+        return Syntax.code('clone {0}', value);
+    }
 }

+ 131 - 0
std/php/_std/haxe/ds/Vector.hx

@@ -0,0 +1,131 @@
+/*
+ * Copyright (C)2005-2018 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 php.*;
+
+private class VectorData<T> {
+	@:allow(haxe.ds.Vector) var length:Int;
+	@:allow(haxe.ds.Vector) var data:NativeIndexedArray<T>;
+
+	public inline function new(length:Int) {
+		this.length = length;
+		data = new NativeIndexedArray();
+	}
+}
+
+abstract Vector<T>(VectorData<T>) {
+
+	public var length(get, never):Int;
+
+	public inline function new(length:Int) {
+		this = new VectorData(length);
+	}
+
+	@:op([]) public inline function get(index:Int):T {
+		return Syntax.coalesce(this.data[index], null);
+	}
+
+	@:op([]) public inline function set(index:Int, val:T):T {
+		return this.data[index] = val;
+	}
+
+	inline function get_length():Int {
+		return this.length;
+	}
+
+	public static function blit<T>(src:Vector<T>, srcPos:Int, dest:Vector<T>, destPos:Int, len:Int):Void {
+		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];
+			}
+		}
+	}
+
+	public function toArray():Array<T> {
+		var result = [];
+		@:privateAccess result.length = length;
+		for(i in 0...length) {
+			@:privateAccess result.arr.push(get(i));
+		}
+		return result;
+	}
+
+	public inline function toData():VectorData<T> {
+		return this;
+	}
+
+	static public inline function fromData<T>(data:VectorData<T>):Vector<T> {
+		return cast data;
+	}
+
+	static public inline function fromArrayCopy<T>(array:Array<T>):Vector<T> {
+		var vectorData = new VectorData(array.length);
+		vectorData.data = @:privateAccess array.arr;
+		return cast vectorData;
+	}
+
+	public inline function copy<T>():Vector<T> {
+		return cast Syntax.clone(this);
+	}
+
+	public function join<T>(sep:String):String {
+		if(this.length == 0) {
+			return '';
+		}
+		var result = Std.string(get(0));
+		for(i in 1...this.length) {
+			result = Syntax.concat(result, Syntax.concat(sep, Std.string(get(i))));
+		}
+		return result;
+	}
+
+	public inline function map<S>(f:T->S):Vector<S> {
+		var result = new Vector(this.length);
+		for(i in 0...this.length) {
+			result[i] = f(get(i));
+		}
+		return result;
+	}
+
+	public inline function sort<T>(f:T->T->Int):Void {
+		Global.usort(this.data, f);
+	}
+}

+ 9 - 1
tests/unit/src/unitstd/haxe/ds/Vector.unit.hx

@@ -30,7 +30,7 @@ vec.get(2) == vNullBool;
 // fromArray
 var arr = ["1", "2", "3"];
 var vec:haxe.ds.Vector<String> = haxe.ds.Vector.fromArrayCopy(arr);
-#if (!flash && !neko && !cs && !java && !lua && !eval)
+#if (!flash && !neko && !cs && !java && !lua && !eval && !php)
 arr != vec.toData();
 #end
 vec.length == 3;
@@ -38,6 +38,14 @@ vec.get(0) == "1";
 vec.get(1) == "2";
 vec.get(2) == "3";
 
+// toArray
+var vec = new haxe.ds.Vector(3);
+vec.set(1, 2);
+var arr = vec.toArray();
+arr[0] == vNullInt;
+arr[1] == 2;
+arr[3] == vNullInt;
+
 // objects
 var tpl = new C();
 var vec:haxe.ds.Vector<C> = haxe.ds.Vector.fromArrayCopy([tpl]);