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