Determine if CTFE or RT

Simen Kjærås simen.kjaras at gmail.com
Mon Jun 25 10:49:26 UTC 2018


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


More information about the Digitalmars-d-learn mailing list