This should compile: import std.contracts; double unrolledDotProduct(double[] a, double[] b) { enum branches = 4; enforce(a.length == b.length); double result = 0; auto n = (a.length / branches) * branches; double temp[branches]; for (size_t i = 0; i != n; i += branches) { static foreach (j ; 0 .. branches) { temp[j] = a[i + j] * b[i + j]; } result += inline_sum(temp); } foreach (j; n .. a.length) { result += a[j] * b[j]; } return result; }
This does compile (on 1.0): template Repeat(T, int I) { static if (!I) alias Tuple!() Repeat; else alias Tuple!(T, Repeat!(T, I - 1)) Repeat; } double unrolledDotProduct(double[] a, double[] b) { const branches = 4; assert(a.length == b.length); double result = 0; auto n = (a.length / branches) * branches; double temp[branches]; for (size_t i = 0; i != n; i += branches) { foreach (j, BOGUS; Repeat!(void, branches)) { temp[j] = a[i + j] * b[i + j]; } result += inline_sum(temp); } foreach (j; n .. a.length) { result += a[j] * b[j]; } return result; }
Many problems have come up with the design of this, so will mark as won't implement until a thorough design is developed.