summaryrefslogtreecommitdiff
path: root/libphobos/libdruntime/core/internal/array/construction.d
diff options
context:
space:
mode:
Diffstat (limited to 'libphobos/libdruntime/core/internal/array/construction.d')
-rw-r--r--libphobos/libdruntime/core/internal/array/construction.d108
1 files changed, 108 insertions, 0 deletions
diff --git a/libphobos/libdruntime/core/internal/array/construction.d b/libphobos/libdruntime/core/internal/array/construction.d
index 54f8767139c..655acc8db57 100644
--- a/libphobos/libdruntime/core/internal/array/construction.d
+++ b/libphobos/libdruntime/core/internal/array/construction.d
@@ -486,3 +486,111 @@ version (D_ProfileGC)
assert(0, "Cannot create new array if compiling without support for runtime type information!");
}
}
+
+/**
+ * Create a new multi-dimensional array. Also initalize elements if their type has an initializer.
+ * Otherwise, not zero-initialize the array.
+ *
+ * ---
+ * void main()
+ * {
+ * S[][] s = new S[][](2, 3)
+ *
+ * // lowering:
+ * S[] s = _d_newarraymTX!(S[][], S)([2, 3]);
+ * }
+ * ---
+ *
+ * Params:
+ * dims = array length values for each dimension
+ * isShared = whether the array should be shared
+ *
+ * Returns:
+ * newly allocated array
+ */
+Tarr _d_newarraymTX(Tarr : U[], T, U)(size_t[] dims, bool isShared=false) @trusted
+{
+ debug(PRINTF) printf("_d_newarraymTX(dims.length = %d)\n", dims.length);
+
+ if (dims.length == 0)
+ return null;
+
+ alias UnqT = Unqual!(T);
+
+ void[] __allocateInnerArray(size_t[] dims)
+ {
+ import core.internal.array.utils : __arrayStart, __setArrayAllocLength, __arrayAlloc;
+
+ auto dim = dims[0];
+
+ debug(PRINTF) printf("__allocateInnerArray(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, dims.length);
+ if (dims.length == 1)
+ {
+ auto r = _d_newarrayT!UnqT(dim, isShared);
+ return *cast(void[]*)(&r);
+ }
+
+ auto allocSize = (void[]).sizeof * dim;
+ auto info = __arrayAlloc!UnqT(allocSize);
+ __setArrayAllocLength!UnqT(info, allocSize, isShared);
+ auto p = __arrayStart(info)[0 .. dim];
+
+ foreach (i; 0..dim)
+ {
+ (cast(void[]*)p.ptr)[i] = __allocateInnerArray(dims[1..$]);
+ }
+ return p;
+ }
+
+ auto result = __allocateInnerArray(dims);
+ debug(PRINTF) printf("result = %llx\n", result.ptr);
+
+ return (cast(U*) result.ptr)[0 .. dims[0]];
+}
+
+unittest
+{
+ int[][] a = _d_newarraymTX!(int[][], int)([2, 3]);
+
+ assert(a.length == 2);
+ for (size_t i = 0; i < a.length; i++)
+ {
+ assert(a[i].length == 3);
+ for (size_t j = 0; j < a[i].length; j++)
+ assert(a[i][j] == 0);
+ }
+}
+
+unittest
+{
+ struct S { int x = 1; }
+
+ S[][] a = _d_newarraymTX!(S[][], S)([2, 3]);
+
+ assert(a.length == 2);
+ for (size_t i = 0; i < a.length; i++)
+ {
+ assert(a[i].length == 3);
+ for (size_t j = 0; j < a[i].length; j++)
+ assert(a[i][j].x == 1);
+ }
+}
+
+version (D_ProfileGC)
+{
+ /**
+ * TraceGC wrapper around $(REF _d_newarraymT, core,internal,array,construction).
+ */
+ Tarr _d_newarraymTXTrace(Tarr : U[], T, U)(string file, int line, string funcname, size_t[] dims, bool isShared=false) @trusted
+ {
+ version (D_TypeInfo)
+ {
+ import core.internal.array.utils : TraceHook, gcStatsPure, accumulatePure;
+ mixin(TraceHook!(T.stringof, "_d_newarraymTX"));
+
+ return _d_newarraymTX!(Tarr, T)(dims, isShared);
+ }
+ else
+ assert(0, "Cannot create new multi-dimensional array if compiling without support for runtime type information!");
+ }
+}