1 module Engine.util; 2 3 import std.range; 4 import std.parallelism; 5 6 package extern (C) Object _d_newclass (in ClassInfo info); 7 8 T copy(T:Object) (T value) 9 { 10 if (value is null) 11 return null; 12 auto size = value.classinfo.init.length; 13 Object v = cast(Object) ( (cast(void*)value) [0..size].dup.ptr ); 14 v.__monitor = null; 15 return cast (T)v; 16 } 17 18 T copy2(T:Object) (T value) 19 { 20 if (value is null) 21 return null; 22 void *c = cast(void*)_d_newclass (value.classinfo); 23 size_t size = value.classinfo.init.length; 24 c[0..size] = (cast (void *) value)[0..size]; 25 (cast(Object)c).__monitor = null; 26 return cast (T)c; 27 } 28 29 30 package Object newInstance (in ClassInfo classInfo) 31 { 32 return _d_newclass(classInfo); 33 } 34 35 template remove(ArrTy, IntTy) { 36 static assert(is(IntTy : int)); 37 void remove(ArrTy arr, IntTy ix) { 38 arr[ix] = arr[$-1]; 39 arr.length = arr.length - 1; 40 } 41 } 42 43 public import std.traits : isPointer; 44 45 template baseType(T : T*) { 46 static if (!is(baseType!T == T)) { 47 alias baseType = baseType!T; 48 } else { 49 alias baseType = T; 50 } 51 } 52 53 template baseType(T) { 54 alias baseType = T; 55 } 56 57 template pointerType(T) { 58 alias Tp = baseType!T; 59 static if (is(Tp == class) || is (Tp == interface)) { 60 alias pointerType = Tp; 61 } 62 else { 63 alias pointerType = Tp*; 64 } 65 } 66 67 unittest { 68 class A { 69 70 } 71 struct B { 72 73 } 74 interface C { 75 76 } 77 assert(is(baseType!A == A)); 78 assert(is(baseType!(A*) == A)); 79 assert(is(baseType!(A**) == A)); 80 assert(is(baseType!(A***) == A)); 81 82 assert(is(baseType!B == B)); 83 assert(is(baseType!(B*) == B)); 84 assert(is(baseType!(B**) == B)); 85 assert(is(baseType!(B***) == B)); 86 87 assert(is(baseType!C == C)); 88 assert(is(baseType!(C*) == C)); 89 assert(is(baseType!(C**) == C)); 90 assert(is(baseType!(C***) == C)); 91 92 assert(is(pointerType!A == A)); 93 assert(is(pointerType!(A*) == A)); 94 assert(is(pointerType!(A**) == A)); 95 assert(is(pointerType!(A***) == A)); 96 97 assert(is(pointerType!B == B*)); 98 assert(is(pointerType!(B*) == B*)); 99 assert(is(pointerType!(B**) == B*)); 100 assert(is(pointerType!(B***) == B*)); 101 102 assert(is(pointerType!C == C)); 103 assert(is(pointerType!(C*) == C)); 104 assert(is(pointerType!(C**) == C)); 105 assert(is(pointerType!(C***) == C)); 106 } 107 108 void parallelRange(int works, T, R)(T t, R range) { 109 typeof(scopedTask(t,range))[works] tasks; 110 int m = range.length/(tasks.length+1); 111 for (int i=0;i<tasks.length;i++) { 112 tasks[i] = scopedTask(t,range[i*m..(i+1)*m]); 113 taskPool.put(tasks[i]); 114 } 115 t(range[(tasks.length)*m..range.length]); 116 } 117 118 struct ConstArray(T) { 119 package T[] array; 120 121 this(T[] array) { 122 this.array = array; 123 } 124 125 @property length() { return array.length; } 126 127 T opIndex(size_t i) { 128 return array[i]; 129 } 130 131 auto opSlice(size_t x, size_t y) { 132 return typeof(this)(array[x..y]); 133 } 134 135 @property front() { return array.front; } 136 @property back() { return array.back; } 137 @property empty() const {return array.empty;} 138 void popFront() {assert(!empty); array.popFront();} 139 void popBack() {assert(!empty); array.popBack();} 140 @property typeof(this) save() {return typeof(this)(array);} 141 142 static assert(isForwardRange!(typeof(this))); 143 static assert(hasLength!(typeof(this))); 144 static assert(isRandomAccessRange!(typeof(this))); 145 }