www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - DRY version of `static if(__traits(compiles, expr)) fun(expr)`

reply Timothee Cour via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
what's the best (and DRY) way to achieve:

```
static if(__traits(compiles, expr))
  fun(expr);
```

ie, without repeating the expression inside expr?

eg:

```
static if(__traits(compiles, foo.bar[2])){
  counter++;
  writeln(" expr = ", foo.bar[2]);
}

```
Dec 13 2016
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 14.12.2016 00:00, Timothee Cour via Digitalmars-d-learn wrote:
 what's the best (and DRY) way to achieve:

 ```
 static if(__traits(compiles, expr))
   fun(expr);
 ```

 ie, without repeating the expression inside expr?

 eg:

 ```
 static if(__traits(compiles, foo.bar[2])){
   counter++;
   writeln(" expr = ", foo.bar[2]);
 }

 ```
I usually do enum code = q{expr}; static if(__traits(compiles,mixin(code))) fun(mixin(code));
Dec 13 2016
parent reply Basile B. <b2.temp gmx.com> writes:
On Tuesday, 13 December 2016 at 23:37:59 UTC, Timon Gehr wrote:
 On 14.12.2016 00:00, Timothee Cour via Digitalmars-d-learn 
 wrote:
 what's the best (and DRY) way to achieve:

 ```
 static if(__traits(compiles, expr))
   fun(expr);
 ```

 ie, without repeating the expression inside expr?

 eg:

 ```
 static if(__traits(compiles, foo.bar[2])){
   counter++;
   writeln(" expr = ", foo.bar[2]);
 }

 ```
I usually do enum code = q{expr}; static if(__traits(compiles,mixin(code))) fun(mixin(code));
Strangely if i put this in a templated enum that doesn't work. If instead i use a delegate literal it works. enum Compiles(string code) = is(typeof((){mixin(code);})); enum Compiles2(string code) = __traits(compiles, mixin(code)); unittest { static assert(Compiles!q{auto a = 1+1;}); static assert(!Compiles!q{1;}); static assert(!Compiles!q{a = 1;}); static assert(Compiles2!q{auto a = 1+1;}); static assert(!Compiles2!q{1;}); static assert(!Compiles2!q{a = 1;}); } wtf ?
Dec 14 2016
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 12/14/2016 09:25 AM, Basile B. wrote:
 On Tuesday, 13 December 2016 at 23:37:59 UTC, Timon Gehr wrote:
 I usually do

 enum code = q{expr};
 static if(__traits(compiles,mixin(code)))
     fun(mixin(code));
Strangely if i put this in a templated enum that doesn't work. If instead i use a delegate literal it works. enum Compiles(string code) = is(typeof((){mixin(code);})); enum Compiles2(string code) = __traits(compiles, mixin(code));
When you do that, the code does not match the syntax of __traits(compiles). Putting the code inside a scope works at least in this case: enum Compiles2(string code) = __traits(compiles, mixin('{' ~ code ~ '}')); Ali
Dec 14 2016
parent reply Basile B. <b2.temp gmx.com> writes:
On Wednesday, 14 December 2016 at 22:06:35 UTC, Ali Çehreli wrote:
 On 12/14/2016 09:25 AM, Basile B. wrote:
 On Tuesday, 13 December 2016 at 23:37:59 UTC, Timon Gehr
wrote:
 I usually do

 enum code = q{expr};
 static if(__traits(compiles,mixin(code)))
     fun(mixin(code));
Strangely if i put this in a templated enum that doesn't work. If instead i use a delegate literal it works. enum Compiles(string code) = is(typeof((){mixin(code);})); enum Compiles2(string code) = __traits(compiles, mixin(code));
When you do that, the code does not match the syntax of __traits(compiles). Putting the code inside a scope works at least in this case: enum Compiles2(string code) = __traits(compiles, mixin('{' ~ code ~ '}')); Ali
I see, it makes sense. Anyway the two templates have a common problem (protection attributes: data used in the code must be visible to the outside), so using them as a shortcut is a false good idea.
Dec 14 2016
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 15.12.2016 01:38, Basile B. wrote:
 On Wednesday, 14 December 2016 at 22:06:35 UTC, Ali Çehreli wrote:
 On 12/14/2016 09:25 AM, Basile B. wrote:
 On Tuesday, 13 December 2016 at 23:37:59 UTC, Timon Gehr
wrote:
 I usually do

 enum code = q{expr};
 static if(__traits(compiles,mixin(code)))
     fun(mixin(code));
Strangely if i put this in a templated enum that doesn't work. If instead i use a delegate literal it works. enum Compiles(string code) = is(typeof((){mixin(code);})); enum Compiles2(string code) = __traits(compiles, mixin(code));
When you do that, the code does not match the syntax of __traits(compiles). Putting the code inside a scope works at least in this case: enum Compiles2(string code) = __traits(compiles, mixin('{' ~ code ~ '}')); Ali
I see, it makes sense. Anyway the two templates have a common problem (protection attributes: data used in the code must be visible to the outside), so using them as a shortcut is a false good idea.
Shortcut that works: enum ifCompiles(string code)=`static if(__traits(compiles,{ `~code~` })){ `~code~` }`; mixin(ifCompiles!q{ ... });
Dec 15 2016