www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to check if string is available at compile time

reply David Bennett <davidbennett bravevision.com> writes:
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.
Sep 21
next sibling parent reply David Bennett <davidbennett bravevision.com> writes:
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?
Sep 21
parent reply Meta <jared771 gmail.com> writes:
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.
Sep 21
parent David Bennett <davidbennett bravevision.com> writes:
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
Sep 21
prev sibling parent B4s1L3 <b2.temp gmx.com> writes:
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"
Sep 22