2

関数を呼び出すと

/** 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;
    }
}

静的配列を使用すると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;
    }
}

それは大丈夫ですか?

4

1 に答える 1

5

静的配列を使用すると、D は foreach を自動的に展開しますか?

いいえ、言語はそれを保証しません。一部の実装 (コンパイラ) は、最適化としてループを展開する場合があります。

そうでない場合、静的 iota (siota) の実装を使用してこれを達成できますか?

はい、タプルに対して foreach を使用すると、「反復」ごとにコードが生成され、ループが効果的に展開されます。

さらに、DMD によって生成されたコードを将来私自身が調査できるように、アセンブリ コードを生成する DMD へのフラグはありますか?

いいえ、DMD はアセンブリ リストを発行できません。代わりに、逆アセンブラー( obj2asmIDAなど) または別のコンパイラーを使用できます。

于 2014-02-06T22:55:48.160 に答える