Если я вызову функцию
/** Check if all Elements, possibly recursively, of $(D x) are zero. */
bool allZero(T)(in T x) @safe pure nothrow {
import std.range: isIterable;
static if (isIterable!T) {
foreach (ref elt; x) {
if (!elt.allZero) { return false; }
}
return true;
} else {
return x == 0;
}
}
со статическим массивом D автоматически развернет foreach
для меня в режиме выпуска?
Если бы не мог
/** Static Iota. */
import std.typetuple: TypeTuple;
template siota(size_t from, size_t to) { alias siotaImpl!(to-1, from) siota; }
private template siotaImpl(size_t to, size_t now) {
static if (now >= to) { alias TypeTuple!(now) siotaImpl; }
else { alias TypeTuple!(now, siotaImpl!(to, now+1)) siotaImpl; }
}
использоваться для развертывания вместо foreach
?
Кроме того, есть ли флаг для DMD, который генерирует ассемблерный код, чтобы я сам в будущем мог исследовать код, сгенерированный DMD?
Обновление: вот мое решение.
/** Check if all Elements, possibly recursively, of $(D x) are zero. */
bool allZero(T, bool useStatic = true)(in T x) @safe pure nothrow { // TODO: Extend to support struct's and classes's'
static if (useStatic && isStaticArray!T) {
foreach (ix; siota!(0, x.length)) {
if (!x[ix].allZero) { return false; } // make use of siota?
}
return true;
} else static if (isIterable!T) {
foreach (ref elt; x) {
if (!elt.allZero) { return false; }
}
return true;
} else {
return x == 0;
}
}
Это выглядит нормально?