Thread overview
How to check if string is available at compile time
Sep 21, 2017
David Bennett
Sep 21, 2017
David Bennett
Sep 21, 2017
Meta
Sep 21, 2017
David Bennett
Sep 22, 2017
B4s1L3
September 21, 2017
Hi Guys,

Is there an easy way to check if the value of string passed to a template is available at compile time?

Here is a cut down example of that I'm doing:

```
string[] escapeCTFE(Args...)(){

    static foreach (arg; Args){
        static if(__traits(compiles, ###WHATDOIPUTHERE###)){
            pragma(msg, "Do work on string: ", arg);
        }else{
            pragma(msg, __traits(identifier, arg), " can only be read at runtime");
        }
    }

}

void main(){

    string a = "a";
    static string b = "b";
    enum string c = "c";
    immutable string d = "d";
    const string e = "e";

    enum escape_as_much_as_possible = escapeCTFE!(a,b,c,d,e,"f");
}

```

I know for ints I can use __traits(compiles, int[arg]) but I'm not sure about strings.

I believe only a and b should be hidden from pragma right?

Thanks,
David.
September 21, 2017
On Thursday, 21 September 2017 at 11:42:36 UTC, David Bennett wrote:
> [snip]
>
> ```
> string[] escapeCTFE(Args...)(){
>
>     static foreach (arg; Args){
>         static if(__traits(compiles, ###WHATDOIPUTHERE###)){
> [snip]


So far the best I've come up with is :

```

enum isCTstring(alias arg) = (!isAssignable!(typeof(arg)) || __traits(compiles, mixin(` "foo" ~ `~__traits(identifier, arg))));

string[] escapeCTFE(Args...)(){

    static foreach (arg; Args){
        static if(isCTstring!(arg)){
            pragma(msg, "Do work on string: ", arg);
        }else{
            pragma(msg, __traits(identifier, arg), " can only be read at runtime");
        }
    }
    return new string[32];
}

```

But this seems quite hackish... any better ideas?
September 21, 2017
On Thursday, 21 September 2017 at 12:30:15 UTC, David Bennett wrote:
> On Thursday, 21 September 2017 at 11:42:36 UTC, David Bennett wrote:
>> [snip]
>>
>> ```
>> string[] escapeCTFE(Args...)(){
>>
>>     static foreach (arg; Args){
>>         static if(__traits(compiles, ###WHATDOIPUTHERE###)){
>> [snip]
>
>
> So far the best I've come up with is :
>
> ```
>
> enum isCTstring(alias arg) = (!isAssignable!(typeof(arg)) || __traits(compiles, mixin(` "foo" ~ `~__traits(identifier, arg))));
>
> string[] escapeCTFE(Args...)(){
>
>     static foreach (arg; Args){
>         static if(isCTstring!(arg)){
>             pragma(msg, "Do work on string: ", arg);
>         }else{
>             pragma(msg, __traits(identifier, arg), " can only be read at runtime");
>         }
>     }
>     return new string[32];
> }
>
> ```
>
> But this seems quite hackish... any better ideas?

Try __traits(compiles, { enum _ = arg; }). Creating an enum necessarily requires that its value is available at compile time.
September 21, 2017
On Thursday, 21 September 2017 at 13:52:25 UTC, Meta wrote:
> On Thursday, 21 September 2017 at 12:30:15 UTC, David Bennett wrote:
>> On Thursday, 21 September 2017 at 11:42:36 UTC, David Bennett wrote:
>>
>> enum isCTstring(alias arg) = (!isAssignable!(typeof(arg)) || __traits(compiles, mixin(` "foo" ~ `~__traits(identifier, arg))));
>>
>> [snip]
>>
>> But this seems quite hackish... any better ideas?
>
> Try __traits(compiles, { enum _ = arg; }). Creating an enum necessarily requires that its value is available at compile time.

Ahh, warping it in {} seems to change the timing of the execution, this is starting to make a lot of sense to me now. (also explains why int[arg] works).

Thats much cleaner and I'll use that from now on.

Thanks a lot!
David
September 22, 2017
On Thursday, 21 September 2017 at 11:42:36 UTC, David Bennett wrote:
> Hi Guys,
>
> Is there an easy way to check if the value of string passed to a template is available at compile time?
>

Yeah , sure and I have such a template in my library: https://github.com/BBasile/iz/blob/master/import/iz/types.d#L627

see just above too, the template "isCompileTimeValue"