1 module nxt.concatenation; 2 3 /** Sum of the lengths of the static arrays 'A'. 4 */ 5 template sumOfLengths(A...) 6 if (A.length) { 7 static if (A.length == 1) { 8 static if (isType!(A[0])) { 9 static if (__traits(isStaticArray, A[0])) 10 enum sumOfLengths = A[0].length; 11 else 12 enum sumOfLengths = 1; 13 } 14 else 15 { 16 static if (__traits(isStaticArray, typeof(A[0]))) 17 enum sumOfLengths = A[0].length; 18 else 19 enum sumOfLengths = 1; 20 } 21 } 22 else 23 enum sumOfLengths = A[0].length + sumOfLengths!(A[1 .. $]); 24 } 25 26 /** Is `true` iff `T` is a type. */ 27 private template isType(T) { enum isType = true; } 28 /// ditto 29 private template isType(alias T) { enum isType = false; } 30 31 pure nothrow @safe @nogc unittest { 32 int[2] x, y, z; 33 int w; 34 static assert(sumOfLengths!(x, y, z, w) == 7); 35 } 36 37 /** Returns: concatenation of the static arrays `Args` as a static array. 38 * Move to Phobos's std.array. 39 */ 40 StaticArrayElementType!(Args[0])[sumOfLengths!Args] concatenate(Args...)(const auto ref Args args) { 41 pragma(inline, true); // must be inlineable 42 typeof(return) result = void; // @trusted 43 foreach (const i, arg; args) { 44 static if (i == 0) 45 enum offset = 0; 46 else 47 enum offset = sumOfLengths!(args[0 .. i]); 48 static if (__traits(isStaticArray, typeof(arg))) 49 result[offset .. offset + arg.length] = arg[]; 50 else 51 result[offset] = arg; 52 } 53 return result; 54 } 55 56 private alias StaticArrayElementType(A : E[n], E, size_t n) = E; 57 58 pure nothrow @safe @nogc unittest { 59 int[2] x = [11, 22]; 60 const int[2] y = [33, 44]; 61 const int w = 55; 62 auto z = concatenate(x, y, w); 63 static assert(is(typeof(z) == int[5])); 64 assert(z == [11, 22, 33, 44, 55]); 65 } 66 67 import core.internal.traits : hasElaborateDestructor; 68 import core.internal.traits : Unqual; 69 70 /** Overload with faster compilation. 71 */ 72 Unqual!T[n + 1] concatenate(T, size_t n)(auto ref T[n] a, T b) 73 if (!hasElaborateDestructor!T) { 74 pragma(inline, true); // must be inlineable 75 typeof(return) c = void; 76 c[0 .. n] = a; 77 c[n] = b; 78 return c; 79 } 80 81 pure nothrow @safe @nogc unittest { 82 const int[2] x = [11, 22]; 83 int y = 33; 84 auto z = concatenate(x, y); 85 static assert(is(typeof(z) == int[3])); 86 assert(z == [11, 22, 33]); 87 }