On Monday, 25 June 2018 at 10:49:26 UTC, Simen Kjærås wrote:
On Monday, 25 June 2018 at 09:36:45 UTC, Martin Tschierschke wrote:
I am not sure that I understood it right, but there is a way to detect the status of a parameter:

My question was different, but I wished to get a ctRegex! or regex used depending on the expression:

 import std.regex:replaceAll,ctRegex,regex;

 auto reg(alias var)(){
       static if (__traits(compiles, {enum ctfeFmt = var;}) ){
                // "Promotion" to compile time value
                enum ctfeReg =  var ;
                pragma(msg, "ctRegex used");
                return(ctRegex!ctfeReg);

       }else{
                return(regex(var));
                pragma(msg,"regex used");
                }
       }
}
So now I can always use reg!("....") and let the compiler decide.

To speed up compilation I made an additional switch, that when using DMD (for development)
alway the runtime version is used.

The trick is to use the alias var in the declaration and check if it can be assigned to enum. The only thing is now, that you now always use the !() compile time parameter to call the function. Even, when in the end is translated to an runtime call.

reg!("....") and not reg("...").

Now try reg!("prefix" ~ var) or reg!(func(var)). This works in some limited cases, but falls apart when you try something more involved. It can sorta be coerced into working by passing lambdas:


template ctfe(T...) if (T.length == 1) {
    import std.traits : isCallable;
    static if (isCallable!(T[0])) {
        static if (is(typeof({enum a = T[0]();}))) {
            enum ctfe = T[0]();
        } else {
            alias ctfe = T[0];
        }
    } else {
        static if (is(typeof({enum a = T[0];}))) {
            enum ctfe = T[0];
        } else {
            alias ctfe = T[0];
        }
    }
}

string fun(string s) { return s; }

unittest {
    auto a = ctfe!"a";
    string b = "a";
    auto c = ctfe!"b";
auto d = ctfe!("a" ~ b); // Error: variable b cannot be read at compile time
    auto e = ctfe!(() => "a" ~ b);
auto f = ctfe!(fun(b)); // Error: variable b cannot be read at compile time
    auto g = ctfe!(() => fun(b));
}

--
  Simen

This doesn't work, the delegate only hides the error until you call it.

auto also does not detect enum. Ideally it should be a manifest constant if precomputed... this allows chaining of optimizations.

auto x = 3;
auto y = foo(x);


the compiler realizes x is an enum int and then it can also precompute foo(x).

Since it converts to a runtime type immediately it prevents any optimizations and template tricks.




Reply via email to