Determine if CTFE or RT

Mr.Bingo Bingo at Namo.com
Mon Jun 25 12:40:54 UTC 2018


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.






More information about the Digitalmars-d-learn mailing list