Static argument optimization

dsimcha dsimcha at yahoo.com
Mon Oct 6 21:24:05 PDT 2008


Here's a hack at least for this special case.  It probably only works for D2,
though.  Not sure if this is the kind of (extremely hackish) thing you had in
mind, but at the very least it was a fun little template puzzle.

Also, note that the pragmas are nice for figuring out what this thing is doing,
but not strictly necessary.  This hack has been through some rudimentary testing,
but nothing particularly thorough.

//CTFE can't be forward referenced.
uint runtimePow(uint n, uint power) {
    uint ret = 1;
    for(uint i = 1; i <= power; i++)
        ret *= n;
    return ret;
}

uint pow(alias n, alias power)() {
    static if(__traits(compiles, test!(n)) && __traits(compiles, test!(power))) {
        pragma(msg, "fully static");
        static const uint ret = runtimePow(n, power);  //CTFE
        return ret;  //Almost surely will be inlined, constant folded.
    } else static if(__traits(compiles, test!(power))) {
        pragma(msg, "partially static");
        pragma(msg, raiseToConstPow!(n, power));
        mixin("return " ~ raiseToConstPow!(n, power));  //Again, inlined.
    } else {
        pragma(msg, "runtime");
        return runtimePow(n, power);
    }
}

template raiseToConstPow(alias n, uint power) {
    static if(power == 0) {
        //Compiler should optimize out the last * 1.
        const char[] raiseToConstPow = "1;";
    } else {
        const char[] raiseToConstPow = "n * " ~ raiseToConstPow!(n, power - 1);
    }
}

template test(uint foo) {
    const uint bar = runtimePow(foo, foo);
}



More information about the Digitalmars-d mailing list